diff options
229 files changed, 12304 insertions, 9993 deletions
diff --git a/.gitlab-ci.d/cirrus/freebsd-12.vars b/.gitlab-ci.d/cirrus/freebsd-12.vars index c3db1d7d30..e3fc3235b9 100644 --- a/.gitlab-ci.d/cirrus/freebsd-12.vars +++ b/.gitlab-ci.d/cirrus/freebsd-12.vars @@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake' NINJA='/usr/local/bin/ninja' PACKAGING_COMMAND='pkg' PIP3='/usr/local/bin/pip-3.8' -PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd' +PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy sndio spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd' PYPI_PKGS='' PYTHON='/usr/local/bin/python3' diff --git a/.gitlab-ci.d/cirrus/freebsd-13.vars b/.gitlab-ci.d/cirrus/freebsd-13.vars index d31faa787f..9f56babd9c 100644 --- a/.gitlab-ci.d/cirrus/freebsd-13.vars +++ b/.gitlab-ci.d/cirrus/freebsd-13.vars @@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake' NINJA='/usr/local/bin/ninja' PACKAGING_COMMAND='pkg' PIP3='/usr/local/bin/pip-3.8' -PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd' +PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache cdrkit-genisoimage cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson ncurses nettle ninja opencv perl5 pixman pkgconf png py39-numpy py39-pillow py39-pip py39-sphinx py39-sphinx_rtd_theme py39-yaml python3 rpm2cpio sdl2 sdl2_image snappy sndio spice-protocol tesseract texinfo usbredir virglrenderer vte3 zstd' PYPI_PKGS='' PYTHON='/usr/local/bin/python3' diff --git a/MAINTAINERS b/MAINTAINERS index 64893e36bc..c41d8d65e2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -84,7 +84,6 @@ T: git https://github.com/vivier/qemu.git trivial-patches Architecture support -------------------- S390 general architecture support -M: Cornelia Huck <cohuck@redhat.com> M: Thomas Huth <thuth@redhat.com> S: Supported F: configs/devices/s390x-softmmu/default.mak @@ -106,7 +105,6 @@ F: docs/system/target-s390x.rst F: docs/system/s390x/ F: tests/migration/s390x/ K: ^Subject:.*(?i)s390x? -T: git https://gitlab.com/cohuck/qemu.git s390-next L: qemu-s390x@nongnu.org MIPS general architecture support @@ -305,6 +303,7 @@ F: target/rx/ S390 TCG CPUs M: Richard Henderson <richard.henderson@linaro.org> M: David Hildenbrand <david@redhat.com> +R: Ilya Leoshkevich <iii@linux.ibm.com> S: Maintained F: target/s390x/ F: target/s390x/tcg @@ -2509,6 +2508,8 @@ S: Supported F: block* F: block/ F: hw/block/ +F: qapi/block*.json +F: qapi/transaction.json F: include/block/ F: include/sysemu/block-*.h F: qemu-img* @@ -2583,16 +2584,6 @@ F: include/qemu/co-shared-resource.h T: git https://gitlab.com/jsnow/qemu.git jobs T: git https://gitlab.com/vsementsov/qemu.git block -Block QAPI, monitor, command line -M: Markus Armbruster <armbru@redhat.com> -S: Supported -F: blockdev.c -F: blockdev-hmp-cmds.c -F: block/qapi.c -F: qapi/block*.json -F: qapi/transaction.json -T: git https://repo.or.cz/qemu/armbru.git block-next - Compute Express Link M: Ben Widawsky <ben.widawsky@intel.com> M: Jonathan Cameron <jonathan.cameron@huawei.com> diff --git a/accel/dummy-cpus.c b/accel/dummy-cpus.c index 10429fdfb2..d6a1b8d0a2 100644 --- a/accel/dummy-cpus.c +++ b/accel/dummy-cpus.c @@ -21,8 +21,6 @@ static void *dummy_cpu_thread_fn(void *arg) { CPUState *cpu = arg; - sigset_t waitset; - int r; rcu_register_thread(); @@ -32,8 +30,13 @@ static void *dummy_cpu_thread_fn(void *arg) cpu->can_do_io = 1; current_cpu = cpu; +#ifndef _WIN32 + sigset_t waitset; + int r; + sigemptyset(&waitset); sigaddset(&waitset, SIG_IPI); +#endif /* signal CPU creation */ cpu_thread_signal_created(cpu); @@ -41,6 +44,7 @@ static void *dummy_cpu_thread_fn(void *arg) do { qemu_mutex_unlock_iothread(); +#ifndef _WIN32 do { int sig; r = sigwait(&waitset, &sig); @@ -49,6 +53,9 @@ static void *dummy_cpu_thread_fn(void *arg) perror("sigwait"); exit(1); } +#else + qemu_sem_wait(&cpu->sem); +#endif qemu_mutex_lock_iothread(); qemu_wait_io_event(cpu); } while (!cpu->unplug); @@ -69,4 +76,7 @@ void dummy_start_vcpu_thread(CPUState *cpu) cpu->cpu_index); qemu_thread_create(cpu->thread, thread_name, dummy_cpu_thread_fn, cpu, QEMU_THREAD_JOINABLE); +#ifdef _WIN32 + qemu_sem_init(&cpu->sem, 0); +#endif } diff --git a/accel/meson.build b/accel/meson.build index b9a963cf80..259c35c4c8 100644 --- a/accel/meson.build +++ b/accel/meson.build @@ -16,5 +16,5 @@ dummy_ss.add(files( 'dummy-cpus.c', )) -specific_ss.add_all(when: ['CONFIG_SOFTMMU', 'CONFIG_POSIX'], if_true: dummy_ss) +specific_ss.add_all(when: ['CONFIG_SOFTMMU'], if_true: dummy_ss) specific_ss.add_all(when: ['CONFIG_XEN'], if_true: dummy_ss) diff --git a/accel/qtest/meson.build b/accel/qtest/meson.build index 4c65600293..176d990ae1 100644 --- a/accel/qtest/meson.build +++ b/accel/qtest/meson.build @@ -1,2 +1 @@ -qtest_module_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_POSIX'], - if_true: files('qtest.c')) +qtest_module_ss.add(when: ['CONFIG_SOFTMMU'], if_true: files('qtest.c')) diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c index 5443a59153..f9c5867e38 100644 --- a/backends/cryptodev-vhost-user.c +++ b/backends/cryptodev-vhost-user.c @@ -339,7 +339,7 @@ static void cryptodev_vhost_user_set_chardev(Object *obj, CRYPTODEV_BACKEND_VHOST_USER(obj); if (s->opened) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property 'chardev' can no longer be set"); } else { g_free(s->chr_name); s->chr_name = g_strdup(value); diff --git a/backends/hostmem.c b/backends/hostmem.c index 4428e06738..8640294c10 100644 --- a/backends/hostmem.c +++ b/backends/hostmem.c @@ -232,7 +232,8 @@ static void host_memory_backend_set_prealloc(Object *obj, bool value, void *ptr = memory_region_get_ram_ptr(&backend->mr); uint64_t sz = memory_region_size(&backend->mr); - os_mem_prealloc(fd, ptr, sz, backend->prealloc_threads, &local_err); + qemu_prealloc_mem(fd, ptr, sz, backend->prealloc_threads, + backend->prealloc_context, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -383,8 +384,9 @@ host_memory_backend_memory_complete(UserCreatable *uc, Error **errp) * specified NUMA policy in place. */ if (backend->prealloc) { - os_mem_prealloc(memory_region_get_fd(&backend->mr), ptr, sz, - backend->prealloc_threads, &local_err); + qemu_prealloc_mem(memory_region_get_fd(&backend->mr), ptr, sz, + backend->prealloc_threads, + backend->prealloc_context, &local_err); if (local_err) { goto out; } @@ -492,6 +494,11 @@ host_memory_backend_class_init(ObjectClass *oc, void *data) NULL, NULL); object_class_property_set_description(oc, "prealloc-threads", "Number of CPU threads to use for prealloc"); + object_class_property_add_link(oc, "prealloc-context", + TYPE_THREAD_CONTEXT, offsetof(HostMemoryBackend, prealloc_context), + object_property_allow_set_link, OBJ_PROP_LINK_STRONG); + object_class_property_set_description(oc, "prealloc-context", + "Context to use for creating CPU threads for preallocation"); object_class_property_add(oc, "size", "int", host_memory_backend_get_size, host_memory_backend_set_size, diff --git a/backends/rng-egd.c b/backends/rng-egd.c index 4de142b9dc..684c3cf3d6 100644 --- a/backends/rng-egd.c +++ b/backends/rng-egd.c @@ -116,7 +116,7 @@ static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp) RngEgd *s = RNG_EGD(b); if (b->opened) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property 'chardev' can no longer be set"); } else { g_free(s->chr_name); s->chr_name = g_strdup(value); diff --git a/backends/rng-random.c b/backends/rng-random.c index 7add272edd..80eb5be138 100644 --- a/backends/rng-random.c +++ b/backends/rng-random.c @@ -96,7 +96,7 @@ static void rng_random_set_filename(Object *obj, const char *filename, RngRandom *s = RNG_RANDOM(obj); if (b->opened) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property 'filename' can no longer be set"); return; } diff --git a/backends/vhost-user.c b/backends/vhost-user.c index 10b39992d2..5dedb2d987 100644 --- a/backends/vhost-user.c +++ b/backends/vhost-user.c @@ -141,7 +141,7 @@ static void set_chardev(Object *obj, const char *value, Error **errp) Chardev *chr; if (b->completed) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property 'chardev' can no longer be set"); return; } @@ -90,13 +90,9 @@ static BlockDriverState *bdrv_open_inherit(const char *filename, static bool bdrv_recurse_has_child(BlockDriverState *bs, BlockDriverState *child); -static void bdrv_child_free(BdrvChild *child); -static void bdrv_replace_child_noperm(BdrvChild **child, - BlockDriverState *new_bs, - bool free_empty_child); -static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, - BdrvChild *child, - Transaction *tran); +static void bdrv_replace_child_noperm(BdrvChild *child, + BlockDriverState *new_bs); +static void bdrv_remove_child(BdrvChild *child, Transaction *tran); static void bdrv_remove_filter_or_cow_child(BlockDriverState *bs, Transaction *tran); @@ -108,6 +104,10 @@ static void bdrv_reopen_abort(BDRVReopenState *reopen_state); static bool bdrv_backing_overridden(BlockDriverState *bs); +static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp); + /* If non-zero, use only whitelisted block drivers */ static int use_bdrv_whitelist; @@ -643,7 +643,7 @@ create_file_fallback_zero_first_sector(BlockBackend *blk, bytes_to_clear = MIN(current_size, BDRV_SECTOR_SIZE); if (bytes_to_clear) { - ret = blk_pwrite_zeroes(blk, 0, bytes_to_clear, BDRV_REQ_MAY_UNMAP); + ret = blk_co_pwrite_zeroes(blk, 0, bytes_to_clear, BDRV_REQ_MAY_UNMAP); if (ret < 0) { error_setg_errno(errp, -ret, "Failed to clear the new image's first sector"); @@ -861,38 +861,42 @@ int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo) /* * Create a uniquely-named empty temporary file. - * Return 0 upon success, otherwise a negative errno value. + * Return the actual file name used upon success, otherwise NULL. + * This string should be freed with g_free() when not needed any longer. + * + * Note: creating a temporary file for the caller to (re)open is + * inherently racy. Use g_file_open_tmp() instead whenever practical. */ -int get_tmp_filename(char *filename, int size) +char *create_tmp_file(Error **errp) { -#ifdef _WIN32 - char temp_dir[MAX_PATH]; - /* GetTempFileName requires that its output buffer (4th param) - have length MAX_PATH or greater. */ - assert(size >= MAX_PATH); - return (GetTempPath(MAX_PATH, temp_dir) - && GetTempFileName(temp_dir, "qem", 0, filename) - ? 0 : -GetLastError()); -#else int fd; const char *tmpdir; - tmpdir = getenv("TMPDIR"); - if (!tmpdir) { + g_autofree char *filename = NULL; + + tmpdir = g_get_tmp_dir(); +#ifndef _WIN32 + /* + * See commit 69bef79 ("block: use /var/tmp instead of /tmp for -snapshot") + * + * This function is used to create temporary disk images (like -snapshot), + * so the files can become very large. /tmp is often a tmpfs where as + * /var/tmp is usually on a disk, so more appropriate for disk images. + */ + if (!g_strcmp0(tmpdir, "/tmp")) { tmpdir = "/var/tmp"; } - if (snprintf(filename, size, "%s/vl.XXXXXX", tmpdir) >= size) { - return -EOVERFLOW; - } - fd = mkstemp(filename); +#endif + + filename = g_strdup_printf("%s/vl.XXXXXX", tmpdir); + fd = g_mkstemp(filename); if (fd < 0) { - return -errno; - } - if (close(fd) != 0) { - unlink(filename); - return -errno; + error_setg_errno(errp, errno, "Could not open temporary file '%s'", + filename); + return NULL; } - return 0; -#endif + close(fd); + + return g_steal_pointer(&filename); } /* @@ -1238,18 +1242,12 @@ static int bdrv_child_cb_inactivate(BdrvChild *child) return 0; } -static bool bdrv_child_cb_can_set_aio_ctx(BdrvChild *child, AioContext *ctx, - GSList **ignore, Error **errp) -{ - BlockDriverState *bs = child->opaque; - return bdrv_can_set_aio_context(bs, ctx, ignore, errp); -} - -static void bdrv_child_cb_set_aio_ctx(BdrvChild *child, AioContext *ctx, - GSList **ignore) +static bool bdrv_child_cb_change_aio_ctx(BdrvChild *child, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp) { BlockDriverState *bs = child->opaque; - return bdrv_set_aio_context_ignore(bs, ctx, ignore); + return bdrv_change_aio_context(bs, ctx, visited, tran, errp); } /* @@ -1443,9 +1441,39 @@ static void bdrv_child_cb_attach(BdrvChild *child) assert_bdrv_graph_writable(bs); QLIST_INSERT_HEAD(&bs->children, child, next); - - if (child->role & BDRV_CHILD_COW) { + if (bs->drv->is_filter || (child->role & BDRV_CHILD_FILTERED)) { + /* + * Here we handle filters and block/raw-format.c when it behave like + * filter. They generally have a single PRIMARY child, which is also the + * FILTERED child, and that they may have multiple more children, which + * are neither PRIMARY nor FILTERED. And never we have a COW child here. + * So bs->file will be the PRIMARY child, unless the PRIMARY child goes + * into bs->backing on exceptional cases; and bs->backing will be + * nothing else. + */ + assert(!(child->role & BDRV_CHILD_COW)); + if (child->role & BDRV_CHILD_PRIMARY) { + assert(child->role & BDRV_CHILD_FILTERED); + assert(!bs->backing); + assert(!bs->file); + + if (bs->drv->filtered_child_is_backing) { + bs->backing = child; + } else { + bs->file = child; + } + } else { + assert(!(child->role & BDRV_CHILD_FILTERED)); + } + } else if (child->role & BDRV_CHILD_COW) { + assert(bs->drv->supports_backing); + assert(!(child->role & BDRV_CHILD_PRIMARY)); + assert(!bs->backing); + bs->backing = child; bdrv_backing_attach(child); + } else if (child->role & BDRV_CHILD_PRIMARY) { + assert(!bs->file); + bs->file = child; } bdrv_apply_subtree_drain(child, bs); @@ -1463,6 +1491,12 @@ static void bdrv_child_cb_detach(BdrvChild *child) assert_bdrv_graph_writable(bs); QLIST_REMOVE(child, next); + if (child == bs->backing) { + assert(child != bs->file); + bs->backing = NULL; + } else if (child == bs->file) { + bs->file = NULL; + } } static int bdrv_child_cb_update_filename(BdrvChild *c, BlockDriverState *base, @@ -1492,8 +1526,7 @@ const BdrvChildClass child_of_bds = { .attach = bdrv_child_cb_attach, .detach = bdrv_child_cb_detach, .inactivate = bdrv_child_cb_inactivate, - .can_set_aio_ctx = bdrv_child_cb_can_set_aio_ctx, - .set_aio_ctx = bdrv_child_cb_set_aio_ctx, + .change_aio_ctx = bdrv_child_cb_change_aio_ctx, .update_filename = bdrv_child_cb_update_filename, .get_parent_aio_context = child_of_bds_get_parent_aio_context, }; @@ -1682,7 +1715,7 @@ open_failed: bs->drv = NULL; if (bs->file != NULL) { bdrv_unref_child(bs, bs->file); - bs->file = NULL; + assert(!bs->file); } g_free(bs->opaque); bs->opaque = NULL; @@ -2353,9 +2386,7 @@ static int bdrv_drv_set_perm(BlockDriverState *bs, uint64_t perm, typedef struct BdrvReplaceChildState { BdrvChild *child; - BdrvChild **childp; BlockDriverState *old_bs; - bool free_empty_child; } BdrvReplaceChildState; static void bdrv_replace_child_commit(void *opaque) @@ -2363,9 +2394,6 @@ static void bdrv_replace_child_commit(void *opaque) BdrvReplaceChildState *s = opaque; GLOBAL_STATE_CODE(); - if (s->free_empty_child && !s->child->bs) { - bdrv_child_free(s->child); - } bdrv_unref(s->old_bs); } @@ -2375,34 +2403,8 @@ static void bdrv_replace_child_abort(void *opaque) BlockDriverState *new_bs = s->child->bs; GLOBAL_STATE_CODE(); - /* - * old_bs reference is transparently moved from @s to s->child. - * - * Pass &s->child here instead of s->childp, because: - * (1) s->old_bs must be non-NULL, so bdrv_replace_child_noperm() will not - * modify the BdrvChild * pointer we indirectly pass to it, i.e. it - * will not modify s->child. From that perspective, it does not matter - * whether we pass s->childp or &s->child. - * (2) If new_bs is not NULL, s->childp will be NULL. We then cannot use - * it here. - * (3) If new_bs is NULL, *s->childp will have been NULLed by - * bdrv_replace_child_tran()'s bdrv_replace_child_noperm() call, and we - * must not pass a NULL *s->childp here. - * - * So whether new_bs was NULL or not, we cannot pass s->childp here; and in - * any case, there is no reason to pass it anyway. - */ - bdrv_replace_child_noperm(&s->child, s->old_bs, true); - /* - * The child was pre-existing, so s->old_bs must be non-NULL, and - * s->child thus must not have been freed - */ - assert(s->child != NULL); - if (!new_bs) { - /* As described above, *s->childp was cleared, so restore it */ - assert(s->childp != NULL); - *s->childp = s->child; - } + /* old_bs reference is transparently moved from @s to @s->child */ + bdrv_replace_child_noperm(s->child, s->old_bs); bdrv_unref(new_bs); } @@ -2418,46 +2420,22 @@ static TransactionActionDrv bdrv_replace_child_drv = { * Note: real unref of old_bs is done only on commit. * * The function doesn't update permissions, caller is responsible for this. - * - * (*childp)->bs must not be NULL. - * - * Note that if new_bs == NULL, @childp is stored in a state object attached - * to @tran, so that the old child can be reinstated in the abort handler. - * Therefore, if @new_bs can be NULL, @childp must stay valid until the - * transaction is committed or aborted. - * - * If @free_empty_child is true and @new_bs is NULL, the BdrvChild is - * freed (on commit). @free_empty_child should only be false if the - * caller will free the BDrvChild themselves (which may be important - * if this is in turn called in another transactional context). */ -static void bdrv_replace_child_tran(BdrvChild **childp, - BlockDriverState *new_bs, - Transaction *tran, - bool free_empty_child) +static void bdrv_replace_child_tran(BdrvChild *child, BlockDriverState *new_bs, + Transaction *tran) { BdrvReplaceChildState *s = g_new(BdrvReplaceChildState, 1); *s = (BdrvReplaceChildState) { - .child = *childp, - .childp = new_bs == NULL ? childp : NULL, - .old_bs = (*childp)->bs, - .free_empty_child = free_empty_child, + .child = child, + .old_bs = child->bs, }; tran_add(tran, &bdrv_replace_child_drv, s); - /* The abort handler relies on this */ - assert(s->old_bs != NULL); - if (new_bs) { bdrv_ref(new_bs); } - /* - * Pass free_empty_child=false, we will free the child (if - * necessary) in bdrv_replace_child_commit() (if our - * @free_empty_child parameter was true). - */ - bdrv_replace_child_noperm(childp, new_bs, false); - /* old_bs reference is transparently moved from *childp to @s */ + bdrv_replace_child_noperm(child, new_bs); + /* old_bs reference is transparently moved from @child to @s */ } /* @@ -2838,24 +2816,9 @@ uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm) return permissions[qapi_perm]; } -/** - * Replace (*childp)->bs by @new_bs. - * - * If @new_bs is NULL, *childp will be set to NULL, too: BDS parents - * generally cannot handle a BdrvChild with .bs == NULL, so clearing - * BdrvChild.bs should generally immediately be followed by the - * BdrvChild pointer being cleared as well. - * - * If @free_empty_child is true and @new_bs is NULL, the BdrvChild is - * freed. @free_empty_child should only be false if the caller will - * free the BdrvChild themselves (this may be important in a - * transactional context, where it may only be freed on commit). - */ -static void bdrv_replace_child_noperm(BdrvChild **childp, - BlockDriverState *new_bs, - bool free_empty_child) +static void bdrv_replace_child_noperm(BdrvChild *child, + BlockDriverState *new_bs) { - BdrvChild *child = *childp; BlockDriverState *old_bs = child->bs; int new_bs_quiesce_counter; int drain_saldo; @@ -2892,9 +2855,6 @@ static void bdrv_replace_child_noperm(BdrvChild **childp, } child->bs = new_bs; - if (!new_bs) { - *childp = NULL; - } if (new_bs) { assert_bdrv_graph_writable(new_bs); @@ -2925,10 +2885,6 @@ static void bdrv_replace_child_noperm(BdrvChild **childp, bdrv_parent_drained_end_single(child); drain_saldo++; } - - if (free_empty_child && !child->bs) { - bdrv_child_free(child); - } } /** @@ -2948,7 +2904,7 @@ static void bdrv_child_free(BdrvChild *child) } typedef struct BdrvAttachChildCommonState { - BdrvChild **child; + BdrvChild *child; AioContext *old_parent_ctx; AioContext *old_child_ctx; } BdrvAttachChildCommonState; @@ -2956,39 +2912,35 @@ typedef struct BdrvAttachChildCommonState { static void bdrv_attach_child_common_abort(void *opaque) { BdrvAttachChildCommonState *s = opaque; - BdrvChild *child = *s->child; - BlockDriverState *bs = child->bs; + BlockDriverState *bs = s->child->bs; GLOBAL_STATE_CODE(); - /* - * Pass free_empty_child=false, because we still need the child - * for the AioContext operations on the parent below; those - * BdrvChildClass methods all work on a BdrvChild object, so we - * need to keep it as an empty shell (after this function, it will - * not be attached to any parent, and it will not have a .bs). - */ - bdrv_replace_child_noperm(s->child, NULL, false); + bdrv_replace_child_noperm(s->child, NULL); if (bdrv_get_aio_context(bs) != s->old_child_ctx) { - bdrv_try_set_aio_context(bs, s->old_child_ctx, &error_abort); + bdrv_try_change_aio_context(bs, s->old_child_ctx, NULL, &error_abort); } - if (bdrv_child_get_parent_aio_context(child) != s->old_parent_ctx) { - GSList *ignore; + if (bdrv_child_get_parent_aio_context(s->child) != s->old_parent_ctx) { + Transaction *tran; + GHashTable *visited; + bool ret; - /* No need to ignore `child`, because it has been detached already */ - ignore = NULL; - child->klass->can_set_aio_ctx(child, s->old_parent_ctx, &ignore, - &error_abort); - g_slist_free(ignore); + tran = tran_new(); - ignore = NULL; - child->klass->set_aio_ctx(child, s->old_parent_ctx, &ignore); - g_slist_free(ignore); + /* No need to visit `child`, because it has been detached already */ + visited = g_hash_table_new(NULL, NULL); + ret = s->child->klass->change_aio_ctx(s->child, s->old_parent_ctx, + visited, tran, &error_abort); + g_hash_table_destroy(visited); + + /* transaction is supposed to always succeed */ + assert(ret == true); + tran_commit(tran); } bdrv_unref(bs); - bdrv_child_free(child); + bdrv_child_free(s->child); } static TransactionActionDrv bdrv_attach_child_common_drv = { @@ -2999,28 +2951,22 @@ static TransactionActionDrv bdrv_attach_child_common_drv = { /* * Common part of attaching bdrv child to bs or to blk or to job * - * Resulting new child is returned through @child. - * At start *@child must be NULL. - * @child is saved to a new entry of @tran, so that *@child could be reverted to - * NULL on abort(). So referenced variable must live at least until transaction - * end. - * * Function doesn't update permissions, caller is responsible for this. + * + * Returns new created child. */ -static int bdrv_attach_child_common(BlockDriverState *child_bs, - const char *child_name, - const BdrvChildClass *child_class, - BdrvChildRole child_role, - uint64_t perm, uint64_t shared_perm, - void *opaque, BdrvChild **child, - Transaction *tran, Error **errp) +static BdrvChild *bdrv_attach_child_common(BlockDriverState *child_bs, + const char *child_name, + const BdrvChildClass *child_class, + BdrvChildRole child_role, + uint64_t perm, uint64_t shared_perm, + void *opaque, + Transaction *tran, Error **errp) { BdrvChild *new_child; AioContext *parent_ctx; AioContext *child_ctx = bdrv_get_aio_context(child_bs); - assert(child); - assert(*child == NULL); assert(child_class->get_parent_desc); GLOBAL_STATE_CODE(); @@ -3043,63 +2989,57 @@ static int bdrv_attach_child_common(BlockDriverState *child_bs, parent_ctx = bdrv_child_get_parent_aio_context(new_child); if (child_ctx != parent_ctx) { Error *local_err = NULL; - int ret = bdrv_try_set_aio_context(child_bs, parent_ctx, &local_err); - - if (ret < 0 && child_class->can_set_aio_ctx) { - GSList *ignore = g_slist_prepend(NULL, new_child); - if (child_class->can_set_aio_ctx(new_child, child_ctx, &ignore, - NULL)) - { + int ret = bdrv_try_change_aio_context(child_bs, parent_ctx, NULL, + &local_err); + + if (ret < 0 && child_class->change_aio_ctx) { + Transaction *tran = tran_new(); + GHashTable *visited = g_hash_table_new(NULL, NULL); + bool ret_child; + + g_hash_table_add(visited, new_child); + ret_child = child_class->change_aio_ctx(new_child, child_ctx, + visited, tran, NULL); + if (ret_child == true) { error_free(local_err); ret = 0; - g_slist_free(ignore); - ignore = g_slist_prepend(NULL, new_child); - child_class->set_aio_ctx(new_child, child_ctx, &ignore); } - g_slist_free(ignore); + tran_finalize(tran, ret_child == true ? 0 : -1); + g_hash_table_destroy(visited); } if (ret < 0) { error_propagate(errp, local_err); bdrv_child_free(new_child); - return ret; + return NULL; } } bdrv_ref(child_bs); - bdrv_replace_child_noperm(&new_child, child_bs, true); - /* child_bs was non-NULL, so new_child must not have been freed */ - assert(new_child != NULL); - - *child = new_child; + bdrv_replace_child_noperm(new_child, child_bs); BdrvAttachChildCommonState *s = g_new(BdrvAttachChildCommonState, 1); *s = (BdrvAttachChildCommonState) { - .child = child, + .child = new_child, .old_parent_ctx = parent_ctx, .old_child_ctx = child_ctx, }; tran_add(tran, &bdrv_attach_child_common_drv, s); - return 0; + return new_child; } /* - * Variable referenced by @child must live at least until transaction end. - * (see bdrv_attach_child_common() doc for details) - * * Function doesn't update permissions, caller is responsible for this. */ -static int bdrv_attach_child_noperm(BlockDriverState *parent_bs, - BlockDriverState *child_bs, - const char *child_name, - const BdrvChildClass *child_class, - BdrvChildRole child_role, - BdrvChild **child, - Transaction *tran, - Error **errp) +static BdrvChild *bdrv_attach_child_noperm(BlockDriverState *parent_bs, + BlockDriverState *child_bs, + const char *child_name, + const BdrvChildClass *child_class, + BdrvChildRole child_role, + Transaction *tran, + Error **errp) { - int ret; uint64_t perm, shared_perm; assert(parent_bs->drv); @@ -3108,29 +3048,25 @@ static int bdrv_attach_child_noperm(BlockDriverState *parent_bs, if (bdrv_recurse_has_child(child_bs, parent_bs)) { error_setg(errp, "Making '%s' a %s child of '%s' would create a cycle", child_bs->node_name, child_name, parent_bs->node_name); - return -EINVAL; + return NULL; } bdrv_get_cumulative_perm(parent_bs, &perm, &shared_perm); bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL, perm, shared_perm, &perm, &shared_perm); - ret = bdrv_attach_child_common(child_bs, child_name, child_class, - child_role, perm, shared_perm, parent_bs, - child, tran, errp); - if (ret < 0) { - return ret; - } - - return 0; + return bdrv_attach_child_common(child_bs, child_name, child_class, + child_role, perm, shared_perm, parent_bs, + tran, errp); } -static void bdrv_detach_child(BdrvChild **childp) +static void bdrv_detach_child(BdrvChild *child) { - BlockDriverState *old_bs = (*childp)->bs; + BlockDriverState *old_bs = child->bs; GLOBAL_STATE_CODE(); - bdrv_replace_child_noperm(childp, NULL, true); + bdrv_replace_child_noperm(child, NULL); + bdrv_child_free(child); if (old_bs) { /* @@ -3144,7 +3080,7 @@ static void bdrv_detach_child(BdrvChild **childp) * When the parent requiring a non-default AioContext is removed, the * node moves back to the main AioContext */ - bdrv_try_set_aio_context(old_bs, qemu_get_aio_context(), NULL); + bdrv_try_change_aio_context(old_bs, qemu_get_aio_context(), NULL, NULL); } } @@ -3166,15 +3102,16 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs, void *opaque, Error **errp) { int ret; - BdrvChild *child = NULL; + BdrvChild *child; Transaction *tran = tran_new(); GLOBAL_STATE_CODE(); - ret = bdrv_attach_child_common(child_bs, child_name, child_class, + child = bdrv_attach_child_common(child_bs, child_name, child_class, child_role, perm, shared_perm, opaque, - &child, tran, errp); - if (ret < 0) { + tran, errp); + if (!child) { + ret = -EINVAL; goto out; } @@ -3182,11 +3119,10 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs, out: tran_finalize(tran, ret); - /* child is unset on failure by bdrv_attach_child_common_abort() */ - assert((ret < 0) == !child); bdrv_unref(child_bs); - return child; + + return ret < 0 ? NULL : child; } /* @@ -3208,14 +3144,15 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, Error **errp) { int ret; - BdrvChild *child = NULL; + BdrvChild *child; Transaction *tran = tran_new(); GLOBAL_STATE_CODE(); - ret = bdrv_attach_child_noperm(parent_bs, child_bs, child_name, child_class, - child_role, &child, tran, errp); - if (ret < 0) { + child = bdrv_attach_child_noperm(parent_bs, child_bs, child_name, + child_class, child_role, tran, errp); + if (!child) { + ret = -EINVAL; goto out; } @@ -3226,12 +3163,10 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, out: tran_finalize(tran, ret); - /* child is unset on failure by bdrv_attach_child_common_abort() */ - assert((ret < 0) == !child); bdrv_unref(child_bs); - return child; + return ret < 0 ? NULL : child; } /* Callers must ensure that child->frozen is false. */ @@ -3242,7 +3177,7 @@ void bdrv_root_unref_child(BdrvChild *child) GLOBAL_STATE_CODE(); child_bs = child->bs; - bdrv_detach_child(&child); + bdrv_detach_child(child); bdrv_unref(child_bs); } @@ -3373,7 +3308,6 @@ static int bdrv_set_file_or_backing_noperm(BlockDriverState *parent_bs, bool is_backing, Transaction *tran, Error **errp) { - int ret = 0; bool update_inherits_from = bdrv_inherits_from_recursive(child_bs, parent_bs); BdrvChild *child = is_backing ? parent_bs->backing : parent_bs->file; @@ -3424,21 +3358,19 @@ static int bdrv_set_file_or_backing_noperm(BlockDriverState *parent_bs, if (child) { bdrv_unset_inherits_from(parent_bs, child, tran); - bdrv_remove_file_or_backing_child(parent_bs, child, tran); + bdrv_remove_child(child, tran); } if (!child_bs) { goto out; } - ret = bdrv_attach_child_noperm(parent_bs, child_bs, - is_backing ? "backing" : "file", - &child_of_bds, role, - is_backing ? &parent_bs->backing : - &parent_bs->file, - tran, errp); - if (ret < 0) { - return ret; + child = bdrv_attach_child_noperm(parent_bs, child_bs, + is_backing ? "backing" : "file", + &child_of_bds, role, + tran, errp); + if (!child) { + return -EINVAL; } @@ -3684,6 +3616,29 @@ BdrvChild *bdrv_open_child(const char *filename, } /* + * Wrapper on bdrv_open_child() for most popular case: open primary child of bs. + */ +int bdrv_open_file_child(const char *filename, + QDict *options, const char *bdref_key, + BlockDriverState *parent, Error **errp) +{ + BdrvChildRole role; + + /* commit_top and mirror_top don't use this function */ + assert(!parent->drv->filtered_child_is_backing); + role = parent->drv->is_filter ? + (BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE; + + if (!bdrv_open_child(filename, options, bdref_key, parent, + &child_of_bds, role, false, errp)) + { + return -EINVAL; + } + + return 0; +} + +/* * TODO Future callers may need to specify parent/child_class in order for * option inheritance to work. Existing callers use it for the root node. */ @@ -3732,8 +3687,7 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs, QDict *snapshot_options, Error **errp) { - /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ - char *tmp_filename = g_malloc0(PATH_MAX + 1); + g_autofree char *tmp_filename = NULL; int64_t total_size; QemuOpts *opts = NULL; BlockDriverState *bs_snapshot = NULL; @@ -3752,9 +3706,8 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs, } /* Create the temporary image */ - ret = get_tmp_filename(tmp_filename, PATH_MAX + 1); - if (ret < 0) { - error_setg_errno(errp, -ret, "Could not get temporary filename"); + tmp_filename = create_tmp_file(errp); + if (!tmp_filename) { goto out; } @@ -3788,7 +3741,6 @@ static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs, out: qobject_unref(snapshot_options); - g_free(tmp_filename); return bs_snapshot; } @@ -4955,8 +4907,8 @@ static void bdrv_close(BlockDriverState *bs) bdrv_unref_child(bs, child); } - bs->backing = NULL; - bs->file = NULL; + assert(!bs->backing); + assert(!bs->file); g_free(bs->opaque); bs->opaque = NULL; qatomic_set(&bs->copy_on_read, 0); @@ -5087,96 +5039,28 @@ static bool should_update_child(BdrvChild *c, BlockDriverState *to) return ret; } -typedef struct BdrvRemoveFilterOrCowChild { - BdrvChild *child; - BlockDriverState *bs; - bool is_backing; -} BdrvRemoveFilterOrCowChild; - -static void bdrv_remove_filter_or_cow_child_abort(void *opaque) +static void bdrv_remove_child_commit(void *opaque) { - BdrvRemoveFilterOrCowChild *s = opaque; - BlockDriverState *parent_bs = s->child->opaque; - - if (s->is_backing) { - parent_bs->backing = s->child; - } else { - parent_bs->file = s->child; - } - - /* - * We don't have to restore child->bs here to undo bdrv_replace_child_tran() - * because that function is transactionable and it registered own completion - * entries in @tran, so .abort() for bdrv_replace_child_safe() will be - * called automatically. - */ -} - -static void bdrv_remove_filter_or_cow_child_commit(void *opaque) -{ - BdrvRemoveFilterOrCowChild *s = opaque; GLOBAL_STATE_CODE(); - bdrv_child_free(s->child); -} - -static void bdrv_remove_filter_or_cow_child_clean(void *opaque) -{ - BdrvRemoveFilterOrCowChild *s = opaque; - - /* Drop the bs reference after the transaction is done */ - bdrv_unref(s->bs); - g_free(s); + bdrv_child_free(opaque); } -static TransactionActionDrv bdrv_remove_filter_or_cow_child_drv = { - .abort = bdrv_remove_filter_or_cow_child_abort, - .commit = bdrv_remove_filter_or_cow_child_commit, - .clean = bdrv_remove_filter_or_cow_child_clean, +static TransactionActionDrv bdrv_remove_child_drv = { + .commit = bdrv_remove_child_commit, }; -/* - * A function to remove backing or file child of @bs. - * Function doesn't update permissions, caller is responsible for this. - */ -static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, - BdrvChild *child, - Transaction *tran) +/* Function doesn't update permissions, caller is responsible for this. */ +static void bdrv_remove_child(BdrvChild *child, Transaction *tran) { - BdrvChild **childp; - BdrvRemoveFilterOrCowChild *s; - if (!child) { return; } - /* - * Keep a reference to @bs so @childp will stay valid throughout the - * transaction (required by bdrv_replace_child_tran()) - */ - bdrv_ref(bs); - if (child == bs->backing) { - childp = &bs->backing; - } else if (child == bs->file) { - childp = &bs->file; - } else { - g_assert_not_reached(); - } - if (child->bs) { - /* - * Pass free_empty_child=false, we will free the child in - * bdrv_remove_filter_or_cow_child_commit() - */ - bdrv_replace_child_tran(childp, NULL, tran, false); + bdrv_replace_child_tran(child, NULL, tran); } - s = g_new(BdrvRemoveFilterOrCowChild, 1); - *s = (BdrvRemoveFilterOrCowChild) { - .child = child, - .bs = bs, - .is_backing = (childp == &bs->backing), - }; - tran_add(tran, &bdrv_remove_filter_or_cow_child_drv, s); + tran_add(tran, &bdrv_remove_child_drv, child); } /* @@ -5187,7 +5071,7 @@ static void bdrv_remove_file_or_backing_child(BlockDriverState *bs, static void bdrv_remove_filter_or_cow_child(BlockDriverState *bs, Transaction *tran) { - bdrv_remove_file_or_backing_child(bs, bdrv_filter_or_cow_child(bs), tran); + bdrv_remove_child(bdrv_filter_or_cow_child(bs), tran); } static int bdrv_replace_node_noperm(BlockDriverState *from, @@ -5197,7 +5081,6 @@ static int bdrv_replace_node_noperm(BlockDriverState *from, { BdrvChild *c, *next; - assert(to != NULL); GLOBAL_STATE_CODE(); QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) { @@ -5215,12 +5098,7 @@ static int bdrv_replace_node_noperm(BlockDriverState *from, c->name, from->node_name); return -EPERM; } - - /* - * Passing a pointer to the local variable @c is fine here, because - * @to is not NULL, and so &c will not be attached to the transaction. - */ - bdrv_replace_child_tran(&c, to, tran, true); + bdrv_replace_child_tran(c, to, tran); } return 0; @@ -5235,8 +5113,6 @@ static int bdrv_replace_node_noperm(BlockDriverState *from, * * With @detach_subchain=true @to must be in a backing chain of @from. In this * case backing link of the cow-parent of @to is removed. - * - * @to must not be NULL. */ static int bdrv_replace_node_common(BlockDriverState *from, BlockDriverState *to, @@ -5250,7 +5126,6 @@ static int bdrv_replace_node_common(BlockDriverState *from, int ret; GLOBAL_STATE_CODE(); - assert(to != NULL); if (detach_subchain) { assert(bdrv_chain_contains(from, to)); @@ -5307,9 +5182,6 @@ out: return ret; } -/** - * Replace node @from by @to (where neither may be NULL). - */ int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to, Error **errp) { @@ -5342,16 +5214,18 @@ int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top, Error **errp) { int ret; + BdrvChild *child; Transaction *tran = tran_new(); GLOBAL_STATE_CODE(); assert(!bs_new->backing); - ret = bdrv_attach_child_noperm(bs_new, bs_top, "backing", - &child_of_bds, bdrv_backing_role(bs_new), - &bs_new->backing, tran, errp); - if (ret < 0) { + child = bdrv_attach_child_noperm(bs_new, bs_top, "backing", + &child_of_bds, bdrv_backing_role(bs_new), + tran, errp); + if (!child) { + ret = -EINVAL; goto out; } @@ -5385,9 +5259,7 @@ int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs, bdrv_drained_begin(old_bs); bdrv_drained_begin(new_bs); - bdrv_replace_child_tran(&child, new_bs, tran, true); - /* @new_bs must have been non-NULL, so @child must not have been freed */ - assert(child != NULL); + bdrv_replace_child_tran(child, new_bs, tran); found = g_hash_table_new(NULL, NULL); refresh_list = bdrv_topological_dfs(refresh_list, found, old_bs); @@ -7299,6 +7171,7 @@ static void bdrv_detach_aio_context(BlockDriverState *bs) if (bs->quiesce_counter) { aio_enable_external(bs->aio_context); } + assert_bdrv_graph_writable(bs); bs->aio_context = NULL; } @@ -7312,6 +7185,7 @@ static void bdrv_attach_aio_context(BlockDriverState *bs, aio_disable_external(new_context); } + assert_bdrv_graph_writable(bs); bs->aio_context = new_context; if (bs->drv && bs->drv->bdrv_attach_aio_context) { @@ -7330,191 +7204,222 @@ static void bdrv_attach_aio_context(BlockDriverState *bs, bs->walking_aio_notifiers = false; } -/* - * Changes the AioContext used for fd handlers, timers, and BHs by this - * BlockDriverState and all its children and parents. - * - * Must be called from the main AioContext. - * - * The caller must own the AioContext lock for the old AioContext of bs, but it - * must not own the AioContext lock for new_context (unless new_context is the - * same as the current context of bs). - * - * @ignore will accumulate all visited BdrvChild object. The caller is - * responsible for freeing the list afterwards. - */ -void bdrv_set_aio_context_ignore(BlockDriverState *bs, - AioContext *new_context, GSList **ignore) -{ - AioContext *old_context = bdrv_get_aio_context(bs); - GSList *children_to_process = NULL; - GSList *parents_to_process = NULL; - GSList *entry; - BdrvChild *child, *parent; - - g_assert(qemu_get_current_aio_context() == qemu_get_aio_context()); - GLOBAL_STATE_CODE(); - - if (old_context == new_context) { - return; - } - - bdrv_drained_begin(bs); - - QLIST_FOREACH(child, &bs->children, next) { - if (g_slist_find(*ignore, child)) { - continue; - } - *ignore = g_slist_prepend(*ignore, child); - children_to_process = g_slist_prepend(children_to_process, child); - } - - QLIST_FOREACH(parent, &bs->parents, next_parent) { - if (g_slist_find(*ignore, parent)) { - continue; - } - *ignore = g_slist_prepend(*ignore, parent); - parents_to_process = g_slist_prepend(parents_to_process, parent); - } - - for (entry = children_to_process; - entry != NULL; - entry = g_slist_next(entry)) { - child = entry->data; - bdrv_set_aio_context_ignore(child->bs, new_context, ignore); - } - g_slist_free(children_to_process); - - for (entry = parents_to_process; - entry != NULL; - entry = g_slist_next(entry)) { - parent = entry->data; - assert(parent->klass->set_aio_ctx); - parent->klass->set_aio_ctx(parent, new_context, ignore); - } - g_slist_free(parents_to_process); - - bdrv_detach_aio_context(bs); - - /* Acquire the new context, if necessary */ - if (qemu_get_aio_context() != new_context) { - aio_context_acquire(new_context); - } - - bdrv_attach_aio_context(bs, new_context); - - /* - * If this function was recursively called from - * bdrv_set_aio_context_ignore(), there may be nodes in the - * subtree that have not yet been moved to the new AioContext. - * Release the old one so bdrv_drained_end() can poll them. - */ - if (qemu_get_aio_context() != old_context) { - aio_context_release(old_context); - } - - bdrv_drained_end(bs); - - if (qemu_get_aio_context() != old_context) { - aio_context_acquire(old_context); - } - if (qemu_get_aio_context() != new_context) { - aio_context_release(new_context); - } -} +typedef struct BdrvStateSetAioContext { + AioContext *new_ctx; + BlockDriverState *bs; +} BdrvStateSetAioContext; -static bool bdrv_parent_can_set_aio_context(BdrvChild *c, AioContext *ctx, - GSList **ignore, Error **errp) +static bool bdrv_parent_change_aio_context(BdrvChild *c, AioContext *ctx, + GHashTable *visited, + Transaction *tran, + Error **errp) { GLOBAL_STATE_CODE(); - if (g_slist_find(*ignore, c)) { + if (g_hash_table_contains(visited, c)) { return true; } - *ignore = g_slist_prepend(*ignore, c); + g_hash_table_add(visited, c); /* * A BdrvChildClass that doesn't handle AioContext changes cannot * tolerate any AioContext changes */ - if (!c->klass->can_set_aio_ctx) { + if (!c->klass->change_aio_ctx) { char *user = bdrv_child_user_desc(c); error_setg(errp, "Changing iothreads is not supported by %s", user); g_free(user); return false; } - if (!c->klass->can_set_aio_ctx(c, ctx, ignore, errp)) { + if (!c->klass->change_aio_ctx(c, ctx, visited, tran, errp)) { assert(!errp || *errp); return false; } return true; } -bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx, - GSList **ignore, Error **errp) +bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp) { GLOBAL_STATE_CODE(); - if (g_slist_find(*ignore, c)) { + if (g_hash_table_contains(visited, c)) { return true; } - *ignore = g_slist_prepend(*ignore, c); - return bdrv_can_set_aio_context(c->bs, ctx, ignore, errp); + g_hash_table_add(visited, c); + return bdrv_change_aio_context(c->bs, ctx, visited, tran, errp); +} + +static void bdrv_set_aio_context_clean(void *opaque) +{ + BdrvStateSetAioContext *state = (BdrvStateSetAioContext *) opaque; + BlockDriverState *bs = (BlockDriverState *) state->bs; + + /* Paired with bdrv_drained_begin in bdrv_change_aio_context() */ + bdrv_drained_end(bs); + + g_free(state); +} + +static void bdrv_set_aio_context_commit(void *opaque) +{ + BdrvStateSetAioContext *state = (BdrvStateSetAioContext *) opaque; + BlockDriverState *bs = (BlockDriverState *) state->bs; + AioContext *new_context = state->new_ctx; + AioContext *old_context = bdrv_get_aio_context(bs); + assert_bdrv_graph_writable(bs); + + /* + * Take the old AioContex when detaching it from bs. + * At this point, new_context lock is already acquired, and we are now + * also taking old_context. This is safe as long as bdrv_detach_aio_context + * does not call AIO_POLL_WHILE(). + */ + if (old_context != qemu_get_aio_context()) { + aio_context_acquire(old_context); + } + bdrv_detach_aio_context(bs); + if (old_context != qemu_get_aio_context()) { + aio_context_release(old_context); + } + bdrv_attach_aio_context(bs, new_context); } -/* @ignore will accumulate all visited BdrvChild object. The caller is - * responsible for freeing the list afterwards. */ -bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx, - GSList **ignore, Error **errp) +static TransactionActionDrv set_aio_context = { + .commit = bdrv_set_aio_context_commit, + .clean = bdrv_set_aio_context_clean, +}; + +/* + * Changes the AioContext used for fd handlers, timers, and BHs by this + * BlockDriverState and all its children and parents. + * + * Must be called from the main AioContext. + * + * The caller must own the AioContext lock for the old AioContext of bs, but it + * must not own the AioContext lock for new_context (unless new_context is the + * same as the current context of bs). + * + * @visited will accumulate all visited BdrvChild objects. The caller is + * responsible for freeing the list afterwards. + */ +static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp) { BdrvChild *c; + BdrvStateSetAioContext *state; + + GLOBAL_STATE_CODE(); if (bdrv_get_aio_context(bs) == ctx) { return true; } - GLOBAL_STATE_CODE(); - QLIST_FOREACH(c, &bs->parents, next_parent) { - if (!bdrv_parent_can_set_aio_context(c, ctx, ignore, errp)) { + if (!bdrv_parent_change_aio_context(c, ctx, visited, tran, errp)) { return false; } } + QLIST_FOREACH(c, &bs->children, next) { - if (!bdrv_child_can_set_aio_context(c, ctx, ignore, errp)) { + if (!bdrv_child_change_aio_context(c, ctx, visited, tran, errp)) { return false; } } + state = g_new(BdrvStateSetAioContext, 1); + *state = (BdrvStateSetAioContext) { + .new_ctx = ctx, + .bs = bs, + }; + + /* Paired with bdrv_drained_end in bdrv_set_aio_context_clean() */ + bdrv_drained_begin(bs); + + tran_add(tran, &set_aio_context, state); + return true; } -int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx, - BdrvChild *ignore_child, Error **errp) +/* + * Change bs's and recursively all of its parents' and children's AioContext + * to the given new context, returning an error if that isn't possible. + * + * If ignore_child is not NULL, that child (and its subgraph) will not + * be touched. + * + * This function still requires the caller to take the bs current + * AioContext lock, otherwise draining will fail since AIO_WAIT_WHILE + * assumes the lock is always held if bs is in another AioContext. + * For the same reason, it temporarily also holds the new AioContext, since + * bdrv_drained_end calls BDRV_POLL_WHILE that assumes the lock is taken too. + * Therefore the new AioContext lock must not be taken by the caller. + */ +int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, + BdrvChild *ignore_child, Error **errp) { - GSList *ignore; - bool ret; - + Transaction *tran; + GHashTable *visited; + int ret; + AioContext *old_context = bdrv_get_aio_context(bs); GLOBAL_STATE_CODE(); - ignore = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL; - ret = bdrv_can_set_aio_context(bs, ctx, &ignore, errp); - g_slist_free(ignore); + /* + * Recursion phase: go through all nodes of the graph. + * Take care of checking that all nodes support changing AioContext + * and drain them, builing a linear list of callbacks to run if everything + * is successful (the transaction itself). + */ + tran = tran_new(); + visited = g_hash_table_new(NULL, NULL); + if (ignore_child) { + g_hash_table_add(visited, ignore_child); + } + ret = bdrv_change_aio_context(bs, ctx, visited, tran, errp); + g_hash_table_destroy(visited); + + /* + * Linear phase: go through all callbacks collected in the transaction. + * Run all callbacks collected in the recursion to switch all nodes + * AioContext lock (transaction commit), or undo all changes done in the + * recursion (transaction abort). + */ if (!ret) { + /* Just run clean() callbacks. No AioContext changed. */ + tran_abort(tran); return -EPERM; } - ignore = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL; - bdrv_set_aio_context_ignore(bs, ctx, &ignore); - g_slist_free(ignore); + /* + * Release old AioContext, it won't be needed anymore, as all + * bdrv_drained_begin() have been called already. + */ + if (qemu_get_aio_context() != old_context) { + aio_context_release(old_context); + } + + /* + * Acquire new AioContext since bdrv_drained_end() is going to be called + * after we switched all nodes in the new AioContext, and the function + * assumes that the lock of the bs is always taken. + */ + if (qemu_get_aio_context() != ctx) { + aio_context_acquire(ctx); + } - return 0; -} + tran_commit(tran); -int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx, - Error **errp) -{ - GLOBAL_STATE_CODE(); - return bdrv_child_try_set_aio_context(bs, ctx, NULL, errp); + if (qemu_get_aio_context() != ctx) { + aio_context_release(ctx); + } + + /* Re-acquire the old AioContext, since the caller takes and releases it. */ + if (qemu_get_aio_context() != old_context) { + aio_context_acquire(old_context); + } + + return 0; } void bdrv_add_aio_context_notifier(BlockDriverState *bs, diff --git a/block/backup.c b/block/backup.c index b2b649e305..6a9ad97a53 100644 --- a/block/backup.c +++ b/block/backup.c @@ -309,7 +309,7 @@ static void coroutine_fn backup_pause(Job *job) } } -static void coroutine_fn backup_set_speed(BlockJob *job, int64_t speed) +static void backup_set_speed(BlockJob *job, int64_t speed) { BackupBlockJob *s = container_of(job, BackupBlockJob, common); diff --git a/block/blkdebug.c b/block/blkdebug.c index bbf2948703..4265ca125e 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -503,12 +503,9 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags, } /* Open the image file */ - bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options, "image", - bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - ret = -EINVAL; + ret = bdrv_open_file_child(qemu_opt_get(opts, "x-image"), options, "image", + bs, errp); + if (ret < 0) { goto out; } @@ -672,7 +669,7 @@ blkdebug_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags); } -static int blkdebug_co_flush(BlockDriverState *bs) +static int coroutine_fn blkdebug_co_flush(BlockDriverState *bs) { int err = rule_check(bs, 0, 0, BLKDEBUG_IO_TYPE_FLUSH); diff --git a/block/blklogwrites.c b/block/blklogwrites.c index e3c6c4039c..cef9efe55d 100644 --- a/block/blklogwrites.c +++ b/block/blklogwrites.c @@ -155,11 +155,8 @@ static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int flags, } /* Open the file */ - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, false, - errp); - if (!bs->file) { - ret = -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { goto fail; } @@ -257,10 +254,6 @@ fail_log: s->log_file = NULL; } fail: - if (ret < 0) { - bdrv_unref_child(bs, bs->file); - bs->file = NULL; - } qemu_opts_del(opts); return ret; } diff --git a/block/blkreplay.c b/block/blkreplay.c index dcbe780ddb..76a0b8d12a 100644 --- a/block/blkreplay.c +++ b/block/blkreplay.c @@ -26,11 +26,8 @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags, int ret; /* Open the image file */ - bs->file = bdrv_open_child(NULL, options, "image", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - ret = -EINVAL; + ret = bdrv_open_file_child(NULL, options, "image", bs, errp); + if (ret < 0) { goto fail; } diff --git a/block/blkverify.c b/block/blkverify.c index f36fd6aeb2..c60a2dc624 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -122,12 +122,9 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags, } /* Open the raw file */ - bs->file = bdrv_open_child(qemu_opt_get(opts, "x-raw"), options, "raw", - bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - ret = -EINVAL; + ret = bdrv_open_file_child(qemu_opt_get(opts, "x-raw"), options, "raw", + bs, errp); + if (ret < 0) { goto fail; } diff --git a/block/block-backend.c b/block/block-backend.c index 4f59664397..c0c7d56c8d 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -134,10 +134,9 @@ static void blk_root_drained_end(BdrvChild *child, int *drained_end_counter); static void blk_root_change_media(BdrvChild *child, bool load); static void blk_root_resize(BdrvChild *child); -static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx, - GSList **ignore, Error **errp); -static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx, - GSList **ignore); +static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp); static char *blk_root_get_parent_desc(BdrvChild *child) { @@ -334,8 +333,7 @@ static const BdrvChildClass child_root = { .attach = blk_root_attach, .detach = blk_root_detach, - .can_set_aio_ctx = blk_root_can_set_aio_ctx, - .set_aio_ctx = blk_root_set_aio_ctx, + .change_aio_ctx = blk_root_change_aio_ctx, .get_parent_aio_context = blk_root_get_parent_aio_context, }; @@ -1946,7 +1944,7 @@ bool blk_enable_write_cache(BlockBackend *blk) void blk_set_enable_write_cache(BlockBackend *blk, bool wce) { - GLOBAL_STATE_CODE(); + IO_CODE(); blk->enable_write_cache = wce; } @@ -2149,8 +2147,11 @@ static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context, bdrv_ref(bs); if (update_root_node) { - ret = bdrv_child_try_set_aio_context(bs, new_context, blk->root, - errp); + /* + * update_root_node MUST be false for blk_root_set_aio_ctx_commit(), + * as we are already in the commit function of a transaction. + */ + ret = bdrv_try_change_aio_context(bs, new_context, blk->root, errp); if (ret < 0) { bdrv_unref(bs); return ret; @@ -2177,33 +2178,54 @@ int blk_set_aio_context(BlockBackend *blk, AioContext *new_context, return blk_do_set_aio_context(blk, new_context, true, errp); } -static bool blk_root_can_set_aio_ctx(BdrvChild *child, AioContext *ctx, - GSList **ignore, Error **errp) +typedef struct BdrvStateBlkRootContext { + AioContext *new_ctx; + BlockBackend *blk; +} BdrvStateBlkRootContext; + +static void blk_root_set_aio_ctx_commit(void *opaque) +{ + BdrvStateBlkRootContext *s = opaque; + BlockBackend *blk = s->blk; + + blk_do_set_aio_context(blk, s->new_ctx, false, &error_abort); +} + +static TransactionActionDrv set_blk_root_context = { + .commit = blk_root_set_aio_ctx_commit, + .clean = g_free, +}; + +static bool blk_root_change_aio_ctx(BdrvChild *child, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp) { BlockBackend *blk = child->opaque; + BdrvStateBlkRootContext *s; - if (blk->allow_aio_context_change) { - return true; + if (!blk->allow_aio_context_change) { + /* + * Manually created BlockBackends (those with a name) that are not + * attached to anything can change their AioContext without updating + * their user; return an error for others. + */ + if (!blk->name || blk->dev) { + /* TODO Add BB name/QOM path */ + error_setg(errp, "Cannot change iothread of active block backend"); + return false; + } } - /* Only manually created BlockBackends that are not attached to anything - * can change their AioContext without updating their user. */ - if (!blk->name || blk->dev) { - /* TODO Add BB name/QOM path */ - error_setg(errp, "Cannot change iothread of active block backend"); - return false; - } + s = g_new(BdrvStateBlkRootContext, 1); + *s = (BdrvStateBlkRootContext) { + .new_ctx = ctx, + .blk = blk, + }; + tran_add(tran, &set_blk_root_context, s); return true; } -static void blk_root_set_aio_ctx(BdrvChild *child, AioContext *ctx, - GSList **ignore) -{ - BlockBackend *blk = child->opaque; - blk_do_set_aio_context(blk, ctx, false, &error_abort); -} - void blk_add_aio_context_notifier(BlockBackend *blk, void (*attached_aio_context)(AioContext *new_context, void *opaque), void (*detach_aio_context)(void *opaque), void *opaque) diff --git a/block/bochs.c b/block/bochs.c index b76f34fe03..e30e3908d9 100644 --- a/block/bochs.c +++ b/block/bochs.c @@ -110,10 +110,9 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags, return ret; } - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } ret = bdrv_pread(bs->file, 0, sizeof(bochs), &bochs, 0); diff --git a/block/cloop.c b/block/cloop.c index 40b146e714..3ff975a94d 100644 --- a/block/cloop.c +++ b/block/cloop.c @@ -71,10 +71,9 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags, return ret; } - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } /* read header */ diff --git a/block/commit.c b/block/commit.c index 38571510cb..0029b31944 100644 --- a/block/commit.c +++ b/block/commit.c @@ -135,7 +135,7 @@ static int coroutine_fn commit_run(Job *job, Error **errp) } if (base_len < len) { - ret = blk_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL); + ret = blk_co_truncate(s->base, len, false, PREALLOC_MODE_OFF, 0, NULL); if (ret) { return ret; } @@ -238,6 +238,7 @@ static BlockDriver bdrv_commit_top = { .bdrv_child_perm = bdrv_commit_top_child_perm, .is_filter = true, + .filtered_child_is_backing = true, }; void commit_start(const char *job_id, BlockDriverState *bs, diff --git a/block/copy-before-write.c b/block/copy-before-write.c index afbdd04489..4abaa7339e 100644 --- a/block/copy-before-write.c +++ b/block/copy-before-write.c @@ -412,6 +412,7 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, int64_t cluster_size; g_autoptr(BlockdevOptions) full_opts = NULL; BlockdevOptionsCbw *opts; + int ret; full_opts = cbw_parse_options(options, errp); if (!full_opts) { @@ -420,11 +421,9 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags, assert(full_opts->driver == BLOCKDEV_DRIVER_COPY_BEFORE_WRITE); opts = &full_opts->u.copy_before_write; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } s->target = bdrv_open_child(NULL, options, "target", bs, &child_of_bds, diff --git a/block/copy-on-read.c b/block/copy-on-read.c index 1fc7fb3333..815ac1d835 100644 --- a/block/copy-on-read.c +++ b/block/copy-on-read.c @@ -41,12 +41,11 @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags, BDRVStateCOR *state = bs->opaque; /* Find a bottom node name, if any */ const char *bottom_node = qdict_get_try_str(options, "bottom"); + int ret; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } bs->supported_read_flags = BDRV_REQ_PREFETCH; diff --git a/block/crypto.c b/block/crypto.c index c7365598a7..2fb8add458 100644 --- a/block/crypto.c +++ b/block/crypto.c @@ -261,15 +261,14 @@ static int block_crypto_open_generic(QCryptoBlockFormat format, { BlockCrypto *crypto = bs->opaque; QemuOpts *opts = NULL; - int ret = -EINVAL; + int ret; QCryptoBlockOpenOptions *open_opts = NULL; unsigned int cflags = 0; QDict *cryptoopts = NULL; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } bs->supported_write_flags = BDRV_REQ_FUA & @@ -277,6 +276,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format, opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort); if (!qemu_opts_absorb_qdict(opts, options, errp)) { + ret = -EINVAL; goto cleanup; } @@ -285,6 +285,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format, open_opts = block_crypto_open_opts_init(cryptoopts, errp); if (!open_opts) { + ret = -EINVAL; goto cleanup; } diff --git a/block/dmg.c b/block/dmg.c index 98db18d82a..422136276a 100644 --- a/block/dmg.c +++ b/block/dmg.c @@ -440,10 +440,9 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags, return ret; } - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } block_module_load_one("dmg-bz2"); diff --git a/block/export/export.c b/block/export/export.c index 4744862915..7cc0c25c1c 100644 --- a/block/export/export.c +++ b/block/export/export.c @@ -129,7 +129,7 @@ BlockExport *blk_exp_add(BlockExportOptions *export, Error **errp) /* Ignore errors with fixed-iothread=false */ set_context_errp = fixed_iothread ? errp : NULL; - ret = bdrv_try_set_aio_context(bs, new_ctx, set_context_errp); + ret = bdrv_try_change_aio_context(bs, new_ctx, NULL, set_context_errp); if (ret == 0) { aio_context_release(ctx); aio_context_acquire(new_ctx); diff --git a/block/filter-compress.c b/block/filter-compress.c index d5be538619..305716c86c 100644 --- a/block/filter-compress.c +++ b/block/filter-compress.c @@ -30,11 +30,9 @@ static int compress_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - return -EINVAL; + int ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } if (!bs->file->bs->drv || !block_driver_can_compress(bs->file->bs->drv)) { diff --git a/block/io.c b/block/io.c index a9673465dd..34b30e304e 100644 --- a/block/io.c +++ b/block/io.c @@ -2744,8 +2744,8 @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset, return 1; } - ret = bdrv_common_block_status_above(bs, NULL, false, false, offset, - bytes, &pnum, NULL, NULL, NULL); + ret = bdrv_co_common_block_status_above(bs, NULL, false, false, offset, + bytes, &pnum, NULL, NULL, NULL); if (ret < 0) { return ret; @@ -2754,8 +2754,8 @@ int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset, return (pnum == bytes) && (ret & BDRV_BLOCK_ZERO); } -int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset, - int64_t bytes, int64_t *pnum) +int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes, + int64_t *pnum) { int ret; int64_t dummy; diff --git a/block/io_uring.c b/block/io_uring.c index a1760152e0..973e15d876 100644 --- a/block/io_uring.c +++ b/block/io_uring.c @@ -11,7 +11,6 @@ #include "qemu/osdep.h" #include <liburing.h> #include "block/aio.h" -#include "qemu/error-report.h" #include "qemu/queue.h" #include "block/block.h" #include "block/raw-aio.h" @@ -19,7 +18,6 @@ #include "qapi/error.h" #include "trace.h" - /* io_uring ring size */ #define MAX_ENTRIES 128 @@ -432,17 +430,8 @@ LuringState *luring_init(Error **errp) } ioq_init(&s->io_q); -#ifdef CONFIG_LIBURING_REGISTER_RING_FD - if (io_uring_register_ring_fd(&s->ring) < 0) { - /* - * Only warn about this error: we will fallback to the non-optimized - * io_uring operations. - */ - warn_report("failed to register linux io_uring ring file descriptor"); - } -#endif - return s; + } void luring_cleanup(LuringState *s) diff --git a/block/mirror.c b/block/mirror.c index bed089d2e0..1a75a47cc3 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -922,8 +922,8 @@ static int coroutine_fn mirror_run(Job *job, Error **errp) * active layer. */ if (s->base == blk_bs(s->target)) { if (s->bdev_length > target_length) { - ret = blk_truncate(s->target, s->bdev_length, false, - PREALLOC_MODE_OFF, 0, NULL); + ret = blk_co_truncate(s->target, s->bdev_length, false, + PREALLOC_MODE_OFF, 0, NULL); if (ret < 0) { goto immediate_exit; } @@ -1589,6 +1589,7 @@ static BlockDriver bdrv_mirror_top = { .bdrv_child_perm = bdrv_mirror_top_child_perm, .is_filter = true, + .filtered_child_is_backing = true, }; static BlockJob *mirror_start_job( diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c index 939a520d17..b6135e9bfe 100644 --- a/block/monitor/block-hmp-cmds.c +++ b/block/monitor/block-hmp-cmds.c @@ -489,7 +489,7 @@ void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, err); } -void hmp_block_resize(Monitor *mon, const QDict *qdict) +void coroutine_fn hmp_block_resize(Monitor *mon, const QDict *qdict) { const char *device = qdict_get_str(qdict, "device"); int64_t size = qdict_get_int(qdict, "size"); diff --git a/block/parallels.c b/block/parallels.c index dd15a44100..fa08c1104b 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -205,18 +205,18 @@ static coroutine_fn int64_t allocate_clusters(BlockDriverState *bs, * force the safer-but-slower fallocate. */ if (s->prealloc_mode == PRL_PREALLOC_MODE_TRUNCATE) { - ret = bdrv_truncate(bs->file, - (s->data_end + space) << BDRV_SECTOR_BITS, - false, PREALLOC_MODE_OFF, BDRV_REQ_ZERO_WRITE, - NULL); + ret = bdrv_co_truncate(bs->file, + (s->data_end + space) << BDRV_SECTOR_BITS, + false, PREALLOC_MODE_OFF, + BDRV_REQ_ZERO_WRITE, NULL); if (ret == -ENOTSUP) { s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE; } } if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) { - ret = bdrv_pwrite_zeroes(bs->file, - s->data_end << BDRV_SECTOR_BITS, - space << BDRV_SECTOR_BITS, 0); + ret = bdrv_co_pwrite_zeroes(bs->file, + s->data_end << BDRV_SECTOR_BITS, + space << BDRV_SECTOR_BITS, 0); } if (ret < 0) { return ret; @@ -278,8 +278,8 @@ static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs) if (off + to_write > s->header_size) { to_write = s->header_size - off; } - ret = bdrv_pwrite(bs->file, off, to_write, (uint8_t *)s->header + off, - 0); + ret = bdrv_co_pwrite(bs->file, off, to_write, + (uint8_t *)s->header + off, 0); if (ret < 0) { qemu_co_mutex_unlock(&s->lock); return ret; @@ -503,8 +503,8 @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs, * In order to really repair the image, we must shrink it. * That means we have to pass exact=true. */ - ret = bdrv_truncate(bs->file, res->image_end_offset, true, - PREALLOC_MODE_OFF, 0, &local_err); + ret = bdrv_co_truncate(bs->file, res->image_end_offset, true, + PREALLOC_MODE_OFF, 0, &local_err); if (ret < 0) { error_report_err(local_err); res->check_errors++; @@ -599,12 +599,12 @@ static int coroutine_fn parallels_co_create(BlockdevCreateOptions* opts, memset(tmp, 0, sizeof(tmp)); memcpy(tmp, &header, sizeof(header)); - ret = blk_pwrite(blk, 0, BDRV_SECTOR_SIZE, tmp, 0); + ret = blk_co_pwrite(blk, 0, BDRV_SECTOR_SIZE, tmp, 0); if (ret < 0) { goto exit; } - ret = blk_pwrite_zeroes(blk, BDRV_SECTOR_SIZE, - (bat_sectors - 1) << BDRV_SECTOR_BITS, 0); + ret = blk_co_pwrite_zeroes(blk, BDRV_SECTOR_SIZE, + (bat_sectors - 1) << BDRV_SECTOR_BITS, 0); if (ret < 0) { goto exit; } @@ -736,10 +736,9 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags, Error *local_err = NULL; char *buf; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } ret = bdrv_pread(bs->file, 0, sizeof(ph), &ph, 0); diff --git a/block/preallocate.c b/block/preallocate.c index e15cb8c74a..d50ee7f49b 100644 --- a/block/preallocate.c +++ b/block/preallocate.c @@ -134,6 +134,7 @@ static int preallocate_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { BDRVPreallocateState *s = bs->opaque; + int ret; /* * s->data_end and friends should be initialized on permission update. @@ -141,11 +142,9 @@ static int preallocate_open(BlockDriverState *bs, QDict *options, int flags, */ s->file_end = s->zero_start = s->data_end = -EINVAL; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } if (!preallocate_absorb_opts(&s->opts, options, bs->file->bs, errp)) { diff --git a/block/qcow.c b/block/qcow.c index e9180c7b61..daa38839ab 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -92,7 +92,8 @@ typedef struct BDRVQcowState { static QemuOptsList qcow_create_opts; -static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset); +static int coroutine_fn decompress_cluster(BlockDriverState *bs, + uint64_t cluster_offset); static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename) { @@ -121,10 +122,8 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags, qdict_extract_subqdict(options, &encryptopts, "encrypt."); encryptfmt = qdict_get_try_str(encryptopts, "format"); - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - ret = -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { goto fail; } @@ -351,10 +350,11 @@ static int qcow_reopen_prepare(BDRVReopenState *state, * return 0 if not allocated, 1 if *result is assigned, and negative * errno on failure. */ -static int get_cluster_offset(BlockDriverState *bs, - uint64_t offset, int allocate, - int compressed_size, - int n_start, int n_end, uint64_t *result) +static int coroutine_fn get_cluster_offset(BlockDriverState *bs, + uint64_t offset, int allocate, + int compressed_size, + int n_start, int n_end, + uint64_t *result) { BDRVQcowState *s = bs->opaque; int min_index, i, j, l1_index, l2_index, ret; @@ -381,9 +381,9 @@ static int get_cluster_offset(BlockDriverState *bs, s->l1_table[l1_index] = l2_offset; tmp = cpu_to_be64(l2_offset); BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE); - ret = bdrv_pwrite_sync(bs->file, - s->l1_table_offset + l1_index * sizeof(tmp), - sizeof(tmp), &tmp, 0); + ret = bdrv_co_pwrite_sync(bs->file, + s->l1_table_offset + l1_index * sizeof(tmp), + sizeof(tmp), &tmp, 0); if (ret < 0) { return ret; } @@ -414,14 +414,14 @@ static int get_cluster_offset(BlockDriverState *bs, BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD); if (new_l2_table) { memset(l2_table, 0, s->l2_size * sizeof(uint64_t)); - ret = bdrv_pwrite_sync(bs->file, l2_offset, - s->l2_size * sizeof(uint64_t), l2_table, 0); + ret = bdrv_co_pwrite_sync(bs->file, l2_offset, + s->l2_size * sizeof(uint64_t), l2_table, 0); if (ret < 0) { return ret; } } else { - ret = bdrv_pread(bs->file, l2_offset, s->l2_size * sizeof(uint64_t), - l2_table, 0); + ret = bdrv_co_pread(bs->file, l2_offset, + s->l2_size * sizeof(uint64_t), l2_table, 0); if (ret < 0) { return ret; } @@ -453,8 +453,8 @@ static int get_cluster_offset(BlockDriverState *bs, cluster_offset = QEMU_ALIGN_UP(cluster_offset, s->cluster_size); /* write the cluster content */ BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); - ret = bdrv_pwrite(bs->file, cluster_offset, s->cluster_size, - s->cluster_cache, 0); + ret = bdrv_co_pwrite(bs->file, cluster_offset, s->cluster_size, + s->cluster_cache, 0); if (ret < 0) { return ret; } @@ -469,8 +469,9 @@ static int get_cluster_offset(BlockDriverState *bs, if (cluster_offset + s->cluster_size > INT64_MAX) { return -E2BIG; } - ret = bdrv_truncate(bs->file, cluster_offset + s->cluster_size, - false, PREALLOC_MODE_OFF, 0, NULL); + ret = bdrv_co_truncate(bs->file, + cluster_offset + s->cluster_size, + false, PREALLOC_MODE_OFF, 0, NULL); if (ret < 0) { return ret; } @@ -492,9 +493,9 @@ static int get_cluster_offset(BlockDriverState *bs, return -EIO; } BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); - ret = bdrv_pwrite(bs->file, cluster_offset + i, - BDRV_SECTOR_SIZE, - s->cluster_data, 0); + ret = bdrv_co_pwrite(bs->file, cluster_offset + i, + BDRV_SECTOR_SIZE, + s->cluster_data, 0); if (ret < 0) { return ret; } @@ -514,8 +515,8 @@ static int get_cluster_offset(BlockDriverState *bs, } else { BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE); } - ret = bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp), - sizeof(tmp), &tmp, 0); + ret = bdrv_co_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp), + sizeof(tmp), &tmp, 0); if (ret < 0) { return ret; } @@ -585,7 +586,8 @@ static int decompress_buffer(uint8_t *out_buf, int out_buf_size, return 0; } -static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset) +static int coroutine_fn decompress_cluster(BlockDriverState *bs, + uint64_t cluster_offset) { BDRVQcowState *s = bs->opaque; int ret, csize; @@ -596,7 +598,7 @@ static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset) csize = cluster_offset >> (63 - s->cluster_bits); csize &= (s->cluster_size - 1); BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED); - ret = bdrv_pread(bs->file, coffset, csize, s->cluster_data, 0); + ret = bdrv_co_pread(bs->file, coffset, csize, s->cluster_data, 0); if (ret < 0) return -1; if (decompress_buffer(s->cluster_cache, s->cluster_size, @@ -888,14 +890,14 @@ static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts, } /* write all the data */ - ret = blk_pwrite(qcow_blk, 0, sizeof(header), &header, 0); + ret = blk_co_pwrite(qcow_blk, 0, sizeof(header), &header, 0); if (ret < 0) { goto exit; } if (qcow_opts->has_backing_file) { - ret = blk_pwrite(qcow_blk, sizeof(header), backing_filename_len, - qcow_opts->backing_file, 0); + ret = blk_co_pwrite(qcow_blk, sizeof(header), backing_filename_len, + qcow_opts->backing_file, 0); if (ret < 0) { goto exit; } @@ -904,8 +906,8 @@ static int coroutine_fn qcow_co_create(BlockdevCreateOptions *opts, tmp = g_malloc0(BDRV_SECTOR_SIZE); for (i = 0; i < DIV_ROUND_UP(sizeof(uint64_t) * l1_size, BDRV_SECTOR_SIZE); i++) { - ret = blk_pwrite(qcow_blk, header_size + BDRV_SECTOR_SIZE * i, - BDRV_SECTOR_SIZE, tmp, 0); + ret = blk_co_pwrite(qcow_blk, header_size + BDRV_SECTOR_SIZE * i, + BDRV_SECTOR_SIZE, tmp, 0); if (ret < 0) { g_free(tmp); goto exit; diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index 7197754843..bcad567c0c 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -955,8 +955,8 @@ static void set_readonly_helper(gpointer bitmap, gpointer value) * If header_updated is not NULL then it is set appropriately regardless of * the return value. */ -bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, bool *header_updated, - Error **errp) +bool coroutine_fn qcow2_load_dirty_bitmaps(BlockDriverState *bs, + bool *header_updated, Error **errp) { BDRVQcow2State *s = bs->opaque; Qcow2BitmapList *bm_list; diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 0f293950a1..40ed847f97 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -31,7 +31,8 @@ #include "qemu/memalign.h" #include "trace.h" -int qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t exact_size) +int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs, + uint64_t exact_size) { BDRVQcow2State *s = bs->opaque; int new_l1_size, i, ret; @@ -47,14 +48,14 @@ int qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t exact_size) #endif BLKDBG_EVENT(bs->file, BLKDBG_L1_SHRINK_WRITE_TABLE); - ret = bdrv_pwrite_zeroes(bs->file, s->l1_table_offset + - new_l1_size * L1E_SIZE, - (s->l1_size - new_l1_size) * L1E_SIZE, 0); + ret = bdrv_co_pwrite_zeroes(bs->file, + s->l1_table_offset + new_l1_size * L1E_SIZE, + (s->l1_size - new_l1_size) * L1E_SIZE, 0); if (ret < 0) { goto fail; } - ret = bdrv_flush(bs->file->bs); + ret = bdrv_co_flush(bs->file->bs); if (ret < 0) { goto fail; } @@ -823,10 +824,10 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset, * * Return 0 on success and -errno in error cases */ -int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, - uint64_t offset, - int compressed_size, - uint64_t *host_offset) +int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, + uint64_t offset, + int compressed_size, + uint64_t *host_offset) { BDRVQcow2State *s = bs->opaque; int l2_index, ret; @@ -1488,8 +1489,9 @@ static int coroutine_fn handle_dependencies(BlockDriverState *bs, * * -errno: in error cases */ -static int handle_copied(BlockDriverState *bs, uint64_t guest_offset, - uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m) +static int coroutine_fn handle_copied(BlockDriverState *bs, + uint64_t guest_offset, uint64_t *host_offset, uint64_t *bytes, + QCowL2Meta **m) { BDRVQcow2State *s = bs->opaque; int l2_index; @@ -1653,8 +1655,9 @@ static int do_alloc_cluster_offset(BlockDriverState *bs, uint64_t guest_offset, * * -errno: in error cases */ -static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset, - uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m) +static int coroutine_fn handle_alloc(BlockDriverState *bs, + uint64_t guest_offset, uint64_t *host_offset, uint64_t *bytes, + QCowL2Meta **m) { BDRVQcow2State *s = bs->opaque; int l2_index; diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 1fbb07ca77..81264740f0 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -97,7 +97,7 @@ static void update_max_refcount_table_index(BDRVQcow2State *s) s->max_refcount_table_index = i; } -int qcow2_refcount_init(BlockDriverState *bs) +int coroutine_fn qcow2_refcount_init(BlockDriverState *bs) { BDRVQcow2State *s = bs->opaque; unsigned int refcount_table_size2, i; @@ -118,8 +118,8 @@ int qcow2_refcount_init(BlockDriverState *bs) goto fail; } BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_LOAD); - ret = bdrv_pread(bs->file, s->refcount_table_offset, - refcount_table_size2, s->refcount_table, 0); + ret = bdrv_co_pread(bs->file, s->refcount_table_offset, + refcount_table_size2, s->refcount_table, 0); if (ret < 0) { goto fail; } @@ -3559,8 +3559,8 @@ static int64_t get_refblock_offset(BlockDriverState *bs, uint64_t offset) return covering_refblock_offset; } -static int qcow2_discard_refcount_block(BlockDriverState *bs, - uint64_t discard_block_offs) +static int coroutine_fn +qcow2_discard_refcount_block(BlockDriverState *bs, uint64_t discard_block_offs) { BDRVQcow2State *s = bs->opaque; int64_t refblock_offs; @@ -3616,7 +3616,7 @@ static int qcow2_discard_refcount_block(BlockDriverState *bs, return 0; } -int qcow2_shrink_reftable(BlockDriverState *bs) +int coroutine_fn qcow2_shrink_reftable(BlockDriverState *bs) { BDRVQcow2State *s = bs->opaque; uint64_t *reftable_tmp = @@ -3657,9 +3657,9 @@ int qcow2_shrink_reftable(BlockDriverState *bs) reftable_tmp[i] = unused_block ? 0 : cpu_to_be64(s->refcount_table[i]); } - ret = bdrv_pwrite_sync(bs->file, s->refcount_table_offset, - s->refcount_table_size * REFTABLE_ENTRY_SIZE, - reftable_tmp, 0); + ret = bdrv_co_pwrite_sync(bs->file, s->refcount_table_offset, + s->refcount_table_size * REFTABLE_ENTRY_SIZE, + reftable_tmp, 0); /* * If the write in the reftable failed the image may contain a partially * overwritten reftable. In this case it would be better to clear the diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index d1d46facbf..62e8a0335d 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -441,9 +441,9 @@ int coroutine_fn qcow2_check_read_snapshot_table(BlockDriverState *bs, } QEMU_PACKED snapshot_table_pointer; /* qcow2_do_open() discards this information in check mode */ - ret = bdrv_pread(bs->file, offsetof(QCowHeader, nb_snapshots), - sizeof(snapshot_table_pointer), &snapshot_table_pointer, - 0); + ret = bdrv_co_pread(bs->file, offsetof(QCowHeader, nb_snapshots), + sizeof(snapshot_table_pointer), &snapshot_table_pointer, + 0); if (ret < 0) { result->check_errors++; fprintf(stderr, "ERROR failed to read the snapshot table pointer from " diff --git a/block/qcow2.c b/block/qcow2.c index b57f7cc8ee..4d6666d3ff 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1306,7 +1306,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, uint64_t l1_vm_state_index; bool update_header = false; - ret = bdrv_pread(bs->file, 0, sizeof(header), &header, 0); + ret = bdrv_co_pread(bs->file, 0, sizeof(header), &header, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Could not read qcow2 header"); goto fail; @@ -1382,9 +1382,9 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, if (header.header_length > sizeof(header)) { s->unknown_header_fields_size = header.header_length - sizeof(header); s->unknown_header_fields = g_malloc(s->unknown_header_fields_size); - ret = bdrv_pread(bs->file, sizeof(header), - s->unknown_header_fields_size, - s->unknown_header_fields, 0); + ret = bdrv_co_pread(bs->file, sizeof(header), + s->unknown_header_fields_size, + s->unknown_header_fields, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Could not read unknown qcow2 header " "fields"); @@ -1579,8 +1579,8 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, ret = -ENOMEM; goto fail; } - ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_size * L1E_SIZE, - s->l1_table, 0); + ret = bdrv_co_pread(bs->file, s->l1_table_offset, s->l1_size * L1E_SIZE, + s->l1_table, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Could not read L1 table"); goto fail; @@ -1699,8 +1699,8 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, } s->image_backing_file = g_malloc(len + 1); - ret = bdrv_pread(bs->file, header.backing_file_offset, len, - s->image_backing_file, 0); + ret = bdrv_co_pread(bs->file, header.backing_file_offset, len, + s->image_backing_file, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Could not read backing file name"); goto fail; @@ -1905,11 +1905,11 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags, .errp = errp, .ret = -EINPROGRESS }; + int ret; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } /* Initialise locks */ @@ -3679,7 +3679,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) cpu_to_be64(QCOW2_INCOMPAT_EXTL2); } - ret = blk_pwrite(blk, 0, cluster_size, header, 0); + ret = blk_co_pwrite(blk, 0, cluster_size, header, 0); g_free(header); if (ret < 0) { error_setg_errno(errp, -ret, "Could not write qcow2 header"); @@ -3689,7 +3689,7 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) /* Write a refcount table with one refcount block */ refcount_table = g_malloc0(2 * cluster_size); refcount_table[0] = cpu_to_be64(2 * cluster_size); - ret = blk_pwrite(blk, cluster_size, 2 * cluster_size, refcount_table, 0); + ret = blk_co_pwrite(blk, cluster_size, 2 * cluster_size, refcount_table, 0); g_free(refcount_table); if (ret < 0) { @@ -3744,8 +3744,8 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) } /* Okay, now that we have a valid image, let's give it the right size */ - ret = blk_truncate(blk, qcow2_opts->size, false, qcow2_opts->preallocation, - 0, errp); + ret = blk_co_truncate(blk, qcow2_opts->size, false, + qcow2_opts->preallocation, 0, errp); if (ret < 0) { error_prepend(errp, "Could not resize image: "); goto out; @@ -5287,8 +5287,8 @@ static int64_t qcow2_check_vmstate_request(BlockDriverState *bs, return pos; } -static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, - int64_t pos) +static coroutine_fn int qcow2_save_vmstate(BlockDriverState *bs, + QEMUIOVector *qiov, int64_t pos) { int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos); if (offset < 0) { @@ -5299,8 +5299,8 @@ static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, return bs->drv->bdrv_co_pwritev_part(bs, offset, qiov->size, qiov, 0, 0); } -static int qcow2_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, - int64_t pos) +static coroutine_fn int qcow2_load_vmstate(BlockDriverState *bs, + QEMUIOVector *qiov, int64_t pos) { int64_t offset = qcow2_check_vmstate_request(bs, qiov, pos); if (offset < 0) { diff --git a/block/qcow2.h b/block/qcow2.h index 3e7c5e80b6..2285f18a73 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -846,7 +846,7 @@ int qcow2_validate_table(BlockDriverState *bs, uint64_t offset, Error **errp); /* qcow2-refcount.c functions */ -int qcow2_refcount_init(BlockDriverState *bs); +int coroutine_fn qcow2_refcount_init(BlockDriverState *bs); void qcow2_refcount_close(BlockDriverState *bs); int qcow2_get_refcount(BlockDriverState *bs, int64_t cluster_index, @@ -893,14 +893,14 @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res, int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order, BlockDriverAmendStatusCB *status_cb, void *cb_opaque, Error **errp); -int qcow2_shrink_reftable(BlockDriverState *bs); +int coroutine_fn qcow2_shrink_reftable(BlockDriverState *bs); int64_t qcow2_get_last_cluster(BlockDriverState *bs, int64_t size); int coroutine_fn qcow2_detect_metadata_preallocation(BlockDriverState *bs); /* qcow2-cluster.c functions */ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size, bool exact_size); -int qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size); +int coroutine_fn qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t max_size); int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index); int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num, uint8_t *buf, int nb_sectors, bool enc, Error **errp); @@ -911,10 +911,10 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset, int coroutine_fn qcow2_alloc_host_offset(BlockDriverState *bs, uint64_t offset, unsigned int *bytes, uint64_t *host_offset, QCowL2Meta **m); -int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, - uint64_t offset, - int compressed_size, - uint64_t *host_offset); +int coroutine_fn qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs, + uint64_t offset, + int compressed_size, + uint64_t *host_offset); void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry, uint64_t *coffset, int *csize); @@ -982,8 +982,8 @@ void qcow2_cache_discard(Qcow2Cache *c, void *table); int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res, void **refcount_table, int64_t *refcount_table_size); -bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, bool *header_updated, - Error **errp); +bool coroutine_fn qcow2_load_dirty_bitmaps(BlockDriverState *bs, + bool *header_updated, Error **errp); bool qcow2_get_bitmap_info_list(BlockDriverState *bs, Qcow2BitmapInfoList **info_list, Error **errp); int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp); @@ -991,13 +991,13 @@ int qcow2_truncate_bitmaps_check(BlockDriverState *bs, Error **errp); bool qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, bool release_stored, Error **errp); int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp); -bool qcow2_co_can_store_new_dirty_bitmap(BlockDriverState *bs, - const char *name, - uint32_t granularity, - Error **errp); -int qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, - const char *name, - Error **errp); +bool coroutine_fn qcow2_co_can_store_new_dirty_bitmap(BlockDriverState *bs, + const char *name, + uint32_t granularity, + Error **errp); +int coroutine_fn qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, + const char *name, + Error **errp); bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs); uint64_t qcow2_get_persistent_dirty_bitmap_size(BlockDriverState *bs, uint32_t cluster_size); diff --git a/block/qed-table.c b/block/qed-table.c index 1cc844b1a5..aa203f2627 100644 --- a/block/qed-table.c +++ b/block/qed-table.c @@ -100,7 +100,7 @@ static int coroutine_fn qed_write_table(BDRVQEDState *s, uint64_t offset, } if (flush) { - ret = bdrv_flush(s->bs); + ret = bdrv_co_flush(s->bs); if (ret < 0) { goto out; } diff --git a/block/qed.c b/block/qed.c index 99a9ec9b57..2f36ad342c 100644 --- a/block/qed.c +++ b/block/qed.c @@ -387,7 +387,7 @@ static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options, int64_t file_size; int ret; - ret = bdrv_pread(bs->file, 0, sizeof(le_header), &le_header, 0); + ret = bdrv_co_pread(bs->file, 0, sizeof(le_header), &le_header, 0); if (ret < 0) { error_setg(errp, "Failed to read QED header"); return ret; @@ -492,7 +492,7 @@ static int coroutine_fn bdrv_qed_do_open(BlockDriverState *bs, QDict *options, } /* From here on only known autoclear feature bits are valid */ - bdrv_flush(bs->file->bs); + bdrv_co_flush(bs->file->bs); } s->l1_table = qed_alloc_table(s); @@ -561,11 +561,11 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags, .errp = errp, .ret = -EINPROGRESS }; + int ret; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } bdrv_qed_init_state(bs); @@ -693,7 +693,7 @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts, * The QED format associates file length with allocation status, * so a new file (which is empty) must have a length of 0. */ - ret = blk_truncate(blk, 0, true, PREALLOC_MODE_OFF, 0, errp); + ret = blk_co_truncate(blk, 0, true, PREALLOC_MODE_OFF, 0, errp); if (ret < 0) { goto out; } @@ -712,18 +712,18 @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCreateOptions *opts, } qed_header_cpu_to_le(&header, &le_header); - ret = blk_pwrite(blk, 0, sizeof(le_header), &le_header, 0); + ret = blk_co_pwrite(blk, 0, sizeof(le_header), &le_header, 0); if (ret < 0) { goto out; } - ret = blk_pwrite(blk, sizeof(le_header), header.backing_filename_size, + ret = blk_co_pwrite(blk, sizeof(le_header), header.backing_filename_size, qed_opts->backing_file, 0); if (ret < 0) { goto out; } l1_table = g_malloc0(l1_size); - ret = blk_pwrite(blk, header.l1_table_offset, l1_size, l1_table, 0); + ret = blk_co_pwrite(blk, header.l1_table_offset, l1_size, l1_table, 0); if (ret < 0) { goto out; } diff --git a/block/raw-format.c b/block/raw-format.c index c8dc9bc850..a68014ef0b 100644 --- a/block/raw-format.c +++ b/block/raw-format.c @@ -460,8 +460,8 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags, file_role = BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY; } - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - file_role, false, errp); + bdrv_open_child(NULL, options, "file", bs, &child_of_bds, + file_role, false, errp); if (!bs->file) { return -EINVAL; } diff --git a/block/replication.c b/block/replication.c index 13f1d39571..f1eed25e43 100644 --- a/block/replication.c +++ b/block/replication.c @@ -88,11 +88,9 @@ static int replication_open(BlockDriverState *bs, QDict *options, const char *mode; const char *top_id; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } ret = -EINVAL; diff --git a/block/snapshot-access.c b/block/snapshot-access.c index 77b87c1946..0a30ec6cd9 100644 --- a/block/snapshot-access.c +++ b/block/snapshot-access.c @@ -82,9 +82,9 @@ static void snapshot_access_refresh_filename(BlockDriverState *bs) static int snapshot_access_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY, - false, errp); + bdrv_open_child(NULL, options, "file", bs, &child_of_bds, + BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY, + false, errp); if (!bs->file) { return -EINVAL; } diff --git a/block/snapshot.c b/block/snapshot.c index d6f53c3065..e22ac3eac6 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -151,41 +151,29 @@ bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs, } /** - * Return a pointer to the child BDS pointer to which we can fall + * Return a pointer to child of given BDS to which we can fall * back if the given BDS does not support snapshots. * Return NULL if there is no BDS to (safely) fall back to. - * - * We need to return an indirect pointer because bdrv_snapshot_goto() - * has to modify the BdrvChild pointer. */ -static BdrvChild **bdrv_snapshot_fallback_ptr(BlockDriverState *bs) +static BdrvChild *bdrv_snapshot_fallback_child(BlockDriverState *bs) { - BdrvChild **fallback; + BdrvChild *fallback = bdrv_primary_child(bs); BdrvChild *child; - /* - * The only BdrvChild pointers that are safe to modify (and which - * we can thus return a reference to) are bs->file and - * bs->backing. - */ - fallback = &bs->file; - if (!*fallback && bs->drv && bs->drv->is_filter) { - fallback = &bs->backing; - } - - if (!*fallback) { + /* We allow fallback only to primary child */ + if (!fallback) { return NULL; } /* * Check that there are no other children that would need to be * snapshotted. If there are, it is not safe to fall back to - * *fallback. + * fallback. */ QLIST_FOREACH(child, &bs->children, next) { if (child->role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA | BDRV_CHILD_FILTERED) && - child != *fallback) + child != fallback) { return NULL; } @@ -196,8 +184,7 @@ static BdrvChild **bdrv_snapshot_fallback_ptr(BlockDriverState *bs) static BlockDriverState *bdrv_snapshot_fallback(BlockDriverState *bs) { - BdrvChild **child_ptr = bdrv_snapshot_fallback_ptr(bs); - return child_ptr ? (*child_ptr)->bs : NULL; + return child_bs(bdrv_snapshot_fallback_child(bs)); } int bdrv_can_snapshot(BlockDriverState *bs) @@ -244,7 +231,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs, Error **errp) { BlockDriver *drv = bs->drv; - BdrvChild **fallback_ptr; + BdrvChild *fallback; int ret, open_ret; GLOBAL_STATE_CODE(); @@ -267,13 +254,13 @@ int bdrv_snapshot_goto(BlockDriverState *bs, return ret; } - fallback_ptr = bdrv_snapshot_fallback_ptr(bs); - if (fallback_ptr) { + fallback = bdrv_snapshot_fallback_child(bs); + if (fallback) { QDict *options; QDict *file_options; Error *local_err = NULL; - BlockDriverState *fallback_bs = (*fallback_ptr)->bs; - char *subqdict_prefix = g_strdup_printf("%s.", (*fallback_ptr)->name); + BlockDriverState *fallback_bs = fallback->bs; + char *subqdict_prefix = g_strdup_printf("%s.", fallback->name); options = qdict_clone_shallow(bs->options); @@ -284,8 +271,8 @@ int bdrv_snapshot_goto(BlockDriverState *bs, qobject_unref(file_options); g_free(subqdict_prefix); - /* Force .bdrv_open() below to re-attach fallback_bs on *fallback_ptr */ - qdict_put_str(options, (*fallback_ptr)->name, + /* Force .bdrv_open() below to re-attach fallback_bs on fallback */ + qdict_put_str(options, fallback->name, bdrv_get_node_name(fallback_bs)); /* Now close bs, apply the snapshot on fallback_bs, and re-open bs */ @@ -294,8 +281,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs, } /* .bdrv_open() will re-attach it */ - bdrv_unref_child(bs, *fallback_ptr); - *fallback_ptr = NULL; + bdrv_unref_child(bs, fallback); ret = bdrv_snapshot_goto(fallback_bs, snapshot_id, errp); open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err); @@ -309,15 +295,12 @@ int bdrv_snapshot_goto(BlockDriverState *bs, } /* - * fallback_ptr is &bs->file or &bs->backing. *fallback_ptr - * was closed above and set to NULL, but the .bdrv_open() call - * has opened it again, because we set the respective option - * (with the qdict_put_str() call above). - * Assert that .bdrv_open() has attached some child on - * *fallback_ptr, and that it has attached the one we wanted - * it to (i.e., fallback_bs). + * fallback was a primary child. It was closed above and set to NULL, + * but the .bdrv_open() call has opened it again, because we set the + * respective option (with the qdict_put_str() call above). + * Assert that .bdrv_open() has attached the right BDS as primary child. */ - assert(*fallback_ptr && fallback_bs == (*fallback_ptr)->bs); + assert(bdrv_primary_bs(bs) == fallback_bs); bdrv_unref(fallback_bs); return ret; } diff --git a/block/ssh.c b/block/ssh.c index a3cddc392c..04726d4ecb 100644 --- a/block/ssh.c +++ b/block/ssh.c @@ -1129,9 +1129,9 @@ static coroutine_fn int ssh_co_readv(BlockDriverState *bs, return ret; } -static int ssh_write(BDRVSSHState *s, BlockDriverState *bs, - int64_t offset, size_t size, - QEMUIOVector *qiov) +static coroutine_fn int ssh_write(BDRVSSHState *s, BlockDriverState *bs, + int64_t offset, size_t size, + QEMUIOVector *qiov) { ssize_t r; size_t written; diff --git a/block/throttle.c b/block/throttle.c index ddd450593a..131eba3ab4 100644 --- a/block/throttle.c +++ b/block/throttle.c @@ -78,11 +78,9 @@ static int throttle_open(BlockDriverState *bs, QDict *options, char *group; int ret; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, - false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } bs->supported_write_flags = bs->file->bs->supported_write_flags | BDRV_REQ_WRITE_UNCHANGED; diff --git a/block/vdi.c b/block/vdi.c index e942325455..c0c111c4b9 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -377,10 +377,9 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags, int ret; QemuUUID uuid_link, uuid_parent; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } logout("\n"); @@ -664,7 +663,8 @@ vdi_co_pwritev(BlockDriverState *bs, int64_t offset, int64_t bytes, * so this full-cluster write does not overlap a partial write * of the same cluster, issued from the "else" branch. */ - ret = bdrv_pwrite(bs->file, data_offset, s->block_size, block, 0); + ret = bdrv_co_pwrite(bs->file, data_offset, s->block_size, block, + 0); qemu_co_rwlock_unlock(&s->bmap_lock); } else { nonallocating_write: @@ -709,7 +709,7 @@ nonallocating_write: assert(VDI_IS_ALLOCATED(bmap_first)); *header = s->header; vdi_header_to_le(header); - ret = bdrv_pwrite(bs->file, 0, sizeof(*header), header, 0); + ret = bdrv_co_pwrite(bs->file, 0, sizeof(*header), header, 0); g_free(header); if (ret < 0) { @@ -726,8 +726,8 @@ nonallocating_write: base = ((uint8_t *)&s->bmap[0]) + bmap_first * SECTOR_SIZE; logout("will write %u block map sectors starting from entry %u\n", n_sectors, bmap_first); - ret = bdrv_pwrite(bs->file, offset * SECTOR_SIZE, - n_sectors * SECTOR_SIZE, base, 0); + ret = bdrv_co_pwrite(bs->file, offset * SECTOR_SIZE, + n_sectors * SECTOR_SIZE, base, 0); } return ret; @@ -845,7 +845,7 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options, vdi_header_print(&header); } vdi_header_to_le(&header); - ret = blk_pwrite(blk, offset, sizeof(header), &header, 0); + ret = blk_co_pwrite(blk, offset, sizeof(header), &header, 0); if (ret < 0) { error_setg(errp, "Error writing header"); goto exit; @@ -866,7 +866,7 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options, bmap[i] = VDI_UNALLOCATED; } } - ret = blk_pwrite(blk, offset, bmap_size, bmap, 0); + ret = blk_co_pwrite(blk, offset, bmap_size, bmap, 0); if (ret < 0) { error_setg(errp, "Error writing bmap"); goto exit; @@ -875,8 +875,8 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreateOptions *create_options, } if (image_type == VDI_TYPE_STATIC) { - ret = blk_truncate(blk, offset + blocks * block_size, false, - PREALLOC_MODE_OFF, 0, errp); + ret = blk_co_truncate(blk, offset + blocks * block_size, false, + PREALLOC_MODE_OFF, 0, errp); if (ret < 0) { error_prepend(errp, "Failed to statically allocate file"); goto exit; diff --git a/block/vhdx.c b/block/vhdx.c index e2344ee0b7..bad9ca691b 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -1001,10 +1001,9 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags, uint64_t signature; Error *local_err = NULL; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } s->bat = NULL; @@ -2011,15 +2010,15 @@ static int coroutine_fn vhdx_co_create(BlockdevCreateOptions *opts, creator = g_utf8_to_utf16("QEMU v" QEMU_VERSION, -1, NULL, &creator_items, NULL); signature = cpu_to_le64(VHDX_FILE_SIGNATURE); - ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET, sizeof(signature), &signature, - 0); + ret = blk_co_pwrite(blk, VHDX_FILE_ID_OFFSET, sizeof(signature), &signature, + 0); if (ret < 0) { error_setg_errno(errp, -ret, "Failed to write file signature"); goto delete_and_exit; } if (creator) { - ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET + sizeof(signature), - creator_items * sizeof(gunichar2), creator, 0); + ret = blk_co_pwrite(blk, VHDX_FILE_ID_OFFSET + sizeof(signature), + creator_items * sizeof(gunichar2), creator, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Failed to write creator field"); goto delete_and_exit; diff --git a/block/vmdk.c b/block/vmdk.c index f7d8856dfb..26376352b9 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1308,10 +1308,9 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags, BDRVVmdkState *s = bs->opaque; uint32_t magic; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } buf = vmdk_read_desc(bs->file, 0, errp); @@ -1404,13 +1403,13 @@ static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp) * [@skip_start_sector, @skip_end_sector) is not copied or written, and leave * it for call to write user data in the request. */ -static int get_whole_cluster(BlockDriverState *bs, - VmdkExtent *extent, - uint64_t cluster_offset, - uint64_t offset, - uint64_t skip_start_bytes, - uint64_t skip_end_bytes, - bool zeroed) +static int coroutine_fn get_whole_cluster(BlockDriverState *bs, + VmdkExtent *extent, + uint64_t cluster_offset, + uint64_t offset, + uint64_t skip_start_bytes, + uint64_t skip_end_bytes, + bool zeroed) { int ret = VMDK_OK; int64_t cluster_bytes; @@ -1441,16 +1440,16 @@ static int get_whole_cluster(BlockDriverState *bs, if (copy_from_backing) { /* qcow2 emits this on bs->file instead of bs->backing */ BLKDBG_EVENT(extent->file, BLKDBG_COW_READ); - ret = bdrv_pread(bs->backing, offset, skip_start_bytes, - whole_grain, 0); + ret = bdrv_co_pread(bs->backing, offset, skip_start_bytes, + whole_grain, 0); if (ret < 0) { ret = VMDK_ERROR; goto exit; } } BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE); - ret = bdrv_pwrite(extent->file, cluster_offset, skip_start_bytes, - whole_grain, 0); + ret = bdrv_co_pwrite(extent->file, cluster_offset, skip_start_bytes, + whole_grain, 0); if (ret < 0) { ret = VMDK_ERROR; goto exit; @@ -1461,18 +1460,18 @@ static int get_whole_cluster(BlockDriverState *bs, if (copy_from_backing) { /* qcow2 emits this on bs->file instead of bs->backing */ BLKDBG_EVENT(extent->file, BLKDBG_COW_READ); - ret = bdrv_pread(bs->backing, offset + skip_end_bytes, - cluster_bytes - skip_end_bytes, - whole_grain + skip_end_bytes, 0); + ret = bdrv_co_pread(bs->backing, offset + skip_end_bytes, + cluster_bytes - skip_end_bytes, + whole_grain + skip_end_bytes, 0); if (ret < 0) { ret = VMDK_ERROR; goto exit; } } BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE); - ret = bdrv_pwrite(extent->file, cluster_offset + skip_end_bytes, - cluster_bytes - skip_end_bytes, - whole_grain + skip_end_bytes, 0); + ret = bdrv_co_pwrite(extent->file, cluster_offset + skip_end_bytes, + cluster_bytes - skip_end_bytes, + whole_grain + skip_end_bytes, 0); if (ret < 0) { ret = VMDK_ERROR; goto exit; @@ -1485,29 +1484,29 @@ exit: return ret; } -static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, - uint32_t offset) +static int coroutine_fn vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, + uint32_t offset) { offset = cpu_to_le32(offset); /* update L2 table */ BLKDBG_EVENT(extent->file, BLKDBG_L2_UPDATE); - if (bdrv_pwrite(extent->file, - ((int64_t)m_data->l2_offset * 512) - + (m_data->l2_index * sizeof(offset)), - sizeof(offset), &offset, 0) < 0) { + if (bdrv_co_pwrite(extent->file, + ((int64_t)m_data->l2_offset * 512) + + (m_data->l2_index * sizeof(offset)), + sizeof(offset), &offset, 0) < 0) { return VMDK_ERROR; } /* update backup L2 table */ if (extent->l1_backup_table_offset != 0) { m_data->l2_offset = extent->l1_backup_table[m_data->l1_index]; - if (bdrv_pwrite(extent->file, - ((int64_t)m_data->l2_offset * 512) - + (m_data->l2_index * sizeof(offset)), - sizeof(offset), &offset, 0) < 0) { + if (bdrv_co_pwrite(extent->file, + ((int64_t)m_data->l2_offset * 512) + + (m_data->l2_index * sizeof(offset)), + sizeof(offset), &offset, 0) < 0) { return VMDK_ERROR; } } - if (bdrv_flush(extent->file->bs) < 0) { + if (bdrv_co_flush(extent->file->bs) < 0) { return VMDK_ERROR; } if (m_data->l2_cache_entry) { @@ -1537,14 +1536,14 @@ static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data, * VMDK_UNALLOC if cluster is not mapped and @allocate is false. * VMDK_ERROR if failed. */ -static int get_cluster_offset(BlockDriverState *bs, - VmdkExtent *extent, - VmdkMetaData *m_data, - uint64_t offset, - bool allocate, - uint64_t *cluster_offset, - uint64_t skip_start_bytes, - uint64_t skip_end_bytes) +static int coroutine_fn get_cluster_offset(BlockDriverState *bs, + VmdkExtent *extent, + VmdkMetaData *m_data, + uint64_t offset, + bool allocate, + uint64_t *cluster_offset, + uint64_t skip_start_bytes, + uint64_t skip_end_bytes) { unsigned int l1_index, l2_offset, l2_index; int min_index, i, j; @@ -1624,11 +1623,10 @@ static int get_cluster_offset(BlockDriverState *bs, } l2_table = (char *)extent->l2_cache + (min_index * l2_size_bytes); BLKDBG_EVENT(extent->file, BLKDBG_L2_LOAD); - if (bdrv_pread(extent->file, + if (bdrv_co_pread(extent->file, (int64_t)l2_offset * 512, l2_size_bytes, - l2_table, - 0 + l2_table, 0 ) < 0) { return VMDK_ERROR; } @@ -1899,7 +1897,8 @@ vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset, cluster_buf = g_malloc(buf_bytes); uncomp_buf = g_malloc(cluster_bytes); BLKDBG_EVENT(extent->file, BLKDBG_READ_COMPRESSED); - ret = bdrv_pread(extent->file, cluster_offset, buf_bytes, cluster_buf, 0); + ret = bdrv_co_pread(extent->file, cluster_offset, buf_bytes, cluster_buf, + 0); if (ret < 0) { goto out; } @@ -2144,8 +2143,8 @@ vmdk_co_pwritev_compressed(BlockDriverState *bs, int64_t offset, int64_t bytes, return length; } length = QEMU_ALIGN_UP(length, BDRV_SECTOR_SIZE); - ret = bdrv_truncate(s->extents[i].file, length, false, - PREALLOC_MODE_OFF, 0, NULL); + ret = bdrv_co_truncate(s->extents[i].file, length, false, + PREALLOC_MODE_OFF, 0, NULL); if (ret < 0) { return ret; } @@ -2586,7 +2585,7 @@ static int coroutine_fn vmdk_co_do_create(int64_t size, desc_offset = 0x200; } - ret = blk_pwrite(blk, desc_offset, desc_len, desc, 0); + ret = blk_co_pwrite(blk, desc_offset, desc_len, desc, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Could not write description"); goto exit; @@ -2594,7 +2593,7 @@ static int coroutine_fn vmdk_co_do_create(int64_t size, /* bdrv_pwrite write padding zeros to align to sector, we don't need that * for description file */ if (desc_offset == 0) { - ret = blk_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp); + ret = blk_co_truncate(blk, desc_len, false, PREALLOC_MODE_OFF, 0, errp); if (ret < 0) { goto exit; } diff --git a/block/vpc.c b/block/vpc.c index 4f49ef207f..95841f259a 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -233,10 +233,9 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags, int ret; int64_t bs_size; - bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds, - BDRV_CHILD_IMAGE, false, errp); - if (!bs->file) { - return -EINVAL; + ret = bdrv_open_file_child(NULL, options, "file", bs, errp); + if (ret < 0) { + return ret; } opts = qemu_opts_create(&vpc_runtime_opts, NULL, 0, &error_abort); diff --git a/block/vvfat.c b/block/vvfat.c index d6dd919683..c5b1442145 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -499,7 +499,7 @@ static bool valid_filename(const unsigned char *name) (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c > 127 || - strchr("$%'-_@~`!(){}^#&.+,;=[]", c) != NULL)) + strchr(" $%'-_@~`!(){}^#&.+,;=[]", c) != NULL)) { return false; } @@ -2993,11 +2993,35 @@ DLOG(checkpoint()); vvfat_close_current_file(s); + if (sector_num == s->offset_to_bootsector && nb_sectors == 1) { + /* + * Write on bootsector. Allow only changing the reserved1 field, + * used to mark volume dirtiness + */ + unsigned char *bootsector = s->first_sectors + + s->offset_to_bootsector * 0x200; + /* + * LATER TODO: if FAT32, this is wrong (see init_directories(), + * which always creates a FAT16 bootsector) + */ + const int reserved1_offset = offsetof(bootsector_t, u.fat16.reserved1); + + for (i = 0; i < 0x200; i++) { + if (i != reserved1_offset && bootsector[i] != buf[i]) { + fprintf(stderr, "Tried to write to protected bootsector\n"); + return -1; + } + } + + /* Update bootsector with the only updatable byte, and return success */ + bootsector[reserved1_offset] = buf[reserved1_offset]; + return 0; + } + /* * Some sanity checks: * - do not allow writing to the boot sector */ - if (sector_num < s->offset_to_fat) return -1; @@ -3146,10 +3170,9 @@ static int enable_write_target(BlockDriverState *bs, Error **errp) array_init(&(s->commits), sizeof(commit_t)); - s->qcow_filename = g_malloc(PATH_MAX); - ret = get_tmp_filename(s->qcow_filename, PATH_MAX); - if (ret < 0) { - error_setg_errno(errp, -ret, "can't create temporary file"); + s->qcow_filename = create_tmp_file(errp); + if (!s->qcow_filename) { + ret = -ENOENT; goto err; } diff --git a/blockdev.c b/blockdev.c index a32bafc07a..3f1dec6242 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1630,8 +1630,8 @@ static void external_snapshot_abort(BlkActionState *common) aio_context_release(aio_context); aio_context_acquire(tmp_context); - ret = bdrv_try_set_aio_context(state->old_bs, - aio_context, NULL); + ret = bdrv_try_change_aio_context(state->old_bs, + aio_context, NULL, NULL); assert(ret == 0); aio_context_release(tmp_context); @@ -1792,12 +1792,12 @@ static void drive_backup_prepare(BlkActionState *common, Error **errp) goto out; } - /* Honor bdrv_try_set_aio_context() context acquisition requirements. */ + /* Honor bdrv_try_change_aio_context() context acquisition requirements. */ old_context = bdrv_get_aio_context(target_bs); aio_context_release(aio_context); aio_context_acquire(old_context); - ret = bdrv_try_set_aio_context(target_bs, aio_context, errp); + ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); if (ret < 0) { bdrv_unref(target_bs); aio_context_release(old_context); @@ -1892,12 +1892,12 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp) return; } - /* Honor bdrv_try_set_aio_context() context acquisition requirements. */ + /* Honor bdrv_try_change_aio_context() context acquisition requirements. */ aio_context = bdrv_get_aio_context(bs); old_context = bdrv_get_aio_context(target_bs); aio_context_acquire(old_context); - ret = bdrv_try_set_aio_context(target_bs, aio_context, errp); + ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); if (ret < 0) { aio_context_release(old_context); return; @@ -2448,7 +2448,7 @@ void coroutine_fn qmp_block_resize(bool has_device, const char *device, bdrv_co_unlock(bs); old_ctx = bdrv_co_enter(bs); - blk_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp); + blk_co_truncate(blk, size, false, PREALLOC_MODE_OFF, 0, errp); bdrv_co_leave(bs, old_ctx); bdrv_co_lock(bs); @@ -3194,12 +3194,12 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) !bdrv_has_zero_init(target_bs))); - /* Honor bdrv_try_set_aio_context() context acquisition requirements. */ + /* Honor bdrv_try_change_aio_context() context acquisition requirements. */ old_context = bdrv_get_aio_context(target_bs); aio_context_release(aio_context); aio_context_acquire(old_context); - ret = bdrv_try_set_aio_context(target_bs, aio_context, errp); + ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); if (ret < 0) { bdrv_unref(target_bs); aio_context_release(old_context); @@ -3266,12 +3266,12 @@ void qmp_blockdev_mirror(bool has_job_id, const char *job_id, zero_target = (sync == MIRROR_SYNC_MODE_FULL); - /* Honor bdrv_try_set_aio_context() context acquisition requirements. */ + /* Honor bdrv_try_change_aio_context() context acquisition requirements. */ old_context = bdrv_get_aio_context(target_bs); aio_context = bdrv_get_aio_context(bs); aio_context_acquire(old_context); - ret = bdrv_try_set_aio_context(target_bs, aio_context, errp); + ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp); aio_context_release(old_context); aio_context_acquire(aio_context); @@ -3767,7 +3767,7 @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread, old_context = bdrv_get_aio_context(bs); aio_context_acquire(old_context); - bdrv_try_set_aio_context(bs, new_context, errp); + bdrv_try_change_aio_context(bs, new_context, NULL, errp); aio_context_release(old_context); } diff --git a/blockjob.c b/blockjob.c index bdf20a0e35..2d86014fa5 100644 --- a/blockjob.c +++ b/blockjob.c @@ -126,37 +126,48 @@ static void child_job_drained_end(BdrvChild *c, int *drained_end_counter) job_resume(&job->job); } -static bool child_job_can_set_aio_ctx(BdrvChild *c, AioContext *ctx, - GSList **ignore, Error **errp) +typedef struct BdrvStateChildJobContext { + AioContext *new_ctx; + BlockJob *job; +} BdrvStateChildJobContext; + +static void child_job_set_aio_ctx_commit(void *opaque) { - BlockJob *job = c->opaque; - GSList *l; + BdrvStateChildJobContext *s = opaque; + BlockJob *job = s->job; - for (l = job->nodes; l; l = l->next) { - BdrvChild *sibling = l->data; - if (!bdrv_child_can_set_aio_context(sibling, ctx, ignore, errp)) { - return false; - } - } - return true; + job_set_aio_context(&job->job, s->new_ctx); } -static void child_job_set_aio_ctx(BdrvChild *c, AioContext *ctx, - GSList **ignore) +static TransactionActionDrv change_child_job_context = { + .commit = child_job_set_aio_ctx_commit, + .clean = g_free, +}; + +static bool child_job_change_aio_ctx(BdrvChild *c, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp) { BlockJob *job = c->opaque; + BdrvStateChildJobContext *s; GSList *l; for (l = job->nodes; l; l = l->next) { BdrvChild *sibling = l->data; - if (g_slist_find(*ignore, sibling)) { - continue; + if (!bdrv_child_change_aio_context(sibling, ctx, visited, + tran, errp)) { + return false; } - *ignore = g_slist_prepend(*ignore, sibling); - bdrv_set_aio_context_ignore(sibling->bs, ctx, ignore); } - job_set_aio_context(&job->job, ctx); + s = g_new(BdrvStateChildJobContext, 1); + *s = (BdrvStateChildJobContext) { + .new_ctx = ctx, + .job = job, + }; + + tran_add(tran, &change_child_job_context, s); + return true; } static AioContext *child_job_get_parent_aio_context(BdrvChild *c) @@ -172,8 +183,7 @@ static const BdrvChildClass child_job = { .drained_begin = child_job_drained_begin, .drained_poll = child_job_drained_poll, .drained_end = child_job_drained_end, - .can_set_aio_ctx = child_job_can_set_aio_ctx, - .set_aio_ctx = child_job_set_aio_ctx, + .change_aio_ctx = child_job_change_aio_ctx, .stay_at_node = true, .get_parent_aio_context = child_job_get_parent_aio_context, }; diff --git a/bsd-user/host/i386/host-signal.h b/bsd-user/host/i386/host-signal.h index 169e61b154..ffdfaba534 100644 --- a/bsd-user/host/i386/host-signal.h +++ b/bsd-user/host/i386/host-signal.h @@ -9,6 +9,7 @@ #ifndef I386_HOST_SIGNAL_H #define I386_HOST_SIGNAL_H +#include <sys/param.h> #include <sys/ucontext.h> #include <machine/trap.h> #include <vm/pmap.h> diff --git a/bsd-user/host/x86_64/host-signal.h b/bsd-user/host/x86_64/host-signal.h index 47ca19f881..32ac4e4180 100644 --- a/bsd-user/host/x86_64/host-signal.h +++ b/bsd-user/host/x86_64/host-signal.h @@ -9,6 +9,7 @@ #ifndef X86_64_HOST_SIGNAL_H #define X86_64_HOST_SIGNAL_H +#include <sys/param.h> #include <sys/ucontext.h> #include <machine/trap.h> #include <vm/pmap.h> diff --git a/configs/devices/mips-softmmu/common.mak b/configs/devices/mips-softmmu/common.mak index d2202c839e..416161f833 100644 --- a/configs/devices/mips-softmmu/common.mak +++ b/configs/devices/mips-softmmu/common.mak @@ -23,7 +23,6 @@ CONFIG_APM=y CONFIG_I8257=y CONFIG_PIIX4=y CONFIG_IDE_ISA=y -CONFIG_IDE_PIIX=y CONFIG_PFLASH_CFI01=y CONFIG_I8259=y CONFIG_MC146818RTC=y diff --git a/configs/devices/mips64el-softmmu/default.mak b/configs/devices/mips64el-softmmu/default.mak index c610749ac1..d5188f7ea5 100644 --- a/configs/devices/mips64el-softmmu/default.mak +++ b/configs/devices/mips64el-softmmu/default.mak @@ -1,7 +1,6 @@ # Default configuration for mips64el-softmmu include ../mips-softmmu/common.mak -CONFIG_IDE_VIA=y CONFIG_FULOONG=y CONFIG_LOONGSON3V=y CONFIG_ATI_VGA=y diff --git a/crypto/block-luks-priv.h b/crypto/block-luks-priv.h new file mode 100644 index 0000000000..90a20d432b --- /dev/null +++ b/crypto/block-luks-priv.h @@ -0,0 +1,143 @@ +/* + * QEMU Crypto block device encryption LUKS format + * + * Copyright (c) 2015-2016 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/bswap.h" + +#include "block-luks.h" + +#include "crypto/hash.h" +#include "crypto/afsplit.h" +#include "crypto/pbkdf.h" +#include "crypto/secret.h" +#include "crypto/random.h" +#include "qemu/uuid.h" + +#include "qemu/coroutine.h" +#include "qemu/bitmap.h" + +/* + * Reference for the LUKS format implemented here is + * + * docs/on-disk-format.pdf + * + * in 'cryptsetup' package source code + * + * This file implements the 1.2.1 specification, dated + * Oct 16, 2011. + */ + +typedef struct QCryptoBlockLUKSHeader QCryptoBlockLUKSHeader; +typedef struct QCryptoBlockLUKSKeySlot QCryptoBlockLUKSKeySlot; + + +/* The following constants are all defined by the LUKS spec */ +#define QCRYPTO_BLOCK_LUKS_VERSION 1 + +#define QCRYPTO_BLOCK_LUKS_MAGIC_LEN 6 +#define QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN 32 +#define QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN 32 +#define QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN 32 +#define QCRYPTO_BLOCK_LUKS_DIGEST_LEN 20 +#define QCRYPTO_BLOCK_LUKS_SALT_LEN 32 +#define QCRYPTO_BLOCK_LUKS_UUID_LEN 40 +#define QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS 8 +#define QCRYPTO_BLOCK_LUKS_STRIPES 4000 +#define QCRYPTO_BLOCK_LUKS_MIN_SLOT_KEY_ITERS 1000 +#define QCRYPTO_BLOCK_LUKS_MIN_MASTER_KEY_ITERS 1000 +#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET 4096 + +#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_DISABLED 0x0000DEAD +#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED 0x00AC71F3 + +#define QCRYPTO_BLOCK_LUKS_SECTOR_SIZE 512LL + +#define QCRYPTO_BLOCK_LUKS_DEFAULT_ITER_TIME_MS 2000 +#define QCRYPTO_BLOCK_LUKS_ERASE_ITERATIONS 40 + +static const char qcrypto_block_luks_magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN] = { + 'L', 'U', 'K', 'S', 0xBA, 0xBE +}; + +/* + * This struct is written to disk in big-endian format, + * but operated upon in native-endian format. + */ +struct QCryptoBlockLUKSKeySlot { + /* state of keyslot, enabled/disable */ + uint32_t active; + /* iterations for PBKDF2 */ + uint32_t iterations; + /* salt for PBKDF2 */ + uint8_t salt[QCRYPTO_BLOCK_LUKS_SALT_LEN]; + /* start sector of key material */ + uint32_t key_offset_sector; + /* number of anti-forensic stripes */ + uint32_t stripes; +}; + +/* + * This struct is written to disk in big-endian format, + * but operated upon in native-endian format. + */ +struct QCryptoBlockLUKSHeader { + /* 'L', 'U', 'K', 'S', '0xBA', '0xBE' */ + char magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN]; + + /* LUKS version, currently 1 */ + uint16_t version; + + /* cipher name specification (aes, etc) */ + char cipher_name[QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN]; + + /* cipher mode specification (cbc-plain, xts-essiv:sha256, etc) */ + char cipher_mode[QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN]; + + /* hash specification (sha256, etc) */ + char hash_spec[QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN]; + + /* start offset of the volume data (in 512 byte sectors) */ + uint32_t payload_offset_sector; + + /* Number of key bytes */ + uint32_t master_key_len; + + /* master key checksum after PBKDF2 */ + uint8_t master_key_digest[QCRYPTO_BLOCK_LUKS_DIGEST_LEN]; + + /* salt for master key PBKDF2 */ + uint8_t master_key_salt[QCRYPTO_BLOCK_LUKS_SALT_LEN]; + + /* iterations for master key PBKDF2 */ + uint32_t master_key_iterations; + + /* UUID of the partition in standard ASCII representation */ + uint8_t uuid[QCRYPTO_BLOCK_LUKS_UUID_LEN]; + + /* key slots */ + QCryptoBlockLUKSKeySlot key_slots[QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS]; +}; + + +void +qcrypto_block_luks_to_disk_endian(QCryptoBlockLUKSHeader *hdr); +void +qcrypto_block_luks_from_disk_endian(QCryptoBlockLUKSHeader *hdr); diff --git a/crypto/block-luks.c b/crypto/block-luks.c index f62be6836b..df2b4105d6 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -23,6 +23,7 @@ #include "qemu/bswap.h" #include "block-luks.h" +#include "block-luks-priv.h" #include "crypto/hash.h" #include "crypto/afsplit.h" @@ -46,37 +47,6 @@ */ typedef struct QCryptoBlockLUKS QCryptoBlockLUKS; -typedef struct QCryptoBlockLUKSHeader QCryptoBlockLUKSHeader; -typedef struct QCryptoBlockLUKSKeySlot QCryptoBlockLUKSKeySlot; - - -/* The following constants are all defined by the LUKS spec */ -#define QCRYPTO_BLOCK_LUKS_VERSION 1 - -#define QCRYPTO_BLOCK_LUKS_MAGIC_LEN 6 -#define QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN 32 -#define QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN 32 -#define QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN 32 -#define QCRYPTO_BLOCK_LUKS_DIGEST_LEN 20 -#define QCRYPTO_BLOCK_LUKS_SALT_LEN 32 -#define QCRYPTO_BLOCK_LUKS_UUID_LEN 40 -#define QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS 8 -#define QCRYPTO_BLOCK_LUKS_STRIPES 4000 -#define QCRYPTO_BLOCK_LUKS_MIN_SLOT_KEY_ITERS 1000 -#define QCRYPTO_BLOCK_LUKS_MIN_MASTER_KEY_ITERS 1000 -#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET 4096 - -#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_DISABLED 0x0000DEAD -#define QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED 0x00AC71F3 - -#define QCRYPTO_BLOCK_LUKS_SECTOR_SIZE 512LL - -#define QCRYPTO_BLOCK_LUKS_DEFAULT_ITER_TIME_MS 2000 -#define QCRYPTO_BLOCK_LUKS_ERASE_ITERATIONS 40 - -static const char qcrypto_block_luks_magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN] = { - 'L', 'U', 'K', 'S', 0xBA, 0xBE -}; typedef struct QCryptoBlockLUKSNameMap QCryptoBlockLUKSNameMap; struct QCryptoBlockLUKSNameMap { @@ -134,69 +104,7 @@ qcrypto_block_luks_cipher_name_map[] = { { "twofish", qcrypto_block_luks_cipher_size_map_twofish }, }; - -/* - * This struct is written to disk in big-endian format, - * but operated upon in native-endian format. - */ -struct QCryptoBlockLUKSKeySlot { - /* state of keyslot, enabled/disable */ - uint32_t active; - /* iterations for PBKDF2 */ - uint32_t iterations; - /* salt for PBKDF2 */ - uint8_t salt[QCRYPTO_BLOCK_LUKS_SALT_LEN]; - /* start sector of key material */ - uint32_t key_offset_sector; - /* number of anti-forensic stripes */ - uint32_t stripes; -}; - QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSKeySlot) != 48); - - -/* - * This struct is written to disk in big-endian format, - * but operated upon in native-endian format. - */ -struct QCryptoBlockLUKSHeader { - /* 'L', 'U', 'K', 'S', '0xBA', '0xBE' */ - char magic[QCRYPTO_BLOCK_LUKS_MAGIC_LEN]; - - /* LUKS version, currently 1 */ - uint16_t version; - - /* cipher name specification (aes, etc) */ - char cipher_name[QCRYPTO_BLOCK_LUKS_CIPHER_NAME_LEN]; - - /* cipher mode specification (cbc-plain, xts-essiv:sha256, etc) */ - char cipher_mode[QCRYPTO_BLOCK_LUKS_CIPHER_MODE_LEN]; - - /* hash specification (sha256, etc) */ - char hash_spec[QCRYPTO_BLOCK_LUKS_HASH_SPEC_LEN]; - - /* start offset of the volume data (in 512 byte sectors) */ - uint32_t payload_offset_sector; - - /* Number of key bytes */ - uint32_t master_key_len; - - /* master key checksum after PBKDF2 */ - uint8_t master_key_digest[QCRYPTO_BLOCK_LUKS_DIGEST_LEN]; - - /* salt for master key PBKDF2 */ - uint8_t master_key_salt[QCRYPTO_BLOCK_LUKS_SALT_LEN]; - - /* iterations for master key PBKDF2 */ - uint32_t master_key_iterations; - - /* UUID of the partition in standard ASCII representation */ - uint8_t uuid[QCRYPTO_BLOCK_LUKS_UUID_LEN]; - - /* key slots */ - QCryptoBlockLUKSKeySlot key_slots[QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS]; -}; - QEMU_BUILD_BUG_ON(sizeof(struct QCryptoBlockLUKSHeader) != 592); @@ -254,7 +162,7 @@ static int qcrypto_block_luks_cipher_name_lookup(const char *name, } } - error_setg(errp, "Algorithm %s with key size %d bytes not supported", + error_setg(errp, "Algorithm '%s' with key size %d bytes not supported", name, key_bytes); return 0; } @@ -290,7 +198,7 @@ static int qcrypto_block_luks_name_lookup(const char *name, int ret = qapi_enum_parse(map, name, -1, NULL); if (ret < 0) { - error_setg(errp, "%s %s not supported", type, name); + error_setg(errp, "%s '%s' not supported", type, name); return 0; } return ret; @@ -440,6 +348,51 @@ qcrypto_block_luks_splitkeylen_sectors(const QCryptoBlockLUKS *luks, return ROUND_UP(splitkeylen_sectors, header_sectors); } + +void +qcrypto_block_luks_to_disk_endian(QCryptoBlockLUKSHeader *hdr) +{ + size_t i; + + /* + * Everything on disk uses Big Endian (tm), so flip header fields + * before writing them + */ + cpu_to_be16s(&hdr->version); + cpu_to_be32s(&hdr->payload_offset_sector); + cpu_to_be32s(&hdr->master_key_len); + cpu_to_be32s(&hdr->master_key_iterations); + + for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { + cpu_to_be32s(&hdr->key_slots[i].active); + cpu_to_be32s(&hdr->key_slots[i].iterations); + cpu_to_be32s(&hdr->key_slots[i].key_offset_sector); + cpu_to_be32s(&hdr->key_slots[i].stripes); + } +} + +void +qcrypto_block_luks_from_disk_endian(QCryptoBlockLUKSHeader *hdr) +{ + size_t i; + + /* + * The header is always stored in big-endian format, so + * convert everything to native + */ + be16_to_cpus(&hdr->version); + be32_to_cpus(&hdr->payload_offset_sector); + be32_to_cpus(&hdr->master_key_len); + be32_to_cpus(&hdr->master_key_iterations); + + for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { + be32_to_cpus(&hdr->key_slots[i].active); + be32_to_cpus(&hdr->key_slots[i].iterations); + be32_to_cpus(&hdr->key_slots[i].key_offset_sector); + be32_to_cpus(&hdr->key_slots[i].stripes); + } +} + /* * Stores the main LUKS header, taking care of endianess */ @@ -451,28 +404,13 @@ qcrypto_block_luks_store_header(QCryptoBlock *block, { const QCryptoBlockLUKS *luks = block->opaque; Error *local_err = NULL; - size_t i; g_autofree QCryptoBlockLUKSHeader *hdr_copy = NULL; /* Create a copy of the header */ hdr_copy = g_new0(QCryptoBlockLUKSHeader, 1); memcpy(hdr_copy, &luks->header, sizeof(QCryptoBlockLUKSHeader)); - /* - * Everything on disk uses Big Endian (tm), so flip header fields - * before writing them - */ - cpu_to_be16s(&hdr_copy->version); - cpu_to_be32s(&hdr_copy->payload_offset_sector); - cpu_to_be32s(&hdr_copy->master_key_len); - cpu_to_be32s(&hdr_copy->master_key_iterations); - - for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { - cpu_to_be32s(&hdr_copy->key_slots[i].active); - cpu_to_be32s(&hdr_copy->key_slots[i].iterations); - cpu_to_be32s(&hdr_copy->key_slots[i].key_offset_sector); - cpu_to_be32s(&hdr_copy->key_slots[i].stripes); - } + qcrypto_block_luks_to_disk_endian(hdr_copy); /* Write out the partition header and key slot headers */ writefunc(block, 0, (const uint8_t *)hdr_copy, sizeof(*hdr_copy), @@ -496,7 +434,6 @@ qcrypto_block_luks_load_header(QCryptoBlock *block, Error **errp) { int rv; - size_t i; QCryptoBlockLUKS *luks = block->opaque; /* @@ -512,21 +449,7 @@ qcrypto_block_luks_load_header(QCryptoBlock *block, return rv; } - /* - * The header is always stored in big-endian format, so - * convert everything to native - */ - be16_to_cpus(&luks->header.version); - be32_to_cpus(&luks->header.payload_offset_sector); - be32_to_cpus(&luks->header.master_key_len); - be32_to_cpus(&luks->header.master_key_iterations); - - for (i = 0; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS; i++) { - be32_to_cpus(&luks->header.key_slots[i].active); - be32_to_cpus(&luks->header.key_slots[i].iterations); - be32_to_cpus(&luks->header.key_slots[i].key_offset_sector); - be32_to_cpus(&luks->header.key_slots[i].stripes); - } + qcrypto_block_luks_from_disk_endian(&luks->header); return 0; } @@ -554,6 +477,36 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp) return -1; } + if (!memchr(luks->header.cipher_name, '\0', + sizeof(luks->header.cipher_name))) { + error_setg(errp, "LUKS header cipher name is not NUL terminated"); + return -1; + } + + if (!memchr(luks->header.cipher_mode, '\0', + sizeof(luks->header.cipher_mode))) { + error_setg(errp, "LUKS header cipher mode is not NUL terminated"); + return -1; + } + + if (!memchr(luks->header.hash_spec, '\0', + sizeof(luks->header.hash_spec))) { + error_setg(errp, "LUKS header hash spec is not NUL terminated"); + return -1; + } + + if (luks->header.payload_offset_sector < + DIV_ROUND_UP(QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET, + QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) { + error_setg(errp, "LUKS payload is overlapping with the header"); + return -1; + } + + if (luks->header.master_key_iterations == 0) { + error_setg(errp, "LUKS key iteration count is zero"); + return -1; + } + /* Check all keyslots for corruption */ for (i = 0 ; i < QCRYPTO_BLOCK_LUKS_NUM_KEY_SLOTS ; i++) { @@ -564,8 +517,9 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp) header_sectors, slot1->stripes); - if (slot1->stripes == 0) { - error_setg(errp, "Keyslot %zu is corrupted (stripes == 0)", i); + if (slot1->stripes != QCRYPTO_BLOCK_LUKS_STRIPES) { + error_setg(errp, "Keyslot %zu is corrupted (stripes %d != %d)", + i, slot1->stripes, QCRYPTO_BLOCK_LUKS_STRIPES); return -1; } @@ -576,6 +530,20 @@ qcrypto_block_luks_check_header(const QCryptoBlockLUKS *luks, Error **errp) return -1; } + if (slot1->active == QCRYPTO_BLOCK_LUKS_KEY_SLOT_ENABLED && + slot1->iterations == 0) { + error_setg(errp, "Keyslot %zu iteration count is zero", i); + return -1; + } + + if (start1 < DIV_ROUND_UP(QCRYPTO_BLOCK_LUKS_KEY_SLOT_OFFSET, + QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)) { + error_setg(errp, + "Keyslot %zu is overlapping with the LUKS header", + i); + return -1; + } + if (start1 + len1 > luks->header.payload_offset_sector) { error_setg(errp, "Keyslot %zu is overlapping with the encrypted payload", @@ -624,7 +592,7 @@ qcrypto_block_luks_parse_header(QCryptoBlockLUKS *luks, Error **errp) */ ivgen_name = strchr(cipher_mode, '-'); if (!ivgen_name) { - error_setg(errp, "Unexpected cipher mode string format %s", + error_setg(errp, "Unexpected cipher mode string format '%s'", luks->header.cipher_mode); return -1; } diff --git a/crypto/pbkdf.c b/crypto/pbkdf.c index 3775ddc6c5..8d198c152c 100644 --- a/crypto/pbkdf.c +++ b/crypto/pbkdf.c @@ -24,6 +24,11 @@ #ifndef _WIN32 #include <sys/resource.h> #endif +#ifdef CONFIG_DARWIN +#include <mach/mach_init.h> +#include <mach/thread_act.h> +#include <mach/mach_port.h> +#endif static int qcrypto_pbkdf2_get_thread_cpu(unsigned long long *val_ms, @@ -45,6 +50,24 @@ static int qcrypto_pbkdf2_get_thread_cpu(unsigned long long *val_ms, /* QuadPart is units of 100ns and we want ms as unit */ *val_ms = thread_time.QuadPart / 10000ll; return 0; +#elif defined(CONFIG_DARWIN) + mach_port_t thread; + kern_return_t kr; + mach_msg_type_number_t count; + thread_basic_info_data_t info; + + thread = mach_thread_self(); + count = THREAD_BASIC_INFO_COUNT; + kr = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t)&info, &count); + mach_port_deallocate(mach_task_self(), thread); + if (kr != KERN_SUCCESS || (info.flags & TH_FLAGS_IDLE) != 0) { + error_setg_errno(errp, errno, "Unable to get thread CPU usage"); + return -1; + } + + *val_ms = ((info.user_time.seconds * 1000ll) + + (info.user_time.microseconds / 1000)); + return 0; #elif defined(RUSAGE_THREAD) struct rusage ru; if (getrusage(RUSAGE_THREAD, &ru) < 0) { diff --git a/crypto/tlscredspsk.c b/crypto/tlscredspsk.c index a4f9891274..546cad1c5a 100644 --- a/crypto/tlscredspsk.c +++ b/crypto/tlscredspsk.c @@ -109,7 +109,12 @@ qcrypto_tls_creds_psk_load(QCryptoTLSCredsPSK *creds, goto cleanup; } - gnutls_psk_set_server_credentials_file(creds->data.server, pskfile); + ret = gnutls_psk_set_server_credentials_file(creds->data.server, pskfile); + if (ret < 0) { + error_setg(errp, "Cannot set PSK server credentials: %s", + gnutls_strerror(ret)); + goto cleanup; + } gnutls_psk_set_server_dh_params(creds->data.server, creds->parent_obj.dh_params); } else { @@ -135,8 +140,13 @@ qcrypto_tls_creds_psk_load(QCryptoTLSCredsPSK *creds, goto cleanup; } - gnutls_psk_set_client_credentials(creds->data.client, - username, &key, GNUTLS_PSK_KEY_HEX); + ret = gnutls_psk_set_client_credentials(creds->data.client, + username, &key, GNUTLS_PSK_KEY_HEX); + if (ret < 0) { + error_setg(errp, "Cannot set PSK client credentials: %s", + gnutls_strerror(ret)); + goto cleanup; + } } rv = 0; diff --git a/disas/meson.build b/disas/meson.build index ba22f7cbcd..1977f5cd92 100644 --- a/disas/meson.build +++ b/disas/meson.build @@ -5,7 +5,7 @@ common_ss.add(when: 'CONFIG_HPPA_DIS', if_true: files('hppa.c')) common_ss.add(when: 'CONFIG_M68K_DIS', if_true: files('m68k.c')) common_ss.add(when: 'CONFIG_MICROBLAZE_DIS', if_true: files('microblaze.c')) common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c')) -common_ss.add(when: 'CONFIG_NANOMIPS_DIS', if_true: files('nanomips.cpp')) +common_ss.add(when: 'CONFIG_NANOMIPS_DIS', if_true: files('nanomips.c')) common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c')) common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files('riscv.c')) common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c')) diff --git a/disas/mips.c b/disas/mips.c index b9a5204304..5aacacb2c8 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -20,6 +20,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" +#include "qemu/bitops.h" #include "disas/dis-asm.h" /* mips.h. Mips opcode list for GDB, the GNU debugger. @@ -1334,9 +1335,9 @@ const struct mips_opcode mips_builtin_opcodes[] = {"balc", "+p", 0xe8000000, 0xfc000000, UBD|WR_31, 0, I32R6}, {"bc", "+p", 0xc8000000, 0xfc000000, UBD|WR_31, 0, I32R6}, {"jic", "t,o", 0xd8000000, 0xffe00000, UBD|RD_t, 0, I32R6}, -{"beqzc", "s,+p", 0xd8000000, 0xfc000000, CBD|RD_s, 0, I32R6}, +{"beqzc", "s,+q", 0xd8000000, 0xfc000000, CBD|RD_s, 0, I32R6}, {"jialc", "t,o", 0xf8000000, 0xffe00000, UBD|RD_t, 0, I32R6}, -{"bnezc", "s,+p", 0xf8000000, 0xfc000000, CBD|RD_s, 0, I32R6}, +{"bnezc", "s,+q", 0xf8000000, 0xfc000000, CBD|RD_s, 0, I32R6}, {"beqzalc", "s,t,p", 0x20000000, 0xffe00000, CBD|RD_s|RD_t, 0, I32R6}, {"bovc", "s,t,p", 0x20000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6}, {"beqc", "s,t,p", 0x20000000, 0xfc000000, CBD|RD_s|RD_t, 0, I32R6}, @@ -4462,6 +4463,13 @@ print_insn_args (const char *d, (*info->print_address_func) (info->target, info); break; + case 'q': + /* Sign extend the displacement with 21 bits. */ + delta = sextract32(l, OP_SH_DELTA, 21); + info->target = (delta << 2) + pc + INSNLEN; + (*info->print_address_func) (info->target, info); + break; + case 't': /* Coprocessor 0 reg name */ (*info->fprintf_func) (info->stream, "%s", mips_cp0_names[(l >> OP_SH_RT) & diff --git a/disas/nanomips.cpp b/disas/nanomips.c index 9be8df75dd..9647f1a8e3 100644 --- a/disas/nanomips.cpp +++ b/disas/nanomips.c @@ -30,274 +30,116 @@ #include "qemu/osdep.h" #include "disas/dis-asm.h" -#include <cstring> -#include <stdexcept> -#include <sstream> +#include <string.h> #include <stdio.h> #include <stdarg.h> -#include "nanomips.h" +typedef int64_t int64; +typedef uint64_t uint64; +typedef uint32_t uint32; +typedef uint16_t uint16; +typedef uint64_t img_address; + +typedef enum { + instruction, + call_instruction, + branch_instruction, + return_instruction, + reserved_block, + pool, +} TABLE_ENTRY_TYPE; + +typedef enum { + 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, +} TABLE_ATTRIBUTE_TYPE; + +typedef struct Dis_info { + img_address m_pc; + fprintf_function fprintf_func; + FILE *stream; + sigjmp_buf buf; +} Dis_info; + +typedef bool (*conditional_function)(uint64 instruction); +typedef char * (*disassembly_function)(uint64 instruction, + Dis_info *info); + +typedef struct Pool { + TABLE_ENTRY_TYPE type; + const struct Pool *next_table; + int next_table_size; + int instructions_size; + uint64 mask; + uint64 value; + disassembly_function disassembly; + conditional_function condition; + uint64 attributes; +} Pool; #define IMGASSERTONCE(test) -int nanomips_dis(char *buf, - unsigned address, - unsigned short one, - unsigned short two, - unsigned short three) +static char *img_format(const char *format, ...) { - 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; + char *buffer; + va_list args; + va_start(args, format); + buffer = g_strdup_vprintf(format, args); + va_end(args); + return buffer; } -namespace img +static char *to_string(img_address a) { - 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%" PRIx64, a); - return buffer; + return g_strdup_printf("0x%" PRIx64, a); } -uint64 extract_bits(uint64 data, uint32 bit_offset, uint32 bit_size) +static 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) +static 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) +static uint64 renumber_registers(uint64 index, uint64 *register_list, + size_t register_list_size, Dis_info *info) { if (index < register_list_size) { return register_list[index]; } - throw std::runtime_error(img::format( - "Invalid register mapping index %" PRIu64 - ", size of list = %zu", - index, register_list_size)); + info->fprintf_func(info->stream, "Invalid register mapping index %" PRIu64 + ", size of list = %zu", index, register_list_size); + siglongjmp(info->buf, 1); } /* - * NMD::decode_gpr_gpr4() - decoder for 'gpr4' gpr encoding type + * decode_gpr_gpr4() - decoder for 'gpr4' gpr encoding type * * Map a 4-bit code to the 5-bit register space according to this pattern: * @@ -322,17 +164,17 @@ uint64 NMD::renumber_registers(uint64 index, uint64 *register_list, * - MUL[4X4] * - SW[4X4] */ -uint64 NMD::decode_gpr_gpr4(uint64 d) +static uint64 decode_gpr_gpr4(uint64 d, Dis_info *info) { 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])); + sizeof(register_list) / sizeof(register_list[0]), info); } /* - * NMD::decode_gpr_gpr4_zero() - decoder for 'gpr4.zero' gpr encoding type + * decode_gpr_gpr4_zero() - decoder for 'gpr4.zero' gpr encoding type * * Map a 4-bit code to the 5-bit register space according to this pattern: * @@ -358,17 +200,17 @@ uint64 NMD::decode_gpr_gpr4(uint64 d) * - MOVEP * - SW[4X4] */ -uint64 NMD::decode_gpr_gpr4_zero(uint64 d) +static uint64 decode_gpr_gpr4_zero(uint64 d, Dis_info *info) { 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])); + sizeof(register_list) / sizeof(register_list[0]), info); } /* - * NMD::decode_gpr_gpr3() - decoder for 'gpr3' gpr encoding type + * decode_gpr_gpr3() - decoder for 'gpr3' gpr encoding type * * Map a 3-bit code to the 5-bit register space according to this pattern: * @@ -417,16 +259,16 @@ uint64 NMD::decode_gpr_gpr4_zero(uint64 d) * - SW[16] * - XOR[16] */ -uint64 NMD::decode_gpr_gpr3(uint64 d) +static uint64 decode_gpr_gpr3(uint64 d, Dis_info *info) { 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])); + sizeof(register_list) / sizeof(register_list[0]), info); } /* - * NMD::decode_gpr_gpr3_src_store() - decoder for 'gpr3.src.store' gpr encoding + * decode_gpr_gpr3_src_store() - decoder for 'gpr3.src.store' gpr encoding * type * * Map a 3-bit code to the 5-bit register space according to this pattern: @@ -457,16 +299,16 @@ uint64 NMD::decode_gpr_gpr3(uint64 d) * - SW[16] * - SW[GP16] */ -uint64 NMD::decode_gpr_gpr3_src_store(uint64 d) +static uint64 decode_gpr_gpr3_src_store(uint64 d, Dis_info *info) { 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])); + sizeof(register_list) / sizeof(register_list[0]), info); } /* - * NMD::decode_gpr_gpr2_reg1() - decoder for 'gpr2.reg1' gpr encoding type + * decode_gpr_gpr2_reg1() - decoder for 'gpr2.reg1' gpr encoding type * * Map a 2-bit code to the 5-bit register space according to this pattern: * @@ -487,16 +329,16 @@ uint64 NMD::decode_gpr_gpr3_src_store(uint64 d) * - MOVEP * - MOVEP[REV] */ -uint64 NMD::decode_gpr_gpr2_reg1(uint64 d) +static uint64 decode_gpr_gpr2_reg1(uint64 d, Dis_info *info) { static uint64 register_list[] = { 4, 5, 6, 7 }; return renumber_registers(d, register_list, - sizeof(register_list) / sizeof(register_list[0])); + sizeof(register_list) / sizeof(register_list[0]), info); } /* - * NMD::decode_gpr_gpr2_reg2() - decoder for 'gpr2.reg2' gpr encoding type + * decode_gpr_gpr2_reg2() - decoder for 'gpr2.reg2' gpr encoding type * * Map a 2-bit code to the 5-bit register space according to this pattern: * @@ -517,16 +359,16 @@ uint64 NMD::decode_gpr_gpr2_reg1(uint64 d) * - MOVEP * - MOVEP[REV] */ -uint64 NMD::decode_gpr_gpr2_reg2(uint64 d) +static uint64 decode_gpr_gpr2_reg2(uint64 d, Dis_info *info) { static uint64 register_list[] = { 5, 6, 7, 8 }; return renumber_registers(d, register_list, - sizeof(register_list) / sizeof(register_list[0])); + sizeof(register_list) / sizeof(register_list[0]), info); } /* - * NMD::decode_gpr_gpr1() - decoder for 'gpr1' gpr encoding type + * decode_gpr_gpr1() - decoder for 'gpr1' gpr encoding type * * Map a 1-bit code to the 5-bit register space according to this pattern: * @@ -546,81 +388,28 @@ uint64 NMD::decode_gpr_gpr2_reg2(uint64 d) * * - MOVE.BALC */ -uint64 NMD::decode_gpr_gpr1(uint64 d) +static uint64 decode_gpr_gpr1(uint64 d, Dis_info *info) { static uint64 register_list[] = { 4, 5 }; return renumber_registers(d, register_list, - sizeof(register_list) / sizeof(register_list[0])); + sizeof(register_list) / sizeof(register_list[0]), info); } -uint64 NMD::copy(uint64 d) -{ - return d; -} - - -int64 NMD::copy(int64 d) -{ - return d; -} - - -int64 NMD::neg_copy(uint64 d) +static int64 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 decode_gpr_gpr3(d); -} - - -/* strange wrapper around gpr3 */ -uint64 NMD::encode_rs3_and_check_rs3_lt_rt3(uint64 d) -{ - return decode_gpr_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) +static uint64 encode_count3_from_count(uint64 d) { IMGASSERTONCE(d < 8); return d == 0ull ? 8ull : d; } -uint64 NMD::encode_shift3_from_shift(uint64 d) +static uint64 encode_shift3_from_shift(uint64 d) { IMGASSERTONCE(d < 8); return d == 0ull ? 8ull : d; @@ -628,21 +417,21 @@ uint64 NMD::encode_shift3_from_shift(uint64 d) /* special value for load literal */ -int64 NMD::encode_eu_from_s_li16(uint64 d) +static int64 encode_eu_from_s_li16(uint64 d) { IMGASSERTONCE(d < 128); return d == 127 ? -1 : (int64)d; } -uint64 NMD::encode_msbd_from_size(uint64 d) +static uint64 encode_msbd_from_size(uint64 d) { IMGASSERTONCE(d < 32); return d + 1; } -uint64 NMD::encode_eu_from_u_andi16(uint64 d) +static uint64 encode_eu_from_u_andi16(uint64 d) { IMGASSERTONCE(d < 16); if (d == 12) { @@ -655,42 +444,14 @@ uint64 NMD::encode_eu_from_u_andi16(uint64 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) +static uint64 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(uint64 reg, Dis_info *info) { static const char *gpr_reg[32] = { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", @@ -703,12 +464,32 @@ std::string NMD::GPR(uint64 reg) return gpr_reg[reg]; } - throw std::runtime_error(img::format("Invalid GPR register index %" PRIu64, - reg)); + info->fprintf_func(info->stream, "Invalid GPR register index %" PRIu64, + reg); + siglongjmp(info->buf, 1); } -std::string NMD::FPR(uint64 reg) +static char *save_restore_list(uint64 rt, uint64 count, uint64 gp, + Dis_info *info) +{ + char *reg_list[34]; + reg_list[0] = (char *)""; + + assert(count <= 32); + 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; + /* glib usage below requires casting away const */ + reg_list[counter + 1] = (char *)GPR(this_rt, info); + } + reg_list[count + 1] = NULL; + + return g_strjoinv(",", reg_list); +} + + +static const char *FPR(uint64 reg, Dis_info *info) { static const char *fpr_reg[32] = { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", @@ -721,12 +502,13 @@ std::string NMD::FPR(uint64 reg) return fpr_reg[reg]; } - throw std::runtime_error(img::format("Invalid FPR register index %" PRIu64, - reg)); + info->fprintf_func(info->stream, "Invalid FPR register index %" PRIu64, + reg); + siglongjmp(info->buf, 1); } -std::string NMD::AC(uint64 reg) +static const char *AC(uint64 reg, Dis_info *info) { static const char *ac_reg[4] = { "ac0", "ac1", "ac2", "ac3" @@ -736,42 +518,22 @@ std::string NMD::AC(uint64 reg) return ac_reg[reg]; } - throw std::runtime_error(img::format("Invalid AC register index %" PRIu64, - reg)); + info->fprintf_func(info->stream, "Invalid AC register index %" PRIu64, + reg); + siglongjmp(info->buf, 1); } -std::string NMD::IMMEDIATE(uint64 value) -{ - return img::format("0x%" PRIx64, value); -} - - -std::string NMD::IMMEDIATE(int64 value) -{ - return img::format("%" PRId64, value); -} - - -std::string NMD::CPR(uint64 reg) -{ - /* needs more work */ - return img::format("CP%" PRIu64, reg); -} - - -std::string NMD::ADDRESS(uint64 value, int instruction_size) +static char *ADDRESS(uint64 value, int instruction_size, Dis_info *info) { /* token for string replace */ - /* const char TOKEN_REPLACE = (char)0xa2; */ - img::address address = m_pc + value + instruction_size; + img_address address = info->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) +static uint64 extract_op_code_value(const uint16 *data, int size) { switch (size) { case 16: @@ -786,13 +548,6 @@ uint64 NMD::extract_op_code_value(const uint16 * data, int size) } -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 @@ -804,74 +559,48 @@ int NMD::Disassemble(const uint16 * data, std::string & dis, * 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 mismatch"; - 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 */ +static int Disassemble(const uint16 *data, char **dis, + TABLE_ENTRY_TYPE *type, const Pool *table, + int table_size, Dis_info *info) +{ + 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 == NULL) || cond(op_code)) { + if (table[i].type == pool) { + return Disassemble(data, dis, type, + table[i].next_table, + table[i].next_table_size, + info); + } else if ((table[i].type == instruction) || + (table[i].type == call_instruction) || + (table[i].type == branch_instruction) || + (table[i].type == return_instruction)) { + disassembly_function dis_fn = table[i].disassembly; + if (dis_fn == 0) { + *dis = g_strdup( + "disassembler failure - bad table entry"); + return -6; } + *type = table[i].type; + *dis = dis_fn(op_code, info); + return table[i].instructions_size; + } else { + *dis = g_strdup("reserved instruction"); + return -2; } } } } - catch (std::exception & e) - { - dis = e.what(); - return -4; /* runtime error */ - } - - dis = "failed to disassemble"; + *dis = g_strdup("failed to disassemble"); return -1; /* failed to disassemble */ } -uint64 NMD::extract_code_18_to_0(uint64 instruction) +static uint64 extract_code_18_to_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 19); @@ -879,7 +608,7 @@ uint64 NMD::extract_code_18_to_0(uint64 instruction) } -uint64 NMD::extract_shift3_2_1_0(uint64 instruction) +static uint64 extract_shift3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 3); @@ -887,7 +616,7 @@ uint64 NMD::extract_shift3_2_1_0(uint64 instruction) } -uint64 NMD::extract_u_11_10_9_8_7_6_5_4_3__s3(uint64 instruction) +static uint64 extract_u_11_10_9_8_7_6_5_4_3__s3(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 3, 9) << 3; @@ -895,7 +624,7 @@ uint64 NMD::extract_u_11_10_9_8_7_6_5_4_3__s3(uint64 instruction) } -uint64 NMD::extract_count_3_2_1_0(uint64 instruction) +static uint64 extract_count_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 4); @@ -903,7 +632,7 @@ uint64 NMD::extract_count_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_rtz3_9_8_7(uint64 instruction) +static uint64 extract_rtz3_9_8_7(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 7, 3); @@ -911,7 +640,7 @@ uint64 NMD::extract_rtz3_9_8_7(uint64 instruction) } -uint64 NMD::extract_u_17_to_1__s1(uint64 instruction) +static uint64 extract_u_17_to_1__s1(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 1, 17) << 1; @@ -919,7 +648,7 @@ uint64 NMD::extract_u_17_to_1__s1(uint64 instruction) } -int64 NMD::extract_s__se9_20_19_18_17_16_15_14_13_12_11(uint64 instruction) +static int64 extract_s__se9_20_19_18_17_16_15_14_13_12_11(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 11, 10); @@ -928,7 +657,7 @@ int64 NMD::extract_s__se9_20_19_18_17_16_15_14_13_12_11(uint64 instruction) } -int64 NMD::extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(uint64 instruction) +static int64 extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 1) << 11; @@ -938,7 +667,7 @@ int64 NMD::extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(uint64 instruction) } -uint64 NMD::extract_u_10(uint64 instruction) +static uint64 extract_u_10(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 10, 1); @@ -946,7 +675,7 @@ uint64 NMD::extract_u_10(uint64 instruction) } -uint64 NMD::extract_rtz4_27_26_25_23_22_21(uint64 instruction) +static uint64 extract_rtz4_27_26_25_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 3); @@ -955,7 +684,7 @@ uint64 NMD::extract_rtz4_27_26_25_23_22_21(uint64 instruction) } -uint64 NMD::extract_sa_15_14_13_12_11(uint64 instruction) +static uint64 extract_sa_15_14_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 5); @@ -963,7 +692,7 @@ uint64 NMD::extract_sa_15_14_13_12_11(uint64 instruction) } -uint64 NMD::extract_shift_4_3_2_1_0(uint64 instruction) +static uint64 extract_shift_4_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 5); @@ -971,7 +700,7 @@ uint64 NMD::extract_shift_4_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_shiftx_10_9_8_7__s1(uint64 instruction) +static uint64 extract_shiftx_10_9_8_7__s1(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 7, 4) << 1; @@ -979,7 +708,7 @@ uint64 NMD::extract_shiftx_10_9_8_7__s1(uint64 instruction) } -uint64 NMD::extract_hint_25_24_23_22_21(uint64 instruction) +static uint64 extract_hint_25_24_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 5); @@ -987,7 +716,7 @@ uint64 NMD::extract_hint_25_24_23_22_21(uint64 instruction) } -uint64 NMD::extract_count3_14_13_12(uint64 instruction) +static uint64 extract_count3_14_13_12(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 12, 3); @@ -995,7 +724,7 @@ uint64 NMD::extract_count3_14_13_12(uint64 instruction) } -int64 NMD::extract_s__se31_0_11_to_2_20_to_12_s12(uint64 instruction) +static int64 extract_s__se31_0_11_to_2_20_to_12_s12(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 1) << 31; @@ -1006,7 +735,7 @@ int64 NMD::extract_s__se31_0_11_to_2_20_to_12_s12(uint64 instruction) } -int64 NMD::extract_s__se7_0_6_5_4_3_2_1_s1(uint64 instruction) +static int64 extract_s__se7_0_6_5_4_3_2_1_s1(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 1) << 7; @@ -1016,7 +745,7 @@ int64 NMD::extract_s__se7_0_6_5_4_3_2_1_s1(uint64 instruction) } -uint64 NMD::extract_u2_10_9(uint64 instruction) +static uint64 extract_u2_10_9(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 9, 2); @@ -1024,7 +753,7 @@ uint64 NMD::extract_u2_10_9(uint64 instruction) } -uint64 NMD::extract_code_25_24_23_22_21_20_19_18_17_16(uint64 instruction) +static uint64 extract_code_25_24_23_22_21_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 10); @@ -1032,7 +761,7 @@ uint64 NMD::extract_code_25_24_23_22_21_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_rs_20_19_18_17_16(uint64 instruction) +static uint64 extract_rs_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1040,7 +769,7 @@ uint64 NMD::extract_rs_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_u_2_1__s1(uint64 instruction) +static uint64 extract_u_2_1__s1(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 1, 2) << 1; @@ -1048,7 +777,7 @@ uint64 NMD::extract_u_2_1__s1(uint64 instruction) } -uint64 NMD::extract_stripe_6(uint64 instruction) +static uint64 extract_stripe_6(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 6, 1); @@ -1056,7 +785,7 @@ uint64 NMD::extract_stripe_6(uint64 instruction) } -uint64 NMD::extract_ac_15_14(uint64 instruction) +static uint64 extract_ac_15_14(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 14, 2); @@ -1064,7 +793,7 @@ uint64 NMD::extract_ac_15_14(uint64 instruction) } -uint64 NMD::extract_shift_20_19_18_17_16(uint64 instruction) +static uint64 extract_shift_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1072,7 +801,7 @@ uint64 NMD::extract_shift_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_rdl_25_24(uint64 instruction) +static uint64 extract_rdl_25_24(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 24, 1); @@ -1080,7 +809,7 @@ uint64 NMD::extract_rdl_25_24(uint64 instruction) } -int64 NMD::extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(uint64 instruction) +static int64 extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 1) << 10; @@ -1090,7 +819,7 @@ int64 NMD::extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(uint64 instruction) } -uint64 NMD::extract_eu_6_5_4_3_2_1_0(uint64 instruction) +static uint64 extract_eu_6_5_4_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 7); @@ -1098,7 +827,7 @@ uint64 NMD::extract_eu_6_5_4_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_shift_5_4_3_2_1_0(uint64 instruction) +static uint64 extract_shift_5_4_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 6); @@ -1106,7 +835,7 @@ uint64 NMD::extract_shift_5_4_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_count_19_18_17_16(uint64 instruction) +static uint64 extract_count_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 4); @@ -1114,7 +843,7 @@ uint64 NMD::extract_count_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_code_2_1_0(uint64 instruction) +static uint64 extract_code_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 3); @@ -1122,7 +851,7 @@ uint64 NMD::extract_code_2_1_0(uint64 instruction) } -uint64 NMD::extract_u_11_10_9_8_7_6_5_4_3_2_1_0(uint64 instruction) +static uint64 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); @@ -1130,7 +859,7 @@ uint64 NMD::extract_u_11_10_9_8_7_6_5_4_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_rs_4_3_2_1_0(uint64 instruction) +static uint64 extract_rs_4_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 5); @@ -1138,7 +867,7 @@ uint64 NMD::extract_rs_4_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_u_20_to_3__s3(uint64 instruction) +static uint64 extract_u_20_to_3__s3(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 3, 18) << 3; @@ -1146,7 +875,7 @@ uint64 NMD::extract_u_20_to_3__s3(uint64 instruction) } -uint64 NMD::extract_u_3_2_1_0__s2(uint64 instruction) +static uint64 extract_u_3_2_1_0__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 4) << 2; @@ -1154,7 +883,7 @@ uint64 NMD::extract_u_3_2_1_0__s2(uint64 instruction) } -uint64 NMD::extract_cofun_25_24_23(uint64 instruction) +static uint64 extract_cofun_25_24_23(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 3, 23); @@ -1162,7 +891,7 @@ uint64 NMD::extract_cofun_25_24_23(uint64 instruction) } -uint64 NMD::extract_u_2_1_0__s2(uint64 instruction) +static uint64 extract_u_2_1_0__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 3) << 2; @@ -1170,7 +899,7 @@ uint64 NMD::extract_u_2_1_0__s2(uint64 instruction) } -uint64 NMD::extract_rd3_3_2_1(uint64 instruction) +static uint64 extract_rd3_3_2_1(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 1, 3); @@ -1178,7 +907,7 @@ uint64 NMD::extract_rd3_3_2_1(uint64 instruction) } -uint64 NMD::extract_sa_15_14_13_12(uint64 instruction) +static uint64 extract_sa_15_14_13_12(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 12, 4); @@ -1186,7 +915,7 @@ uint64 NMD::extract_sa_15_14_13_12(uint64 instruction) } -uint64 NMD::extract_rt_25_24_23_22_21(uint64 instruction) +static uint64 extract_rt_25_24_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 5); @@ -1194,7 +923,7 @@ uint64 NMD::extract_rt_25_24_23_22_21(uint64 instruction) } -uint64 NMD::extract_ru_7_6_5_4_3(uint64 instruction) +static uint64 extract_ru_7_6_5_4_3(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 3, 5); @@ -1202,7 +931,7 @@ uint64 NMD::extract_ru_7_6_5_4_3(uint64 instruction) } -uint64 NMD::extract_u_17_to_0(uint64 instruction) +static uint64 extract_u_17_to_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 18); @@ -1210,7 +939,7 @@ uint64 NMD::extract_u_17_to_0(uint64 instruction) } -uint64 NMD::extract_rsz4_4_2_1_0(uint64 instruction) +static uint64 extract_rsz4_4_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 3); @@ -1219,7 +948,7 @@ uint64 NMD::extract_rsz4_4_2_1_0(uint64 instruction) } -int64 NMD::extract_s__se21_0_20_to_1_s1(uint64 instruction) +static int64 extract_s__se21_0_20_to_1_s1(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 1) << 21; @@ -1229,7 +958,7 @@ int64 NMD::extract_s__se21_0_20_to_1_s1(uint64 instruction) } -uint64 NMD::extract_op_25_to_3(uint64 instruction) +static uint64 extract_op_25_to_3(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 3, 23); @@ -1237,7 +966,7 @@ uint64 NMD::extract_op_25_to_3(uint64 instruction) } -uint64 NMD::extract_rs4_4_2_1_0(uint64 instruction) +static uint64 extract_rs4_4_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 3); @@ -1246,7 +975,7 @@ uint64 NMD::extract_rs4_4_2_1_0(uint64 instruction) } -uint64 NMD::extract_bit_23_22_21(uint64 instruction) +static uint64 extract_bit_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 3); @@ -1254,7 +983,7 @@ uint64 NMD::extract_bit_23_22_21(uint64 instruction) } -uint64 NMD::extract_rt_41_40_39_38_37(uint64 instruction) +static uint64 extract_rt_41_40_39_38_37(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 37, 5); @@ -1262,7 +991,7 @@ uint64 NMD::extract_rt_41_40_39_38_37(uint64 instruction) } -int64 NMD::extract_shift__se5_21_20_19_18_17_16(uint64 instruction) +static int64 extract_shift__se5_21_20_19_18_17_16(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 16, 6); @@ -1271,7 +1000,7 @@ int64 NMD::extract_shift__se5_21_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_rd2_3_8(uint64 instruction) +static uint64 extract_rd2_3_8(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 3, 1) << 1; @@ -1280,7 +1009,7 @@ uint64 NMD::extract_rd2_3_8(uint64 instruction) } -uint64 NMD::extract_code_17_to_0(uint64 instruction) +static uint64 extract_code_17_to_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 18); @@ -1288,7 +1017,7 @@ uint64 NMD::extract_code_17_to_0(uint64 instruction) } -uint64 NMD::extract_size_20_19_18_17_16(uint64 instruction) +static uint64 extract_size_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1296,7 +1025,7 @@ uint64 NMD::extract_size_20_19_18_17_16(uint64 instruction) } -int64 NMD::extract_s__se8_15_7_6_5_4_3_2_s2(uint64 instruction) +static int64 extract_s__se8_15_7_6_5_4_3_2_s2(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 2, 6) << 2; @@ -1306,7 +1035,7 @@ int64 NMD::extract_s__se8_15_7_6_5_4_3_2_s2(uint64 instruction) } -uint64 NMD::extract_u_15_to_0(uint64 instruction) +static uint64 extract_u_15_to_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 16); @@ -1314,7 +1043,7 @@ uint64 NMD::extract_u_15_to_0(uint64 instruction) } -uint64 NMD::extract_fs_20_19_18_17_16(uint64 instruction) +static uint64 extract_fs_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1322,7 +1051,7 @@ uint64 NMD::extract_fs_20_19_18_17_16(uint64 instruction) } -int64 NMD::extract_s__se8_15_7_6_5_4_3_2_1_0(uint64 instruction) +static int64 extract_s__se8_15_7_6_5_4_3_2_1_0(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 8); @@ -1332,7 +1061,7 @@ int64 NMD::extract_s__se8_15_7_6_5_4_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_stype_20_19_18_17_16(uint64 instruction) +static uint64 extract_stype_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1340,7 +1069,7 @@ uint64 NMD::extract_stype_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_rtl_11(uint64 instruction) +static uint64 extract_rtl_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 9, 1); @@ -1348,7 +1077,7 @@ uint64 NMD::extract_rtl_11(uint64 instruction) } -uint64 NMD::extract_hs_20_19_18_17_16(uint64 instruction) +static uint64 extract_hs_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1356,7 +1085,7 @@ uint64 NMD::extract_hs_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_sel_13_12_11(uint64 instruction) +static uint64 extract_sel_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 3); @@ -1364,7 +1093,7 @@ uint64 NMD::extract_sel_13_12_11(uint64 instruction) } -uint64 NMD::extract_lsb_4_3_2_1_0(uint64 instruction) +static uint64 extract_lsb_4_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 5); @@ -1372,7 +1101,7 @@ uint64 NMD::extract_lsb_4_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_gp_2(uint64 instruction) +static uint64 extract_gp_2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 2, 1); @@ -1380,7 +1109,7 @@ uint64 NMD::extract_gp_2(uint64 instruction) } -uint64 NMD::extract_rt3_9_8_7(uint64 instruction) +static uint64 extract_rt3_9_8_7(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 7, 3); @@ -1388,7 +1117,7 @@ uint64 NMD::extract_rt3_9_8_7(uint64 instruction) } -uint64 NMD::extract_ft_25_24_23_22_21(uint64 instruction) +static uint64 extract_ft_25_24_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 5); @@ -1396,7 +1125,7 @@ uint64 NMD::extract_ft_25_24_23_22_21(uint64 instruction) } -uint64 NMD::extract_u_17_16_15_14_13_12_11(uint64 instruction) +static uint64 extract_u_17_16_15_14_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 7); @@ -1404,7 +1133,7 @@ uint64 NMD::extract_u_17_16_15_14_13_12_11(uint64 instruction) } -uint64 NMD::extract_cs_20_19_18_17_16(uint64 instruction) +static uint64 extract_cs_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1412,7 +1141,7 @@ uint64 NMD::extract_cs_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_rt4_9_7_6_5(uint64 instruction) +static uint64 extract_rt4_9_7_6_5(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 5, 3); @@ -1421,7 +1150,7 @@ uint64 NMD::extract_rt4_9_7_6_5(uint64 instruction) } -uint64 NMD::extract_msbt_10_9_8_7_6(uint64 instruction) +static uint64 extract_msbt_10_9_8_7_6(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 6, 5); @@ -1429,7 +1158,7 @@ uint64 NMD::extract_msbt_10_9_8_7_6(uint64 instruction) } -uint64 NMD::extract_u_5_4_3_2_1_0__s2(uint64 instruction) +static uint64 extract_u_5_4_3_2_1_0__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 6) << 2; @@ -1437,7 +1166,7 @@ uint64 NMD::extract_u_5_4_3_2_1_0__s2(uint64 instruction) } -uint64 NMD::extract_sa_15_14_13(uint64 instruction) +static uint64 extract_sa_15_14_13(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 13, 3); @@ -1445,7 +1174,7 @@ uint64 NMD::extract_sa_15_14_13(uint64 instruction) } -int64 NMD::extract_s__se14_0_13_to_1_s1(uint64 instruction) +static int64 extract_s__se14_0_13_to_1_s1(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 1) << 14; @@ -1455,7 +1184,7 @@ int64 NMD::extract_s__se14_0_13_to_1_s1(uint64 instruction) } -uint64 NMD::extract_rs3_6_5_4(uint64 instruction) +static uint64 extract_rs3_6_5_4(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 4, 3); @@ -1463,7 +1192,7 @@ uint64 NMD::extract_rs3_6_5_4(uint64 instruction) } -uint64 NMD::extract_u_31_to_0__s32(uint64 instruction) +static uint64 extract_u_31_to_0__s32(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 32) << 32; @@ -1471,7 +1200,7 @@ uint64 NMD::extract_u_31_to_0__s32(uint64 instruction) } -uint64 NMD::extract_shift_10_9_8_7_6(uint64 instruction) +static uint64 extract_shift_10_9_8_7_6(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 6, 5); @@ -1479,7 +1208,7 @@ uint64 NMD::extract_shift_10_9_8_7_6(uint64 instruction) } -uint64 NMD::extract_cs_25_24_23_22_21(uint64 instruction) +static uint64 extract_cs_25_24_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 5); @@ -1487,7 +1216,7 @@ uint64 NMD::extract_cs_25_24_23_22_21(uint64 instruction) } -uint64 NMD::extract_shiftx_11_10_9_8_7_6(uint64 instruction) +static uint64 extract_shiftx_11_10_9_8_7_6(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 6, 6); @@ -1495,7 +1224,7 @@ uint64 NMD::extract_shiftx_11_10_9_8_7_6(uint64 instruction) } -uint64 NMD::extract_rt_9_8_7_6_5(uint64 instruction) +static uint64 extract_rt_9_8_7_6_5(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 5, 5); @@ -1503,7 +1232,7 @@ uint64 NMD::extract_rt_9_8_7_6_5(uint64 instruction) } -uint64 NMD::extract_op_25_24_23_22_21(uint64 instruction) +static uint64 extract_op_25_24_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 5); @@ -1511,7 +1240,7 @@ uint64 NMD::extract_op_25_24_23_22_21(uint64 instruction) } -uint64 NMD::extract_u_6_5_4_3_2_1_0__s2(uint64 instruction) +static uint64 extract_u_6_5_4_3_2_1_0__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 7) << 2; @@ -1519,7 +1248,7 @@ uint64 NMD::extract_u_6_5_4_3_2_1_0__s2(uint64 instruction) } -uint64 NMD::extract_bit_16_15_14_13_12_11(uint64 instruction) +static uint64 extract_bit_16_15_14_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 6); @@ -1527,7 +1256,7 @@ uint64 NMD::extract_bit_16_15_14_13_12_11(uint64 instruction) } -uint64 NMD::extract_mask_20_19_18_17_16_15_14(uint64 instruction) +static uint64 extract_mask_20_19_18_17_16_15_14(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 14, 7); @@ -1535,7 +1264,7 @@ uint64 NMD::extract_mask_20_19_18_17_16_15_14(uint64 instruction) } -uint64 NMD::extract_eu_3_2_1_0(uint64 instruction) +static uint64 extract_eu_3_2_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 4); @@ -1543,7 +1272,7 @@ uint64 NMD::extract_eu_3_2_1_0(uint64 instruction) } -uint64 NMD::extract_u_7_6_5_4__s4(uint64 instruction) +static uint64 extract_u_7_6_5_4__s4(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 4, 4) << 4; @@ -1551,7 +1280,7 @@ uint64 NMD::extract_u_7_6_5_4__s4(uint64 instruction) } -int64 NMD::extract_s__se8_15_7_6_5_4_3_s3(uint64 instruction) +static int64 extract_s__se8_15_7_6_5_4_3_s3(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 3, 5) << 3; @@ -1561,7 +1290,7 @@ int64 NMD::extract_s__se8_15_7_6_5_4_3_s3(uint64 instruction) } -uint64 NMD::extract_ft_15_14_13_12_11(uint64 instruction) +static uint64 extract_ft_15_14_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 5); @@ -1569,7 +1298,7 @@ uint64 NMD::extract_ft_15_14_13_12_11(uint64 instruction) } -int64 NMD::extract_s__se31_15_to_0_31_to_16(uint64 instruction) +static int64 extract_s__se31_15_to_0_31_to_16(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 16) << 16; @@ -1579,7 +1308,7 @@ int64 NMD::extract_s__se31_15_to_0_31_to_16(uint64 instruction) } -uint64 NMD::extract_u_20_19_18_17_16_15_14_13(uint64 instruction) +static uint64 extract_u_20_19_18_17_16_15_14_13(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 13, 8); @@ -1587,7 +1316,7 @@ uint64 NMD::extract_u_20_19_18_17_16_15_14_13(uint64 instruction) } -uint64 NMD::extract_u_17_to_2__s2(uint64 instruction) +static uint64 extract_u_17_to_2__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 2, 16) << 2; @@ -1595,7 +1324,7 @@ uint64 NMD::extract_u_17_to_2__s2(uint64 instruction) } -uint64 NMD::extract_rd_15_14_13_12_11(uint64 instruction) +static uint64 extract_rd_15_14_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 5); @@ -1603,7 +1332,7 @@ uint64 NMD::extract_rd_15_14_13_12_11(uint64 instruction) } -uint64 NMD::extract_c0s_20_19_18_17_16(uint64 instruction) +static uint64 extract_c0s_20_19_18_17_16(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 16, 5); @@ -1611,7 +1340,7 @@ uint64 NMD::extract_c0s_20_19_18_17_16(uint64 instruction) } -uint64 NMD::extract_code_1_0(uint64 instruction) +static uint64 extract_code_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 2); @@ -1619,7 +1348,7 @@ uint64 NMD::extract_code_1_0(uint64 instruction) } -int64 NMD::extract_s__se25_0_24_to_1_s1(uint64 instruction) +static int64 extract_s__se25_0_24_to_1_s1(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 1) << 25; @@ -1629,7 +1358,7 @@ int64 NMD::extract_s__se25_0_24_to_1_s1(uint64 instruction) } -uint64 NMD::extract_u_1_0(uint64 instruction) +static uint64 extract_u_1_0(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 2); @@ -1637,7 +1366,7 @@ uint64 NMD::extract_u_1_0(uint64 instruction) } -uint64 NMD::extract_u_3_8__s2(uint64 instruction) +static uint64 extract_u_3_8__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 3, 1) << 3; @@ -1646,7 +1375,7 @@ uint64 NMD::extract_u_3_8__s2(uint64 instruction) } -uint64 NMD::extract_fd_15_14_13_12_11(uint64 instruction) +static uint64 extract_fd_15_14_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 5); @@ -1654,7 +1383,7 @@ uint64 NMD::extract_fd_15_14_13_12_11(uint64 instruction) } -uint64 NMD::extract_u_4_3_2_1_0__s2(uint64 instruction) +static uint64 extract_u_4_3_2_1_0__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 5) << 2; @@ -1662,7 +1391,7 @@ uint64 NMD::extract_u_4_3_2_1_0__s2(uint64 instruction) } -uint64 NMD::extract_rtz4_9_7_6_5(uint64 instruction) +static uint64 extract_rtz4_9_7_6_5(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 5, 3); @@ -1671,7 +1400,7 @@ uint64 NMD::extract_rtz4_9_7_6_5(uint64 instruction) } -uint64 NMD::extract_sel_15_14_13_12_11(uint64 instruction) +static uint64 extract_sel_15_14_13_12_11(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 11, 5); @@ -1679,7 +1408,7 @@ uint64 NMD::extract_sel_15_14_13_12_11(uint64 instruction) } -uint64 NMD::extract_ct_25_24_23_22_21(uint64 instruction) +static uint64 extract_ct_25_24_23_22_21(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 21, 5); @@ -1687,7 +1416,7 @@ uint64 NMD::extract_ct_25_24_23_22_21(uint64 instruction) } -uint64 NMD::extract_u_20_to_2__s2(uint64 instruction) +static uint64 extract_u_20_to_2__s2(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 2, 19) << 2; @@ -1695,7 +1424,7 @@ uint64 NMD::extract_u_20_to_2__s2(uint64 instruction) } -int64 NMD::extract_s__se3_4_2_1_0(uint64 instruction) +static int64 extract_s__se3_4_2_1_0(uint64 instruction) { int64 value = 0; value |= extract_bits(instruction, 0, 3); @@ -1705,7 +1434,7 @@ int64 NMD::extract_s__se3_4_2_1_0(uint64 instruction) } -uint64 NMD::extract_u_3_2_1_0__s1(uint64 instruction) +static uint64 extract_u_3_2_1_0__s1(uint64 instruction) { uint64 value = 0; value |= extract_bits(instruction, 0, 4) << 1; @@ -1714,28 +1443,28 @@ uint64 NMD::extract_u_3_2_1_0__s1(uint64 instruction) -bool NMD::ADDIU_32__cond(uint64 instruction) +static bool 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) +static bool ADDIU_RS5__cond(uint64 instruction) { uint64 rt = extract_rt_9_8_7_6_5(instruction); return rt != 0; } -bool NMD::BALRSC_cond(uint64 instruction) +static bool BALRSC_cond(uint64 instruction) { uint64 rt = extract_rt_25_24_23_22_21(instruction); return rt != 0; } -bool NMD::BEQC_16__cond(uint64 instruction) +static bool BEQC_16__cond(uint64 instruction) { uint64 rs3 = extract_rs3_6_5_4(instruction); uint64 rt3 = extract_rt3_9_8_7(instruction); @@ -1744,7 +1473,7 @@ bool NMD::BEQC_16__cond(uint64 instruction) } -bool NMD::BNEC_16__cond(uint64 instruction) +static bool BNEC_16__cond(uint64 instruction) { uint64 rs3 = extract_rs3_6_5_4(instruction); uint64 rt3 = extract_rt3_9_8_7(instruction); @@ -1753,35 +1482,35 @@ bool NMD::BNEC_16__cond(uint64 instruction) } -bool NMD::MOVE_cond(uint64 instruction) +static bool MOVE_cond(uint64 instruction) { uint64 rt = extract_rt_9_8_7_6_5(instruction); return rt != 0; } -bool NMD::P16_BR1_cond(uint64 instruction) +static bool P16_BR1_cond(uint64 instruction) { uint64 u = extract_u_3_2_1_0__s1(instruction); return u != 0; } -bool NMD::PREF_S9__cond(uint64 instruction) +static bool PREF_S9__cond(uint64 instruction) { uint64 hint = extract_hint_25_24_23_22_21(instruction); return hint != 31; } -bool NMD::PREFE_cond(uint64 instruction) +static bool PREFE_cond(uint64 instruction) { uint64 hint = extract_hint_25_24_23_22_21(instruction); return hint != 31; } -bool NMD::SLTU_cond(uint64 instruction) +static bool SLTU_cond(uint64 instruction) { uint64 rd = extract_rd_15_14_13_12_11(instruction); return rd != 0; @@ -1799,15 +1528,15 @@ bool NMD::SLTU_cond(uint64 instruction) * fs ----- * fd ----- */ -std::string NMD::ABS_D(uint64 instruction) +static char *ABS_D(uint64 instruction, Dis_info *info) { uint64 fd_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string fs = FPR(copy(fs_value)); - std::string fd = FPR(copy(fd_value)); + const char *fs = FPR(fs_value, info); + const char *fd = FPR(fd_value, info); - return img::format("ABS.D %s, %s", fd, fs); + return img_format("ABS.D %s, %s", fd, fs); } @@ -1821,15 +1550,15 @@ std::string NMD::ABS_D(uint64 instruction) * fd ----- * fs ----- */ -std::string NMD::ABS_S(uint64 instruction) +static char *ABS_S(uint64 instruction, Dis_info *info) { uint64 fd_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string fs = FPR(copy(fs_value)); - std::string fd = FPR(copy(fd_value)); + const char *fs = FPR(fs_value, info); + const char *fd = FPR(fd_value, info); - return img::format("ABS.S %s, %s", fd, fs); + return img_format("ABS.S %s, %s", fd, fs); } @@ -1843,15 +1572,15 @@ std::string NMD::ABS_S(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ABSQ_S_PH(uint64 instruction) +static char *ABSQ_S_PH(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("ABSQ_S.PH %s, %s", rt, rs); + return img_format("ABSQ_S.PH %s, %s", rt, rs); } @@ -1865,15 +1594,15 @@ std::string NMD::ABSQ_S_PH(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ABSQ_S_QB(uint64 instruction) +static char *ABSQ_S_QB(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("ABSQ_S.QB %s, %s", rt, rs); + return img_format("ABSQ_S.QB %s, %s", rt, rs); } @@ -1887,15 +1616,15 @@ std::string NMD::ABSQ_S_QB(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ABSQ_S_W(uint64 instruction) +static char *ABSQ_S_W(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("ABSQ_S.W %s, %s", rt, rs); + return img_format("ABSQ_S.W %s, %s", rt, rs); } @@ -1908,17 +1637,16 @@ std::string NMD::ABSQ_S_W(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ACLR(uint64 instruction) +static char *ACLR(uint64 instruction, Dis_info *info) { uint64 bit_value = extract_bit_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string bit = IMMEDIATE(copy(bit_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rs = GPR(rs_value, info); - return img::format("ACLR %s, %s(%s)", bit, s, rs); + return img_format("ACLR 0x%" PRIx64 ", %" PRId64 "(%s)", + bit_value, s_value, rs); } @@ -1931,17 +1659,17 @@ std::string NMD::ACLR(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADD(uint64 instruction) +static char *ADD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADD %s, %s, %s", rd, rs, rt); + return img_format("ADD %s, %s, %s", rd, rs, rt); } @@ -1956,17 +1684,17 @@ std::string NMD::ADD(uint64 instruction) * fs ----- * fd ----- */ -std::string NMD::ADD_D(uint64 instruction) +static char *ADD_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); - std::string fd = FPR(copy(fd_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); + const char *fd = FPR(fd_value, info); - return img::format("ADD.D %s, %s, %s", fd, fs, ft); + return img_format("ADD.D %s, %s, %s", fd, fs, ft); } @@ -1981,17 +1709,17 @@ std::string NMD::ADD_D(uint64 instruction) * fs ----- * fd ----- */ -std::string NMD::ADD_S(uint64 instruction) +static char *ADD_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); - std::string fd = FPR(copy(fd_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); + const char *fd = FPR(fd_value, info); - return img::format("ADD.S %s, %s, %s", fd, fs, ft); + return img_format("ADD.S %s, %s, %s", fd, fs, ft); } @@ -2004,17 +1732,16 @@ std::string NMD::ADD_S(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_32_(uint64 instruction) +static char *ADDIU_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_15_to_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("ADDIU %s, %s, %s", rt, rs, u); + return img_format("ADDIU %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -2027,15 +1754,14 @@ std::string NMD::ADDIU_32_(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_48_(uint64 instruction) +static char *ADDIU_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); + const char *rt = GPR(rt_value, info); - return img::format("ADDIU %s, %s", rt, s); + return img_format("ADDIU %s, %" PRId64, rt, s_value); } @@ -2048,15 +1774,14 @@ std::string NMD::ADDIU_48_(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_GP48_(uint64 instruction) +static char *ADDIU_GP48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); + const char *rt = GPR(rt_value, info); - return img::format("ADDIU %s, $%d, %s", rt, 28, s); + return img_format("ADDIU %s, $%d, %" PRId64, rt, 28, s_value); } @@ -2069,15 +1794,14 @@ std::string NMD::ADDIU_GP48_(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_GP_B_(uint64 instruction) +static char *ADDIU_GP_B_(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("ADDIU %s, $%d, %s", rt, 28, u); + return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt, 28, u_value); } @@ -2090,15 +1814,14 @@ std::string NMD::ADDIU_GP_B_(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_GP_W_(uint64 instruction) +static char *ADDIU_GP_W_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); - return img::format("ADDIU %s, $%d, %s", rt, 28, u); + return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt, 28, u_value); } @@ -2111,17 +1834,17 @@ std::string NMD::ADDIU_GP_W_(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_NEG_(uint64 instruction) +static char *ADDIU_NEG_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(neg_copy(u_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); + int64 u = neg_copy(u_value); - return img::format("ADDIU %s, %s, %s", rt, rs, u); + return img_format("ADDIU %s, %s, %" PRId64, rt, rs, u); } @@ -2134,15 +1857,14 @@ std::string NMD::ADDIU_NEG_(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_R1_SP_(uint64 instruction) +static char *ADDIU_R1_SP_(uint64 instruction, Dis_info *info) { uint64 u_value = extract_u_5_4_3_2_1_0__s2(instruction); uint64 rt3_value = extract_rt3_9_8_7(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); - return img::format("ADDIU %s, $%d, %s", rt3, 29, u); + return img_format("ADDIU %s, $%d, 0x%" PRIx64, rt3, 29, u_value); } @@ -2155,17 +1877,16 @@ std::string NMD::ADDIU_R1_SP_(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::ADDIU_R2_(uint64 instruction) +static char *ADDIU_R2_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_2_1_0__s2(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); - return img::format("ADDIU %s, %s, %s", rt3, rs3, u); + return img_format("ADDIU %s, %s, 0x%" PRIx64, rt3, rs3, u_value); } @@ -2177,15 +1898,14 @@ std::string NMD::ADDIU_R2_(uint64 instruction) * rt ----- * s - --- */ -std::string NMD::ADDIU_RS5_(uint64 instruction) +static char *ADDIU_RS5_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); int64 s_value = extract_s__se3_4_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); + const char *rt = GPR(rt_value, info); - return img::format("ADDIU %s, %s", rt, s); + return img_format("ADDIU %s, %" PRId64, rt, s_value); } @@ -2199,15 +1919,15 @@ std::string NMD::ADDIU_RS5_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDIUPC_32_(uint64 instruction) +static char *ADDIUPC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se21_0_20_to_1_s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("ADDIUPC %s, %s", rt, s); + return img_format("ADDIUPC %s, %s", rt, s); } @@ -2221,15 +1941,15 @@ std::string NMD::ADDIUPC_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDIUPC_48_(uint64 instruction) +static char *ADDIUPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 6, info); - return img::format("ADDIUPC %s, %s", rt, s); + return img_format("ADDIUPC %s, %s", rt, s); } @@ -2243,17 +1963,17 @@ std::string NMD::ADDIUPC_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDQ_PH(uint64 instruction) +static char *ADDQ_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDQ.PH %s, %s, %s", rd, rs, rt); + return img_format("ADDQ.PH %s, %s, %s", rd, rs, rt); } @@ -2268,17 +1988,17 @@ std::string NMD::ADDQ_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDQ_S_PH(uint64 instruction) +static char *ADDQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDQ_S.PH %s, %s, %s", rd, rs, rt); + return img_format("ADDQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -2292,17 +2012,17 @@ std::string NMD::ADDQ_S_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDQ_S_W(uint64 instruction) +static char *ADDQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDQ_S.W %s, %s, %s", rd, rs, rt); + return img_format("ADDQ_S.W %s, %s, %s", rd, rs, rt); } @@ -2317,17 +2037,17 @@ std::string NMD::ADDQ_S_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDQH_PH(uint64 instruction) +static char *ADDQH_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDQH.PH %s, %s, %s", rd, rs, rt); + return img_format("ADDQH.PH %s, %s, %s", rd, rs, rt); } @@ -2342,17 +2062,17 @@ std::string NMD::ADDQH_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDQH_R_PH(uint64 instruction) +static char *ADDQH_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDQH_R.PH %s, %s, %s", rd, rs, rt); + return img_format("ADDQH_R.PH %s, %s, %s", rd, rs, rt); } @@ -2367,17 +2087,17 @@ std::string NMD::ADDQH_R_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDQH_R_W(uint64 instruction) +static char *ADDQH_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDQH_R.W %s, %s, %s", rd, rs, rt); + return img_format("ADDQH_R.W %s, %s, %s", rd, rs, rt); } @@ -2392,17 +2112,17 @@ std::string NMD::ADDQH_R_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDQH_W(uint64 instruction) +static char *ADDQH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDQH.W %s, %s, %s", rd, rs, rt); + return img_format("ADDQH.W %s, %s, %s", rd, rs, rt); } @@ -2416,17 +2136,17 @@ std::string NMD::ADDQH_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDSC(uint64 instruction) +static char *ADDSC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDSC %s, %s, %s", rd, rs, rt); + return img_format("ADDSC %s, %s, %s", rd, rs, rt); } @@ -2439,17 +2159,17 @@ std::string NMD::ADDSC(uint64 instruction) * rs3 --- * rd3 --- */ -std::string NMD::ADDU_16_(uint64 instruction) +static char *ADDU_16_(uint64 instruction, Dis_info *info) { 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(decode_gpr_gpr3(rt3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string rd3 = GPR(decode_gpr_gpr3(rd3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + const char *rd3 = GPR(decode_gpr_gpr3(rd3_value, info), info); - return img::format("ADDU %s, %s, %s", rd3, rs3, rt3); + return img_format("ADDU %s, %s, %s", rd3, rs3, rt3); } @@ -2463,17 +2183,17 @@ std::string NMD::ADDU_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDU_32_(uint64 instruction) +static char *ADDU_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDU %s, %s, %s", rd, rs, rt); + return img_format("ADDU %s, %s, %s", rd, rs, rt); } @@ -2487,15 +2207,15 @@ std::string NMD::ADDU_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDU_4X4_(uint64 instruction) +static char *ADDU_4X4_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); - std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); - std::string rt4 = GPR(decode_gpr_gpr4(rt4_value)); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value, info), info); + const char *rt4 = GPR(decode_gpr_gpr4(rt4_value, info), info); - return img::format("ADDU %s, %s", rs4, rt4); + return img_format("ADDU %s, %s", rs4, rt4); } @@ -2509,17 +2229,17 @@ std::string NMD::ADDU_4X4_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDU_PH(uint64 instruction) +static char *ADDU_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDU.PH %s, %s, %s", rd, rs, rt); + return img_format("ADDU.PH %s, %s, %s", rd, rs, rt); } @@ -2533,17 +2253,17 @@ std::string NMD::ADDU_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDU_QB(uint64 instruction) +static char *ADDU_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDU.QB %s, %s, %s", rd, rs, rt); + return img_format("ADDU.QB %s, %s, %s", rd, rs, rt); } @@ -2558,17 +2278,17 @@ std::string NMD::ADDU_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDU_S_PH(uint64 instruction) +static char *ADDU_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDU_S.PH %s, %s, %s", rd, rs, rt); + return img_format("ADDU_S.PH %s, %s, %s", rd, rs, rt); } @@ -2582,17 +2302,17 @@ std::string NMD::ADDU_S_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDU_S_QB(uint64 instruction) +static char *ADDU_S_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDU_S.QB %s, %s, %s", rd, rs, rt); + return img_format("ADDU_S.QB %s, %s, %s", rd, rs, rt); } @@ -2607,17 +2327,17 @@ std::string NMD::ADDU_S_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDUH_QB(uint64 instruction) +static char *ADDUH_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDUH.QB %s, %s, %s", rd, rs, rt); + return img_format("ADDUH.QB %s, %s, %s", rd, rs, rt); } @@ -2632,17 +2352,17 @@ std::string NMD::ADDUH_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDUH_R_QB(uint64 instruction) +static char *ADDUH_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDUH_R.QB %s, %s, %s", rd, rs, rt); + return img_format("ADDUH_R.QB %s, %s, %s", rd, rs, rt); } /* @@ -2655,17 +2375,17 @@ std::string NMD::ADDUH_R_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ADDWC(uint64 instruction) +static char *ADDWC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ADDWC %s, %s, %s", rd, rs, rt); + return img_format("ADDWC %s, %s, %s", rd, rs, rt); } @@ -2679,15 +2399,15 @@ std::string NMD::ADDWC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ALUIPC(uint64 instruction) +static char *ALUIPC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("ALUIPC %s, %%pcrel_hi(%s)", rt, s); + return img_format("ALUIPC %s, %%pcrel_hi(%s)", rt, s); } @@ -2700,15 +2420,15 @@ std::string NMD::ALUIPC(uint64 instruction) * rs3 --- * eu ---- */ -std::string NMD::AND_16_(uint64 instruction) +static char *AND_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); - return img::format("AND %s, %s", rs3, rt3); + return img_format("AND %s, %s", rs3, rt3); } @@ -2722,17 +2442,17 @@ std::string NMD::AND_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::AND_32_(uint64 instruction) +static char *AND_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("AND %s, %s, %s", rd, rs, rt); + return img_format("AND %s, %s, %s", rd, rs, rt); } @@ -2745,17 +2465,17 @@ std::string NMD::AND_32_(uint64 instruction) * rs3 --- * eu ---- */ -std::string NMD::ANDI_16_(uint64 instruction) +static char *ANDI_16_(uint64 instruction, Dis_info *info) { 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(decode_gpr_gpr3(rt3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string eu = IMMEDIATE(encode_eu_from_u_andi16(eu_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + uint64 eu = encode_eu_from_u_andi16(eu_value); - return img::format("ANDI %s, %s, %s", rt3, rs3, eu); + return img_format("ANDI %s, %s, 0x%" PRIx64, rt3, rs3, eu); } @@ -2769,17 +2489,16 @@ std::string NMD::ANDI_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ANDI_32_(uint64 instruction) +static char *ANDI_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("ANDI %s, %s, %s", rt, rs, u); + return img_format("ANDI %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -2793,17 +2512,16 @@ std::string NMD::ANDI_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::APPEND(uint64 instruction) +static char *APPEND(uint64 instruction, Dis_info *info) { 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_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("APPEND %s, %s, %s", rt, rs, sa); + return img_format("APPEND %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -2817,17 +2535,16 @@ std::string NMD::APPEND(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ASET(uint64 instruction) +static char *ASET(uint64 instruction, Dis_info *info) { uint64 bit_value = extract_bit_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string bit = IMMEDIATE(copy(bit_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rs = GPR(rs_value, info); - return img::format("ASET %s, %s(%s)", bit, s, rs); + return img_format("ASET 0x%" PRIx64 ", %" PRId64 "(%s)", + bit_value, s_value, rs); } @@ -2841,13 +2558,13 @@ std::string NMD::ASET(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BALC_16_(uint64 instruction) +static char *BALC_16_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 2); + g_autofree char *s = ADDRESS(s_value, 2, info); - return img::format("BALC %s", s); + return img_format("BALC %s", s); } @@ -2861,13 +2578,13 @@ std::string NMD::BALC_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BALC_32_(uint64 instruction) +static char *BALC_32_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se25_0_24_to_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BALC %s", s); + return img_format("BALC %s", s); } @@ -2881,15 +2598,15 @@ std::string NMD::BALC_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BALRSC(uint64 instruction) +static char *BALRSC(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("BALRSC %s, %s", rt, rs); + return img_format("BALRSC %s, %s", rt, rs); } @@ -2903,17 +2620,16 @@ std::string NMD::BALRSC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BBEQZC(uint64 instruction) +static char *BBEQZC(uint64 instruction, Dis_info *info) { 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 = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(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); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BBEQZC %s, %s, %s", rt, bit, s); + return img_format("BBEQZC %s, 0x%" PRIx64 ", %s", rt, bit_value, s); } @@ -2927,17 +2643,16 @@ std::string NMD::BBEQZC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BBNEZC(uint64 instruction) +static char *BBNEZC(uint64 instruction, Dis_info *info) { 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 = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(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); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BBNEZC %s, %s, %s", rt, bit, s); + return img_format("BBNEZC %s, 0x%" PRIx64 ", %s", rt, bit_value, s); } @@ -2951,13 +2666,13 @@ std::string NMD::BBNEZC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BC_16_(uint64 instruction) +static char *BC_16_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 2); + g_autofree char *s = ADDRESS(s_value, 2, info); - return img::format("BC %s", s); + return img_format("BC %s", s); } @@ -2971,13 +2686,13 @@ std::string NMD::BC_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BC_32_(uint64 instruction) +static char *BC_32_(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se25_0_24_to_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BC %s", s); + return img_format("BC %s", s); } @@ -2991,15 +2706,15 @@ std::string NMD::BC_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BC1EQZC(uint64 instruction) +static char *BC1EQZC(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string ft = FPR(copy(ft_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + const char *ft = FPR(ft_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BC1EQZC %s, %s", ft, s); + return img_format("BC1EQZC %s, %s", ft, s); } @@ -3013,15 +2728,15 @@ std::string NMD::BC1EQZC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BC1NEZC(uint64 instruction) +static char *BC1NEZC(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string ft = FPR(copy(ft_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + const char *ft = FPR(ft_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BC1NEZC %s, %s", ft, s); + return img_format("BC1NEZC %s, %s", ft, s); } @@ -3035,15 +2750,14 @@ std::string NMD::BC1NEZC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BC2EQZC(uint64 instruction) +static char *BC2EQZC(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string ct = CPR(copy(ct_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BC2EQZC %s, %s", ct, s); + return img_format("BC2EQZC CP%" PRIu64 ", %s", ct_value, s); } @@ -3057,15 +2771,14 @@ std::string NMD::BC2EQZC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BC2NEZC(uint64 instruction) +static char *BC2NEZC(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string ct = CPR(copy(ct_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BC2NEZC %s, %s", ct, s); + return img_format("BC2NEZC CP%" PRIu64 ", %s", ct_value, s); } @@ -3079,17 +2792,17 @@ std::string NMD::BC2NEZC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BEQC_16_(uint64 instruction) +static char *BEQC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_3_2_1_0__s1(instruction); - std::string rs3 = GPR(encode_rs3_and_check_rs3_lt_rt3(rs3_value)); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = ADDRESS(encode_u_from_address(u_value), 2); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + g_autofree char *u = ADDRESS(u_value, 2, info); - return img::format("BEQC %s, %s, %s", rs3, rt3, u); + return img_format("BEQC %s, %s, %s", rs3, rt3, u); } @@ -3103,17 +2816,17 @@ std::string NMD::BEQC_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BEQC_32_(uint64 instruction) +static char *BEQC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(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); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BEQC %s, %s, %s", rs, rt, s); + return img_format("BEQC %s, %s, %s", rs, rt, s); } @@ -3127,17 +2840,16 @@ std::string NMD::BEQC_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BEQIC(uint64 instruction) +static char *BEQIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(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); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BEQIC %s, %s, %s", rt, u, s); + return img_format("BEQIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -3151,15 +2863,15 @@ std::string NMD::BEQIC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BEQZC_16_(uint64 instruction) +static char *BEQZC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); int64 s_value = extract_s__se7_0_6_5_4_3_2_1_s1(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 2); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + g_autofree char *s = ADDRESS(s_value, 2, info); - return img::format("BEQZC %s, %s", rt3, s); + return img_format("BEQZC %s, %s", rt3, s); } @@ -3173,17 +2885,17 @@ std::string NMD::BEQZC_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BGEC(uint64 instruction) +static char *BGEC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(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); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BGEC %s, %s, %s", rs, rt, s); + return img_format("BGEC %s, %s, %s", rs, rt, s); } @@ -3197,17 +2909,16 @@ std::string NMD::BGEC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BGEIC(uint64 instruction) +static char *BGEIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(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); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BGEIC %s, %s, %s", rt, u, s); + return img_format("BGEIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -3221,17 +2932,16 @@ std::string NMD::BGEIC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BGEIUC(uint64 instruction) +static char *BGEIUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(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); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BGEIUC %s, %s, %s", rt, u, s); + return img_format("BGEIUC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -3245,17 +2955,17 @@ std::string NMD::BGEIUC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BGEUC(uint64 instruction) +static char *BGEUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(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); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BGEUC %s, %s, %s", rs, rt, s); + return img_format("BGEUC %s, %s, %s", rs, rt, s); } @@ -3269,17 +2979,17 @@ std::string NMD::BGEUC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BLTC(uint64 instruction) +static char *BLTC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(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); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BLTC %s, %s, %s", rs, rt, s); + return img_format("BLTC %s, %s, %s", rs, rt, s); } @@ -3293,17 +3003,16 @@ std::string NMD::BLTC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BLTIC(uint64 instruction) +static char *BLTIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(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); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BLTIC %s, %s, %s", rt, u, s); + return img_format("BLTIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -3317,17 +3026,16 @@ std::string NMD::BLTIC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BLTIUC(uint64 instruction) +static char *BLTIUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(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); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BLTIUC %s, %s, %s", rt, u, s); + return img_format("BLTIUC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -3341,17 +3049,17 @@ std::string NMD::BLTIUC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BLTUC(uint64 instruction) +static char *BLTUC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(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); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BLTUC %s, %s, %s", rs, rt, s); + return img_format("BLTUC %s, %s, %s", rs, rt, s); } @@ -3365,17 +3073,17 @@ std::string NMD::BLTUC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BNEC_16_(uint64 instruction) +static char *BNEC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_3_2_1_0__s1(instruction); - std::string rs3 = GPR(encode_rs3_and_check_rs3_ge_rt3(rs3_value)); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = ADDRESS(encode_u_from_address(u_value), 2); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + g_autofree char *u = ADDRESS(u_value, 2, info); - return img::format("BNEC %s, %s, %s", rs3, rt3, u); + return img_format("BNEC %s, %s, %s", rs3, rt3, u); } @@ -3389,17 +3097,17 @@ std::string NMD::BNEC_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BNEC_32_(uint64 instruction) +static char *BNEC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se14_0_13_to_1_s1(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); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BNEC %s, %s, %s", rs, rt, s); + return img_format("BNEC %s, %s, %s", rs, rt, s); } @@ -3413,17 +3121,16 @@ std::string NMD::BNEC_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BNEIC(uint64 instruction) +static char *BNEIC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_16_15_14_13_12_11(instruction); int64 s_value = extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(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); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BNEIC %s, %s, %s", rt, u, s); + return img_format("BNEIC %s, 0x%" PRIx64 ", %s", rt, u_value, s); } @@ -3437,15 +3144,15 @@ std::string NMD::BNEIC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BNEZC_16_(uint64 instruction) +static char *BNEZC_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); int64 s_value = extract_s__se7_0_6_5_4_3_2_1_s1(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 2); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + g_autofree char *s = ADDRESS(s_value, 2, info); - return img::format("BNEZC %s, %s", rt3, s); + return img_format("BNEZC %s, %s", rt3, s); } @@ -3459,13 +3166,13 @@ std::string NMD::BNEZC_16_(uint64 instruction) * s[13:1] ------------- * s[14] - */ -std::string NMD::BPOSGE32C(uint64 instruction) +static char *BPOSGE32C(uint64 instruction, Dis_info *info) { int64 s_value = extract_s__se14_0_13_to_1_s1(instruction); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("BPOSGE32C %s", s); + return img_format("BPOSGE32C %s", s); } @@ -3479,13 +3186,12 @@ std::string NMD::BPOSGE32C(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BREAK_16_(uint64 instruction) +static char *BREAK_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_2_1_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); - return img::format("BREAK %s", code); + return img_format("BREAK 0x%" PRIx64, code_value); } @@ -3499,13 +3205,12 @@ std::string NMD::BREAK_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BREAK_32_(uint64 instruction) +static char *BREAK_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); - return img::format("BREAK %s", code); + return img_format("BREAK 0x%" PRIx64, code_value); } @@ -3519,13 +3224,13 @@ std::string NMD::BREAK_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::BRSC(uint64 instruction) +static char *BRSC(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); - std::string rs = GPR(copy(rs_value)); + const char *rs = GPR(rs_value, info); - return img::format("BRSC %s", rs); + return img_format("BRSC %s", rs); } @@ -3539,17 +3244,15 @@ std::string NMD::BRSC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CACHE(uint64 instruction) +static char *CACHE(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string op = IMMEDIATE(copy(op_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rs = GPR(rs_value, info); - return img::format("CACHE %s, %s(%s)", op, s, rs); + return img_format("CACHE 0x%" PRIx64 ", %s(%s)", op_value, s_value, rs); } @@ -3563,17 +3266,15 @@ std::string NMD::CACHE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CACHEE(uint64 instruction) +static char *CACHEE(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string op = IMMEDIATE(copy(op_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rs = GPR(rs_value, info); - return img::format("CACHEE %s, %s(%s)", op, s, rs); + return img_format("CACHEE 0x%" PRIx64 ", %s(%s)", op_value, s_value, rs); } @@ -3587,15 +3288,15 @@ std::string NMD::CACHEE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CEIL_L_D(uint64 instruction) +static char *CEIL_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CEIL.L.D %s, %s", ft, fs); + return img_format("CEIL.L.D %s, %s", ft, fs); } @@ -3609,15 +3310,15 @@ std::string NMD::CEIL_L_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CEIL_L_S(uint64 instruction) +static char *CEIL_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CEIL.L.S %s, %s", ft, fs); + return img_format("CEIL.L.S %s, %s", ft, fs); } @@ -3631,15 +3332,15 @@ std::string NMD::CEIL_L_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CEIL_W_D(uint64 instruction) +static char *CEIL_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CEIL.W.D %s, %s", ft, fs); + return img_format("CEIL.W.D %s, %s", ft, fs); } @@ -3653,15 +3354,15 @@ std::string NMD::CEIL_W_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CEIL_W_S(uint64 instruction) +static char *CEIL_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CEIL.W.S %s, %s", ft, fs); + return img_format("CEIL.W.S %s, %s", ft, fs); } @@ -3675,15 +3376,14 @@ std::string NMD::CEIL_W_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CFC1(uint64 instruction) +static char *CFC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + const char *rt = GPR(rt_value, info); - return img::format("CFC1 %s, %s", rt, cs); + return img_format("CFC1 %s, CP%" PRIu64, rt, cs_value); } @@ -3697,15 +3397,14 @@ std::string NMD::CFC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CFC2(uint64 instruction) +static char *CFC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + const char *rt = GPR(rt_value, info); - return img::format("CFC2 %s, %s", rt, cs); + return img_format("CFC2 %s, CP%" PRIu64, rt, cs_value); } @@ -3719,15 +3418,15 @@ std::string NMD::CFC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CLASS_D(uint64 instruction) +static char *CLASS_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CLASS.D %s, %s", ft, fs); + return img_format("CLASS.D %s, %s", ft, fs); } @@ -3741,15 +3440,15 @@ std::string NMD::CLASS_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CLASS_S(uint64 instruction) +static char *CLASS_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CLASS.S %s, %s", ft, fs); + return img_format("CLASS.S %s, %s", ft, fs); } @@ -3763,15 +3462,15 @@ std::string NMD::CLASS_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CLO(uint64 instruction) +static char *CLO(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("CLO %s, %s", rt, rs); + return img_format("CLO %s, %s", rt, rs); } @@ -3785,15 +3484,15 @@ std::string NMD::CLO(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CLZ(uint64 instruction) +static char *CLZ(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("CLZ %s, %s", rt, rs); + return img_format("CLZ %s, %s", rt, rs); } @@ -3807,17 +3506,17 @@ std::string NMD::CLZ(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_AF_D(uint64 instruction) +static char *CMP_AF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.AF.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.AF.D %s, %s, %s", fd, fs, ft); } @@ -3831,17 +3530,17 @@ std::string NMD::CMP_AF_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_AF_S(uint64 instruction) +static char *CMP_AF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.AF.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.AF.S %s, %s, %s", fd, fs, ft); } @@ -3855,17 +3554,17 @@ std::string NMD::CMP_AF_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_EQ_D(uint64 instruction) +static char *CMP_EQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.EQ.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.EQ.D %s, %s, %s", fd, fs, ft); } @@ -3878,15 +3577,15 @@ std::string NMD::CMP_EQ_D(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::CMP_EQ_PH(uint64 instruction) +static char *CMP_EQ_PH(uint64 instruction, Dis_info *info) { 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)); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("CMP.EQ.PH %s, %s", rs, rt); + return img_format("CMP.EQ.PH %s, %s", rs, rt); } @@ -3900,17 +3599,17 @@ std::string NMD::CMP_EQ_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_EQ_S(uint64 instruction) +static char *CMP_EQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.EQ.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.EQ.S %s, %s, %s", fd, fs, ft); } @@ -3924,17 +3623,17 @@ std::string NMD::CMP_EQ_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_LE_D(uint64 instruction) +static char *CMP_LE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.LE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.LE.D %s, %s, %s", fd, fs, ft); } @@ -3947,15 +3646,15 @@ std::string NMD::CMP_LE_D(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::CMP_LE_PH(uint64 instruction) +static char *CMP_LE_PH(uint64 instruction, Dis_info *info) { 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)); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("CMP.LE.PH %s, %s", rs, rt); + return img_format("CMP.LE.PH %s, %s", rs, rt); } @@ -3969,17 +3668,17 @@ std::string NMD::CMP_LE_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_LE_S(uint64 instruction) +static char *CMP_LE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.LE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.LE.S %s, %s, %s", fd, fs, ft); } @@ -3993,17 +3692,17 @@ std::string NMD::CMP_LE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_LT_D(uint64 instruction) +static char *CMP_LT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.LT.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.LT.D %s, %s, %s", fd, fs, ft); } @@ -4016,15 +3715,15 @@ std::string NMD::CMP_LT_D(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::CMP_LT_PH(uint64 instruction) +static char *CMP_LT_PH(uint64 instruction, Dis_info *info) { 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)); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("CMP.LT.PH %s, %s", rs, rt); + return img_format("CMP.LT.PH %s, %s", rs, rt); } @@ -4038,17 +3737,17 @@ std::string NMD::CMP_LT_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_LT_S(uint64 instruction) +static char *CMP_LT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.LT.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.LT.S %s, %s, %s", fd, fs, ft); } @@ -4062,17 +3761,17 @@ std::string NMD::CMP_LT_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_NE_D(uint64 instruction) +static char *CMP_NE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.NE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.NE.D %s, %s, %s", fd, fs, ft); } @@ -4086,17 +3785,17 @@ std::string NMD::CMP_NE_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_NE_S(uint64 instruction) +static char *CMP_NE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.NE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.NE.S %s, %s, %s", fd, fs, ft); } @@ -4110,17 +3809,17 @@ std::string NMD::CMP_NE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_OR_D(uint64 instruction) +static char *CMP_OR_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.OR.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.OR.D %s, %s, %s", fd, fs, ft); } @@ -4134,17 +3833,17 @@ std::string NMD::CMP_OR_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_OR_S(uint64 instruction) +static char *CMP_OR_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.OR.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.OR.S %s, %s, %s", fd, fs, ft); } @@ -4158,17 +3857,17 @@ std::string NMD::CMP_OR_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SAF_D(uint64 instruction) +static char *CMP_SAF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SAF.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SAF.D %s, %s, %s", fd, fs, ft); } @@ -4182,17 +3881,17 @@ std::string NMD::CMP_SAF_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SAF_S(uint64 instruction) +static char *CMP_SAF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SAF.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SAF.S %s, %s, %s", fd, fs, ft); } @@ -4206,17 +3905,17 @@ std::string NMD::CMP_SAF_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SEQ_D(uint64 instruction) +static char *CMP_SEQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SEQ.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SEQ.D %s, %s, %s", fd, fs, ft); } @@ -4230,17 +3929,17 @@ std::string NMD::CMP_SEQ_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SEQ_S(uint64 instruction) +static char *CMP_SEQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SEQ.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SEQ.S %s, %s, %s", fd, fs, ft); } @@ -4254,17 +3953,17 @@ std::string NMD::CMP_SEQ_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SLE_D(uint64 instruction) +static char *CMP_SLE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SLE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SLE.D %s, %s, %s", fd, fs, ft); } @@ -4278,17 +3977,17 @@ std::string NMD::CMP_SLE_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SLE_S(uint64 instruction) +static char *CMP_SLE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SLE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SLE.S %s, %s, %s", fd, fs, ft); } @@ -4302,17 +4001,17 @@ std::string NMD::CMP_SLE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SLT_D(uint64 instruction) +static char *CMP_SLT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SLT.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SLT.D %s, %s, %s", fd, fs, ft); } @@ -4326,17 +4025,17 @@ std::string NMD::CMP_SLT_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SLT_S(uint64 instruction) +static char *CMP_SLT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SLT.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SLT.S %s, %s, %s", fd, fs, ft); } @@ -4350,17 +4049,17 @@ std::string NMD::CMP_SLT_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SNE_D(uint64 instruction) +static char *CMP_SNE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SNE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SNE.D %s, %s, %s", fd, fs, ft); } @@ -4374,17 +4073,17 @@ std::string NMD::CMP_SNE_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SNE_S(uint64 instruction) +static char *CMP_SNE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SNE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SNE.S %s, %s, %s", fd, fs, ft); } @@ -4398,17 +4097,17 @@ std::string NMD::CMP_SNE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SOR_D(uint64 instruction) +static char *CMP_SOR_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SOR.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SOR.D %s, %s, %s", fd, fs, ft); } @@ -4422,17 +4121,17 @@ std::string NMD::CMP_SOR_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SOR_S(uint64 instruction) +static char *CMP_SOR_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SOR.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SOR.S %s, %s, %s", fd, fs, ft); } @@ -4446,17 +4145,17 @@ std::string NMD::CMP_SOR_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SUEQ_D(uint64 instruction) +static char *CMP_SUEQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SUEQ.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SUEQ.D %s, %s, %s", fd, fs, ft); } @@ -4470,17 +4169,17 @@ std::string NMD::CMP_SUEQ_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SUEQ_S(uint64 instruction) +static char *CMP_SUEQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SUEQ.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SUEQ.S %s, %s, %s", fd, fs, ft); } @@ -4494,17 +4193,17 @@ std::string NMD::CMP_SUEQ_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SULE_D(uint64 instruction) +static char *CMP_SULE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SULE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SULE.D %s, %s, %s", fd, fs, ft); } @@ -4518,17 +4217,17 @@ std::string NMD::CMP_SULE_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SULE_S(uint64 instruction) +static char *CMP_SULE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SULE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SULE.S %s, %s, %s", fd, fs, ft); } @@ -4542,17 +4241,17 @@ std::string NMD::CMP_SULE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SULT_D(uint64 instruction) +static char *CMP_SULT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SULT.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SULT.D %s, %s, %s", fd, fs, ft); } @@ -4566,17 +4265,17 @@ std::string NMD::CMP_SULT_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SULT_S(uint64 instruction) +static char *CMP_SULT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SULT.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SULT.S %s, %s, %s", fd, fs, ft); } @@ -4590,17 +4289,17 @@ std::string NMD::CMP_SULT_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SUN_D(uint64 instruction) +static char *CMP_SUN_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SUN.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SUN.D %s, %s, %s", fd, fs, ft); } @@ -4614,17 +4313,17 @@ std::string NMD::CMP_SUN_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SUNE_D(uint64 instruction) +static char *CMP_SUNE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SUNE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.SUNE.D %s, %s, %s", fd, fs, ft); } @@ -4638,17 +4337,17 @@ std::string NMD::CMP_SUNE_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SUNE_S(uint64 instruction) +static char *CMP_SUNE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SUNE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SUNE.S %s, %s, %s", fd, fs, ft); } @@ -4662,17 +4361,17 @@ std::string NMD::CMP_SUNE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_SUN_S(uint64 instruction) +static char *CMP_SUN_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.SUN.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.SUN.S %s, %s, %s", fd, fs, ft); } @@ -4686,17 +4385,17 @@ std::string NMD::CMP_SUN_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_UEQ_D(uint64 instruction) +static char *CMP_UEQ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.UEQ.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.UEQ.D %s, %s, %s", fd, fs, ft); } @@ -4710,17 +4409,17 @@ std::string NMD::CMP_UEQ_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_UEQ_S(uint64 instruction) +static char *CMP_UEQ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.UEQ.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.UEQ.S %s, %s, %s", fd, fs, ft); } @@ -4734,17 +4433,17 @@ std::string NMD::CMP_UEQ_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_ULE_D(uint64 instruction) +static char *CMP_ULE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.ULE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.ULE.D %s, %s, %s", fd, fs, ft); } @@ -4758,17 +4457,17 @@ std::string NMD::CMP_ULE_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_ULE_S(uint64 instruction) +static char *CMP_ULE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.ULE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.ULE.S %s, %s, %s", fd, fs, ft); } @@ -4782,17 +4481,17 @@ std::string NMD::CMP_ULE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_ULT_D(uint64 instruction) +static char *CMP_ULT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.ULT.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.ULT.D %s, %s, %s", fd, fs, ft); } @@ -4806,17 +4505,17 @@ std::string NMD::CMP_ULT_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_ULT_S(uint64 instruction) +static char *CMP_ULT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.ULT.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.ULT.S %s, %s, %s", fd, fs, ft); } @@ -4830,17 +4529,17 @@ std::string NMD::CMP_ULT_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_UN_D(uint64 instruction) +static char *CMP_UN_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.UN.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.UN.D %s, %s, %s", fd, fs, ft); } @@ -4854,17 +4553,17 @@ std::string NMD::CMP_UN_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_UNE_D(uint64 instruction) +static char *CMP_UNE_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.UNE.D %s, %s, %s", fd, fs, ft); + return img_format("CMP.UNE.D %s, %s, %s", fd, fs, ft); } @@ -4878,17 +4577,17 @@ std::string NMD::CMP_UNE_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_UNE_S(uint64 instruction) +static char *CMP_UNE_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.UNE.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.UNE.S %s, %s, %s", fd, fs, ft); } @@ -4902,17 +4601,17 @@ std::string NMD::CMP_UNE_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMP_UN_S(uint64 instruction) +static char *CMP_UN_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("CMP.UN.S %s, %s, %s", fd, fs, ft); + return img_format("CMP.UN.S %s, %s, %s", fd, fs, ft); } @@ -4927,17 +4626,17 @@ std::string NMD::CMP_UN_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMPGDU_EQ_QB(uint64 instruction) +static char *CMPGDU_EQ_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("CMPGDU.EQ.QB %s, %s, %s", rd, rs, rt); + return img_format("CMPGDU.EQ.QB %s, %s, %s", rd, rs, rt); } @@ -4952,17 +4651,17 @@ std::string NMD::CMPGDU_EQ_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMPGDU_LE_QB(uint64 instruction) +static char *CMPGDU_LE_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("CMPGDU.LE.QB %s, %s, %s", rd, rs, rt); + return img_format("CMPGDU.LE.QB %s, %s, %s", rd, rs, rt); } @@ -4977,17 +4676,17 @@ std::string NMD::CMPGDU_LE_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMPGDU_LT_QB(uint64 instruction) +static char *CMPGDU_LT_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("CMPGDU.LT.QB %s, %s, %s", rd, rs, rt); + return img_format("CMPGDU.LT.QB %s, %s, %s", rd, rs, rt); } @@ -5002,17 +4701,17 @@ std::string NMD::CMPGDU_LT_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMPGU_EQ_QB(uint64 instruction) +static char *CMPGU_EQ_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("CMPGU.EQ.QB %s, %s, %s", rd, rs, rt); + return img_format("CMPGU.EQ.QB %s, %s, %s", rd, rs, rt); } @@ -5027,17 +4726,17 @@ std::string NMD::CMPGU_EQ_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMPGU_LE_QB(uint64 instruction) +static char *CMPGU_LE_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("CMPGU.LE.QB %s, %s, %s", rd, rs, rt); + return img_format("CMPGU.LE.QB %s, %s, %s", rd, rs, rt); } @@ -5052,17 +4751,17 @@ std::string NMD::CMPGU_LE_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CMPGU_LT_QB(uint64 instruction) +static char *CMPGU_LT_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("CMPGU.LT.QB %s, %s, %s", rd, rs, rt); + return img_format("CMPGU.LT.QB %s, %s, %s", rd, rs, rt); } @@ -5076,15 +4775,15 @@ std::string NMD::CMPGU_LT_QB(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::CMPU_EQ_QB(uint64 instruction) +static char *CMPU_EQ_QB(uint64 instruction, Dis_info *info) { 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)); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("CMPU.EQ.QB %s, %s", rs, rt); + return img_format("CMPU.EQ.QB %s, %s", rs, rt); } @@ -5098,15 +4797,15 @@ std::string NMD::CMPU_EQ_QB(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::CMPU_LE_QB(uint64 instruction) +static char *CMPU_LE_QB(uint64 instruction, Dis_info *info) { 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)); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("CMPU.LE.QB %s, %s", rs, rt); + return img_format("CMPU.LE.QB %s, %s", rs, rt); } @@ -5120,15 +4819,15 @@ std::string NMD::CMPU_LE_QB(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::CMPU_LT_QB(uint64 instruction) +static char *CMPU_LT_QB(uint64 instruction, Dis_info *info) { 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)); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("CMPU.LT.QB %s, %s", rs, rt); + return img_format("CMPU.LT.QB %s, %s", rs, rt); } @@ -5142,13 +4841,12 @@ std::string NMD::CMPU_LT_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::COP2_1(uint64 instruction) +static char *COP2_1(uint64 instruction, Dis_info *info) { uint64 cofun_value = extract_cofun_25_24_23(instruction); - std::string cofun = IMMEDIATE(copy(cofun_value)); - return img::format("COP2_1 %s", cofun); + return img_format("COP2_1 0x%" PRIx64, cofun_value); } @@ -5162,15 +4860,14 @@ std::string NMD::COP2_1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CTC1(uint64 instruction) +static char *CTC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + const char *rt = GPR(rt_value, info); - return img::format("CTC1 %s, %s", rt, cs); + return img_format("CTC1 %s, CP%" PRIu64, rt, cs_value); } @@ -5184,15 +4881,14 @@ std::string NMD::CTC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CTC2(uint64 instruction) +static char *CTC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + const char *rt = GPR(rt_value, info); - return img::format("CTC2 %s, %s", rt, cs); + return img_format("CTC2 %s, CP%" PRIu64, rt, cs_value); } @@ -5206,15 +4902,15 @@ std::string NMD::CTC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_D_L(uint64 instruction) +static char *CVT_D_L(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CVT.D.L %s, %s", ft, fs); + return img_format("CVT.D.L %s, %s", ft, fs); } @@ -5228,15 +4924,15 @@ std::string NMD::CVT_D_L(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_D_S(uint64 instruction) +static char *CVT_D_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CVT.D.S %s, %s", ft, fs); + return img_format("CVT.D.S %s, %s", ft, fs); } @@ -5250,15 +4946,15 @@ std::string NMD::CVT_D_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_D_W(uint64 instruction) +static char *CVT_D_W(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CVT.D.W %s, %s", ft, fs); + return img_format("CVT.D.W %s, %s", ft, fs); } @@ -5272,15 +4968,15 @@ std::string NMD::CVT_D_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_L_D(uint64 instruction) +static char *CVT_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CVT.L.D %s, %s", ft, fs); + return img_format("CVT.L.D %s, %s", ft, fs); } @@ -5294,15 +4990,15 @@ std::string NMD::CVT_L_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_L_S(uint64 instruction) +static char *CVT_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CVT.L.S %s, %s", ft, fs); + return img_format("CVT.L.S %s, %s", ft, fs); } @@ -5316,15 +5012,15 @@ std::string NMD::CVT_L_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_S_D(uint64 instruction) +static char *CVT_S_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CVT.S.D %s, %s", ft, fs); + return img_format("CVT.S.D %s, %s", ft, fs); } @@ -5338,15 +5034,15 @@ std::string NMD::CVT_S_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_S_L(uint64 instruction) +static char *CVT_S_L(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CVT.S.L %s, %s", ft, fs); + return img_format("CVT.S.L %s, %s", ft, fs); } @@ -5360,15 +5056,15 @@ std::string NMD::CVT_S_L(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_S_PL(uint64 instruction) +static char *CVT_S_PL(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CVT.S.PL %s, %s", ft, fs); + return img_format("CVT.S.PL %s, %s", ft, fs); } @@ -5382,15 +5078,15 @@ std::string NMD::CVT_S_PL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_S_PU(uint64 instruction) +static char *CVT_S_PU(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CVT.S.PU %s, %s", ft, fs); + return img_format("CVT.S.PU %s, %s", ft, fs); } @@ -5404,15 +5100,15 @@ std::string NMD::CVT_S_PU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_S_W(uint64 instruction) +static char *CVT_S_W(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CVT.S.W %s, %s", ft, fs); + return img_format("CVT.S.W %s, %s", ft, fs); } @@ -5426,15 +5122,15 @@ std::string NMD::CVT_S_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_W_D(uint64 instruction) +static char *CVT_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CVT.W.D %s, %s", ft, fs); + return img_format("CVT.W.D %s, %s", ft, fs); } @@ -5448,15 +5144,15 @@ std::string NMD::CVT_W_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::CVT_W_S(uint64 instruction) +static char *CVT_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("CVT.W.S %s, %s", ft, fs); + return img_format("CVT.W.S %s, %s", ft, fs); } @@ -5470,15 +5166,14 @@ std::string NMD::CVT_W_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DADDIU_48_(uint64 instruction) +static char *DADDIU_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); + const char *rt = GPR(rt_value, info); - return img::format("DADDIU %s, %s", rt, s); + return img_format("DADDIU %s, %s", rt, s_value); } @@ -5492,17 +5187,17 @@ std::string NMD::DADDIU_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DADDIU_NEG_(uint64 instruction) +static char *DADDIU_NEG_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(neg_copy(u_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); + int64 u = neg_copy(u_value); - return img::format("DADDIU %s, %s, %s", rt, rs, u); + return img_format("DADDIU %s, %s, %" PRId64, rt, rs, u); } @@ -5516,17 +5211,16 @@ std::string NMD::DADDIU_NEG_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DADDIU_U12_(uint64 instruction) +static char *DADDIU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("DADDIU %s, %s, %s", rt, rs, u); + return img_format("DADDIU %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -5540,17 +5234,17 @@ std::string NMD::DADDIU_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DADD(uint64 instruction) +static char *DADD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DADD %s, %s, %s", rd, rs, rt); + return img_format("DADD %s, %s, %s", rd, rs, rt); } @@ -5564,17 +5258,17 @@ std::string NMD::DADD(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DADDU(uint64 instruction) +static char *DADDU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DADDU %s, %s, %s", rd, rs, rt); + return img_format("DADDU %s, %s, %s", rd, rs, rt); } @@ -5588,15 +5282,15 @@ std::string NMD::DADDU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DCLO(uint64 instruction) +static char *DCLO(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("DCLO %s, %s", rt, rs); + return img_format("DCLO %s, %s", rt, rs); } @@ -5610,15 +5304,15 @@ std::string NMD::DCLO(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DCLZ(uint64 instruction) +static char *DCLZ(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("DCLZ %s, %s", rt, rs); + return img_format("DCLZ %s, %s", rt, rs); } @@ -5632,17 +5326,17 @@ std::string NMD::DCLZ(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DDIV(uint64 instruction) +static char *DDIV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DDIV %s, %s, %s", rd, rs, rt); + return img_format("DDIV %s, %s, %s", rd, rs, rt); } @@ -5656,17 +5350,17 @@ std::string NMD::DDIV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DDIVU(uint64 instruction) +static char *DDIVU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DDIVU %s, %s, %s", rd, rs, rt); + return img_format("DDIVU %s, %s, %s", rd, rs, rt); } @@ -5680,11 +5374,11 @@ std::string NMD::DDIVU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DERET(uint64 instruction) +static char *DERET(uint64 instruction, Dis_info *info) { (void)instruction; - return "DERET "; + return g_strdup("DERET "); } @@ -5698,19 +5392,19 @@ std::string NMD::DERET(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DEXTM(uint64 instruction) +static char *DEXTM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); + uint64 msbd = encode_msbd_from_size(msbd_value); - return img::format("DEXTM %s, %s, %s, %s", rt, rs, lsb, msbd); + return img_format("DEXTM %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd); } @@ -5724,19 +5418,19 @@ std::string NMD::DEXTM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DEXT(uint64 instruction) +static char *DEXT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); + uint64 msbd = encode_msbd_from_size(msbd_value); - return img::format("DEXT %s, %s, %s, %s", rt, rs, lsb, msbd); + return img_format("DEXT %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd); } @@ -5750,19 +5444,19 @@ std::string NMD::DEXT(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DEXTU(uint64 instruction) +static char *DEXTU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); + uint64 msbd = encode_msbd_from_size(msbd_value); - return img::format("DEXTU %s, %s, %s, %s", rt, rs, lsb, msbd); + return img_format("DEXTU %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd); } @@ -5776,20 +5470,19 @@ std::string NMD::DEXTU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DINSM(uint64 instruction) +static char *DINSM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); /* !!!!!!!!!! - no conversion function */ - return img::format("DINSM %s, %s, %s, %s", rt, rs, pos, size); + return img_format("DINSM %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd_value); /* hand edited */ } @@ -5804,20 +5497,19 @@ std::string NMD::DINSM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DINS(uint64 instruction) +static char *DINS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); /* !!!!!!!!!! - no conversion function */ - return img::format("DINS %s, %s, %s, %s", rt, rs, pos, size); + return img_format("DINS %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd_value); /* hand edited */ } @@ -5832,20 +5524,19 @@ std::string NMD::DINS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DINSU(uint64 instruction) +static char *DINSU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); /* !!!!!!!!!! - no conversion function */ - return img::format("DINSU %s, %s, %s, %s", rt, rs, pos, size); + return img_format("DINSU %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd_value); /* hand edited */ } @@ -5860,13 +5551,13 @@ std::string NMD::DINSU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DI(uint64 instruction) +static char *DI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + const char *rt = GPR(rt_value, info); - return img::format("DI %s", rt); + return img_format("DI %s", rt); } @@ -5880,17 +5571,17 @@ std::string NMD::DI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DIV(uint64 instruction) +static char *DIV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DIV %s, %s, %s", rd, rs, rt); + return img_format("DIV %s, %s, %s", rd, rs, rt); } @@ -5904,17 +5595,17 @@ std::string NMD::DIV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DIV_D(uint64 instruction) +static char *DIV_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("DIV.D %s, %s, %s", fd, fs, ft); + return img_format("DIV.D %s, %s, %s", fd, fs, ft); } @@ -5928,17 +5619,17 @@ std::string NMD::DIV_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DIV_S(uint64 instruction) +static char *DIV_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("DIV.S %s, %s, %s", fd, fs, ft); + return img_format("DIV.S %s, %s, %s", fd, fs, ft); } @@ -5952,17 +5643,17 @@ std::string NMD::DIV_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DIVU(uint64 instruction) +static char *DIVU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DIVU %s, %s, %s", rd, rs, rt); + return img_format("DIVU %s, %s, %s", rd, rs, rt); } @@ -5976,19 +5667,18 @@ std::string NMD::DIVU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DLSA(uint64 instruction) +static char *DLSA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 u2_value = extract_u2_10_9(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)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DLSA %s, %s, %s, %s", rd, rs, rt, u2); + return img_format("DLSA %s, %s, %s, 0x%" PRIx64, rd, rs, rt, u2_value); } @@ -6002,15 +5692,14 @@ std::string NMD::DLSA(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DLUI_48_(uint64 instruction) +static char *DLUI_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); uint64 u_value = extract_u_31_to_0__s32(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); - return img::format("DLUI %s, %s", rt, u); + return img_format("DLUI %s, 0x%" PRIx64, rt, u_value); } @@ -6024,17 +5713,16 @@ std::string NMD::DLUI_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMFC0(uint64 instruction) +static char *DMFC0(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("DMFC0 %s, %s, %s", rt, c0s, sel); + return img_format("DMFC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -6048,15 +5736,15 @@ std::string NMD::DMFC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMFC1(uint64 instruction) +static char *DMFC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string fs = FPR(copy(fs_value)); + const char *rt = GPR(rt_value, info); + const char *fs = FPR(fs_value, info); - return img::format("DMFC1 %s, %s", rt, fs); + return img_format("DMFC1 %s, %s", rt, fs); } @@ -6070,15 +5758,14 @@ std::string NMD::DMFC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMFC2(uint64 instruction) +static char *DMFC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + const char *rt = GPR(rt_value, info); - return img::format("DMFC2 %s, %s", rt, cs); + return img_format("DMFC2 %s, CP%" PRIu64, rt, cs_value); } @@ -6092,17 +5779,16 @@ std::string NMD::DMFC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMFGC0(uint64 instruction) +static char *DMFGC0(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("DMFGC0 %s, %s, %s", rt, c0s, sel); + return img_format("DMFGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -6116,17 +5802,17 @@ std::string NMD::DMFGC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMOD(uint64 instruction) +static char *DMOD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DMOD %s, %s, %s", rd, rs, rt); + return img_format("DMOD %s, %s, %s", rd, rs, rt); } @@ -6140,17 +5826,17 @@ std::string NMD::DMOD(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMODU(uint64 instruction) +static char *DMODU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DMODU %s, %s, %s", rd, rs, rt); + return img_format("DMODU %s, %s, %s", rd, rs, rt); } @@ -6164,17 +5850,16 @@ std::string NMD::DMODU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMTC0(uint64 instruction) +static char *DMTC0(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("DMTC0 %s, %s, %s", rt, c0s, sel); + return img_format("DMTC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -6188,15 +5873,15 @@ std::string NMD::DMTC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMTC1(uint64 instruction) +static char *DMTC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string fs = FPR(copy(fs_value)); + const char *rt = GPR(rt_value, info); + const char *fs = FPR(fs_value, info); - return img::format("DMTC1 %s, %s", rt, fs); + return img_format("DMTC1 %s, %s", rt, fs); } @@ -6210,15 +5895,14 @@ std::string NMD::DMTC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMTC2(uint64 instruction) +static char *DMTC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + const char *rt = GPR(rt_value, info); - return img::format("DMTC2 %s, %s", rt, cs); + return img_format("DMTC2 %s, CP%" PRIu64, rt, cs_value); } @@ -6232,17 +5916,16 @@ std::string NMD::DMTC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMTGC0(uint64 instruction) +static char *DMTGC0(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("DMTGC0 %s, %s, %s", rt, c0s, sel); + return img_format("DMTGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -6256,13 +5939,13 @@ std::string NMD::DMTGC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMT(uint64 instruction) +static char *DMT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + const char *rt = GPR(rt_value, info); - return img::format("DMT %s", rt); + return img_format("DMT %s", rt); } @@ -6276,17 +5959,17 @@ std::string NMD::DMT(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMUH(uint64 instruction) +static char *DMUH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DMUH %s, %s, %s", rd, rs, rt); + return img_format("DMUH %s, %s, %s", rd, rs, rt); } @@ -6300,17 +5983,17 @@ std::string NMD::DMUH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMUHU(uint64 instruction) +static char *DMUHU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DMUHU %s, %s, %s", rd, rs, rt); + return img_format("DMUHU %s, %s, %s", rd, rs, rt); } @@ -6324,17 +6007,17 @@ std::string NMD::DMUHU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMUL(uint64 instruction) +static char *DMUL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DMUL %s, %s, %s", rd, rs, rt); + return img_format("DMUL %s, %s, %s", rd, rs, rt); } @@ -6348,17 +6031,17 @@ std::string NMD::DMUL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DMULU(uint64 instruction) +static char *DMULU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DMULU %s, %s, %s", rd, rs, rt); + return img_format("DMULU %s, %s, %s", rd, rs, rt); } @@ -6373,17 +6056,17 @@ std::string NMD::DMULU(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::DPA_W_PH(uint64 instruction) +static char *DPA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPA.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6397,17 +6080,17 @@ std::string NMD::DPA_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPAQ_SA_L_W(uint64 instruction) +static char *DPAQ_SA_L_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPAQ_SA.L.W %s, %s, %s", ac, rs, rt); + return img_format("DPAQ_SA.L.W %s, %s, %s", ac, rs, rt); } @@ -6421,17 +6104,17 @@ std::string NMD::DPAQ_SA_L_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPAQ_S_W_PH(uint64 instruction) +static char *DPAQ_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPAQ_S.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPAQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6445,17 +6128,17 @@ std::string NMD::DPAQ_S_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPAQX_SA_W_PH(uint64 instruction) +static char *DPAQX_SA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPAQX_SA.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPAQX_SA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6469,17 +6152,17 @@ std::string NMD::DPAQX_SA_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPAQX_S_W_PH(uint64 instruction) +static char *DPAQX_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPAQX_S.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPAQX_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6493,17 +6176,17 @@ std::string NMD::DPAQX_S_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPAU_H_QBL(uint64 instruction) +static char *DPAU_H_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPAU.H.QBL %s, %s, %s", ac, rs, rt); + return img_format("DPAU.H.QBL %s, %s, %s", ac, rs, rt); } @@ -6517,17 +6200,17 @@ std::string NMD::DPAU_H_QBL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPAU_H_QBR(uint64 instruction) +static char *DPAU_H_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPAU.H.QBR %s, %s, %s", ac, rs, rt); + return img_format("DPAU.H.QBR %s, %s, %s", ac, rs, rt); } @@ -6541,17 +6224,17 @@ std::string NMD::DPAU_H_QBR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPAX_W_PH(uint64 instruction) +static char *DPAX_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPAX.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPAX.W.PH %s, %s, %s", ac, rs, rt); } @@ -6565,17 +6248,17 @@ std::string NMD::DPAX_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPS_W_PH(uint64 instruction) +static char *DPS_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPS.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPS.W.PH %s, %s, %s", ac, rs, rt); } @@ -6589,17 +6272,17 @@ std::string NMD::DPS_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPSQ_SA_L_W(uint64 instruction) +static char *DPSQ_SA_L_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPSQ_SA.L.W %s, %s, %s", ac, rs, rt); + return img_format("DPSQ_SA.L.W %s, %s, %s", ac, rs, rt); } @@ -6613,17 +6296,17 @@ std::string NMD::DPSQ_SA_L_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPSQ_S_W_PH(uint64 instruction) +static char *DPSQ_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPSQ_S.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPSQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6637,17 +6320,17 @@ std::string NMD::DPSQ_S_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPSQX_SA_W_PH(uint64 instruction) +static char *DPSQX_SA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPSQX_SA.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPSQX_SA.W.PH %s, %s, %s", ac, rs, rt); } @@ -6661,17 +6344,17 @@ std::string NMD::DPSQX_SA_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPSQX_S_W_PH(uint64 instruction) +static char *DPSQX_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPSQX_S.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPSQX_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -6685,17 +6368,17 @@ std::string NMD::DPSQX_S_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPSU_H_QBL(uint64 instruction) +static char *DPSU_H_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPSU.H.QBL %s, %s, %s", ac, rs, rt); + return img_format("DPSU.H.QBL %s, %s, %s", ac, rs, rt); } @@ -6709,17 +6392,17 @@ std::string NMD::DPSU_H_QBL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPSU_H_QBR(uint64 instruction) +static char *DPSU_H_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPSU.H.QBR %s, %s, %s", ac, rs, rt); + return img_format("DPSU.H.QBR %s, %s, %s", ac, rs, rt); } @@ -6733,17 +6416,17 @@ std::string NMD::DPSU_H_QBR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DPSX_W_PH(uint64 instruction) +static char *DPSX_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DPSX.W.PH %s, %s, %s", ac, rs, rt); + return img_format("DPSX.W.PH %s, %s, %s", ac, rs, rt); } @@ -6757,17 +6440,16 @@ std::string NMD::DPSX_W_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DROTR(uint64 instruction) +static char *DROTR(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("DROTR %s, %s, %s", rt, rs, shift); + return img_format("DROTR %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6781,17 +6463,16 @@ std::string NMD::DROTR(uint64 instruction) * rs ----- * shift ----- */ -std::string NMD::DROTR32(uint64 instruction) +static char *DROTR32(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("DROTR32 %s, %s, %s", rt, rs, shift); + return img_format("DROTR32 %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6805,17 +6486,17 @@ std::string NMD::DROTR32(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DROTRV(uint64 instruction) +static char *DROTRV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DROTRV %s, %s, %s", rd, rs, rt); + return img_format("DROTRV %s, %s, %s", rd, rs, rt); } @@ -6829,19 +6510,18 @@ std::string NMD::DROTRV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DROTX(uint64 instruction) +static char *DROTX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 shiftx_value = extract_shiftx_11_10_9_8_7_6(instruction); uint64 shift_value = extract_shift_5_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)); - std::string shiftx = IMMEDIATE(copy(shiftx_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("DROTX %s, %s, %s, %s", rt, rs, shift, shiftx); + return img_format("DROTX %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, shift_value, shiftx_value); } @@ -6855,17 +6535,16 @@ std::string NMD::DROTX(uint64 instruction) * rs ----- * shift ----- */ -std::string NMD::DSLL(uint64 instruction) +static char *DSLL(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("DSLL %s, %s, %s", rt, rs, shift); + return img_format("DSLL %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6879,17 +6558,16 @@ std::string NMD::DSLL(uint64 instruction) * rs ----- * shift ----- */ -std::string NMD::DSLL32(uint64 instruction) +static char *DSLL32(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("DSLL32 %s, %s, %s", rt, rs, shift); + return img_format("DSLL32 %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6903,17 +6581,17 @@ std::string NMD::DSLL32(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DSLLV(uint64 instruction) +static char *DSLLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DSLLV %s, %s, %s", rd, rs, rt); + return img_format("DSLLV %s, %s, %s", rd, rs, rt); } @@ -6927,17 +6605,16 @@ std::string NMD::DSLLV(uint64 instruction) * rs ----- * shift ----- */ -std::string NMD::DSRA(uint64 instruction) +static char *DSRA(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("DSRA %s, %s, %s", rt, rs, shift); + return img_format("DSRA %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6951,17 +6628,16 @@ std::string NMD::DSRA(uint64 instruction) * rs ----- * shift ----- */ -std::string NMD::DSRA32(uint64 instruction) +static char *DSRA32(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("DSRA32 %s, %s, %s", rt, rs, shift); + return img_format("DSRA32 %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -6975,17 +6651,17 @@ std::string NMD::DSRA32(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DSRAV(uint64 instruction) +static char *DSRAV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DSRAV %s, %s, %s", rd, rs, rt); + return img_format("DSRAV %s, %s, %s", rd, rs, rt); } @@ -6999,17 +6675,16 @@ std::string NMD::DSRAV(uint64 instruction) * rs ----- * shift ----- */ -std::string NMD::DSRL(uint64 instruction) +static char *DSRL(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("DSRL %s, %s, %s", rt, rs, shift); + return img_format("DSRL %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -7023,17 +6698,16 @@ std::string NMD::DSRL(uint64 instruction) * rs ----- * shift ----- */ -std::string NMD::DSRL32(uint64 instruction) +static char *DSRL32(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("DSRL32 %s, %s, %s", rt, rs, shift); + return img_format("DSRL32 %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -7047,17 +6721,17 @@ std::string NMD::DSRL32(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DSRLV(uint64 instruction) +static char *DSRLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DSRLV %s, %s, %s", rd, rs, rt); + return img_format("DSRLV %s, %s, %s", rd, rs, rt); } @@ -7071,17 +6745,17 @@ std::string NMD::DSRLV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DSUB(uint64 instruction) +static char *DSUB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DSUB %s, %s, %s", rd, rs, rt); + return img_format("DSUB %s, %s, %s", rd, rs, rt); } @@ -7095,17 +6769,17 @@ std::string NMD::DSUB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DSUBU(uint64 instruction) +static char *DSUBU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("DSUBU %s, %s, %s", rd, rs, rt); + return img_format("DSUBU %s, %s, %s", rd, rs, rt); } @@ -7119,13 +6793,13 @@ std::string NMD::DSUBU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DVPE(uint64 instruction) +static char *DVPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + const char *rt = GPR(rt_value, info); - return img::format("DVPE %s", rt); + return img_format("DVPE %s", rt); } @@ -7139,13 +6813,13 @@ std::string NMD::DVPE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::DVP(uint64 instruction) +static char *DVP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + const char *rt = GPR(rt_value, info); - return img::format("DVP %s", rt); + return img_format("DVP %s", rt); } @@ -7159,11 +6833,11 @@ std::string NMD::DVP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EHB(uint64 instruction) +static char *EHB(uint64 instruction, Dis_info *info) { (void)instruction; - return "EHB "; + return g_strdup("EHB "); } @@ -7177,13 +6851,13 @@ std::string NMD::EHB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EI(uint64 instruction) +static char *EI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + const char *rt = GPR(rt_value, info); - return img::format("EI %s", rt); + return img_format("EI %s", rt); } @@ -7197,13 +6871,13 @@ std::string NMD::EI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EMT(uint64 instruction) +static char *EMT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + const char *rt = GPR(rt_value, info); - return img::format("EMT %s", rt); + return img_format("EMT %s", rt); } @@ -7217,11 +6891,11 @@ std::string NMD::EMT(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ERET(uint64 instruction) +static char *ERET(uint64 instruction, Dis_info *info) { (void)instruction; - return "ERET "; + return g_strdup("ERET "); } @@ -7235,11 +6909,11 @@ std::string NMD::ERET(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ERETNC(uint64 instruction) +static char *ERETNC(uint64 instruction, Dis_info *info) { (void)instruction; - return "ERETNC "; + return g_strdup("ERETNC "); } @@ -7253,13 +6927,13 @@ std::string NMD::ERETNC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EVP(uint64 instruction) +static char *EVP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + const char *rt = GPR(rt_value, info); - return img::format("EVP %s", rt); + return img_format("EVP %s", rt); } @@ -7273,13 +6947,13 @@ std::string NMD::EVP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EVPE(uint64 instruction) +static char *EVPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); - std::string rt = GPR(copy(rt_value)); + const char *rt = GPR(rt_value, info); - return img::format("EVPE %s", rt); + return img_format("EVPE %s", rt); } @@ -7293,19 +6967,19 @@ std::string NMD::EVPE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EXT(uint64 instruction) +static char *EXT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); + uint64 msbd = encode_msbd_from_size(msbd_value); - return img::format("EXT %s, %s, %s, %s", rt, rs, lsb, msbd); + return img_format("EXT %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd); } @@ -7319,19 +6993,18 @@ std::string NMD::EXT(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EXTD(uint64 instruction) +static char *EXTD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 shift_value = extract_shift_10_9_8_7_6(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)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("EXTD %s, %s, %s, %s", rd, rs, rt, shift); + return img_format("EXTD %s, %s, %s, 0x%" PRIx64, rd, rs, rt, shift_value); } @@ -7345,19 +7018,18 @@ std::string NMD::EXTD(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EXTD32(uint64 instruction) +static char *EXTD32(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 shift_value = extract_shift_10_9_8_7_6(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)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("EXTD32 %s, %s, %s, %s", rd, rs, rt, shift); + return img_format("EXTD32 %s, %s, %s, 0x%" PRIx64, rd, rs, rt, shift_value); } @@ -7371,17 +7043,16 @@ std::string NMD::EXTD32(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EXTPDP(uint64 instruction) +static char *EXTPDP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 size_value = extract_size_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string size = IMMEDIATE(copy(size_value)); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); - return img::format("EXTPDP %s, %s, %s", rt, ac, size); + return img_format("EXTPDP %s, %s, 0x%" PRIx64, rt, ac, size_value); } @@ -7395,17 +7066,17 @@ std::string NMD::EXTPDP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EXTPDPV(uint64 instruction) +static char *EXTPDPV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); - return img::format("EXTPDPV %s, %s, %s", rt, ac, rs); + return img_format("EXTPDPV %s, %s, %s", rt, ac, rs); } @@ -7419,17 +7090,16 @@ std::string NMD::EXTPDPV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EXTP(uint64 instruction) +static char *EXTP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 size_value = extract_size_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string size = IMMEDIATE(copy(size_value)); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); - return img::format("EXTP %s, %s, %s", rt, ac, size); + return img_format("EXTP %s, %s, 0x%" PRIx64, rt, ac, size_value); } @@ -7443,17 +7113,17 @@ std::string NMD::EXTP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::EXTPV(uint64 instruction) +static char *EXTPV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); - return img::format("EXTPV %s, %s, %s", rt, ac, rs); + return img_format("EXTPV %s, %s, %s", rt, ac, rs); } @@ -7468,17 +7138,16 @@ std::string NMD::EXTPV(uint64 instruction) * shift ----- * ac -- */ -std::string NMD::EXTR_RS_W(uint64 instruction) +static char *EXTR_RS_W(uint64 instruction, Dis_info *info) { 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_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); - return img::format("EXTR_RS.W %s, %s, %s", rt, ac, shift); + return img_format("EXTR_RS.W %s, %s, 0x%" PRIx64, rt, ac, shift_value); } @@ -7493,17 +7162,16 @@ std::string NMD::EXTR_RS_W(uint64 instruction) * shift ----- * ac -- */ -std::string NMD::EXTR_R_W(uint64 instruction) +static char *EXTR_R_W(uint64 instruction, Dis_info *info) { 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_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); - return img::format("EXTR_R.W %s, %s, %s", rt, ac, shift); + return img_format("EXTR_R.W %s, %s, 0x%" PRIx64, rt, ac, shift_value); } @@ -7518,17 +7186,16 @@ std::string NMD::EXTR_R_W(uint64 instruction) * shift ----- * ac -- */ -std::string NMD::EXTR_S_H(uint64 instruction) +static char *EXTR_S_H(uint64 instruction, Dis_info *info) { 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_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); - return img::format("EXTR_S.H %s, %s, %s", rt, ac, shift); + return img_format("EXTR_S.H %s, %s, 0x%" PRIx64, rt, ac, shift_value); } @@ -7543,17 +7210,16 @@ std::string NMD::EXTR_S_H(uint64 instruction) * shift ----- * ac -- */ -std::string NMD::EXTR_W(uint64 instruction) +static char *EXTR_W(uint64 instruction, Dis_info *info) { 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_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string shift = IMMEDIATE(copy(shift_value)); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); - return img::format("EXTR.W %s, %s, %s", rt, ac, shift); + return img_format("EXTR.W %s, %s, 0x%" PRIx64, rt, ac, shift_value); } @@ -7568,17 +7234,17 @@ std::string NMD::EXTR_W(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::EXTRV_RS_W(uint64 instruction) +static char *EXTRV_RS_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); - return img::format("EXTRV_RS.W %s, %s, %s", rt, ac, rs); + return img_format("EXTRV_RS.W %s, %s, %s", rt, ac, rs); } @@ -7593,17 +7259,17 @@ std::string NMD::EXTRV_RS_W(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::EXTRV_R_W(uint64 instruction) +static char *EXTRV_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); - return img::format("EXTRV_R.W %s, %s, %s", rt, ac, rs); + return img_format("EXTRV_R.W %s, %s, %s", rt, ac, rs); } @@ -7618,17 +7284,17 @@ std::string NMD::EXTRV_R_W(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::EXTRV_S_H(uint64 instruction) +static char *EXTRV_S_H(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); - return img::format("EXTRV_S.H %s, %s, %s", rt, ac, rs); + return img_format("EXTRV_S.H %s, %s, %s", rt, ac, rs); } @@ -7643,17 +7309,17 @@ std::string NMD::EXTRV_S_H(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::EXTRV_W(uint64 instruction) +static char *EXTRV_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); - return img::format("EXTRV.W %s, %s, %s", rt, ac, rs); + return img_format("EXTRV.W %s, %s, %s", rt, ac, rs); } @@ -7668,19 +7334,18 @@ std::string NMD::EXTRV_W(uint64 instruction) * rd ----- * shift ----- */ -std::string NMD::EXTW(uint64 instruction) +static char *EXTW(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 shift_value = extract_shift_10_9_8_7_6(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)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("EXTW %s, %s, %s, %s", rd, rs, rt, shift); + return img_format("EXTW %s, %s, %s, 0x%" PRIx64, rd, rs, rt, shift_value); } @@ -7694,15 +7359,15 @@ std::string NMD::EXTW(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::FLOOR_L_D(uint64 instruction) +static char *FLOOR_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("FLOOR.L.D %s, %s", ft, fs); + return img_format("FLOOR.L.D %s, %s", ft, fs); } @@ -7716,15 +7381,15 @@ std::string NMD::FLOOR_L_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::FLOOR_L_S(uint64 instruction) +static char *FLOOR_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("FLOOR.L.S %s, %s", ft, fs); + return img_format("FLOOR.L.S %s, %s", ft, fs); } @@ -7738,15 +7403,15 @@ std::string NMD::FLOOR_L_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::FLOOR_W_D(uint64 instruction) +static char *FLOOR_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("FLOOR.W.D %s, %s", ft, fs); + return img_format("FLOOR.W.D %s, %s", ft, fs); } @@ -7760,15 +7425,15 @@ std::string NMD::FLOOR_W_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::FLOOR_W_S(uint64 instruction) +static char *FLOOR_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("FLOOR.W.S %s, %s", ft, fs); + return img_format("FLOOR.W.S %s, %s", ft, fs); } @@ -7782,17 +7447,17 @@ std::string NMD::FLOOR_W_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::FORK(uint64 instruction) +static char *FORK(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("FORK %s, %s, %s", rd, rs, rt); + return img_format("FORK %s, %s, %s", rd, rs, rt); } @@ -7806,13 +7471,12 @@ std::string NMD::FORK(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::HYPCALL(uint64 instruction) +static char *HYPCALL(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_17_to_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); - return img::format("HYPCALL %s", code); + return img_format("HYPCALL 0x%" PRIx64, code_value); } @@ -7826,13 +7490,12 @@ std::string NMD::HYPCALL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::HYPCALL_16_(uint64 instruction) +static char *HYPCALL_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_1_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); - return img::format("HYPCALL %s", code); + return img_format("HYPCALL 0x%" PRIx64, code_value); } @@ -7846,20 +7509,19 @@ std::string NMD::HYPCALL_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::INS(uint64 instruction) +static char *INS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 msbd_value = extract_msbt_10_9_8_7_6(instruction); uint64 lsb_value = extract_lsb_4_3_2_1_0(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); /* !!!!!!!!!! - no conversion function */ - return img::format("INS %s, %s, %s, %s", rt, rs, pos, size); + return img_format("INS %s, %s, 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, lsb_value, msbd_value); /* hand edited */ } @@ -7873,15 +7535,15 @@ std::string NMD::INS(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::INSV(uint64 instruction) +static char *INSV(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("INSV %s, %s", rt, rs); + return img_format("INSV %s, %s", rt, rs); } @@ -7895,11 +7557,11 @@ std::string NMD::INSV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::IRET(uint64 instruction) +static char *IRET(uint64 instruction, Dis_info *info) { (void)instruction; - return "IRET "; + return g_strdup("IRET "); } @@ -7913,13 +7575,13 @@ std::string NMD::IRET(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::JALRC_16_(uint64 instruction) +static char *JALRC_16_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); - std::string rt = GPR(copy(rt_value)); + const char *rt = GPR(rt_value, info); - return img::format("JALRC $%d, %s", 31, rt); + return img_format("JALRC $%d, %s", 31, rt); } @@ -7933,15 +7595,15 @@ std::string NMD::JALRC_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::JALRC_32_(uint64 instruction) +static char *JALRC_32_(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("JALRC %s, %s", rt, rs); + return img_format("JALRC %s, %s", rt, rs); } @@ -7955,15 +7617,15 @@ std::string NMD::JALRC_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::JALRC_HB(uint64 instruction) +static char *JALRC_HB(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("JALRC.HB %s, %s", rt, rs); + return img_format("JALRC.HB %s, %s", rt, rs); } @@ -7977,13 +7639,13 @@ std::string NMD::JALRC_HB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::JRC(uint64 instruction) +static char *JRC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); - std::string rt = GPR(copy(rt_value)); + const char *rt = GPR(rt_value, info); - return img::format("JRC %s", rt); + return img_format("JRC %s", rt); } @@ -7997,17 +7659,16 @@ std::string NMD::JRC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LB_16_(uint64 instruction) +static char *LB_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_1_0(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); - return img::format("LB %s, %s(%s)", rt3, u, rs3); + return img_format("LB %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -8021,15 +7682,14 @@ std::string NMD::LB_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LB_GP_(uint64 instruction) +static char *LB_GP_(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("LB %s, %s($%d)", rt, u, 28); + return img_format("LB %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -8043,17 +7703,16 @@ std::string NMD::LB_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LB_S9_(uint64 instruction) +static char *LB_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LB %s, %s(%s)", rt, s, rs); + return img_format("LB %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8067,17 +7726,16 @@ std::string NMD::LB_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LB_U12_(uint64 instruction) +static char *LB_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LB %s, %s(%s)", rt, u, rs); + return img_format("LB %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -8091,17 +7749,16 @@ std::string NMD::LB_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBE(uint64 instruction) +static char *LBE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LBE %s, %s(%s)", rt, s, rs); + return img_format("LBE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8115,17 +7772,16 @@ std::string NMD::LBE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBU_16_(uint64 instruction) +static char *LBU_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_1_0(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); - return img::format("LBU %s, %s(%s)", rt3, u, rs3); + return img_format("LBU %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -8139,15 +7795,14 @@ std::string NMD::LBU_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBU_GP_(uint64 instruction) +static char *LBU_GP_(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("LBU %s, %s($%d)", rt, u, 28); + return img_format("LBU %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -8161,17 +7816,16 @@ std::string NMD::LBU_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBU_S9_(uint64 instruction) +static char *LBU_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LBU %s, %s(%s)", rt, s, rs); + return img_format("LBU %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8185,17 +7839,16 @@ std::string NMD::LBU_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBU_U12_(uint64 instruction) +static char *LBU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LBU %s, %s(%s)", rt, u, rs); + return img_format("LBU %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -8209,17 +7862,16 @@ std::string NMD::LBU_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBUE(uint64 instruction) +static char *LBUE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LBUE %s, %s(%s)", rt, s, rs); + return img_format("LBUE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8233,17 +7885,17 @@ std::string NMD::LBUE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBUX(uint64 instruction) +static char *LBUX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LBUX %s, %s(%s)", rd, rs, rt); + return img_format("LBUX %s, %s(%s)", rd, rs, rt); } @@ -8257,17 +7909,17 @@ std::string NMD::LBUX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LBX(uint64 instruction) +static char *LBX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LBX %s, %s(%s)", rd, rs, rt); + return img_format("LBX %s, %s(%s)", rd, rs, rt); } @@ -8281,15 +7933,14 @@ std::string NMD::LBX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LD_GP_(uint64 instruction) +static char *LD_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_3__s3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); - return img::format("LD %s, %s($%d)", rt, u, 28); + return img_format("LD %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -8303,17 +7954,16 @@ std::string NMD::LD_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LD_S9_(uint64 instruction) +static char *LD_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LD %s, %s(%s)", rt, s, rs); + return img_format("LD %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8327,17 +7977,16 @@ std::string NMD::LD_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LD_U12_(uint64 instruction) +static char *LD_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LD %s, %s(%s)", rt, u, rs); + return img_format("LD %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -8351,15 +8000,14 @@ std::string NMD::LD_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDC1_GP_(uint64 instruction) +static char *LDC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *ft = FPR(ft_value, info); - return img::format("LDC1 %s, %s($%d)", ft, u, 28); + return img_format("LDC1 %s, 0x%" PRIx64 "($%d)", ft, u_value, 28); } @@ -8373,17 +8021,16 @@ std::string NMD::LDC1_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDC1_S9_(uint64 instruction) +static char *LDC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LDC1 %s, %s(%s)", ft, s, rs); + return img_format("LDC1 %s, %" PRId64 "(%s)", ft, s_value, rs); } @@ -8397,17 +8044,16 @@ std::string NMD::LDC1_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDC1_U12_(uint64 instruction) +static char *LDC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LDC1 %s, %s(%s)", ft, u, rs); + return img_format("LDC1 %s, 0x%" PRIx64 "(%s)", ft, u_value, rs); } @@ -8421,17 +8067,17 @@ std::string NMD::LDC1_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDC1XS(uint64 instruction) +static char *LDC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LDC1XS %s, %s(%s)", ft, rs, rt); + return img_format("LDC1XS %s, %s(%s)", ft, rs, rt); } @@ -8445,17 +8091,17 @@ std::string NMD::LDC1XS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDC1X(uint64 instruction) +static char *LDC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LDC1X %s, %s(%s)", ft, rs, rt); + return img_format("LDC1X %s, %s(%s)", ft, rs, rt); } @@ -8469,17 +8115,16 @@ std::string NMD::LDC1X(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDC2(uint64 instruction) +static char *LDC2(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ct = CPR(copy(ct_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rs = GPR(rs_value, info); - return img::format("LDC2 %s, %s(%s)", ct, s, rs); + return img_format("LDC2 CP%" PRIu64 ", %" PRId64 "(%s)", + ct_value, s_value, rs); } @@ -8493,19 +8138,19 @@ std::string NMD::LDC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDM(uint64 instruction) +static char *LDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); + uint64 count3 = encode_count3_from_count(count3_value); - return img::format("LDM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("LDM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -8519,15 +8164,15 @@ std::string NMD::LDM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDPC_48_(uint64 instruction) +static char *LDPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 6, info); - return img::format("LDPC %s, %s", rt, s); + return img_format("LDPC %s, %s", rt, s); } @@ -8541,17 +8186,17 @@ std::string NMD::LDPC_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDX(uint64 instruction) +static char *LDX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LDX %s, %s(%s)", rd, rs, rt); + return img_format("LDX %s, %s(%s)", rd, rs, rt); } @@ -8565,17 +8210,17 @@ std::string NMD::LDX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LDXS(uint64 instruction) +static char *LDXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LDXS %s, %s(%s)", rd, rs, rt); + return img_format("LDXS %s, %s(%s)", rd, rs, rt); } @@ -8589,17 +8234,16 @@ std::string NMD::LDXS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LH_16_(uint64 instruction) +static char *LH_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_2_1__s1(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); - return img::format("LH %s, %s(%s)", rt3, u, rs3); + return img_format("LH %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -8613,15 +8257,14 @@ std::string NMD::LH_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LH_GP_(uint64 instruction) +static char *LH_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); - return img::format("LH %s, %s($%d)", rt, u, 28); + return img_format("LH %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -8635,17 +8278,16 @@ std::string NMD::LH_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LH_S9_(uint64 instruction) +static char *LH_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LH %s, %s(%s)", rt, s, rs); + return img_format("LH %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8659,17 +8301,16 @@ std::string NMD::LH_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LH_U12_(uint64 instruction) +static char *LH_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LH %s, %s(%s)", rt, u, rs); + return img_format("LH %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -8683,17 +8324,16 @@ std::string NMD::LH_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHE(uint64 instruction) +static char *LHE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LHE %s, %s(%s)", rt, s, rs); + return img_format("LHE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8707,17 +8347,16 @@ std::string NMD::LHE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHU_16_(uint64 instruction) +static char *LHU_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_2_1__s1(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); - return img::format("LHU %s, %s(%s)", rt3, u, rs3); + return img_format("LHU %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -8731,15 +8370,14 @@ std::string NMD::LHU_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHU_GP_(uint64 instruction) +static char *LHU_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); - return img::format("LHU %s, %s($%d)", rt, u, 28); + return img_format("LHU %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -8753,17 +8391,16 @@ std::string NMD::LHU_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHU_S9_(uint64 instruction) +static char *LHU_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LHU %s, %s(%s)", rt, s, rs); + return img_format("LHU %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8777,17 +8414,16 @@ std::string NMD::LHU_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHU_U12_(uint64 instruction) +static char *LHU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LHU %s, %s(%s)", rt, u, rs); + return img_format("LHU %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -8801,17 +8437,16 @@ std::string NMD::LHU_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHUE(uint64 instruction) +static char *LHUE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LHUE %s, %s(%s)", rt, s, rs); + return img_format("LHUE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8825,17 +8460,17 @@ std::string NMD::LHUE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHUX(uint64 instruction) +static char *LHUX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LHUX %s, %s(%s)", rd, rs, rt); + return img_format("LHUX %s, %s(%s)", rd, rs, rt); } @@ -8849,17 +8484,17 @@ std::string NMD::LHUX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHUXS(uint64 instruction) +static char *LHUXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LHUXS %s, %s(%s)", rd, rs, rt); + return img_format("LHUXS %s, %s(%s)", rd, rs, rt); } @@ -8873,17 +8508,17 @@ std::string NMD::LHUXS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHXS(uint64 instruction) +static char *LHXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LHXS %s, %s(%s)", rd, rs, rt); + return img_format("LHXS %s, %s(%s)", rd, rs, rt); } @@ -8897,17 +8532,17 @@ std::string NMD::LHXS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LHX(uint64 instruction) +static char *LHX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LHX %s, %s(%s)", rd, rs, rt); + return img_format("LHX %s, %s(%s)", rd, rs, rt); } @@ -8921,15 +8556,15 @@ std::string NMD::LHX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LI_16_(uint64 instruction) +static char *LI_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 eu_value = extract_eu_6_5_4_3_2_1_0(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string eu = IMMEDIATE(encode_eu_from_s_li16(eu_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + int64 eu = encode_eu_from_s_li16(eu_value); - return img::format("LI %s, %s", rt3, eu); + return img_format("LI %s, %" PRId64, rt3, eu); } @@ -8943,15 +8578,14 @@ std::string NMD::LI_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LI_48_(uint64 instruction) +static char *LI_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); + const char *rt = GPR(rt_value, info); - return img::format("LI %s, %s", rt, s); + return img_format("LI %s, %" PRId64, rt, s_value); } @@ -8965,17 +8599,16 @@ std::string NMD::LI_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LL(uint64 instruction) +static char *LL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LL %s, %s(%s)", rt, s, rs); + return img_format("LL %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -8989,17 +8622,16 @@ std::string NMD::LL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LLD(uint64 instruction) +static char *LLD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_s3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LLD %s, %s(%s)", rt, s, rs); + return img_format("LLD %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -9013,17 +8645,17 @@ std::string NMD::LLD(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LLDP(uint64 instruction) +static char *LLDP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ru = GPR(copy(ru_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *ru = GPR(ru_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LLDP %s, %s, (%s)", rt, ru, rs); + return img_format("LLDP %s, %s, (%s)", rt, ru, rs); } @@ -9037,17 +8669,16 @@ std::string NMD::LLDP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LLE(uint64 instruction) +static char *LLE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LLE %s, %s(%s)", rt, s, rs); + return img_format("LLE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -9061,17 +8692,17 @@ std::string NMD::LLE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LLWP(uint64 instruction) +static char *LLWP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ru = GPR(copy(ru_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *ru = GPR(ru_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LLWP %s, %s, (%s)", rt, ru, rs); + return img_format("LLWP %s, %s, (%s)", rt, ru, rs); } @@ -9085,17 +8716,17 @@ std::string NMD::LLWP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LLWPE(uint64 instruction) +static char *LLWPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ru = GPR(copy(ru_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *ru = GPR(ru_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LLWPE %s, %s, (%s)", rt, ru, rs); + return img_format("LLWPE %s, %s, (%s)", rt, ru, rs); } @@ -9109,19 +8740,18 @@ std::string NMD::LLWPE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LSA(uint64 instruction) +static char *LSA(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); uint64 u2_value = extract_u2_10_9(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)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LSA %s, %s, %s, %s", rd, rs, rt, u2); + return img_format("LSA %s, %s, %s, 0x%" PRIx64, rd, rs, rt, u2_value); } @@ -9135,15 +8765,14 @@ std::string NMD::LSA(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LUI(uint64 instruction) +static char *LUI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se31_0_11_to_2_20_to_12_s12(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); + const char *rt = GPR(rt_value, info); - return img::format("LUI %s, %%hi(%s)", rt, s); + return img_format("LUI %s, %%hi(%" PRId64 ")", rt, s_value); } @@ -9157,17 +8786,16 @@ std::string NMD::LUI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LW_16_(uint64 instruction) +static char *LW_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_3_2_1_0__s2(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); - return img::format("LW %s, %s(%s)", rt3, u, rs3); + return img_format("LW %s, 0x%" PRIx64 "(%s)", rt3, u_value, rs3); } @@ -9181,17 +8809,16 @@ std::string NMD::LW_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LW_4X4_(uint64 instruction) +static char *LW_4X4_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); uint64 u_value = extract_u_3_8__s2(instruction); - std::string rt4 = GPR(decode_gpr_gpr4(rt4_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); + const char *rt4 = GPR(decode_gpr_gpr4(rt4_value, info), info); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value, info), info); - return img::format("LW %s, %s(%s)", rt4, u, rs4); + return img_format("LW %s, 0x%" PRIx64 "(%s)", rt4, u_value, rs4); } @@ -9205,15 +8832,14 @@ std::string NMD::LW_4X4_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LW_GP_(uint64 instruction) +static char *LW_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); - return img::format("LW %s, %s($%d)", rt, u, 28); + return img_format("LW %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -9227,15 +8853,14 @@ std::string NMD::LW_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LW_GP16_(uint64 instruction) +static char *LW_GP16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 u_value = extract_u_6_5_4_3_2_1_0__s2(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); - return img::format("LW %s, %s($%d)", rt3, u, 28); + return img_format("LW %s, 0x%" PRIx64 "($%d)", rt3, u_value, 28); } @@ -9249,17 +8874,16 @@ std::string NMD::LW_GP16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LW_S9_(uint64 instruction) +static char *LW_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LW %s, %s(%s)", rt, s, rs); + return img_format("LW %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -9273,15 +8897,14 @@ std::string NMD::LW_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LW_SP_(uint64 instruction) +static char *LW_SP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 u_value = extract_u_4_3_2_1_0__s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); - return img::format("LW %s, %s($%d)", rt, u, 29); + return img_format("LW %s, 0x%" PRIx64 "($%d)", rt, u_value, 29); } @@ -9295,17 +8918,16 @@ std::string NMD::LW_SP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LW_U12_(uint64 instruction) +static char *LW_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LW %s, %s(%s)", rt, u, rs); + return img_format("LW %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -9319,15 +8941,14 @@ std::string NMD::LW_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWC1_GP_(uint64 instruction) +static char *LWC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *ft = FPR(ft_value, info); - return img::format("LWC1 %s, %s($%d)", ft, u, 28); + return img_format("LWC1 %s, 0x%" PRIx64 "($%d)", ft, u_value, 28); } @@ -9341,17 +8962,16 @@ std::string NMD::LWC1_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWC1_S9_(uint64 instruction) +static char *LWC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LWC1 %s, %s(%s)", ft, s, rs); + return img_format("LWC1 %s, %" PRId64 "(%s)", ft, s_value, rs); } @@ -9365,17 +8985,16 @@ std::string NMD::LWC1_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWC1_U12_(uint64 instruction) +static char *LWC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LWC1 %s, %s(%s)", ft, u, rs); + return img_format("LWC1 %s, 0x%" PRIx64 "(%s)", ft, u_value, rs); } @@ -9389,17 +9008,17 @@ std::string NMD::LWC1_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWC1X(uint64 instruction) +static char *LWC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LWC1X %s, %s(%s)", ft, rs, rt); + return img_format("LWC1X %s, %s(%s)", ft, rs, rt); } @@ -9413,17 +9032,17 @@ std::string NMD::LWC1X(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWC1XS(uint64 instruction) +static char *LWC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LWC1XS %s, %s(%s)", ft, rs, rt); + return img_format("LWC1XS %s, %s(%s)", ft, rs, rt); } @@ -9437,17 +9056,16 @@ std::string NMD::LWC1XS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWC2(uint64 instruction) +static char *LWC2(uint64 instruction, Dis_info *info) { uint64 ct_value = extract_ct_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ct = CPR(copy(ct_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rs = GPR(rs_value, info); - return img::format("LWC2 %s, %s(%s)", ct, s, rs); + return img_format("LWC2 CP%" PRIu64 ", %" PRId64 "(%s)", + ct_value, s_value, rs); } @@ -9461,17 +9079,16 @@ std::string NMD::LWC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWE(uint64 instruction) +static char *LWE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LWE %s, %s(%s)", rt, s, rs); + return img_format("LWE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -9485,19 +9102,19 @@ std::string NMD::LWE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWM(uint64 instruction) +static char *LWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); + uint64 count3 = encode_count3_from_count(count3_value); - return img::format("LWM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("LWM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -9511,15 +9128,15 @@ std::string NMD::LWM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWPC_48_(uint64 instruction) +static char *LWPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 6, info); - return img::format("LWPC %s, %s", rt, s); + return img_format("LWPC %s, %s", rt, s); } @@ -9533,15 +9150,14 @@ std::string NMD::LWPC_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWU_GP_(uint64 instruction) +static char *LWU_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); - return img::format("LWU %s, %s($%d)", rt, u, 28); + return img_format("LWU %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -9555,17 +9171,16 @@ std::string NMD::LWU_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWU_S9_(uint64 instruction) +static char *LWU_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LWU %s, %s(%s)", rt, s, rs); + return img_format("LWU %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -9579,17 +9194,16 @@ std::string NMD::LWU_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWU_U12_(uint64 instruction) +static char *LWU_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("LWU %s, %s(%s)", rt, u, rs); + return img_format("LWU %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -9603,17 +9217,17 @@ std::string NMD::LWU_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWUX(uint64 instruction) +static char *LWUX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LWUX %s, %s(%s)", rd, rs, rt); + return img_format("LWUX %s, %s(%s)", rd, rs, rt); } @@ -9627,17 +9241,17 @@ std::string NMD::LWUX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWUXS(uint64 instruction) +static char *LWUXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LWUXS %s, %s(%s)", rd, rs, rt); + return img_format("LWUXS %s, %s(%s)", rd, rs, rt); } @@ -9651,17 +9265,17 @@ std::string NMD::LWUXS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWX(uint64 instruction) +static char *LWX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LWX %s, %s(%s)", rd, rs, rt); + return img_format("LWX %s, %s(%s)", rd, rs, rt); } @@ -9675,17 +9289,17 @@ std::string NMD::LWX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWXS_16_(uint64 instruction) +static char *LWXS_16_(uint64 instruction, Dis_info *info) { 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 rd3 = GPR(decode_gpr_gpr3(rd3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string rt3 = IMMEDIATE(decode_gpr_gpr3(rt3_value)); + const char *rd3 = GPR(decode_gpr_gpr3(rd3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + uint64 rt3 = decode_gpr_gpr3(rt3_value, info); - return img::format("LWXS %s, %s(%s)", rd3, rs3, rt3); + return img_format("LWXS %s, %s(0x%" PRIx64 ")", rd3, rs3, rt3); } @@ -9699,17 +9313,17 @@ std::string NMD::LWXS_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::LWXS_32_(uint64 instruction) +static char *LWXS_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("LWXS %s, %s(%s)", rd, rs, rt); + return img_format("LWXS %s, %s(%s)", rd, rs, rt); } @@ -9724,17 +9338,17 @@ std::string NMD::LWXS_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MADD_DSP_(uint64 instruction) +static char *MADD_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MADD %s, %s, %s", ac, rs, rt); + return img_format("MADD %s, %s, %s", ac, rs, rt); } @@ -9748,17 +9362,17 @@ std::string NMD::MADD_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MADDF_D(uint64 instruction) +static char *MADDF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("MADDF.D %s, %s, %s", fd, fs, ft); + return img_format("MADDF.D %s, %s, %s", fd, fs, ft); } @@ -9772,17 +9386,17 @@ std::string NMD::MADDF_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MADDF_S(uint64 instruction) +static char *MADDF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("MADDF.S %s, %s, %s", fd, fs, ft); + return img_format("MADDF.S %s, %s, %s", fd, fs, ft); } @@ -9797,17 +9411,17 @@ std::string NMD::MADDF_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MADDU_DSP_(uint64 instruction) +static char *MADDU_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MADDU %s, %s, %s", ac, rs, rt); + return img_format("MADDU %s, %s, %s", ac, rs, rt); } @@ -9822,17 +9436,17 @@ std::string NMD::MADDU_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAQ_S_W_PHL(uint64 instruction) +static char *MAQ_S_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MAQ_S.W.PHL %s, %s, %s", ac, rs, rt); + return img_format("MAQ_S.W.PHL %s, %s, %s", ac, rs, rt); } @@ -9847,17 +9461,17 @@ std::string NMD::MAQ_S_W_PHL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAQ_S_W_PHR(uint64 instruction) +static char *MAQ_S_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MAQ_S.W.PHR %s, %s, %s", ac, rs, rt); + return img_format("MAQ_S.W.PHR %s, %s, %s", ac, rs, rt); } @@ -9872,17 +9486,17 @@ std::string NMD::MAQ_S_W_PHR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAQ_SA_W_PHL(uint64 instruction) +static char *MAQ_SA_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MAQ_SA.W.PHL %s, %s, %s", ac, rs, rt); + return img_format("MAQ_SA.W.PHL %s, %s, %s", ac, rs, rt); } @@ -9897,17 +9511,17 @@ std::string NMD::MAQ_SA_W_PHL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAQ_SA_W_PHR(uint64 instruction) +static char *MAQ_SA_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MAQ_SA.W.PHR %s, %s, %s", ac, rs, rt); + return img_format("MAQ_SA.W.PHR %s, %s, %s", ac, rs, rt); } @@ -9921,17 +9535,17 @@ std::string NMD::MAQ_SA_W_PHR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAX_D(uint64 instruction) +static char *MAX_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("MAX.D %s, %s, %s", fd, fs, ft); + return img_format("MAX.D %s, %s, %s", fd, fs, ft); } @@ -9945,17 +9559,17 @@ std::string NMD::MAX_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAX_S(uint64 instruction) +static char *MAX_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("MAX.S %s, %s, %s", fd, fs, ft); + return img_format("MAX.S %s, %s, %s", fd, fs, ft); } @@ -9969,17 +9583,17 @@ std::string NMD::MAX_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAXA_D(uint64 instruction) +static char *MAXA_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("MAXA.D %s, %s, %s", fd, fs, ft); + return img_format("MAXA.D %s, %s, %s", fd, fs, ft); } @@ -9993,17 +9607,17 @@ std::string NMD::MAXA_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MAXA_S(uint64 instruction) +static char *MAXA_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("MAXA.S %s, %s, %s", fd, fs, ft); + return img_format("MAXA.S %s, %s, %s", fd, fs, ft); } @@ -10017,17 +9631,16 @@ std::string NMD::MAXA_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFC0(uint64 instruction) +static char *MFC0(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("MFC0 %s, %s, %s", rt, c0s, sel); + return img_format("MFC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -10041,15 +9654,15 @@ std::string NMD::MFC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFC1(uint64 instruction) +static char *MFC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string fs = FPR(copy(fs_value)); + const char *rt = GPR(rt_value, info); + const char *fs = FPR(fs_value, info); - return img::format("MFC1 %s, %s", rt, fs); + return img_format("MFC1 %s, %s", rt, fs); } @@ -10063,15 +9676,14 @@ std::string NMD::MFC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFC2(uint64 instruction) +static char *MFC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + const char *rt = GPR(rt_value, info); - return img::format("MFC2 %s, %s", rt, cs); + return img_format("MFC2 %s, CP%" PRIu64, rt, cs_value); } @@ -10085,17 +9697,16 @@ std::string NMD::MFC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFGC0(uint64 instruction) +static char *MFGC0(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("MFGC0 %s, %s, %s", rt, c0s, sel); + return img_format("MFGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -10109,17 +9720,16 @@ std::string NMD::MFGC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFHC0(uint64 instruction) +static char *MFHC0(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("MFHC0 %s, %s, %s", rt, c0s, sel); + return img_format("MFHC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -10133,15 +9743,15 @@ std::string NMD::MFHC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFHC1(uint64 instruction) +static char *MFHC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string fs = FPR(copy(fs_value)); + const char *rt = GPR(rt_value, info); + const char *fs = FPR(fs_value, info); - return img::format("MFHC1 %s, %s", rt, fs); + return img_format("MFHC1 %s, %s", rt, fs); } @@ -10155,15 +9765,14 @@ std::string NMD::MFHC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFHC2(uint64 instruction) +static char *MFHC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + const char *rt = GPR(rt_value, info); - return img::format("MFHC2 %s, %s", rt, cs); + return img_format("MFHC2 %s, CP%" PRIu64, rt, cs_value); } @@ -10177,17 +9786,16 @@ std::string NMD::MFHC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFHGC0(uint64 instruction) +static char *MFHGC0(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("MFHGC0 %s, %s, %s", rt, c0s, sel); + return img_format("MFHGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -10200,15 +9808,15 @@ std::string NMD::MFHGC0(uint64 instruction) * rt ----- * ac -- */ -std::string NMD::MFHI_DSP_(uint64 instruction) +static char *MFHI_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); - return img::format("MFHI %s, %s", rt, ac); + return img_format("MFHI %s, %s", rt, ac); } @@ -10222,19 +9830,17 @@ std::string NMD::MFHI_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFHTR(uint64 instruction) +static char *MFHTR(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("MFHTR %s, %s, %s, %s", rt, c0s, u, sel); + return img_format("MFHTR %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, + rt, c0s_value, u_value, sel_value); } @@ -10247,15 +9853,15 @@ std::string NMD::MFHTR(uint64 instruction) * rt ----- * ac -- */ -std::string NMD::MFLO_DSP_(uint64 instruction) +static char *MFLO_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ac = AC(copy(ac_value)); + const char *rt = GPR(rt_value, info); + const char *ac = AC(ac_value, info); - return img::format("MFLO %s, %s", rt, ac); + return img_format("MFLO %s, %s", rt, ac); } @@ -10269,19 +9875,17 @@ std::string NMD::MFLO_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MFTR(uint64 instruction) +static char *MFTR(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("MFTR %s, %s, %s, %s", rt, c0s, u, sel); + return img_format("MFTR %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, + rt, c0s_value, u_value, sel_value); } @@ -10295,17 +9899,17 @@ std::string NMD::MFTR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MIN_D(uint64 instruction) +static char *MIN_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("MIN.D %s, %s, %s", fd, fs, ft); + return img_format("MIN.D %s, %s, %s", fd, fs, ft); } @@ -10319,17 +9923,17 @@ std::string NMD::MIN_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MIN_S(uint64 instruction) +static char *MIN_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("MIN.S %s, %s, %s", fd, fs, ft); + return img_format("MIN.S %s, %s, %s", fd, fs, ft); } @@ -10343,17 +9947,17 @@ std::string NMD::MIN_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MINA_D(uint64 instruction) +static char *MINA_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("MINA.D %s, %s, %s", fd, fs, ft); + return img_format("MINA.D %s, %s, %s", fd, fs, ft); } @@ -10367,17 +9971,17 @@ std::string NMD::MINA_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MINA_S(uint64 instruction) +static char *MINA_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("MINA.S %s, %s, %s", fd, fs, ft); + return img_format("MINA.S %s, %s, %s", fd, fs, ft); } @@ -10391,17 +9995,17 @@ std::string NMD::MINA_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOD(uint64 instruction) +static char *MOD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MOD %s, %s, %s", rd, rs, rt); + return img_format("MOD %s, %s, %s", rd, rs, rt); } @@ -10415,17 +10019,17 @@ std::string NMD::MOD(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MODSUB(uint64 instruction) +static char *MODSUB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MODSUB %s, %s, %s", rd, rs, rt); + return img_format("MODSUB %s, %s, %s", rd, rs, rt); } @@ -10439,17 +10043,17 @@ std::string NMD::MODSUB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MODU(uint64 instruction) +static char *MODU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MODU %s, %s, %s", rd, rs, rt); + return img_format("MODU %s, %s, %s", rd, rs, rt); } @@ -10463,15 +10067,15 @@ std::string NMD::MODU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOV_D(uint64 instruction) +static char *MOV_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("MOV.D %s, %s", ft, fs); + return img_format("MOV.D %s, %s", ft, fs); } @@ -10485,15 +10089,15 @@ std::string NMD::MOV_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOV_S(uint64 instruction) +static char *MOV_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("MOV.S %s, %s", ft, fs); + return img_format("MOV.S %s, %s", ft, fs); } @@ -10507,17 +10111,17 @@ std::string NMD::MOV_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOVE_BALC(uint64 instruction) +static char *MOVE_BALC(uint64 instruction, Dis_info *info) { uint64 rtz4_value = extract_rtz4_27_26_25_23_22_21(instruction); uint64 rd1_value = extract_rdl_25_24(instruction); int64 s_value = extract_s__se21_0_20_to_1_s1(instruction); - std::string rd1 = GPR(decode_gpr_gpr1(rd1_value)); - std::string rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 4); + const char *rd1 = GPR(decode_gpr_gpr1(rd1_value, info), info); + const char *rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value, info), info); + g_autofree char *s = ADDRESS(s_value, 4, info); - return img::format("MOVE.BALC %s, %s, %s", rd1, rtz4, s); + return img_format("MOVE.BALC %s, %s, %s", rd1, rtz4, s); } @@ -10531,19 +10135,19 @@ std::string NMD::MOVE_BALC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOVEP(uint64 instruction) +static char *MOVEP(uint64 instruction, Dis_info *info) { uint64 rtz4_value = extract_rtz4_9_7_6_5(instruction); uint64 rd2_value = extract_rd2_3_8(instruction); uint64 rsz4_value = extract_rsz4_4_2_1_0(instruction); - std::string rd2 = GPR(decode_gpr_gpr2_reg1(rd2_value)); - std::string re2 = GPR(decode_gpr_gpr2_reg2(rd2_value)); + const char *rd2 = GPR(decode_gpr_gpr2_reg1(rd2_value, info), info); + const char *re2 = GPR(decode_gpr_gpr2_reg2(rd2_value, info), info); /* !!!!!!!!!! - no conversion function */ - std::string rsz4 = GPR(decode_gpr_gpr4_zero(rsz4_value)); - std::string rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); + const char *rsz4 = GPR(decode_gpr_gpr4_zero(rsz4_value, info), info); + const char *rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value, info), info); - return img::format("MOVEP %s, %s, %s, %s", rd2, re2, rsz4, rtz4); + return img_format("MOVEP %s, %s, %s, %s", rd2, re2, rsz4, rtz4); /* hand edited */ } @@ -10558,19 +10162,19 @@ std::string NMD::MOVEP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOVEP_REV_(uint64 instruction) +static char *MOVEP_REV_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rd2_value = extract_rd2_3_8(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); - std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); - std::string rt4 = GPR(decode_gpr_gpr4(rt4_value)); - std::string rd2 = GPR(decode_gpr_gpr2_reg1(rd2_value)); - std::string rs2 = GPR(decode_gpr_gpr2_reg2(rd2_value)); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value, info), info); + const char *rt4 = GPR(decode_gpr_gpr4(rt4_value, info), info); + const char *rd2 = GPR(decode_gpr_gpr2_reg1(rd2_value, info), info); + const char *rs2 = GPR(decode_gpr_gpr2_reg2(rd2_value, info), info); /* !!!!!!!!!! - no conversion function */ - return img::format("MOVEP %s, %s, %s, %s", rs4, rt4, rd2, rs2); + return img_format("MOVEP %s, %s, %s, %s", rs4, rt4, rd2, rs2); /* hand edited */ } @@ -10585,15 +10189,15 @@ std::string NMD::MOVEP_REV_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOVE(uint64 instruction) +static char *MOVE(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("MOVE %s, %s", rt, rs); + return img_format("MOVE %s, %s", rt, rs); } @@ -10607,17 +10211,17 @@ std::string NMD::MOVE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOVN(uint64 instruction) +static char *MOVN(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MOVN %s, %s, %s", rd, rs, rt); + return img_format("MOVN %s, %s, %s", rd, rs, rt); } @@ -10631,17 +10235,17 @@ std::string NMD::MOVN(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MOVZ(uint64 instruction) +static char *MOVZ(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MOVZ %s, %s, %s", rd, rs, rt); + return img_format("MOVZ %s, %s, %s", rd, rs, rt); } @@ -10655,17 +10259,17 @@ std::string NMD::MOVZ(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MSUB_DSP_(uint64 instruction) +static char *MSUB_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MSUB %s, %s, %s", ac, rs, rt); + return img_format("MSUB %s, %s, %s", ac, rs, rt); } @@ -10679,17 +10283,17 @@ std::string NMD::MSUB_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MSUBF_D(uint64 instruction) +static char *MSUBF_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("MSUBF.D %s, %s, %s", fd, fs, ft); + return img_format("MSUBF.D %s, %s, %s", fd, fs, ft); } @@ -10703,17 +10307,17 @@ std::string NMD::MSUBF_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MSUBF_S(uint64 instruction) +static char *MSUBF_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("MSUBF.S %s, %s, %s", fd, fs, ft); + return img_format("MSUBF.S %s, %s, %s", fd, fs, ft); } @@ -10727,17 +10331,17 @@ std::string NMD::MSUBF_S(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MSUBU_DSP_(uint64 instruction) +static char *MSUBU_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MSUBU %s, %s, %s", ac, rs, rt); + return img_format("MSUBU %s, %s, %s", ac, rs, rt); } @@ -10751,17 +10355,16 @@ std::string NMD::MSUBU_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTC0(uint64 instruction) +static char *MTC0(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("MTC0 %s, %s, %s", rt, c0s, sel); + return img_format("MTC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -10775,15 +10378,15 @@ std::string NMD::MTC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTC1(uint64 instruction) +static char *MTC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string fs = FPR(copy(fs_value)); + const char *rt = GPR(rt_value, info); + const char *fs = FPR(fs_value, info); - return img::format("MTC1 %s, %s", rt, fs); + return img_format("MTC1 %s, %s", rt, fs); } @@ -10797,15 +10400,14 @@ std::string NMD::MTC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTC2(uint64 instruction) +static char *MTC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + const char *rt = GPR(rt_value, info); - return img::format("MTC2 %s, %s", rt, cs); + return img_format("MTC2 %s, CP%" PRIu64, rt, cs_value); } @@ -10819,17 +10421,16 @@ std::string NMD::MTC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTGC0(uint64 instruction) +static char *MTGC0(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("MTGC0 %s, %s, %s", rt, c0s, sel); + return img_format("MTGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -10843,17 +10444,16 @@ std::string NMD::MTGC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTHC0(uint64 instruction) +static char *MTHC0(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("MTHC0 %s, %s, %s", rt, c0s, sel); + return img_format("MTHC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -10867,15 +10467,15 @@ std::string NMD::MTHC0(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTHC1(uint64 instruction) +static char *MTHC1(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string fs = FPR(copy(fs_value)); + const char *rt = GPR(rt_value, info); + const char *fs = FPR(fs_value, info); - return img::format("MTHC1 %s, %s", rt, fs); + return img_format("MTHC1 %s, %s", rt, fs); } @@ -10889,15 +10489,14 @@ std::string NMD::MTHC1(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTHC2(uint64 instruction) +static char *MTHC2(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 cs_value = extract_cs_20_19_18_17_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string cs = CPR(copy(cs_value)); + const char *rt = GPR(rt_value, info); - return img::format("MTHC2 %s, %s", rt, cs); + return img_format("MTHC2 %s, CP%" PRIu64, rt, cs_value); } @@ -10911,17 +10510,16 @@ std::string NMD::MTHC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTHGC0(uint64 instruction) +static char *MTHGC0(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("MTHGC0 %s, %s, %s", rt, c0s, sel); + return img_format("MTHGC0 %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, c0s_value, sel_value); } @@ -10934,15 +10532,15 @@ std::string NMD::MTHGC0(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MTHI_DSP_(uint64 instruction) +static char *MTHI_DSP_(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rs = GPR(copy(rs_value)); - std::string ac = AC(copy(ac_value)); + const char *rs = GPR(rs_value, info); + const char *ac = AC(ac_value, info); - return img::format("MTHI %s, %s", rs, ac); + return img_format("MTHI %s, %s", rs, ac); } @@ -10955,15 +10553,15 @@ std::string NMD::MTHI_DSP_(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MTHLIP(uint64 instruction) +static char *MTHLIP(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rs = GPR(copy(rs_value)); - std::string ac = AC(copy(ac_value)); + const char *rs = GPR(rs_value, info); + const char *ac = AC(ac_value, info); - return img::format("MTHLIP %s, %s", rs, ac); + return img_format("MTHLIP %s, %s", rs, ac); } @@ -10977,19 +10575,17 @@ std::string NMD::MTHLIP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTHTR(uint64 instruction) +static char *MTHTR(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("MTHTR %s, %s, %s, %s", rt, c0s, u, sel); + return img_format("MTHTR %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, + rt, c0s_value, u_value, sel_value); } @@ -11002,15 +10598,15 @@ std::string NMD::MTHTR(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MTLO_DSP_(uint64 instruction) +static char *MTLO_DSP_(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rs = GPR(copy(rs_value)); - std::string ac = AC(copy(ac_value)); + const char *rs = GPR(rs_value, info); + const char *ac = AC(ac_value, info); - return img::format("MTLO %s, %s", rs, ac); + return img_format("MTLO %s, %s", rs, ac); } @@ -11024,19 +10620,17 @@ std::string NMD::MTLO_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MTTR(uint64 instruction) +static char *MTTR(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("MTTR %s, %s, %s, %s", rt, c0s, u, sel); + return img_format("MTTR %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, + rt, c0s_value, u_value, sel_value); } @@ -11050,17 +10644,17 @@ std::string NMD::MTTR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUH(uint64 instruction) +static char *MUH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MUH %s, %s, %s", rd, rs, rt); + return img_format("MUH %s, %s, %s", rd, rs, rt); } @@ -11074,17 +10668,17 @@ std::string NMD::MUH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUHU(uint64 instruction) +static char *MUHU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MUHU %s, %s, %s", rd, rs, rt); + return img_format("MUHU %s, %s, %s", rd, rs, rt); } @@ -11098,17 +10692,17 @@ std::string NMD::MUHU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUL_32_(uint64 instruction) +static char *MUL_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MUL %s, %s, %s", rd, rs, rt); + return img_format("MUL %s, %s, %s", rd, rs, rt); } @@ -11122,15 +10716,15 @@ std::string NMD::MUL_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUL_4X4_(uint64 instruction) +static char *MUL_4X4_(uint64 instruction, Dis_info *info) { uint64 rt4_value = extract_rt4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); - std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); - std::string rt4 = GPR(decode_gpr_gpr4(rt4_value)); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value, info), info); + const char *rt4 = GPR(decode_gpr_gpr4(rt4_value, info), info); - return img::format("MUL %s, %s", rs4, rt4); + return img_format("MUL %s, %s", rs4, rt4); } @@ -11144,17 +10738,17 @@ std::string NMD::MUL_4X4_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUL_D(uint64 instruction) +static char *MUL_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("MUL.D %s, %s, %s", fd, fs, ft); + return img_format("MUL.D %s, %s, %s", fd, fs, ft); } @@ -11169,17 +10763,17 @@ std::string NMD::MUL_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUL_PH(uint64 instruction) +static char *MUL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MUL.PH %s, %s, %s", rd, rs, rt); + return img_format("MUL.PH %s, %s, %s", rd, rs, rt); } @@ -11194,17 +10788,17 @@ std::string NMD::MUL_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUL_S_PH(uint64 instruction) +static char *MUL_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MUL_S.PH %s, %s, %s", rd, rs, rt); + return img_format("MUL_S.PH %s, %s, %s", rd, rs, rt); } @@ -11218,17 +10812,17 @@ std::string NMD::MUL_S_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MUL_S(uint64 instruction) +static char *MUL_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("MUL.S %s, %s, %s", fd, fs, ft); + return img_format("MUL.S %s, %s, %s", fd, fs, ft); } @@ -11243,17 +10837,17 @@ std::string NMD::MUL_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULEQ_S_W_PHL(uint64 instruction) +static char *MULEQ_S_W_PHL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MULEQ_S.W.PHL %s, %s, %s", rd, rs, rt); + return img_format("MULEQ_S.W.PHL %s, %s, %s", rd, rs, rt); } @@ -11268,17 +10862,17 @@ std::string NMD::MULEQ_S_W_PHL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULEQ_S_W_PHR(uint64 instruction) +static char *MULEQ_S_W_PHR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MULEQ_S.W.PHR %s, %s, %s", rd, rs, rt); + return img_format("MULEQ_S.W.PHR %s, %s, %s", rd, rs, rt); } @@ -11293,17 +10887,17 @@ std::string NMD::MULEQ_S_W_PHR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULEU_S_PH_QBL(uint64 instruction) +static char *MULEU_S_PH_QBL(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MULEU_S.PH.QBL %s, %s, %s", rd, rs, rt); + return img_format("MULEU_S.PH.QBL %s, %s, %s", rd, rs, rt); } @@ -11318,17 +10912,17 @@ std::string NMD::MULEU_S_PH_QBL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULEU_S_PH_QBR(uint64 instruction) +static char *MULEU_S_PH_QBR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MULEU_S.PH.QBR %s, %s, %s", rd, rs, rt); + return img_format("MULEU_S.PH.QBR %s, %s, %s", rd, rs, rt); } @@ -11343,17 +10937,17 @@ std::string NMD::MULEU_S_PH_QBR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULQ_RS_PH(uint64 instruction) +static char *MULQ_RS_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MULQ_RS.PH %s, %s, %s", rd, rs, rt); + return img_format("MULQ_RS.PH %s, %s, %s", rd, rs, rt); } @@ -11368,17 +10962,17 @@ std::string NMD::MULQ_RS_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULQ_RS_W(uint64 instruction) +static char *MULQ_RS_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MULQ_RS.W %s, %s, %s", rd, rs, rt); + return img_format("MULQ_RS.W %s, %s, %s", rd, rs, rt); } @@ -11393,17 +10987,17 @@ std::string NMD::MULQ_RS_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULQ_S_PH(uint64 instruction) +static char *MULQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MULQ_S.PH %s, %s, %s", rd, rs, rt); + return img_format("MULQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -11418,17 +11012,17 @@ std::string NMD::MULQ_S_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULQ_S_W(uint64 instruction) +static char *MULQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MULQ_S.W %s, %s, %s", rd, rs, rt); + return img_format("MULQ_S.W %s, %s, %s", rd, rs, rt); } @@ -11443,17 +11037,17 @@ std::string NMD::MULQ_S_W(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MULSA_W_PH(uint64 instruction) +static char *MULSA_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MULSA.W.PH %s, %s, %s", ac, rs, rt); + return img_format("MULSA.W.PH %s, %s, %s", ac, rs, rt); } @@ -11468,17 +11062,17 @@ std::string NMD::MULSA_W_PH(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MULSAQ_S_W_PH(uint64 instruction) +static char *MULSAQ_S_W_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MULSAQ_S.W.PH %s, %s, %s", ac, rs, rt); + return img_format("MULSAQ_S.W.PH %s, %s, %s", ac, rs, rt); } @@ -11492,17 +11086,17 @@ std::string NMD::MULSAQ_S_W_PH(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MULT_DSP_(uint64 instruction) +static char *MULT_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MULT %s, %s, %s", ac, rs, rt); + return img_format("MULT %s, %s, %s", ac, rs, rt); } @@ -11516,17 +11110,17 @@ std::string NMD::MULT_DSP_(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::MULTU_DSP_(uint64 instruction) +static char *MULTU_DSP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string ac = AC(copy(ac_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ac = AC(ac_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MULTU %s, %s, %s", ac, rs, rt); + return img_format("MULTU %s, %s, %s", ac, rs, rt); } @@ -11540,17 +11134,17 @@ std::string NMD::MULTU_DSP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::MULU(uint64 instruction) +static char *MULU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("MULU %s, %s, %s", rd, rs, rt); + return img_format("MULU %s, %s, %s", rd, rs, rt); } @@ -11564,15 +11158,15 @@ std::string NMD::MULU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::NEG_D(uint64 instruction) +static char *NEG_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("NEG.D %s, %s", ft, fs); + return img_format("NEG.D %s, %s", ft, fs); } @@ -11586,15 +11180,15 @@ std::string NMD::NEG_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::NEG_S(uint64 instruction) +static char *NEG_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("NEG.S %s, %s", ft, fs); + return img_format("NEG.S %s, %s", ft, fs); } @@ -11608,11 +11202,11 @@ std::string NMD::NEG_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::NOP_16_(uint64 instruction) +static char *NOP_16_(uint64 instruction, Dis_info *info) { (void)instruction; - return "NOP "; + return g_strdup("NOP "); } @@ -11626,11 +11220,11 @@ std::string NMD::NOP_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::NOP_32_(uint64 instruction) +static char *NOP_32_(uint64 instruction, Dis_info *info) { (void)instruction; - return "NOP "; + return g_strdup("NOP "); } @@ -11644,17 +11238,17 @@ std::string NMD::NOP_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::NOR(uint64 instruction) +static char *NOR(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("NOR %s, %s, %s", rd, rs, rt); + return img_format("NOR %s, %s, %s", rd, rs, rt); } @@ -11668,15 +11262,15 @@ std::string NMD::NOR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::NOT_16_(uint64 instruction) +static char *NOT_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); - return img::format("NOT %s, %s", rt3, rs3); + return img_format("NOT %s, %s", rt3, rs3); } @@ -11690,15 +11284,15 @@ std::string NMD::NOT_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::OR_16_(uint64 instruction) +static char *OR_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); - return img::format("OR %s, %s", rs3, rt3); + return img_format("OR %s, %s", rs3, rt3); } @@ -11712,17 +11306,17 @@ std::string NMD::OR_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::OR_32_(uint64 instruction) +static char *OR_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("OR %s, %s, %s", rd, rs, rt); + return img_format("OR %s, %s, %s", rd, rs, rt); } @@ -11736,17 +11330,16 @@ std::string NMD::OR_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ORI(uint64 instruction) +static char *ORI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("ORI %s, %s, %s", rt, rs, u); + return img_format("ORI %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -11761,17 +11354,17 @@ std::string NMD::ORI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PACKRL_PH(uint64 instruction) +static char *PACKRL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("PACKRL.PH %s, %s, %s", rd, rs, rt); + return img_format("PACKRL.PH %s, %s, %s", rd, rs, rt); } @@ -11785,11 +11378,11 @@ std::string NMD::PACKRL_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PAUSE(uint64 instruction) +static char *PAUSE(uint64 instruction, Dis_info *info) { (void)instruction; - return "PAUSE "; + return g_strdup("PAUSE "); } @@ -11804,17 +11397,17 @@ std::string NMD::PAUSE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PICK_PH(uint64 instruction) +static char *PICK_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("PICK.PH %s, %s, %s", rd, rs, rt); + return img_format("PICK.PH %s, %s, %s", rd, rs, rt); } @@ -11829,17 +11422,17 @@ std::string NMD::PICK_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PICK_QB(uint64 instruction) +static char *PICK_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("PICK.QB %s, %s, %s", rd, rs, rt); + return img_format("PICK.QB %s, %s, %s", rd, rs, rt); } @@ -11854,15 +11447,15 @@ std::string NMD::PICK_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEQ_W_PHL(uint64 instruction) +static char *PRECEQ_W_PHL(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("PRECEQ.W.PHL %s, %s", rt, rs); + return img_format("PRECEQ.W.PHL %s, %s", rt, rs); } @@ -11877,15 +11470,15 @@ std::string NMD::PRECEQ_W_PHL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEQ_W_PHR(uint64 instruction) +static char *PRECEQ_W_PHR(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("PRECEQ.W.PHR %s, %s", rt, rs); + return img_format("PRECEQ.W.PHR %s, %s", rt, rs); } @@ -11900,15 +11493,15 @@ std::string NMD::PRECEQ_W_PHR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEQU_PH_QBLA(uint64 instruction) +static char *PRECEQU_PH_QBLA(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("PRECEQU.PH.QBLA %s, %s", rt, rs); + return img_format("PRECEQU.PH.QBLA %s, %s", rt, rs); } @@ -11923,15 +11516,15 @@ std::string NMD::PRECEQU_PH_QBLA(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEQU_PH_QBL(uint64 instruction) +static char *PRECEQU_PH_QBL(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("PRECEQU.PH.QBL %s, %s", rt, rs); + return img_format("PRECEQU.PH.QBL %s, %s", rt, rs); } @@ -11946,15 +11539,15 @@ std::string NMD::PRECEQU_PH_QBL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEQU_PH_QBRA(uint64 instruction) +static char *PRECEQU_PH_QBRA(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("PRECEQU.PH.QBRA %s, %s", rt, rs); + return img_format("PRECEQU.PH.QBRA %s, %s", rt, rs); } @@ -11969,15 +11562,15 @@ std::string NMD::PRECEQU_PH_QBRA(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEQU_PH_QBR(uint64 instruction) +static char *PRECEQU_PH_QBR(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("PRECEQU.PH.QBR %s, %s", rt, rs); + return img_format("PRECEQU.PH.QBR %s, %s", rt, rs); } @@ -11993,15 +11586,15 @@ std::string NMD::PRECEQU_PH_QBR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEU_PH_QBLA(uint64 instruction) +static char *PRECEU_PH_QBLA(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("PRECEU.PH.QBLA %s, %s", rt, rs); + return img_format("PRECEU.PH.QBLA %s, %s", rt, rs); } @@ -12016,15 +11609,15 @@ std::string NMD::PRECEU_PH_QBLA(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEU_PH_QBL(uint64 instruction) +static char *PRECEU_PH_QBL(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("PRECEU.PH.QBL %s, %s", rt, rs); + return img_format("PRECEU.PH.QBL %s, %s", rt, rs); } @@ -12040,15 +11633,15 @@ std::string NMD::PRECEU_PH_QBL(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEU_PH_QBRA(uint64 instruction) +static char *PRECEU_PH_QBRA(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("PRECEU.PH.QBRA %s, %s", rt, rs); + return img_format("PRECEU.PH.QBRA %s, %s", rt, rs); } @@ -12063,15 +11656,15 @@ std::string NMD::PRECEU_PH_QBRA(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECEU_PH_QBR(uint64 instruction) +static char *PRECEU_PH_QBR(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("PRECEU.PH.QBR %s, %s", rt, rs); + return img_format("PRECEU.PH.QBR %s, %s", rt, rs); } @@ -12086,17 +11679,17 @@ std::string NMD::PRECEU_PH_QBR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECR_QB_PH(uint64 instruction) +static char *PRECR_QB_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("PRECR.QB.PH %s, %s, %s", rd, rs, rt); + return img_format("PRECR.QB.PH %s, %s, %s", rd, rs, rt); } @@ -12111,17 +11704,16 @@ std::string NMD::PRECR_QB_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECR_SRA_PH_W(uint64 instruction) +static char *PRECR_SRA_PH_W(uint64 instruction, Dis_info *info) { 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_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("PRECR_SRA.PH.W %s, %s, %s", rt, rs, sa); + return img_format("PRECR_SRA.PH.W %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -12136,17 +11728,16 @@ std::string NMD::PRECR_SRA_PH_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECR_SRA_R_PH_W(uint64 instruction) +static char *PRECR_SRA_R_PH_W(uint64 instruction, Dis_info *info) { 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_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("PRECR_SRA_R.PH.W %s, %s, %s", rt, rs, sa); + return img_format("PRECR_SRA_R.PH.W %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -12161,17 +11752,17 @@ std::string NMD::PRECR_SRA_R_PH_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECRQ_PH_W(uint64 instruction) +static char *PRECRQ_PH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("PRECRQ.PH.W %s, %s, %s", rd, rs, rt); + return img_format("PRECRQ.PH.W %s, %s, %s", rd, rs, rt); } @@ -12186,17 +11777,17 @@ std::string NMD::PRECRQ_PH_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECRQ_QB_PH(uint64 instruction) +static char *PRECRQ_QB_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("PRECRQ.QB.PH %s, %s, %s", rd, rs, rt); + return img_format("PRECRQ.QB.PH %s, %s, %s", rd, rs, rt); } @@ -12211,17 +11802,17 @@ std::string NMD::PRECRQ_QB_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECRQ_RS_PH_W(uint64 instruction) +static char *PRECRQ_RS_PH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("PRECRQ_RS.PH.W %s, %s, %s", rd, rs, rt); + return img_format("PRECRQ_RS.PH.W %s, %s, %s", rd, rs, rt); } @@ -12236,17 +11827,17 @@ std::string NMD::PRECRQ_RS_PH_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PRECRQU_S_QB_PH(uint64 instruction) +static char *PRECRQU_S_QB_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("PRECRQU_S.QB.PH %s, %s, %s", rd, rs, rt); + return img_format("PRECRQU_S.QB.PH %s, %s, %s", rd, rs, rt); } @@ -12260,17 +11851,16 @@ std::string NMD::PRECRQU_S_QB_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PREF_S9_(uint64 instruction) +static char *PREF_S9_(uint64 instruction, Dis_info *info) { uint64 hint_value = extract_hint_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string hint = IMMEDIATE(copy(hint_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rs = GPR(rs_value, info); - return img::format("PREF %s, %s(%s)", hint, s, rs); + return img_format("PREF 0x%" PRIx64 ", %s(%s)", + hint_value, s_value, rs); } @@ -12284,17 +11874,16 @@ std::string NMD::PREF_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PREF_U12_(uint64 instruction) +static char *PREF_U12_(uint64 instruction, Dis_info *info) { uint64 hint_value = extract_hint_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string hint = IMMEDIATE(copy(hint_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *rs = GPR(rs_value, info); - return img::format("PREF %s, %s(%s)", hint, u, rs); + return img_format("PREF 0x%" PRIx64 ", 0x%" PRIx64 "(%s)", + hint_value, u_value, rs); } @@ -12308,17 +11897,15 @@ std::string NMD::PREF_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PREFE(uint64 instruction) +static char *PREFE(uint64 instruction, Dis_info *info) { uint64 hint_value = extract_hint_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string hint = IMMEDIATE(copy(hint_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rs = GPR(rs_value, info); - return img::format("PREFE %s, %s(%s)", hint, s, rs); + return img_format("PREFE 0x%" PRIx64 ", %s(%s)", hint_value, s_value, rs); } @@ -12332,17 +11919,16 @@ std::string NMD::PREFE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::PREPEND(uint64 instruction) +static char *PREPEND(uint64 instruction, Dis_info *info) { 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_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("PREPEND %s, %s, %s", rt, rs, sa); + return img_format("PREPEND %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -12355,15 +11941,15 @@ std::string NMD::PREPEND(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::RADDU_W_QB(uint64 instruction) +static char *RADDU_W_QB(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("RADDU.W.QB %s, %s", rt, rs); + return img_format("RADDU.W.QB %s, %s", rt, rs); } @@ -12376,15 +11962,14 @@ std::string NMD::RADDU_W_QB(uint64 instruction) * rt ----- * mask ------- */ -std::string NMD::RDDSP(uint64 instruction) +static char *RDDSP(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("RDDSP %s, %s", rt, mask); + return img_format("RDDSP %s, 0x%" PRIx64, rt, mask_value); } @@ -12398,17 +11983,16 @@ std::string NMD::RDDSP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RDHWR(uint64 instruction) +static char *RDHWR(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("RDHWR %s, %s, %s", rt, hs, sel); + return img_format("RDHWR %s, CP%" PRIu64 ", 0x%" PRIx64, + rt, hs_value, sel_value); } @@ -12422,15 +12006,15 @@ std::string NMD::RDHWR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RDPGPR(uint64 instruction) +static char *RDPGPR(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("RDPGPR %s, %s", rt, rs); + return img_format("RDPGPR %s, %s", rt, rs); } @@ -12444,15 +12028,15 @@ std::string NMD::RDPGPR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RECIP_D(uint64 instruction) +static char *RECIP_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("RECIP.D %s, %s", ft, fs); + return img_format("RECIP.D %s, %s", ft, fs); } @@ -12466,15 +12050,15 @@ std::string NMD::RECIP_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RECIP_S(uint64 instruction) +static char *RECIP_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("RECIP.S %s, %s", ft, fs); + return img_format("RECIP.S %s, %s", ft, fs); } @@ -12488,15 +12072,14 @@ std::string NMD::RECIP_S(uint64 instruction) * rt ----- * s ---------- */ -std::string NMD::REPL_PH(uint64 instruction) +static char *REPL_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se9_20_19_18_17_16_15_14_13_12_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); + const char *rt = GPR(rt_value, info); - return img::format("REPL.PH %s, %s", rt, s); + return img_format("REPL.PH %s, %s", rt, s_value); } @@ -12510,15 +12093,14 @@ std::string NMD::REPL_PH(uint64 instruction) * rt ----- * u -------- */ -std::string NMD::REPL_QB(uint64 instruction) +static char *REPL_QB(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("REPL.QB %s, %s", rt, u); + return img_format("REPL.QB %s, 0x%" PRIx64, rt, u_value); } @@ -12532,15 +12114,15 @@ std::string NMD::REPL_QB(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::REPLV_PH(uint64 instruction) +static char *REPLV_PH(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("REPLV.PH %s, %s", rt, rs); + return img_format("REPLV.PH %s, %s", rt, rs); } @@ -12553,15 +12135,15 @@ std::string NMD::REPLV_PH(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::REPLV_QB(uint64 instruction) +static char *REPLV_QB(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("REPLV.QB %s, %s", rt, rs); + return img_format("REPLV.QB %s, %s", rt, rs); } @@ -12575,16 +12157,16 @@ std::string NMD::REPLV_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RESTORE_32_(uint64 instruction) +static char *RESTORE_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(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)); + g_autofree char *save_restore_str = save_restore_list( + rt_value, count_value, gp_value, info); + return img_format("RESTORE 0x%" PRIx64 "%s", u_value, save_restore_str); } @@ -12598,15 +12180,15 @@ std::string NMD::RESTORE_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RESTORE_JRC_16_(uint64 instruction) +static char *RESTORE_JRC_16_(uint64 instruction, Dis_info *info) { uint64 rt1_value = extract_rtl_11(instruction); uint64 u_value = extract_u_7_6_5_4__s4(instruction); uint64 count_value = extract_count_3_2_1_0(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)); + g_autofree char *save_restore_str = save_restore_list( + encode_rt1_from_rt(rt1_value), count_value, 0, info); + return img_format("RESTORE.JRC 0x%" PRIx64 "%s", u_value, save_restore_str); } @@ -12620,16 +12202,17 @@ std::string NMD::RESTORE_JRC_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RESTORE_JRC_32_(uint64 instruction) +static char *RESTORE_JRC_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(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)); + g_autofree char *save_restore_str = save_restore_list( + rt_value, count_value, gp_value, info); + return img_format("RESTORE.JRC 0x%" PRIx64 "%s", u_value, + save_restore_str); } @@ -12643,15 +12226,13 @@ std::string NMD::RESTORE_JRC_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RESTOREF(uint64 instruction) +static char *RESTOREF(uint64 instruction, Dis_info *info) { uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); - std::string u = IMMEDIATE(copy(u_value)); - std::string count = IMMEDIATE(copy(count_value)); - return img::format("RESTOREF %s, %s", u, count); + return img_format("RESTOREF 0x%" PRIx64 ", %s", u_value, count_value); } @@ -12665,15 +12246,15 @@ std::string NMD::RESTOREF(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RINT_D(uint64 instruction) +static char *RINT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("RINT.D %s, %s", ft, fs); + return img_format("RINT.D %s, %s", ft, fs); } @@ -12687,15 +12268,15 @@ std::string NMD::RINT_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RINT_S(uint64 instruction) +static char *RINT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("RINT.S %s, %s", ft, fs); + return img_format("RINT.S %s, %s", ft, fs); } @@ -12709,17 +12290,16 @@ std::string NMD::RINT_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ROTR(uint64 instruction) +static char *ROTR(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("ROTR %s, %s, %s", rt, rs, shift); + return img_format("ROTR %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -12733,17 +12313,17 @@ std::string NMD::ROTR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ROTRV(uint64 instruction) +static char *ROTRV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("ROTRV %s, %s, %s", rd, rs, rt); + return img_format("ROTRV %s, %s, %s", rd, rs, rt); } @@ -12757,7 +12337,7 @@ std::string NMD::ROTRV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ROTX(uint64 instruction) +static char *ROTX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); @@ -12765,14 +12345,11 @@ std::string NMD::ROTX(uint64 instruction) uint64 stripe_value = extract_stripe_6(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)); - std::string shiftx = IMMEDIATE(copy(shiftx_value)); - std::string stripe = IMMEDIATE(copy(stripe_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("ROTX %s, %s, %s, %s, %s", - rt, rs, shift, shiftx, stripe); + return img_format("ROTX %s, %s, 0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRIx64, + rt, rs, shift_value, shiftx_value, stripe_value); } @@ -12786,15 +12363,15 @@ std::string NMD::ROTX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ROUND_L_D(uint64 instruction) +static char *ROUND_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("ROUND.L.D %s, %s", ft, fs); + return img_format("ROUND.L.D %s, %s", ft, fs); } @@ -12808,15 +12385,15 @@ std::string NMD::ROUND_L_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ROUND_L_S(uint64 instruction) +static char *ROUND_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("ROUND.L.S %s, %s", ft, fs); + return img_format("ROUND.L.S %s, %s", ft, fs); } @@ -12830,15 +12407,15 @@ std::string NMD::ROUND_L_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ROUND_W_D(uint64 instruction) +static char *ROUND_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("ROUND.W.D %s, %s", ft, fs); + return img_format("ROUND.W.D %s, %s", ft, fs); } @@ -12852,15 +12429,15 @@ std::string NMD::ROUND_W_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::ROUND_W_S(uint64 instruction) +static char *ROUND_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("ROUND.W.S %s, %s", ft, fs); + return img_format("ROUND.W.S %s, %s", ft, fs); } @@ -12874,15 +12451,15 @@ std::string NMD::ROUND_W_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RSQRT_D(uint64 instruction) +static char *RSQRT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("RSQRT.D %s, %s", ft, fs); + return img_format("RSQRT.D %s, %s", ft, fs); } @@ -12896,15 +12473,15 @@ std::string NMD::RSQRT_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::RSQRT_S(uint64 instruction) +static char *RSQRT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("RSQRT.S %s, %s", ft, fs); + return img_format("RSQRT.S %s, %s", ft, fs); } @@ -12918,15 +12495,15 @@ std::string NMD::RSQRT_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SAVE_16_(uint64 instruction) +static char *SAVE_16_(uint64 instruction, Dis_info *info) { uint64 rt1_value = extract_rtl_11(instruction); uint64 u_value = extract_u_7_6_5_4__s4(instruction); uint64 count_value = extract_count_3_2_1_0(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)); + g_autofree char *save_restore_str = save_restore_list( + encode_rt1_from_rt(rt1_value), count_value, 0, info); + return img_format("SAVE 0x%" PRIx64 "%s", u_value, save_restore_str); } @@ -12940,16 +12517,16 @@ std::string NMD::SAVE_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SAVE_32_(uint64 instruction) +static char *SAVE_32_(uint64 instruction, Dis_info *info) { uint64 count_value = extract_count_19_18_17_16(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__s3(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)); + g_autofree char *save_restore_str = save_restore_list( + rt_value, count_value, gp_value, info); + return img_format("SAVE 0x%" PRIx64 "%s", u_value, save_restore_str); } @@ -12963,15 +12540,13 @@ std::string NMD::SAVE_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SAVEF(uint64 instruction) +static char *SAVEF(uint64 instruction, Dis_info *info) { uint64 count_value = extract_count_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction); - std::string u = IMMEDIATE(copy(u_value)); - std::string count = IMMEDIATE(copy(count_value)); - return img::format("SAVEF %s, %s", u, count); + return img_format("SAVEF 0x%" PRIx64 ", 0x%" PRIx64, u_value, count_value); } @@ -12985,17 +12560,16 @@ std::string NMD::SAVEF(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SB_16_(uint64 instruction) +static char *SB_16_(uint64 instruction, Dis_info *info) { uint64 rtz3_value = extract_rtz3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_1_0(instruction); - std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); - return img::format("SB %s, %s(%s)", rtz3, u, rs3); + return img_format("SB %s, 0x%" PRIx64 "(%s)", rtz3, u_value, rs3); } @@ -13009,15 +12583,14 @@ std::string NMD::SB_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SB_GP_(uint64 instruction) +static char *SB_GP_(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("SB %s, %s($%d)", rt, u, 28); + return img_format("SB %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -13031,17 +12604,16 @@ std::string NMD::SB_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SB_S9_(uint64 instruction) +static char *SB_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SB %s, %s(%s)", rt, s, rs); + return img_format("SB %s, %s(%s)", rt, s_value, rs); } @@ -13055,17 +12627,16 @@ std::string NMD::SB_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SB_U12_(uint64 instruction) +static char *SB_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SB %s, %s(%s)", rt, u, rs); + return img_format("SB %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -13079,17 +12650,16 @@ std::string NMD::SB_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SBE(uint64 instruction) +static char *SBE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SBE %s, %s(%s)", rt, s, rs); + return img_format("SBE %s, %s(%s)", rt, s_value, rs); } @@ -13103,17 +12673,17 @@ std::string NMD::SBE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SBX(uint64 instruction) +static char *SBX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SBX %s, %s(%s)", rd, rs, rt); + return img_format("SBX %s, %s(%s)", rd, rs, rt); } @@ -13127,17 +12697,16 @@ std::string NMD::SBX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SC(uint64 instruction) +static char *SC(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SC %s, %s(%s)", rt, s, rs); + return img_format("SC %s, %s(%s)", rt, s_value, rs); } @@ -13151,17 +12720,16 @@ std::string NMD::SC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SCD(uint64 instruction) +static char *SCD(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_s3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SCD %s, %s(%s)", rt, s, rs); + return img_format("SCD %s, %s(%s)", rt, s_value, rs); } @@ -13175,17 +12743,17 @@ std::string NMD::SCD(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SCDP(uint64 instruction) +static char *SCDP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ru = GPR(copy(ru_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *ru = GPR(ru_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SCDP %s, %s, (%s)", rt, ru, rs); + return img_format("SCDP %s, %s, (%s)", rt, ru, rs); } @@ -13199,17 +12767,16 @@ std::string NMD::SCDP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SCE(uint64 instruction) +static char *SCE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SCE %s, %s(%s)", rt, s, rs); + return img_format("SCE %s, %s(%s)", rt, s_value, rs); } @@ -13223,17 +12790,17 @@ std::string NMD::SCE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SCWP(uint64 instruction) +static char *SCWP(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ru = GPR(copy(ru_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *ru = GPR(ru_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SCWP %s, %s, (%s)", rt, ru, rs); + return img_format("SCWP %s, %s, (%s)", rt, ru, rs); } @@ -13247,17 +12814,17 @@ std::string NMD::SCWP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SCWPE(uint64 instruction) +static char *SCWPE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ru_value = extract_ru_7_6_5_4_3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string ru = GPR(copy(ru_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *ru = GPR(ru_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SCWPE %s, %s, (%s)", rt, ru, rs); + return img_format("SCWPE %s, %s, (%s)", rt, ru, rs); } @@ -13271,15 +12838,14 @@ std::string NMD::SCWPE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SD_GP_(uint64 instruction) +static char *SD_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_3__s3(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); - return img::format("SD %s, %s($%d)", rt, u, 28); + return img_format("SD %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -13293,17 +12859,16 @@ std::string NMD::SD_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SD_S9_(uint64 instruction) +static char *SD_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SD %s, %s(%s)", rt, s, rs); + return img_format("SD %s, %s(%s)", rt, s_value, rs); } @@ -13317,17 +12882,16 @@ std::string NMD::SD_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SD_U12_(uint64 instruction) +static char *SD_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SD %s, %s(%s)", rt, u, rs); + return img_format("SD %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -13341,13 +12905,12 @@ std::string NMD::SD_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDBBP_16_(uint64 instruction) +static char *SDBBP_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_2_1_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); - return img::format("SDBBP %s", code); + return img_format("SDBBP 0x%" PRIx64, code_value); } @@ -13361,13 +12924,12 @@ std::string NMD::SDBBP_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDBBP_32_(uint64 instruction) +static char *SDBBP_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); - return img::format("SDBBP %s", code); + return img_format("SDBBP 0x%" PRIx64, code_value); } @@ -13381,15 +12943,14 @@ std::string NMD::SDBBP_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDC1_GP_(uint64 instruction) +static char *SDC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *ft = FPR(ft_value, info); - return img::format("SDC1 %s, %s($%d)", ft, u, 28); + return img_format("SDC1 %s, 0x%" PRIx64 "($%d)", ft, u_value, 28); } @@ -13403,17 +12964,16 @@ std::string NMD::SDC1_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDC1_S9_(uint64 instruction) +static char *SDC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SDC1 %s, %s(%s)", ft, s, rs); + return img_format("SDC1 %s, %s(%s)", ft, s_value, rs); } @@ -13427,17 +12987,16 @@ std::string NMD::SDC1_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDC1_U12_(uint64 instruction) +static char *SDC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SDC1 %s, %s(%s)", ft, u, rs); + return img_format("SDC1 %s, 0x%" PRIx64 "(%s)", ft, u_value, rs); } @@ -13451,17 +13010,17 @@ std::string NMD::SDC1_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDC1X(uint64 instruction) +static char *SDC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SDC1X %s, %s(%s)", ft, rs, rt); + return img_format("SDC1X %s, %s(%s)", ft, rs, rt); } @@ -13475,17 +13034,17 @@ std::string NMD::SDC1X(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDC1XS(uint64 instruction) +static char *SDC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SDC1XS %s, %s(%s)", ft, rs, rt); + return img_format("SDC1XS %s, %s(%s)", ft, rs, rt); } @@ -13499,17 +13058,15 @@ std::string NMD::SDC1XS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDC2(uint64 instruction) +static char *SDC2(uint64 instruction, Dis_info *info) { uint64 cs_value = extract_cs_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string cs = CPR(copy(cs_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rs = GPR(rs_value, info); - return img::format("SDC2 %s, %s(%s)", cs, s, rs); + return img_format("SDC2 CP%" PRIu64 ", %s(%s)", cs_value, s_value, rs); } @@ -13523,19 +13080,18 @@ std::string NMD::SDC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDM(uint64 instruction) +static char *SDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); + uint64 count3 = encode_count3_from_count(count3_value); - return img::format("SDM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("SDM %s, %s(%s), 0x%" PRIx64, rt, s_value, rs, count3); } @@ -13549,15 +13105,15 @@ std::string NMD::SDM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDPC_48_(uint64 instruction) +static char *SDPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 6, info); - return img::format("SDPC %s, %s", rt, s); + return img_format("SDPC %s, %s", rt, s); } @@ -13571,17 +13127,17 @@ std::string NMD::SDPC_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDXS(uint64 instruction) +static char *SDXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SDXS %s, %s(%s)", rd, rs, rt); + return img_format("SDXS %s, %s(%s)", rd, rs, rt); } @@ -13595,17 +13151,17 @@ std::string NMD::SDXS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SDX(uint64 instruction) +static char *SDX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SDX %s, %s(%s)", rd, rs, rt); + return img_format("SDX %s, %s(%s)", rd, rs, rt); } @@ -13619,15 +13175,15 @@ std::string NMD::SDX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SEB(uint64 instruction) +static char *SEB(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SEB %s, %s", rt, rs); + return img_format("SEB %s, %s", rt, rs); } @@ -13641,15 +13197,15 @@ std::string NMD::SEB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SEH(uint64 instruction) +static char *SEH(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SEH %s, %s", rt, rs); + return img_format("SEH %s, %s", rt, rs); } @@ -13663,17 +13219,17 @@ std::string NMD::SEH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SEL_D(uint64 instruction) +static char *SEL_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("SEL.D %s, %s, %s", fd, fs, ft); + return img_format("SEL.D %s, %s, %s", fd, fs, ft); } @@ -13687,17 +13243,17 @@ std::string NMD::SEL_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SEL_S(uint64 instruction) +static char *SEL_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("SEL.S %s, %s, %s", fd, fs, ft); + return img_format("SEL.S %s, %s, %s", fd, fs, ft); } @@ -13711,17 +13267,17 @@ std::string NMD::SEL_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SELEQZ_D(uint64 instruction) +static char *SELEQZ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("SELEQZ.D %s, %s, %s", fd, fs, ft); + return img_format("SELEQZ.D %s, %s, %s", fd, fs, ft); } @@ -13735,17 +13291,17 @@ std::string NMD::SELEQZ_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SELEQZ_S(uint64 instruction) +static char *SELEQZ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("SELEQZ.S %s, %s, %s", fd, fs, ft); + return img_format("SELEQZ.S %s, %s, %s", fd, fs, ft); } @@ -13759,17 +13315,17 @@ std::string NMD::SELEQZ_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SELNEZ_D(uint64 instruction) +static char *SELNEZ_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("SELNEZ.D %s, %s, %s", fd, fs, ft); + return img_format("SELNEZ.D %s, %s, %s", fd, fs, ft); } @@ -13783,17 +13339,17 @@ std::string NMD::SELNEZ_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SELNEZ_S(uint64 instruction) +static char *SELNEZ_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("SELNEZ.S %s, %s, %s", fd, fs, ft); + return img_format("SELNEZ.S %s, %s, %s", fd, fs, ft); } @@ -13807,17 +13363,16 @@ std::string NMD::SELNEZ_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SEQI(uint64 instruction) +static char *SEQI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SEQI %s, %s, %s", rt, rs, u); + return img_format("SEQI %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -13831,17 +13386,16 @@ std::string NMD::SEQI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SH_16_(uint64 instruction) +static char *SH_16_(uint64 instruction, Dis_info *info) { uint64 rtz3_value = extract_rtz3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_2_1__s1(instruction); - std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); - return img::format("SH %s, %s(%s)", rtz3, u, rs3); + return img_format("SH %s, 0x%" PRIx64 "(%s)", rtz3, u_value, rs3); } @@ -13855,15 +13409,14 @@ std::string NMD::SH_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SH_GP_(uint64 instruction) +static char *SH_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_1__s1(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); - return img::format("SH %s, %s($%d)", rt, u, 28); + return img_format("SH %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -13877,17 +13430,16 @@ std::string NMD::SH_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SH_S9_(uint64 instruction) +static char *SH_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SH %s, %s(%s)", rt, s, rs); + return img_format("SH %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -13901,17 +13453,16 @@ std::string NMD::SH_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SH_U12_(uint64 instruction) +static char *SH_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SH %s, %s(%s)", rt, u, rs); + return img_format("SH %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -13925,17 +13476,16 @@ std::string NMD::SH_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHE(uint64 instruction) +static char *SHE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHE %s, %s(%s)", rt, s, rs); + return img_format("SHE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -13949,15 +13499,14 @@ std::string NMD::SHE(uint64 instruction) * shift ------ * ac -- */ -std::string NMD::SHILO(uint64 instruction) +static char *SHILO(uint64 instruction, Dis_info *info) { int64 shift_value = extract_shift__se5_21_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string shift = IMMEDIATE(copy(shift_value)); - std::string ac = AC(copy(ac_value)); + const char *ac = AC(ac_value, info); - return img::format("SHILO %s, %s", ac, shift); + return img_format("SHILO %s, 0x%" PRIx64, ac, shift_value); } @@ -13971,15 +13520,15 @@ std::string NMD::SHILO(uint64 instruction) * rs ----- * ac -- */ -std::string NMD::SHILOV(uint64 instruction) +static char *SHILOV(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ac_value = extract_ac_15_14(instruction); - std::string rs = GPR(copy(rs_value)); - std::string ac = AC(copy(ac_value)); + const char *rs = GPR(rs_value, info); + const char *ac = AC(ac_value, info); - return img::format("SHILOV %s, %s", ac, rs); + return img_format("SHILOV %s, %s", ac, rs); } @@ -13993,17 +13542,16 @@ std::string NMD::SHILOV(uint64 instruction) * rs ----- * sa ---- */ -std::string NMD::SHLL_PH(uint64 instruction) +static char *SHLL_PH(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHLL.PH %s, %s, %s", rt, rs, sa); + return img_format("SHLL.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14017,17 +13565,16 @@ std::string NMD::SHLL_PH(uint64 instruction) * rs ----- * sa --- */ -std::string NMD::SHLL_QB(uint64 instruction) +static char *SHLL_QB(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHLL.QB %s, %s, %s", rt, rs, sa); + return img_format("SHLL.QB %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14042,17 +13589,16 @@ std::string NMD::SHLL_QB(uint64 instruction) * rs ----- * sa ---- */ -std::string NMD::SHLL_S_PH(uint64 instruction) +static char *SHLL_S_PH(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHLL_S.PH %s, %s, %s", rt, rs, sa); + return img_format("SHLL_S.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14066,17 +13612,16 @@ std::string NMD::SHLL_S_PH(uint64 instruction) * rs ----- * sa ----- */ -std::string NMD::SHLL_S_W(uint64 instruction) +static char *SHLL_S_W(uint64 instruction, Dis_info *info) { 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_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHLL_S.W %s, %s, %s", rt, rs, sa); + return img_format("SHLL_S.W %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14091,17 +13636,17 @@ std::string NMD::SHLL_S_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHLLV_PH(uint64 instruction) +static char *SHLLV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHLLV.PH %s, %s, %s", rd, rt, rs); + return img_format("SHLLV.PH %s, %s, %s", rd, rt, rs); } @@ -14115,17 +13660,17 @@ std::string NMD::SHLLV_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHLLV_QB(uint64 instruction) +static char *SHLLV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHLLV.QB %s, %s, %s", rd, rt, rs); + return img_format("SHLLV.QB %s, %s, %s", rd, rt, rs); } @@ -14140,17 +13685,17 @@ std::string NMD::SHLLV_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHLLV_S_PH(uint64 instruction) +static char *SHLLV_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHLLV_S.PH %s, %s, %s", rd, rt, rs); + return img_format("SHLLV_S.PH %s, %s, %s", rd, rt, rs); } @@ -14164,17 +13709,17 @@ std::string NMD::SHLLV_S_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHLLV_S_W(uint64 instruction) +static char *SHLLV_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHLLV_S.W %s, %s, %s", rd, rt, rs); + return img_format("SHLLV_S.W %s, %s, %s", rd, rt, rs); } @@ -14188,17 +13733,16 @@ std::string NMD::SHLLV_S_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRA_PH(uint64 instruction) +static char *SHRA_PH(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHRA.PH %s, %s, %s", rt, rs, sa); + return img_format("SHRA.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14212,17 +13756,16 @@ std::string NMD::SHRA_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRA_QB(uint64 instruction) +static char *SHRA_QB(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHRA.QB %s, %s, %s", rt, rs, sa); + return img_format("SHRA.QB %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14236,17 +13779,16 @@ std::string NMD::SHRA_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRA_R_PH(uint64 instruction) +static char *SHRA_R_PH(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHRA_R.PH %s, %s, %s", rt, rs, sa); + return img_format("SHRA_R.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14260,17 +13802,16 @@ std::string NMD::SHRA_R_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRA_R_QB(uint64 instruction) +static char *SHRA_R_QB(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHRA_R.QB %s, %s, %s", rt, rs, sa); + return img_format("SHRA_R.QB %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14284,17 +13825,16 @@ std::string NMD::SHRA_R_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRA_R_W(uint64 instruction) +static char *SHRA_R_W(uint64 instruction, Dis_info *info) { 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_11(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string sa = IMMEDIATE(copy(sa_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHRA_R.W %s, %s, %s", rt, rs, sa); + return img_format("SHRA_R.W %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14308,17 +13848,17 @@ std::string NMD::SHRA_R_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRAV_PH(uint64 instruction) +static char *SHRAV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHRAV.PH %s, %s, %s", rd, rt, rs); + return img_format("SHRAV.PH %s, %s, %s", rd, rt, rs); } @@ -14332,17 +13872,17 @@ std::string NMD::SHRAV_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRAV_QB(uint64 instruction) +static char *SHRAV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHRAV.QB %s, %s, %s", rd, rt, rs); + return img_format("SHRAV.QB %s, %s, %s", rd, rt, rs); } @@ -14356,17 +13896,17 @@ std::string NMD::SHRAV_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRAV_R_PH(uint64 instruction) +static char *SHRAV_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHRAV_R.PH %s, %s, %s", rd, rt, rs); + return img_format("SHRAV_R.PH %s, %s, %s", rd, rt, rs); } @@ -14380,17 +13920,17 @@ std::string NMD::SHRAV_R_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRAV_R_QB(uint64 instruction) +static char *SHRAV_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHRAV_R.QB %s, %s, %s", rd, rt, rs); + return img_format("SHRAV_R.QB %s, %s, %s", rd, rt, rs); } @@ -14404,17 +13944,17 @@ std::string NMD::SHRAV_R_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRAV_R_W(uint64 instruction) +static char *SHRAV_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHRAV_R.W %s, %s, %s", rd, rt, rs); + return img_format("SHRAV_R.W %s, %s, %s", rd, rt, rs); } @@ -14428,17 +13968,16 @@ std::string NMD::SHRAV_R_W(uint64 instruction) * rs ----- * sa ---- */ -std::string NMD::SHRL_PH(uint64 instruction) +static char *SHRL_PH(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHRL.PH %s, %s, %s", rt, rs, sa); + return img_format("SHRL.PH %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14452,17 +13991,16 @@ std::string NMD::SHRL_PH(uint64 instruction) * rs ----- * sa --- */ -std::string NMD::SHRL_QB(uint64 instruction) +static char *SHRL_QB(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHRL.QB %s, %s, %s", rt, rs, sa); + return img_format("SHRL.QB %s, %s, 0x%" PRIx64, rt, rs, sa_value); } @@ -14477,17 +14015,17 @@ std::string NMD::SHRL_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRLV_PH(uint64 instruction) +static char *SHRLV_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHRLV.PH %s, %s, %s", rd, rt, rs); + return img_format("SHRLV.PH %s, %s, %s", rd, rt, rs); } @@ -14501,17 +14039,17 @@ std::string NMD::SHRLV_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHRLV_QB(uint64 instruction) +static char *SHRLV_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); + const char *rd = GPR(rd_value, info); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SHRLV.QB %s, %s, %s", rd, rt, rs); + return img_format("SHRLV.QB %s, %s, %s", rd, rt, rs); } @@ -14525,17 +14063,17 @@ std::string NMD::SHRLV_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHX(uint64 instruction) +static char *SHX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SHX %s, %s(%s)", rd, rs, rt); + return img_format("SHX %s, %s(%s)", rd, rs, rt); } @@ -14549,17 +14087,17 @@ std::string NMD::SHX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SHXS(uint64 instruction) +static char *SHXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SHXS %s, %s(%s)", rd, rs, rt); + return img_format("SHXS %s, %s(%s)", rd, rs, rt); } @@ -14573,13 +14111,12 @@ std::string NMD::SHXS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SIGRIE(uint64 instruction) +static char *SIGRIE(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_18_to_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); - return img::format("SIGRIE %s", code); + return img_format("SIGRIE 0x%" PRIx64, code_value); } @@ -14593,17 +14130,17 @@ std::string NMD::SIGRIE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SLL_16_(uint64 instruction) +static char *SLL_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 shift3_value = extract_shift3_2_1_0(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string shift3 = IMMEDIATE(encode_shift3_from_shift(shift3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + uint64 shift3 = encode_shift3_from_shift(shift3_value); - return img::format("SLL %s, %s, %s", rt3, rs3, shift3); + return img_format("SLL %s, %s, 0x%" PRIx64, rt3, rs3, shift3); } @@ -14617,17 +14154,16 @@ std::string NMD::SLL_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SLL_32_(uint64 instruction) +static char *SLL_32_(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SLL %s, %s, %s", rt, rs, shift); + return img_format("SLL %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -14641,17 +14177,17 @@ std::string NMD::SLL_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SLLV(uint64 instruction) +static char *SLLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SLLV %s, %s, %s", rd, rs, rt); + return img_format("SLLV %s, %s, %s", rd, rs, rt); } @@ -14665,17 +14201,17 @@ std::string NMD::SLLV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SLT(uint64 instruction) +static char *SLT(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SLT %s, %s, %s", rd, rs, rt); + return img_format("SLT %s, %s, %s", rd, rs, rt); } @@ -14689,17 +14225,16 @@ std::string NMD::SLT(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SLTI(uint64 instruction) +static char *SLTI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SLTI %s, %s, %s", rt, rs, u); + return img_format("SLTI %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -14713,17 +14248,16 @@ std::string NMD::SLTI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SLTIU(uint64 instruction) +static char *SLTIU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SLTIU %s, %s, %s", rt, rs, u); + return img_format("SLTIU %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -14737,17 +14271,17 @@ std::string NMD::SLTIU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SLTU(uint64 instruction) +static char *SLTU(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SLTU %s, %s, %s", rd, rs, rt); + return img_format("SLTU %s, %s, %s", rd, rs, rt); } @@ -14761,17 +14295,17 @@ std::string NMD::SLTU(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SOV(uint64 instruction) +static char *SOV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SOV %s, %s, %s", rd, rs, rt); + return img_format("SOV %s, %s, %s", rd, rs, rt); } @@ -14785,13 +14319,12 @@ std::string NMD::SOV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SPECIAL2(uint64 instruction) +static char *SPECIAL2(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_to_3(instruction); - std::string op = IMMEDIATE(copy(op_value)); - return img::format("SPECIAL2 %s", op); + return img_format("SPECIAL2 0x%" PRIx64, op_value); } @@ -14805,15 +14338,15 @@ std::string NMD::SPECIAL2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SQRT_D(uint64 instruction) +static char *SQRT_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("SQRT.D %s, %s", ft, fs); + return img_format("SQRT.D %s, %s", ft, fs); } @@ -14827,15 +14360,15 @@ std::string NMD::SQRT_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SQRT_S(uint64 instruction) +static char *SQRT_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("SQRT.S %s, %s", ft, fs); + return img_format("SQRT.S %s, %s", ft, fs); } @@ -14849,17 +14382,16 @@ std::string NMD::SQRT_S(uint64 instruction) * rd ----- * sa ----- */ -std::string NMD::SRA(uint64 instruction) +static char *SRA(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SRA %s, %s, %s", rt, rs, shift); + return img_format("SRA %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -14873,17 +14405,17 @@ std::string NMD::SRA(uint64 instruction) * rt ----- * rd ----- */ -std::string NMD::SRAV(uint64 instruction) +static char *SRAV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SRAV %s, %s, %s", rd, rs, rt); + return img_format("SRAV %s, %s, %s", rd, rs, rt); } @@ -14897,17 +14429,17 @@ std::string NMD::SRAV(uint64 instruction) * rt ----- * rd ----- */ -std::string NMD::SRL_16_(uint64 instruction) +static char *SRL_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 shift3_value = extract_shift3_2_1_0(instruction); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string shift3 = IMMEDIATE(encode_shift3_from_shift(shift3_value)); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + uint64 shift3 = encode_shift3_from_shift(shift3_value); - return img::format("SRL %s, %s, %s", rt3, rs3, shift3); + return img_format("SRL %s, %s, 0x%" PRIx64, rt3, rs3, shift3); } @@ -14921,17 +14453,16 @@ std::string NMD::SRL_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SRL_32_(uint64 instruction) +static char *SRL_32_(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SRL %s, %s, %s", rt, rs, shift); + return img_format("SRL %s, %s, 0x%" PRIx64, rt, rs, shift_value); } @@ -14945,17 +14476,17 @@ std::string NMD::SRL_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SRLV(uint64 instruction) +static char *SRLV(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SRLV %s, %s, %s", rd, rs, rt); + return img_format("SRLV %s, %s, %s", rd, rs, rt); } @@ -14969,17 +14500,17 @@ std::string NMD::SRLV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUB(uint64 instruction) +static char *SUB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUB %s, %s, %s", rd, rs, rt); + return img_format("SUB %s, %s, %s", rd, rs, rt); } @@ -14993,17 +14524,17 @@ std::string NMD::SUB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUB_D(uint64 instruction) +static char *SUB_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("SUB.D %s, %s, %s", fd, fs, ft); + return img_format("SUB.D %s, %s, %s", fd, fs, ft); } @@ -15017,17 +14548,17 @@ std::string NMD::SUB_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUB_S(uint64 instruction) +static char *SUB_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); uint64 fd_value = extract_fd_15_14_13_12_11(instruction); - std::string fd = FPR(copy(fd_value)); - std::string fs = FPR(copy(fs_value)); - std::string ft = FPR(copy(ft_value)); + const char *fd = FPR(fd_value, info); + const char *fs = FPR(fs_value, info); + const char *ft = FPR(ft_value, info); - return img::format("SUB.S %s, %s, %s", fd, fs, ft); + return img_format("SUB.S %s, %s, %s", fd, fs, ft); } @@ -15041,17 +14572,17 @@ std::string NMD::SUB_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBQ_PH(uint64 instruction) +static char *SUBQ_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUBQ.PH %s, %s, %s", rd, rs, rt); + return img_format("SUBQ.PH %s, %s, %s", rd, rs, rt); } @@ -15066,17 +14597,17 @@ std::string NMD::SUBQ_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBQ_S_PH(uint64 instruction) +static char *SUBQ_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUBQ_S.PH %s, %s, %s", rd, rs, rt); + return img_format("SUBQ_S.PH %s, %s, %s", rd, rs, rt); } @@ -15091,17 +14622,17 @@ std::string NMD::SUBQ_S_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBQ_S_W(uint64 instruction) +static char *SUBQ_S_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUBQ_S.W %s, %s, %s", rd, rs, rt); + return img_format("SUBQ_S.W %s, %s, %s", rd, rs, rt); } @@ -15116,17 +14647,17 @@ std::string NMD::SUBQ_S_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBQH_PH(uint64 instruction) +static char *SUBQH_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUBQH.PH %s, %s, %s", rd, rs, rt); + return img_format("SUBQH.PH %s, %s, %s", rd, rs, rt); } @@ -15141,17 +14672,17 @@ std::string NMD::SUBQH_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBQH_R_PH(uint64 instruction) +static char *SUBQH_R_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUBQH_R.PH %s, %s, %s", rd, rs, rt); + return img_format("SUBQH_R.PH %s, %s, %s", rd, rs, rt); } @@ -15166,17 +14697,17 @@ std::string NMD::SUBQH_R_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBQH_R_W(uint64 instruction) +static char *SUBQH_R_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUBQH_R.W %s, %s, %s", rd, rs, rt); + return img_format("SUBQH_R.W %s, %s, %s", rd, rs, rt); } @@ -15191,17 +14722,17 @@ std::string NMD::SUBQH_R_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBQH_W(uint64 instruction) +static char *SUBQH_W(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUBQH.W %s, %s, %s", rd, rs, rt); + return img_format("SUBQH.W %s, %s, %s", rd, rs, rt); } @@ -15215,17 +14746,17 @@ std::string NMD::SUBQH_W(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBU_16_(uint64 instruction) +static char *SUBU_16_(uint64 instruction, Dis_info *info) { 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 rd3 = GPR(decode_gpr_gpr3(rd3_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rd3 = GPR(decode_gpr_gpr3(rd3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); - return img::format("SUBU %s, %s, %s", rd3, rs3, rt3); + return img_format("SUBU %s, %s, %s", rd3, rs3, rt3); } @@ -15239,17 +14770,17 @@ std::string NMD::SUBU_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBU_32_(uint64 instruction) +static char *SUBU_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUBU %s, %s, %s", rd, rs, rt); + return img_format("SUBU %s, %s, %s", rd, rs, rt); } @@ -15263,17 +14794,17 @@ std::string NMD::SUBU_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBU_PH(uint64 instruction) +static char *SUBU_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUBU.PH %s, %s, %s", rd, rs, rt); + return img_format("SUBU.PH %s, %s, %s", rd, rs, rt); } @@ -15287,17 +14818,17 @@ std::string NMD::SUBU_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBU_QB(uint64 instruction) +static char *SUBU_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUBU.QB %s, %s, %s", rd, rs, rt); + return img_format("SUBU.QB %s, %s, %s", rd, rs, rt); } @@ -15312,17 +14843,17 @@ std::string NMD::SUBU_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBU_S_PH(uint64 instruction) +static char *SUBU_S_PH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUBU_S.PH %s, %s, %s", rd, rs, rt); + return img_format("SUBU_S.PH %s, %s, %s", rd, rs, rt); } @@ -15337,17 +14868,17 @@ std::string NMD::SUBU_S_PH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBU_S_QB(uint64 instruction) +static char *SUBU_S_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUBU_S.QB %s, %s, %s", rd, rs, rt); + return img_format("SUBU_S.QB %s, %s, %s", rd, rs, rt); } @@ -15362,17 +14893,17 @@ std::string NMD::SUBU_S_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBUH_QB(uint64 instruction) +static char *SUBUH_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUBUH.QB %s, %s, %s", rd, rs, rt); + return img_format("SUBUH.QB %s, %s, %s", rd, rs, rt); } @@ -15387,17 +14918,17 @@ std::string NMD::SUBUH_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SUBUH_R_QB(uint64 instruction) +static char *SUBUH_R_QB(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SUBUH_R.QB %s, %s, %s", rd, rs, rt); + return img_format("SUBUH_R.QB %s, %s, %s", rd, rs, rt); } @@ -15411,17 +14942,16 @@ std::string NMD::SUBUH_R_QB(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SW_16_(uint64 instruction) +static char *SW_16_(uint64 instruction, Dis_info *info) { uint64 rtz3_value = extract_rtz3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); uint64 u_value = extract_u_3_2_1_0__s2(instruction); - std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); + const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value, info), info); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); - return img::format("SW %s, %s(%s)", rtz3, u, rs3); + return img_format("SW %s, 0x%" PRIx64 "(%s)", rtz3, u_value, rs3); } @@ -15435,17 +14965,16 @@ std::string NMD::SW_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SW_4X4_(uint64 instruction) +static char *SW_4X4_(uint64 instruction, Dis_info *info) { uint64 rtz4_value = extract_rtz4_9_7_6_5(instruction); uint64 rs4_value = extract_rs4_4_2_1_0(instruction); uint64 u_value = extract_u_3_8__s2(instruction); - std::string rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs4 = GPR(decode_gpr_gpr4(rs4_value)); + const char *rtz4 = GPR(decode_gpr_gpr4_zero(rtz4_value, info), info); + const char *rs4 = GPR(decode_gpr_gpr4(rs4_value, info), info); - return img::format("SW %s, %s(%s)", rtz4, u, rs4); + return img_format("SW %s, 0x%" PRIx64 "(%s)", rtz4, u_value, rs4); } @@ -15459,15 +14988,14 @@ std::string NMD::SW_4X4_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SW_GP16_(uint64 instruction) +static char *SW_GP16_(uint64 instruction, Dis_info *info) { uint64 u_value = extract_u_6_5_4_3_2_1_0__s2(instruction); uint64 rtz3_value = extract_rtz3_9_8_7(instruction); - std::string rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rtz3 = GPR(decode_gpr_gpr3_src_store(rtz3_value, info), info); - return img::format("SW %s, %s($%d)", rtz3, u, 28); + return img_format("SW %s, 0x%" PRIx64 "($%d)", rtz3, u_value, 28); } @@ -15481,15 +15009,14 @@ std::string NMD::SW_GP16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SW_GP_(uint64 instruction) +static char *SW_GP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 u_value = extract_u_20_to_2__s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); - return img::format("SW %s, %s($%d)", rt, u, 28); + return img_format("SW %s, 0x%" PRIx64 "($%d)", rt, u_value, 28); } @@ -15503,17 +15030,16 @@ std::string NMD::SW_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SW_S9_(uint64 instruction) +static char *SW_S9_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); int64 s_value = extract_s__se8_15_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 s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SW %s, %s(%s)", rt, s, rs); + return img_format("SW %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -15527,15 +15053,14 @@ std::string NMD::SW_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SW_SP_(uint64 instruction) +static char *SW_SP_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_9_8_7_6_5(instruction); uint64 u_value = extract_u_4_3_2_1_0__s2(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); - return img::format("SW %s, %s($%d)", rt, u, 29); + return img_format("SW %s, 0x%" PRIx64 "($%d)", rt, u_value, 29); } @@ -15549,17 +15074,16 @@ std::string NMD::SW_SP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SW_U12_(uint64 instruction) +static char *SW_U12_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SW %s, %s(%s)", rt, u, rs); + return img_format("SW %s, 0x%" PRIx64 "(%s)", rt, u_value, rs); } @@ -15573,15 +15097,14 @@ std::string NMD::SW_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWC1_GP_(uint64 instruction) +static char *SWC1_GP_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 u_value = extract_u_17_to_2__s2(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *ft = FPR(ft_value, info); - return img::format("SWC1 %s, %s($%d)", ft, u, 28); + return img_format("SWC1 %s, 0x%" PRIx64 "($%d)", ft, u_value, 28); } @@ -15595,17 +15118,16 @@ std::string NMD::SWC1_GP_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWC1_S9_(uint64 instruction) +static char *SWC1_S9_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SWC1 %s, %s(%s)", ft, s, rs); + return img_format("SWC1 %s, %" PRId64 "(%s)", ft, s_value, rs); } @@ -15619,17 +15141,16 @@ std::string NMD::SWC1_S9_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWC1_U12_(uint64 instruction) +static char *SWC1_U12_(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string ft = FPR(copy(ft_value)); - std::string u = IMMEDIATE(copy(u_value)); - std::string rs = GPR(copy(rs_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SWC1 %s, %s(%s)", ft, u, rs); + return img_format("SWC1 %s, 0x%" PRIx64 "(%s)", ft, u_value, rs); } @@ -15643,17 +15164,17 @@ std::string NMD::SWC1_U12_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWC1X(uint64 instruction) +static char *SWC1X(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SWC1X %s, %s(%s)", ft, rs, rt); + return img_format("SWC1X %s, %s(%s)", ft, rs, rt); } @@ -15667,17 +15188,17 @@ std::string NMD::SWC1X(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWC1XS(uint64 instruction) +static char *SWC1XS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 ft_value = extract_ft_15_14_13_12_11(instruction); - std::string ft = FPR(copy(ft_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *ft = FPR(ft_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SWC1XS %s, %s(%s)", ft, rs, rt); + return img_format("SWC1XS %s, %s(%s)", ft, rs, rt); } @@ -15691,17 +15212,16 @@ std::string NMD::SWC1XS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWC2(uint64 instruction) +static char *SWC2(uint64 instruction, Dis_info *info) { uint64 cs_value = extract_cs_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string cs = CPR(copy(cs_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rs = GPR(rs_value, info); - return img::format("SWC2 %s, %s(%s)", cs, s, rs); + return img_format("SWC2 CP%" PRIu64 ", %" PRId64 "(%s)", + cs_value, s_value, rs); } @@ -15715,17 +15235,16 @@ std::string NMD::SWC2(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWE(uint64 instruction) +static char *SWE(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("SWE %s, %s(%s)", rt, s, rs); + return img_format("SWE %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -15739,19 +15258,19 @@ std::string NMD::SWE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWM(uint64 instruction) +static char *SWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); + uint64 count3 = encode_count3_from_count(count3_value); - return img::format("SWM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("SWM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -15765,15 +15284,15 @@ std::string NMD::SWM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWPC_48_(uint64 instruction) +static char *SWPC_48_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_41_40_39_38_37(instruction); int64 s_value = extract_s__se31_15_to_0_31_to_16(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = ADDRESS(encode_s_from_address(s_value), 6); + const char *rt = GPR(rt_value, info); + g_autofree char *s = ADDRESS(s_value, 6, info); - return img::format("SWPC %s, %s", rt, s); + return img_format("SWPC %s, %s", rt, s); } @@ -15787,17 +15306,17 @@ std::string NMD::SWPC_48_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWX(uint64 instruction) +static char *SWX(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SWX %s, %s(%s)", rd, rs, rt); + return img_format("SWX %s, %s(%s)", rd, rs, rt); } @@ -15811,17 +15330,17 @@ std::string NMD::SWX(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SWXS(uint64 instruction) +static char *SWXS(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("SWXS %s, %s(%s)", rd, rs, rt); + return img_format("SWXS %s, %s(%s)", rd, rs, rt); } @@ -15835,13 +15354,12 @@ std::string NMD::SWXS(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SYNC(uint64 instruction) +static char *SYNC(uint64 instruction, Dis_info *info) { uint64 stype_value = extract_stype_20_19_18_17_16(instruction); - std::string stype = IMMEDIATE(copy(stype_value)); - return img::format("SYNC %s", stype); + return img_format("SYNC 0x%" PRIx64, stype_value); } @@ -15855,15 +15373,14 @@ std::string NMD::SYNC(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SYNCI(uint64 instruction) +static char *SYNCI(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rs = GPR(rs_value, info); - return img::format("SYNCI %s(%s)", s, rs); + return img_format("SYNCI %" PRId64 "(%s)", s_value, rs); } @@ -15877,15 +15394,14 @@ std::string NMD::SYNCI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SYNCIE(uint64 instruction) +static char *SYNCIE(uint64 instruction, Dis_info *info) { uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rs = GPR(rs_value, info); - return img::format("SYNCIE %s(%s)", s, rs); + return img_format("SYNCIE %" PRId64 "(%s)", s_value, rs); } @@ -15899,13 +15415,12 @@ std::string NMD::SYNCIE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::SYSCALL_16_(uint64 instruction) +static char *SYSCALL_16_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_1_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); - return img::format("SYSCALL %s", code); + return img_format("SYSCALL 0x%" PRIx64, code_value); } @@ -15917,13 +15432,12 @@ std::string NMD::SYSCALL_16_(uint64 instruction) * 00000000000010 * code ------------------ */ -std::string NMD::SYSCALL_32_(uint64 instruction) +static char *SYSCALL_32_(uint64 instruction, Dis_info *info) { uint64 code_value = extract_code_17_to_0(instruction); - std::string code = IMMEDIATE(copy(code_value)); - return img::format("SYSCALL %s", code); + return img_format("SYSCALL 0x%" PRIx64, code_value); } @@ -15937,15 +15451,15 @@ std::string NMD::SYSCALL_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TEQ(uint64 instruction) +static char *TEQ(uint64 instruction, Dis_info *info) { 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)); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("TEQ %s, %s", rs, rt); + return img_format("TEQ %s, %s", rs, rt); } @@ -15959,11 +15473,11 @@ std::string NMD::TEQ(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBGINV(uint64 instruction) +static char *TLBGINV(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBGINV "; + return g_strdup("TLBGINV "); } @@ -15977,11 +15491,11 @@ std::string NMD::TLBGINV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBGINVF(uint64 instruction) +static char *TLBGINVF(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBGINVF "; + return g_strdup("TLBGINVF "); } @@ -15995,11 +15509,11 @@ std::string NMD::TLBGINVF(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBGP(uint64 instruction) +static char *TLBGP(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBGP "; + return g_strdup("TLBGP "); } @@ -16013,11 +15527,11 @@ std::string NMD::TLBGP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBGR(uint64 instruction) +static char *TLBGR(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBGR "; + return g_strdup("TLBGR "); } @@ -16031,11 +15545,11 @@ std::string NMD::TLBGR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBGWI(uint64 instruction) +static char *TLBGWI(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBGWI "; + return g_strdup("TLBGWI "); } @@ -16049,11 +15563,11 @@ std::string NMD::TLBGWI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBGWR(uint64 instruction) +static char *TLBGWR(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBGWR "; + return g_strdup("TLBGWR "); } @@ -16067,11 +15581,11 @@ std::string NMD::TLBGWR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBINV(uint64 instruction) +static char *TLBINV(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBINV "; + return g_strdup("TLBINV "); } @@ -16085,11 +15599,11 @@ std::string NMD::TLBINV(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBINVF(uint64 instruction) +static char *TLBINVF(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBINVF "; + return g_strdup("TLBINVF "); } @@ -16103,11 +15617,11 @@ std::string NMD::TLBINVF(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBP(uint64 instruction) +static char *TLBP(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBP "; + return g_strdup("TLBP "); } @@ -16121,11 +15635,11 @@ std::string NMD::TLBP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBR(uint64 instruction) +static char *TLBR(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBR "; + return g_strdup("TLBR "); } @@ -16139,11 +15653,11 @@ std::string NMD::TLBR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBWI(uint64 instruction) +static char *TLBWI(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBWI "; + return g_strdup("TLBWI "); } @@ -16157,11 +15671,11 @@ std::string NMD::TLBWI(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TLBWR(uint64 instruction) +static char *TLBWR(uint64 instruction, Dis_info *info) { (void)instruction; - return "TLBWR "; + return g_strdup("TLBWR "); } @@ -16175,15 +15689,15 @@ std::string NMD::TLBWR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TNE(uint64 instruction) +static char *TNE(uint64 instruction, Dis_info *info) { 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)); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("TNE %s, %s", rs, rt); + return img_format("TNE %s, %s", rs, rt); } @@ -16197,15 +15711,15 @@ std::string NMD::TNE(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TRUNC_L_D(uint64 instruction) +static char *TRUNC_L_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("TRUNC.L.D %s, %s", ft, fs); + return img_format("TRUNC.L.D %s, %s", ft, fs); } @@ -16219,15 +15733,15 @@ std::string NMD::TRUNC_L_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TRUNC_L_S(uint64 instruction) +static char *TRUNC_L_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("TRUNC.L.S %s, %s", ft, fs); + return img_format("TRUNC.L.S %s, %s", ft, fs); } @@ -16241,15 +15755,15 @@ std::string NMD::TRUNC_L_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TRUNC_W_D(uint64 instruction) +static char *TRUNC_W_D(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("TRUNC.W.D %s, %s", ft, fs); + return img_format("TRUNC.W.D %s, %s", ft, fs); } @@ -16263,15 +15777,15 @@ std::string NMD::TRUNC_W_D(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::TRUNC_W_S(uint64 instruction) +static char *TRUNC_W_S(uint64 instruction, Dis_info *info) { uint64 ft_value = extract_ft_25_24_23_22_21(instruction); uint64 fs_value = extract_fs_20_19_18_17_16(instruction); - std::string ft = FPR(copy(ft_value)); - std::string fs = FPR(copy(fs_value)); + const char *ft = FPR(ft_value, info); + const char *fs = FPR(fs_value, info); - return img::format("TRUNC.W.S %s, %s", ft, fs); + return img_format("TRUNC.W.S %s, %s", ft, fs); } @@ -16285,19 +15799,19 @@ std::string NMD::TRUNC_W_S(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::UALDM(uint64 instruction) +static char *UALDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); + uint64 count3 = encode_count3_from_count(count3_value); - return img::format("UALDM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("UALDM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -16311,17 +15825,16 @@ std::string NMD::UALDM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::UALH(uint64 instruction) +static char *UALH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("UALH %s, %s(%s)", rt, s, rs); + return img_format("UALH %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -16335,19 +15848,19 @@ std::string NMD::UALH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::UALWM(uint64 instruction) +static char *UALWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); + uint64 count3 = encode_count3_from_count(count3_value); - return img::format("UALWM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("UALWM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -16361,19 +15874,19 @@ std::string NMD::UALWM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::UASDM(uint64 instruction) +static char *UASDM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); + uint64 count3 = encode_count3_from_count(count3_value); - return img::format("UASDM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("UASDM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -16387,17 +15900,16 @@ std::string NMD::UASDM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::UASH(uint64 instruction) +static char *UASH(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string s = IMMEDIATE(copy(s_value)); - std::string rs = GPR(copy(rs_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("UASH %s, %s(%s)", rt, s, rs); + return img_format("UASH %s, %" PRId64 "(%s)", rt, s_value, rs); } @@ -16411,19 +15923,19 @@ std::string NMD::UASH(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::UASWM(uint64 instruction) +static char *UASWM(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); int64 s_value = extract_s__se8_15_7_6_5_4_3_2_1_0(instruction); uint64 count3_value = extract_count3_14_13_12(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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); + uint64 count3 = encode_count3_from_count(count3_value); - return img::format("UASWM %s, %s(%s), %s", rt, s, rs, count3); + return img_format("UASWM %s, %" PRId64 "(%s), 0x%" PRIx64, + rt, s_value, rs, count3); } @@ -16437,13 +15949,12 @@ std::string NMD::UASWM(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::UDI(uint64 instruction) +static char *UDI(uint64 instruction, Dis_info *info) { uint64 op_value = extract_op_25_to_3(instruction); - std::string op = IMMEDIATE(copy(op_value)); - return img::format("UDI %s", op); + return img_format("UDI 0x%" PRIx64, op_value); } @@ -16455,13 +15966,12 @@ std::string NMD::UDI(uint64 instruction) * 001000 1100001101111111 * code ---------- */ -std::string NMD::WAIT(uint64 instruction) +static char *WAIT(uint64 instruction, Dis_info *info) { 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); + return img_format("WAIT 0x%" PRIx64, code_value); } @@ -16475,15 +15985,14 @@ std::string NMD::WAIT(uint64 instruction) * rt ----- * mask ------- */ -std::string NMD::WRDSP(uint64 instruction) +static char *WRDSP(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); - return img::format("WRDSP %s, %s", rt, mask); + return img_format("WRDSP %s, 0x%" PRIx64, rt, mask_value); } @@ -16497,15 +16006,15 @@ std::string NMD::WRDSP(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::WRPGPR(uint64 instruction) +static char *WRPGPR(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("WRPGPR %s, %s", rt, rs); + return img_format("WRPGPR %s, %s", rt, rs); } @@ -16519,15 +16028,15 @@ std::string NMD::WRPGPR(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::XOR_16_(uint64 instruction) +static char *XOR_16_(uint64 instruction, Dis_info *info) { uint64 rt3_value = extract_rt3_9_8_7(instruction); uint64 rs3_value = extract_rs3_6_5_4(instruction); - std::string rs3 = GPR(decode_gpr_gpr3(rs3_value)); - std::string rt3 = GPR(decode_gpr_gpr3(rt3_value)); + const char *rs3 = GPR(decode_gpr_gpr3(rs3_value, info), info); + const char *rt3 = GPR(decode_gpr_gpr3(rt3_value, info), info); - return img::format("XOR %s, %s", rs3, rt3); + return img_format("XOR %s, %s", rs3, rt3); } @@ -16541,17 +16050,17 @@ std::string NMD::XOR_16_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::XOR_32_(uint64 instruction) +static char *XOR_32_(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 rd_value = extract_rd_15_14_13_12_11(instruction); - std::string rd = GPR(copy(rd_value)); - std::string rs = GPR(copy(rs_value)); - std::string rt = GPR(copy(rt_value)); + const char *rd = GPR(rd_value, info); + const char *rs = GPR(rs_value, info); + const char *rt = GPR(rt_value, info); - return img::format("XOR %s, %s, %s", rd, rs, rt); + return img_format("XOR %s, %s, %s", rd, rs, rt); } @@ -16565,17 +16074,16 @@ std::string NMD::XOR_32_(uint64 instruction) * rs ----- * rd ----- */ -std::string NMD::XORI(uint64 instruction) +static char *XORI(uint64 instruction, Dis_info *info) { uint64 rt_value = extract_rt_25_24_23_22_21(instruction); uint64 rs_value = extract_rs_20_19_18_17_16(instruction); uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3_2_1_0(instruction); - std::string rt = GPR(copy(rt_value)); - std::string rs = GPR(copy(rs_value)); - std::string u = IMMEDIATE(copy(u_value)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("XORI %s, %s, %s", rt, rs, u); + return img_format("XORI %s, %s, 0x%" PRIx64, rt, rs, u_value); } @@ -16588,15 +16096,15 @@ std::string NMD::XORI(uint64 instruction) * rt ----- * rs ----- */ -std::string NMD::YIELD(uint64 instruction) +static char *YIELD(uint64 instruction, Dis_info *info) { 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)); + const char *rt = GPR(rt_value, info); + const char *rs = GPR(rs_value, info); - return img::format("YIELD %s, %s", rt, rs); + return img_format("YIELD %s, %s", rt, rs); } @@ -16703,83 +16211,83 @@ std::string NMD::YIELD(uint64 instruction) * */ -NMD::Pool NMD::P_SYSCALL[2] = { +static const Pool P_SYSCALL[2] = { { instruction , 0 , 0 , 32, - 0xfffc0000, 0x00080000, &NMD::SYSCALL_32_ , 0, + 0xfffc0000, 0x00080000, &SYSCALL_32_ , 0, 0x0 }, /* SYSCALL[32] */ { instruction , 0 , 0 , 32, - 0xfffc0000, 0x000c0000, &NMD::HYPCALL , 0, + 0xfffc0000, 0x000c0000, &HYPCALL , 0, CP0_ | VZ_ }, /* HYPCALL */ }; -NMD::Pool NMD::P_RI[4] = { +static const Pool P_RI[4] = { { instruction , 0 , 0 , 32, - 0xfff80000, 0x00000000, &NMD::SIGRIE , 0, + 0xfff80000, 0x00000000, &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, + 0xfff80000, 0x00100000, &BREAK_32_ , 0, 0x0 }, /* BREAK[32] */ { instruction , 0 , 0 , 32, - 0xfff80000, 0x00180000, &NMD::SDBBP_32_ , 0, + 0xfff80000, 0x00180000, &SDBBP_32_ , 0, EJTAG_ }, /* SDBBP[32] */ }; -NMD::Pool NMD::P_ADDIU[2] = { +static const Pool 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 , + 0xfc000000, 0x00000000, &ADDIU_32_ , &ADDIU_32__cond , 0x0 }, /* ADDIU[32] */ }; -NMD::Pool NMD::P_TRAP[2] = { +static const Pool P_TRAP[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000000, &NMD::TEQ , 0, + 0xfc0007ff, 0x20000000, &TEQ , 0, XMMS_ }, /* TEQ */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000400, &NMD::TNE , 0, + 0xfc0007ff, 0x20000400, &TNE , 0, XMMS_ }, /* TNE */ }; -NMD::Pool NMD::P_CMOVE[2] = { +static const Pool P_CMOVE[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000210, &NMD::MOVZ , 0, + 0xfc0007ff, 0x20000210, &MOVZ , 0, 0x0 }, /* MOVZ */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000610, &NMD::MOVN , 0, + 0xfc0007ff, 0x20000610, &MOVN , 0, 0x0 }, /* MOVN */ }; -NMD::Pool NMD::P_D_MT_VPE[2] = { +static const Pool P_D_MT_VPE[2] = { { instruction , 0 , 0 , 32, - 0xfc1f3fff, 0x20010ab0, &NMD::DMT , 0, + 0xfc1f3fff, 0x20010ab0, &DMT , 0, MT_ }, /* DMT */ { instruction , 0 , 0 , 32, - 0xfc1f3fff, 0x20000ab0, &NMD::DVPE , 0, + 0xfc1f3fff, 0x20000ab0, &DVPE , 0, MT_ }, /* DVPE */ }; -NMD::Pool NMD::P_E_MT_VPE[2] = { +static const Pool P_E_MT_VPE[2] = { { instruction , 0 , 0 , 32, - 0xfc1f3fff, 0x20010eb0, &NMD::EMT , 0, + 0xfc1f3fff, 0x20010eb0, &EMT , 0, MT_ }, /* EMT */ { instruction , 0 , 0 , 32, - 0xfc1f3fff, 0x20000eb0, &NMD::EVPE , 0, + 0xfc1f3fff, 0x20000eb0, &EVPE , 0, MT_ }, /* EVPE */ }; -NMD::Pool NMD::_P_MT_VPE[2] = { +static const Pool _P_MT_VPE[2] = { { pool , P_D_MT_VPE , 2 , 32, 0xfc003fff, 0x20000ab0, 0 , 0, 0x0 }, /* P.D_MT_VPE */ @@ -16789,7 +16297,7 @@ NMD::Pool NMD::_P_MT_VPE[2] = { }; -NMD::Pool NMD::P_MT_VPE[8] = { +static const Pool P_MT_VPE[8] = { { reserved_block , 0 , 0 , 32, 0xfc003bff, 0x200002b0, 0 , 0, 0x0 }, /* P.MT_VPE~*(0) */ @@ -16817,38 +16325,38 @@ NMD::Pool NMD::P_MT_VPE[8] = { }; -NMD::Pool NMD::P_DVP[2] = { +static const Pool P_DVP[2] = { { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20000390, &NMD::DVP , 0, + 0xfc00ffff, 0x20000390, &DVP , 0, 0x0 }, /* DVP */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20000790, &NMD::EVP , 0, + 0xfc00ffff, 0x20000790, &EVP , 0, 0x0 }, /* EVP */ }; -NMD::Pool NMD::P_SLTU[2] = { +static const Pool 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 , + 0xfc0003ff, 0x20000390, &SLTU , &SLTU_cond , 0x0 }, /* SLTU */ }; -NMD::Pool NMD::_POOL32A0[128] = { +static const Pool _POOL32A0[128] = { { pool , P_TRAP , 2 , 32, 0xfc0003ff, 0x20000000, 0 , 0, 0x0 }, /* P.TRAP */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000008, &NMD::SEB , 0, + 0xfc0003ff, 0x20000008, &SEB , 0, XMMS_ }, /* SEB */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000010, &NMD::SLLV , 0, + 0xfc0003ff, 0x20000010, &SLLV , 0, 0x0 }, /* SLLV */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000018, &NMD::MUL_32_ , 0, + 0xfc0003ff, 0x20000018, &MUL_32_ , 0, 0x0 }, /* MUL[32] */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000020, 0 , 0, @@ -16857,22 +16365,22 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000028, 0 , 0, 0x0 }, /* _POOL32A0~*(5) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000030, &NMD::MFC0 , 0, + 0xfc0003ff, 0x20000030, &MFC0 , 0, 0x0 }, /* MFC0 */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000038, &NMD::MFHC0 , 0, + 0xfc0003ff, 0x20000038, &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, + 0xfc0003ff, 0x20000048, &SEH , 0, 0x0 }, /* SEH */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000050, &NMD::SRLV , 0, + 0xfc0003ff, 0x20000050, &SRLV , 0, 0x0 }, /* SRLV */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000058, &NMD::MUH , 0, + 0xfc0003ff, 0x20000058, &MUH , 0, 0x0 }, /* MUH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000060, 0 , 0, @@ -16881,10 +16389,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000068, 0 , 0, 0x0 }, /* _POOL32A0~*(13) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000070, &NMD::MTC0 , 0, + 0xfc0003ff, 0x20000070, &MTC0 , 0, CP0_ }, /* MTC0 */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000078, &NMD::MTHC0 , 0, + 0xfc0003ff, 0x20000078, &MTHC0 , 0, CP0_ | MVH_ }, /* MTHC0 */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000080, 0 , 0, @@ -16893,10 +16401,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000088, 0 , 0, 0x0 }, /* _POOL32A0~*(17) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000090, &NMD::SRAV , 0, + 0xfc0003ff, 0x20000090, &SRAV , 0, 0x0 }, /* SRAV */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000098, &NMD::MULU , 0, + 0xfc0003ff, 0x20000098, &MULU , 0, 0x0 }, /* MULU */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200000a0, 0 , 0, @@ -16905,10 +16413,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x200000a8, 0 , 0, 0x0 }, /* _POOL32A0~*(21) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000b0, &NMD::MFGC0 , 0, + 0xfc0003ff, 0x200000b0, &MFGC0 , 0, CP0_ | VZ_ }, /* MFGC0 */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000b8, &NMD::MFHGC0 , 0, + 0xfc0003ff, 0x200000b8, &MFHGC0 , 0, CP0_ | VZ_ | MVH_ }, /* MFHGC0 */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200000c0, 0 , 0, @@ -16917,10 +16425,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x200000c8, 0 , 0, 0x0 }, /* _POOL32A0~*(25) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000d0, &NMD::ROTRV , 0, + 0xfc0003ff, 0x200000d0, &ROTRV , 0, 0x0 }, /* ROTRV */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000d8, &NMD::MUHU , 0, + 0xfc0003ff, 0x200000d8, &MUHU , 0, 0x0 }, /* MUHU */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200000e0, 0 , 0, @@ -16929,10 +16437,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x200000e8, 0 , 0, 0x0 }, /* _POOL32A0~*(29) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000f0, &NMD::MTGC0 , 0, + 0xfc0003ff, 0x200000f0, &MTGC0 , 0, CP0_ | VZ_ }, /* MTGC0 */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000f8, &NMD::MTHGC0 , 0, + 0xfc0003ff, 0x200000f8, &MTHGC0 , 0, CP0_ | VZ_ | MVH_ }, /* MTHGC0 */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000100, 0 , 0, @@ -16941,10 +16449,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000108, 0 , 0, 0x0 }, /* _POOL32A0~*(33) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000110, &NMD::ADD , 0, + 0xfc0003ff, 0x20000110, &ADD , 0, XMMS_ }, /* ADD */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000118, &NMD::DIV , 0, + 0xfc0003ff, 0x20000118, &DIV , 0, 0x0 }, /* DIV */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000120, 0 , 0, @@ -16953,7 +16461,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000128, 0 , 0, 0x0 }, /* _POOL32A0~*(37) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000130, &NMD::DMFC0 , 0, + 0xfc0003ff, 0x20000130, &DMFC0 , 0, CP0_ | MIPS64_ }, /* DMFC0 */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000138, 0 , 0, @@ -16965,10 +16473,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000148, 0 , 0, 0x0 }, /* _POOL32A0~*(41) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000150, &NMD::ADDU_32_ , 0, + 0xfc0003ff, 0x20000150, &ADDU_32_ , 0, 0x0 }, /* ADDU[32] */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000158, &NMD::MOD , 0, + 0xfc0003ff, 0x20000158, &MOD , 0, 0x0 }, /* MOD */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000160, 0 , 0, @@ -16977,7 +16485,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000168, 0 , 0, 0x0 }, /* _POOL32A0~*(45) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000170, &NMD::DMTC0 , 0, + 0xfc0003ff, 0x20000170, &DMTC0 , 0, CP0_ | MIPS64_ }, /* DMTC0 */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000178, 0 , 0, @@ -16989,10 +16497,10 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000188, 0 , 0, 0x0 }, /* _POOL32A0~*(49) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000190, &NMD::SUB , 0, + 0xfc0003ff, 0x20000190, &SUB , 0, XMMS_ }, /* SUB */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000198, &NMD::DIVU , 0, + 0xfc0003ff, 0x20000198, &DIVU , 0, 0x0 }, /* DIVU */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200001a0, 0 , 0, @@ -17001,22 +16509,22 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x200001a8, 0 , 0, 0x0 }, /* _POOL32A0~*(53) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001b0, &NMD::DMFGC0 , 0, + 0xfc0003ff, 0x200001b0, &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, + 0xfc0003ff, 0x200001c0, &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, + 0xfc0003ff, 0x200001d0, &SUBU_32_ , 0, 0x0 }, /* SUBU[32] */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001d8, &NMD::MODU , 0, + 0xfc0003ff, 0x200001d8, &MODU , 0, 0x0 }, /* MODU */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200001e0, 0 , 0, @@ -17025,7 +16533,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x200001e8, 0 , 0, 0x0 }, /* _POOL32A0~*(61) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001f0, &NMD::DMTGC0 , 0, + 0xfc0003ff, 0x200001f0, &DMTGC0 , 0, CP0_ | MIPS64_ | VZ_}, /* DMTGC0 */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200001f8, 0 , 0, @@ -17046,13 +16554,13 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000220, 0 , 0, 0x0 }, /* _POOL32A0~*(68) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000228, &NMD::FORK , 0, + 0xfc0003ff, 0x20000228, &FORK , 0, MT_ }, /* FORK */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000230, &NMD::MFTR , 0, + 0xfc0003ff, 0x20000230, &MFTR , 0, MT_ }, /* MFTR */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000238, &NMD::MFHTR , 0, + 0xfc0003ff, 0x20000238, &MFHTR , 0, MT_ }, /* MFHTR */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000240, 0 , 0, @@ -17061,7 +16569,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000248, 0 , 0, 0x0 }, /* _POOL32A0~*(73) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000250, &NMD::AND_32_ , 0, + 0xfc0003ff, 0x20000250, &AND_32_ , 0, 0x0 }, /* AND[32] */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000258, 0 , 0, @@ -17070,13 +16578,13 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000260, 0 , 0, 0x0 }, /* _POOL32A0~*(76) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000268, &NMD::YIELD , 0, + 0xfc0003ff, 0x20000268, &YIELD , 0, MT_ }, /* YIELD */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000270, &NMD::MTTR , 0, + 0xfc0003ff, 0x20000270, &MTTR , 0, MT_ }, /* MTTR */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000278, &NMD::MTHTR , 0, + 0xfc0003ff, 0x20000278, &MTHTR , 0, MT_ }, /* MTHTR */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000280, 0 , 0, @@ -17085,7 +16593,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000288, 0 , 0, 0x0 }, /* _POOL32A0~*(81) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000290, &NMD::OR_32_ , 0, + 0xfc0003ff, 0x20000290, &OR_32_ , 0, 0x0 }, /* OR[32] */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000298, 0 , 0, @@ -17109,7 +16617,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x200002c8, 0 , 0, 0x0 }, /* _POOL32A0~*(89) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200002d0, &NMD::NOR , 0, + 0xfc0003ff, 0x200002d0, &NOR , 0, 0x0 }, /* NOR */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200002d8, 0 , 0, @@ -17133,7 +16641,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000308, 0 , 0, 0x0 }, /* _POOL32A0~*(97) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000310, &NMD::XOR_32_ , 0, + 0xfc0003ff, 0x20000310, &XOR_32_ , 0, 0x0 }, /* XOR[32] */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000318, 0 , 0, @@ -17157,7 +16665,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x20000348, 0 , 0, 0x0 }, /* _POOL32A0~*(105) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000350, &NMD::SLT , 0, + 0xfc0003ff, 0x20000350, &SLT , 0, 0x0 }, /* SLT */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000358, 0 , 0, @@ -17205,7 +16713,7 @@ NMD::Pool NMD::_POOL32A0[128] = { 0xfc0003ff, 0x200003c8, 0 , 0, 0x0 }, /* _POOL32A0~*(121) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200003d0, &NMD::SOV , 0, + 0xfc0003ff, 0x200003d0, &SOV , 0, 0x0 }, /* SOV */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200003d8, 0 , 0, @@ -17225,185 +16733,185 @@ NMD::Pool NMD::_POOL32A0[128] = { }; -NMD::Pool NMD::ADDQ__S__PH[2] = { +static const Pool ADDQ__S__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000000d, &NMD::ADDQ_PH , 0, + 0xfc0007ff, 0x2000000d, &ADDQ_PH , 0, DSP_ }, /* ADDQ.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000040d, &NMD::ADDQ_S_PH , 0, + 0xfc0007ff, 0x2000040d, &ADDQ_S_PH , 0, DSP_ }, /* ADDQ_S.PH */ }; -NMD::Pool NMD::MUL__S__PH[2] = { +static const Pool MUL__S__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000002d, &NMD::MUL_PH , 0, + 0xfc0007ff, 0x2000002d, &MUL_PH , 0, DSP_ }, /* MUL.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000042d, &NMD::MUL_S_PH , 0, + 0xfc0007ff, 0x2000042d, &MUL_S_PH , 0, DSP_ }, /* MUL_S.PH */ }; -NMD::Pool NMD::ADDQH__R__PH[2] = { +static const Pool ADDQH__R__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000004d, &NMD::ADDQH_PH , 0, + 0xfc0007ff, 0x2000004d, &ADDQH_PH , 0, DSP_ }, /* ADDQH.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000044d, &NMD::ADDQH_R_PH , 0, + 0xfc0007ff, 0x2000044d, &ADDQH_R_PH , 0, DSP_ }, /* ADDQH_R.PH */ }; -NMD::Pool NMD::ADDQH__R__W[2] = { +static const Pool ADDQH__R__W[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000008d, &NMD::ADDQH_W , 0, + 0xfc0007ff, 0x2000008d, &ADDQH_W , 0, DSP_ }, /* ADDQH.W */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000048d, &NMD::ADDQH_R_W , 0, + 0xfc0007ff, 0x2000048d, &ADDQH_R_W , 0, DSP_ }, /* ADDQH_R.W */ }; -NMD::Pool NMD::ADDU__S__QB[2] = { +static const Pool ADDU__S__QB[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200000cd, &NMD::ADDU_QB , 0, + 0xfc0007ff, 0x200000cd, &ADDU_QB , 0, DSP_ }, /* ADDU.QB */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200004cd, &NMD::ADDU_S_QB , 0, + 0xfc0007ff, 0x200004cd, &ADDU_S_QB , 0, DSP_ }, /* ADDU_S.QB */ }; -NMD::Pool NMD::ADDU__S__PH[2] = { +static const Pool ADDU__S__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000010d, &NMD::ADDU_PH , 0, + 0xfc0007ff, 0x2000010d, &ADDU_PH , 0, DSP_ }, /* ADDU.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000050d, &NMD::ADDU_S_PH , 0, + 0xfc0007ff, 0x2000050d, &ADDU_S_PH , 0, DSP_ }, /* ADDU_S.PH */ }; -NMD::Pool NMD::ADDUH__R__QB[2] = { +static const Pool ADDUH__R__QB[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000014d, &NMD::ADDUH_QB , 0, + 0xfc0007ff, 0x2000014d, &ADDUH_QB , 0, DSP_ }, /* ADDUH.QB */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000054d, &NMD::ADDUH_R_QB , 0, + 0xfc0007ff, 0x2000054d, &ADDUH_R_QB , 0, DSP_ }, /* ADDUH_R.QB */ }; -NMD::Pool NMD::SHRAV__R__PH[2] = { +static const Pool SHRAV__R__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000018d, &NMD::SHRAV_PH , 0, + 0xfc0007ff, 0x2000018d, &SHRAV_PH , 0, DSP_ }, /* SHRAV.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000058d, &NMD::SHRAV_R_PH , 0, + 0xfc0007ff, 0x2000058d, &SHRAV_R_PH , 0, DSP_ }, /* SHRAV_R.PH */ }; -NMD::Pool NMD::SHRAV__R__QB[2] = { +static const Pool SHRAV__R__QB[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200001cd, &NMD::SHRAV_QB , 0, + 0xfc0007ff, 0x200001cd, &SHRAV_QB , 0, DSP_ }, /* SHRAV.QB */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200005cd, &NMD::SHRAV_R_QB , 0, + 0xfc0007ff, 0x200005cd, &SHRAV_R_QB , 0, DSP_ }, /* SHRAV_R.QB */ }; -NMD::Pool NMD::SUBQ__S__PH[2] = { +static const Pool SUBQ__S__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000020d, &NMD::SUBQ_PH , 0, + 0xfc0007ff, 0x2000020d, &SUBQ_PH , 0, DSP_ }, /* SUBQ.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000060d, &NMD::SUBQ_S_PH , 0, + 0xfc0007ff, 0x2000060d, &SUBQ_S_PH , 0, DSP_ }, /* SUBQ_S.PH */ }; -NMD::Pool NMD::SUBQH__R__PH[2] = { +static const Pool SUBQH__R__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000024d, &NMD::SUBQH_PH , 0, + 0xfc0007ff, 0x2000024d, &SUBQH_PH , 0, DSP_ }, /* SUBQH.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000064d, &NMD::SUBQH_R_PH , 0, + 0xfc0007ff, 0x2000064d, &SUBQH_R_PH , 0, DSP_ }, /* SUBQH_R.PH */ }; -NMD::Pool NMD::SUBQH__R__W[2] = { +static const Pool SUBQH__R__W[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000028d, &NMD::SUBQH_W , 0, + 0xfc0007ff, 0x2000028d, &SUBQH_W , 0, DSP_ }, /* SUBQH.W */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000068d, &NMD::SUBQH_R_W , 0, + 0xfc0007ff, 0x2000068d, &SUBQH_R_W , 0, DSP_ }, /* SUBQH_R.W */ }; -NMD::Pool NMD::SUBU__S__QB[2] = { +static const Pool SUBU__S__QB[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200002cd, &NMD::SUBU_QB , 0, + 0xfc0007ff, 0x200002cd, &SUBU_QB , 0, DSP_ }, /* SUBU.QB */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200006cd, &NMD::SUBU_S_QB , 0, + 0xfc0007ff, 0x200006cd, &SUBU_S_QB , 0, DSP_ }, /* SUBU_S.QB */ }; -NMD::Pool NMD::SUBU__S__PH[2] = { +static const Pool SUBU__S__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000030d, &NMD::SUBU_PH , 0, + 0xfc0007ff, 0x2000030d, &SUBU_PH , 0, DSP_ }, /* SUBU.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000070d, &NMD::SUBU_S_PH , 0, + 0xfc0007ff, 0x2000070d, &SUBU_S_PH , 0, DSP_ }, /* SUBU_S.PH */ }; -NMD::Pool NMD::SHRA__R__PH[2] = { +static const Pool SHRA__R__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000335, &NMD::SHRA_PH , 0, + 0xfc0007ff, 0x20000335, &SHRA_PH , 0, DSP_ }, /* SHRA.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000735, &NMD::SHRA_R_PH , 0, + 0xfc0007ff, 0x20000735, &SHRA_R_PH , 0, DSP_ }, /* SHRA_R.PH */ }; -NMD::Pool NMD::SUBUH__R__QB[2] = { +static const Pool SUBUH__R__QB[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000034d, &NMD::SUBUH_QB , 0, + 0xfc0007ff, 0x2000034d, &SUBUH_QB , 0, DSP_ }, /* SUBUH.QB */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000074d, &NMD::SUBUH_R_QB , 0, + 0xfc0007ff, 0x2000074d, &SUBUH_R_QB , 0, DSP_ }, /* SUBUH_R.QB */ }; -NMD::Pool NMD::SHLLV__S__PH[2] = { +static const Pool SHLLV__S__PH[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000038d, &NMD::SHLLV_PH , 0, + 0xfc0007ff, 0x2000038d, &SHLLV_PH , 0, DSP_ }, /* SHLLV.PH */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x2000078d, &NMD::SHLLV_S_PH , 0, + 0xfc0007ff, 0x2000078d, &SHLLV_S_PH , 0, DSP_ }, /* SHLLV_S.PH */ }; -NMD::Pool NMD::SHLL__S__PH[4] = { +static const Pool SHLL__S__PH[4] = { { instruction , 0 , 0 , 32, - 0xfc000fff, 0x200003b5, &NMD::SHLL_PH , 0, + 0xfc000fff, 0x200003b5, &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, + 0xfc000fff, 0x20000bb5, &SHLL_S_PH , 0, DSP_ }, /* SHLL_S.PH */ { reserved_block , 0 , 0 , 32, 0xfc000fff, 0x20000fb5, 0 , 0, @@ -17411,19 +16919,19 @@ NMD::Pool NMD::SHLL__S__PH[4] = { }; -NMD::Pool NMD::PRECR_SRA__R__PH_W[2] = { +static const Pool PRECR_SRA__R__PH_W[2] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200003cd, &NMD::PRECR_SRA_PH_W , 0, + 0xfc0007ff, 0x200003cd, &PRECR_SRA_PH_W , 0, DSP_ }, /* PRECR_SRA.PH.W */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200007cd, &NMD::PRECR_SRA_R_PH_W , 0, + 0xfc0007ff, 0x200007cd, &PRECR_SRA_R_PH_W , 0, DSP_ }, /* PRECR_SRA_R.PH.W */ }; -NMD::Pool NMD::_POOL32A5[128] = { +static const Pool _POOL32A5[128] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000005, &NMD::CMP_EQ_PH , 0, + 0xfc0003ff, 0x20000005, &CMP_EQ_PH , 0, DSP_ }, /* CMP.EQ.PH */ { pool , ADDQ__S__PH , 2 , 32, 0xfc0003ff, 0x2000000d, 0 , 0, @@ -17432,10 +16940,10 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x20000015, 0 , 0, 0x0 }, /* _POOL32A5~*(2) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x2000001d, &NMD::SHILO , 0, + 0xfc0003ff, 0x2000001d, &SHILO , 0, DSP_ }, /* SHILO */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000025, &NMD::MULEQ_S_W_PHL , 0, + 0xfc0003ff, 0x20000025, &MULEQ_S_W_PHL , 0, DSP_ }, /* MULEQ_S.W.PHL */ { pool , MUL__S__PH , 2 , 32, 0xfc0003ff, 0x2000002d, 0 , 0, @@ -17444,10 +16952,10 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x20000035, 0 , 0, 0x0 }, /* _POOL32A5~*(6) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x2000003d, &NMD::REPL_PH , 0, + 0xfc0003ff, 0x2000003d, &REPL_PH , 0, DSP_ }, /* REPL.PH */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000045, &NMD::CMP_LT_PH , 0, + 0xfc0003ff, 0x20000045, &CMP_LT_PH , 0, DSP_ }, /* CMP.LT.PH */ { pool , ADDQH__R__PH , 2 , 32, 0xfc0003ff, 0x2000004d, 0 , 0, @@ -17459,10 +16967,10 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000005d, 0 , 0, 0x0 }, /* _POOL32A5~*(11) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000065, &NMD::MULEQ_S_W_PHR , 0, + 0xfc0003ff, 0x20000065, &MULEQ_S_W_PHR , 0, DSP_ }, /* MULEQ_S.W.PHR */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x2000006d, &NMD::PRECR_QB_PH , 0, + 0xfc0003ff, 0x2000006d, &PRECR_QB_PH , 0, DSP_ }, /* PRECR.QB.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000075, 0 , 0, @@ -17471,13 +16979,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000007d, 0 , 0, 0x0 }, /* _POOL32A5~*(15) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000085, &NMD::CMP_LE_PH , 0, + 0xfc0003ff, 0x20000085, &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, + 0xfc0003ff, 0x20000095, &MULEU_S_PH_QBL , 0, DSP_ }, /* MULEU_S.PH.QBL */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000009d, 0 , 0, @@ -17486,7 +16994,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200000a5, 0 , 0, 0x0 }, /* _POOL32A5~*(20) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000ad, &NMD::PRECRQ_QB_PH , 0, + 0xfc0003ff, 0x200000ad, &PRECRQ_QB_PH , 0, DSP_ }, /* PRECRQ.QB.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200000b5, 0 , 0, @@ -17495,13 +17003,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200000bd, 0 , 0, 0x0 }, /* _POOL32A5~*(23) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000c5, &NMD::CMPGU_EQ_QB , 0, + 0xfc0003ff, 0x200000c5, &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, + 0xfc0003ff, 0x200000d5, &MULEU_S_PH_QBR , 0, DSP_ }, /* MULEU_S.PH.QBR */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200000dd, 0 , 0, @@ -17510,7 +17018,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200000e5, 0 , 0, 0x0 }, /* _POOL32A5~*(28) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200000ed, &NMD::PRECRQ_PH_W , 0, + 0xfc0003ff, 0x200000ed, &PRECRQ_PH_W , 0, DSP_ }, /* PRECRQ.PH.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200000f5, 0 , 0, @@ -17519,13 +17027,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200000fd, 0 , 0, 0x0 }, /* _POOL32A5~*(31) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000105, &NMD::CMPGU_LT_QB , 0, + 0xfc0003ff, 0x20000105, &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, + 0xfc0003ff, 0x20000115, &MULQ_RS_PH , 0, DSP_ }, /* MULQ_RS.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000011d, 0 , 0, @@ -17534,7 +17042,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x20000125, 0 , 0, 0x0 }, /* _POOL32A5~*(36) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x2000012d, &NMD::PRECRQ_RS_PH_W , 0, + 0xfc0003ff, 0x2000012d, &PRECRQ_RS_PH_W , 0, DSP_ }, /* PRECRQ_RS.PH.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000135, 0 , 0, @@ -17543,13 +17051,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000013d, 0 , 0, 0x0 }, /* _POOL32A5~*(39) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000145, &NMD::CMPGU_LE_QB , 0, + 0xfc0003ff, 0x20000145, &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, + 0xfc0003ff, 0x20000155, &MULQ_S_PH , 0, DSP_ }, /* MULQ_S.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000015d, 0 , 0, @@ -17558,7 +17066,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x20000165, 0 , 0, 0x0 }, /* _POOL32A5~*(44) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x2000016d, &NMD::PRECRQU_S_QB_PH , 0, + 0xfc0003ff, 0x2000016d, &PRECRQU_S_QB_PH , 0, DSP_ }, /* PRECRQU_S.QB.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000175, 0 , 0, @@ -17567,13 +17075,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000017d, 0 , 0, 0x0 }, /* _POOL32A5~*(47) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000185, &NMD::CMPGDU_EQ_QB , 0, + 0xfc0003ff, 0x20000185, &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, + 0xfc0003ff, 0x20000195, &MULQ_RS_W , 0, DSP_ }, /* MULQ_RS.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000019d, 0 , 0, @@ -17582,7 +17090,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200001a5, 0 , 0, 0x0 }, /* _POOL32A5~*(52) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001ad, &NMD::PACKRL_PH , 0, + 0xfc0003ff, 0x200001ad, &PACKRL_PH , 0, DSP_ }, /* PACKRL.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200001b5, 0 , 0, @@ -17591,13 +17099,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200001bd, 0 , 0, 0x0 }, /* _POOL32A5~*(55) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001c5, &NMD::CMPGDU_LT_QB , 0, + 0xfc0003ff, 0x200001c5, &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, + 0xfc0003ff, 0x200001d5, &MULQ_S_W , 0, DSP_ }, /* MULQ_S.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200001dd, 0 , 0, @@ -17606,7 +17114,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200001e5, 0 , 0, 0x0 }, /* _POOL32A5~*(60) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200001ed, &NMD::PICK_QB , 0, + 0xfc0003ff, 0x200001ed, &PICK_QB , 0, DSP_ }, /* PICK.QB */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200001f5, 0 , 0, @@ -17615,13 +17123,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200001fd, 0 , 0, 0x0 }, /* _POOL32A5~*(63) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000205, &NMD::CMPGDU_LE_QB , 0, + 0xfc0003ff, 0x20000205, &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, + 0xfc0003ff, 0x20000215, &APPEND , 0, DSP_ }, /* APPEND */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000021d, 0 , 0, @@ -17630,7 +17138,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x20000225, 0 , 0, 0x0 }, /* _POOL32A5~*(68) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x2000022d, &NMD::PICK_PH , 0, + 0xfc0003ff, 0x2000022d, &PICK_PH , 0, DSP_ }, /* PICK.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x20000235, 0 , 0, @@ -17639,13 +17147,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000023d, 0 , 0, 0x0 }, /* _POOL32A5~*(71) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000245, &NMD::CMPU_EQ_QB , 0, + 0xfc0003ff, 0x20000245, &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, + 0xfc0003ff, 0x20000255, &PREPEND , 0, DSP_ }, /* PREPEND */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000025d, 0 , 0, @@ -17663,13 +17171,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000027d, 0 , 0, 0x0 }, /* _POOL32A5~*(79) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000285, &NMD::CMPU_LT_QB , 0, + 0xfc0003ff, 0x20000285, &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, + 0xfc0003ff, 0x20000295, &MODSUB , 0, DSP_ }, /* MODSUB */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000029d, 0 , 0, @@ -17687,13 +17195,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200002bd, 0 , 0, 0x0 }, /* _POOL32A5~*(87) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200002c5, &NMD::CMPU_LE_QB , 0, + 0xfc0003ff, 0x200002c5, &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, + 0xfc0003ff, 0x200002d5, &SHRAV_R_W , 0, DSP_ }, /* SHRAV_R.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200002dd, 0 , 0, @@ -17705,19 +17213,19 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200002ed, 0 , 0, 0x0 }, /* _POOL32A5~*(93) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200002f5, &NMD::SHRA_R_W , 0, + 0xfc0003ff, 0x200002f5, &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, + 0xfc0003ff, 0x20000305, &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, + 0xfc0003ff, 0x20000315, &SHRLV_PH , 0, DSP_ }, /* SHRLV.PH */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000031d, 0 , 0, @@ -17735,13 +17243,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000033d, 0 , 0, 0x0 }, /* _POOL32A5~*(103) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000345, &NMD::SUBQ_S_W , 0, + 0xfc0003ff, 0x20000345, &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, + 0xfc0003ff, 0x20000355, &SHRLV_QB , 0, DSP_ }, /* SHRLV.QB */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000035d, 0 , 0, @@ -17759,13 +17267,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x2000037d, 0 , 0, 0x0 }, /* _POOL32A5~*(111) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x20000385, &NMD::ADDSC , 0, + 0xfc0003ff, 0x20000385, &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, + 0xfc0003ff, 0x20000395, &SHLLV_QB , 0, DSP_ }, /* SHLLV.QB */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x2000039d, 0 , 0, @@ -17783,13 +17291,13 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200003bd, 0 , 0, 0x0 }, /* _POOL32A5~*(119) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200003c5, &NMD::ADDWC , 0, + 0xfc0003ff, 0x200003c5, &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, + 0xfc0003ff, 0x200003d5, &SHLLV_S_W , 0, DSP_ }, /* SHLLV_S.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200003dd, 0 , 0, @@ -17801,7 +17309,7 @@ NMD::Pool NMD::_POOL32A5[128] = { 0xfc0003ff, 0x200003ed, 0 , 0, 0x0 }, /* _POOL32A5~*(125) */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0x200003f5, &NMD::SHLL_S_W , 0, + 0xfc0003ff, 0x200003f5, &SHLL_S_W , 0, DSP_ }, /* SHLL_S.W */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0x200003fd, 0 , 0, @@ -17809,59 +17317,59 @@ NMD::Pool NMD::_POOL32A5[128] = { }; -NMD::Pool NMD::PP_LSX[16] = { +static const Pool PP_LSX[16] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000007, &NMD::LBX , 0, + 0xfc0007ff, 0x20000007, &LBX , 0, 0x0 }, /* LBX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000087, &NMD::SBX , 0, + 0xfc0007ff, 0x20000087, &SBX , 0, XMMS_ }, /* SBX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000107, &NMD::LBUX , 0, + 0xfc0007ff, 0x20000107, &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, + 0xfc0007ff, 0x20000207, &LHX , 0, 0x0 }, /* LHX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000287, &NMD::SHX , 0, + 0xfc0007ff, 0x20000287, &SHX , 0, XMMS_ }, /* SHX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000307, &NMD::LHUX , 0, + 0xfc0007ff, 0x20000307, &LHUX , 0, 0x0 }, /* LHUX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000387, &NMD::LWUX , 0, + 0xfc0007ff, 0x20000387, &LWUX , 0, MIPS64_ }, /* LWUX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000407, &NMD::LWX , 0, + 0xfc0007ff, 0x20000407, &LWX , 0, 0x0 }, /* LWX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000487, &NMD::SWX , 0, + 0xfc0007ff, 0x20000487, &SWX , 0, XMMS_ }, /* SWX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000507, &NMD::LWC1X , 0, + 0xfc0007ff, 0x20000507, &LWC1X , 0, CP1_ }, /* LWC1X */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000587, &NMD::SWC1X , 0, + 0xfc0007ff, 0x20000587, &SWC1X , 0, CP1_ }, /* SWC1X */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000607, &NMD::LDX , 0, + 0xfc0007ff, 0x20000607, &LDX , 0, MIPS64_ }, /* LDX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000687, &NMD::SDX , 0, + 0xfc0007ff, 0x20000687, &SDX , 0, MIPS64_ }, /* SDX */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000707, &NMD::LDC1X , 0, + 0xfc0007ff, 0x20000707, &LDC1X , 0, CP1_ }, /* LDC1X */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000787, &NMD::SDC1X , 0, + 0xfc0007ff, 0x20000787, &SDC1X , 0, CP1_ }, /* SDC1X */ }; -NMD::Pool NMD::PP_LSXS[16] = { +static const Pool PP_LSXS[16] = { { reserved_block , 0 , 0 , 32, 0xfc0007ff, 0x20000047, 0 , 0, 0x0 }, /* PP.LSXS~*(0) */ @@ -17875,45 +17383,45 @@ NMD::Pool NMD::PP_LSXS[16] = { 0xfc0007ff, 0x200001c7, 0 , 0, 0x0 }, /* PP.LSXS~*(3) */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000247, &NMD::LHXS , 0, + 0xfc0007ff, 0x20000247, &LHXS , 0, 0x0 }, /* LHXS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200002c7, &NMD::SHXS , 0, + 0xfc0007ff, 0x200002c7, &SHXS , 0, XMMS_ }, /* SHXS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000347, &NMD::LHUXS , 0, + 0xfc0007ff, 0x20000347, &LHUXS , 0, 0x0 }, /* LHUXS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200003c7, &NMD::LWUXS , 0, + 0xfc0007ff, 0x200003c7, &LWUXS , 0, MIPS64_ }, /* LWUXS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000447, &NMD::LWXS_32_ , 0, + 0xfc0007ff, 0x20000447, &LWXS_32_ , 0, 0x0 }, /* LWXS[32] */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200004c7, &NMD::SWXS , 0, + 0xfc0007ff, 0x200004c7, &SWXS , 0, XMMS_ }, /* SWXS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000547, &NMD::LWC1XS , 0, + 0xfc0007ff, 0x20000547, &LWC1XS , 0, CP1_ }, /* LWC1XS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200005c7, &NMD::SWC1XS , 0, + 0xfc0007ff, 0x200005c7, &SWC1XS , 0, CP1_ }, /* SWC1XS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000647, &NMD::LDXS , 0, + 0xfc0007ff, 0x20000647, &LDXS , 0, MIPS64_ }, /* LDXS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200006c7, &NMD::SDXS , 0, + 0xfc0007ff, 0x200006c7, &SDXS , 0, MIPS64_ }, /* SDXS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x20000747, &NMD::LDC1XS , 0, + 0xfc0007ff, 0x20000747, &LDC1XS , 0, CP1_ }, /* LDC1XS */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0x200007c7, &NMD::SDC1XS , 0, + 0xfc0007ff, 0x200007c7, &SDC1XS , 0, CP1_ }, /* SDC1XS */ }; -NMD::Pool NMD::P_LSX[2] = { +static const Pool P_LSX[2] = { { pool , PP_LSX , 16 , 32, 0xfc00007f, 0x20000007, 0 , 0, 0x0 }, /* PP.LSX */ @@ -17923,28 +17431,28 @@ NMD::Pool NMD::P_LSX[2] = { }; -NMD::Pool NMD::POOL32Axf_1_0[4] = { +static const Pool POOL32Axf_1_0[4] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000007f, &NMD::MFHI_DSP_ , 0, + 0xfc003fff, 0x2000007f, &MFHI_DSP_ , 0, DSP_ }, /* MFHI[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000107f, &NMD::MFLO_DSP_ , 0, + 0xfc003fff, 0x2000107f, &MFLO_DSP_ , 0, DSP_ }, /* MFLO[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000207f, &NMD::MTHI_DSP_ , 0, + 0xfc003fff, 0x2000207f, &MTHI_DSP_ , 0, DSP_ }, /* MTHI[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000307f, &NMD::MTLO_DSP_ , 0, + 0xfc003fff, 0x2000307f, &MTLO_DSP_ , 0, DSP_ }, /* MTLO[DSP] */ }; -NMD::Pool NMD::POOL32Axf_1_1[4] = { +static const Pool POOL32Axf_1_1[4] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000027f, &NMD::MTHLIP , 0, + 0xfc003fff, 0x2000027f, &MTHLIP , 0, DSP_ }, /* MTHLIP */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000127f, &NMD::SHILOV , 0, + 0xfc003fff, 0x2000127f, &SHILOV , 0, DSP_ }, /* SHILOV */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0x2000227f, 0 , 0, @@ -17955,53 +17463,53 @@ NMD::Pool NMD::POOL32Axf_1_1[4] = { }; -NMD::Pool NMD::POOL32Axf_1_3[4] = { +static const Pool POOL32Axf_1_3[4] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000067f, &NMD::RDDSP , 0, + 0xfc003fff, 0x2000067f, &RDDSP , 0, DSP_ }, /* RDDSP */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000167f, &NMD::WRDSP , 0, + 0xfc003fff, 0x2000167f, &WRDSP , 0, DSP_ }, /* WRDSP */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000267f, &NMD::EXTP , 0, + 0xfc003fff, 0x2000267f, &EXTP , 0, DSP_ }, /* EXTP */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x2000367f, &NMD::EXTPDP , 0, + 0xfc003fff, 0x2000367f, &EXTPDP , 0, DSP_ }, /* EXTPDP */ }; -NMD::Pool NMD::POOL32Axf_1_4[2] = { +static const Pool POOL32Axf_1_4[2] = { { instruction , 0 , 0 , 32, - 0xfc001fff, 0x2000087f, &NMD::SHLL_QB , 0, + 0xfc001fff, 0x2000087f, &SHLL_QB , 0, DSP_ }, /* SHLL.QB */ { instruction , 0 , 0 , 32, - 0xfc001fff, 0x2000187f, &NMD::SHRL_QB , 0, + 0xfc001fff, 0x2000187f, &SHRL_QB , 0, DSP_ }, /* SHRL.QB */ }; -NMD::Pool NMD::MAQ_S_A__W_PHR[2] = { +static const Pool MAQ_S_A__W_PHR[2] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20000a7f, &NMD::MAQ_S_W_PHR , 0, + 0xfc003fff, 0x20000a7f, &MAQ_S_W_PHR , 0, DSP_ }, /* MAQ_S.W.PHR */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20002a7f, &NMD::MAQ_SA_W_PHR , 0, + 0xfc003fff, 0x20002a7f, &MAQ_SA_W_PHR , 0, DSP_ }, /* MAQ_SA.W.PHR */ }; -NMD::Pool NMD::MAQ_S_A__W_PHL[2] = { +static const Pool MAQ_S_A__W_PHL[2] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20001a7f, &NMD::MAQ_S_W_PHL , 0, + 0xfc003fff, 0x20001a7f, &MAQ_S_W_PHL , 0, DSP_ }, /* MAQ_S.W.PHL */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20003a7f, &NMD::MAQ_SA_W_PHL , 0, + 0xfc003fff, 0x20003a7f, &MAQ_SA_W_PHL , 0, DSP_ }, /* MAQ_SA.W.PHL */ }; -NMD::Pool NMD::POOL32Axf_1_5[2] = { +static const Pool POOL32Axf_1_5[2] = { { pool , MAQ_S_A__W_PHR , 2 , 32, 0xfc001fff, 0x20000a7f, 0 , 0, 0x0 }, /* MAQ_S[A].W.PHR */ @@ -18011,23 +17519,23 @@ NMD::Pool NMD::POOL32Axf_1_5[2] = { }; -NMD::Pool NMD::POOL32Axf_1_7[4] = { +static const Pool POOL32Axf_1_7[4] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20000e7f, &NMD::EXTR_W , 0, + 0xfc003fff, 0x20000e7f, &EXTR_W , 0, DSP_ }, /* EXTR.W */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20001e7f, &NMD::EXTR_R_W , 0, + 0xfc003fff, 0x20001e7f, &EXTR_R_W , 0, DSP_ }, /* EXTR_R.W */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20002e7f, &NMD::EXTR_RS_W , 0, + 0xfc003fff, 0x20002e7f, &EXTR_RS_W , 0, DSP_ }, /* EXTR_RS.W */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20003e7f, &NMD::EXTR_S_H , 0, + 0xfc003fff, 0x20003e7f, &EXTR_S_H , 0, DSP_ }, /* EXTR_S.H */ }; -NMD::Pool NMD::POOL32Axf_1[8] = { +static const Pool POOL32Axf_1[8] = { { pool , POOL32Axf_1_0 , 4 , 32, 0xfc000fff, 0x2000007f, 0 , 0, 0x0 }, /* POOL32Axf_1_0 */ @@ -18055,119 +17563,119 @@ NMD::Pool NMD::POOL32Axf_1[8] = { }; -NMD::Pool NMD::POOL32Axf_2_DSP__0_7[8] = { +static const Pool POOL32Axf_2_DSP__0_7[8] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200000bf, &NMD::DPA_W_PH , 0, + 0xfc003fff, 0x200000bf, &DPA_W_PH , 0, DSP_ }, /* DPA.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200002bf, &NMD::DPAQ_S_W_PH , 0, + 0xfc003fff, 0x200002bf, &DPAQ_S_W_PH , 0, DSP_ }, /* DPAQ_S.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200004bf, &NMD::DPS_W_PH , 0, + 0xfc003fff, 0x200004bf, &DPS_W_PH , 0, DSP_ }, /* DPS.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200006bf, &NMD::DPSQ_S_W_PH , 0, + 0xfc003fff, 0x200006bf, &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, + 0xfc003fff, 0x20000abf, &MADD_DSP_ , 0, DSP_ }, /* MADD[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20000cbf, &NMD::MULT_DSP_ , 0, + 0xfc003fff, 0x20000cbf, &MULT_DSP_ , 0, DSP_ }, /* MULT[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20000ebf, &NMD::EXTRV_W , 0, + 0xfc003fff, 0x20000ebf, &EXTRV_W , 0, DSP_ }, /* EXTRV.W */ }; -NMD::Pool NMD::POOL32Axf_2_DSP__8_15[8] = { +static const Pool POOL32Axf_2_DSP__8_15[8] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200010bf, &NMD::DPAX_W_PH , 0, + 0xfc003fff, 0x200010bf, &DPAX_W_PH , 0, DSP_ }, /* DPAX.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200012bf, &NMD::DPAQ_SA_L_W , 0, + 0xfc003fff, 0x200012bf, &DPAQ_SA_L_W , 0, DSP_ }, /* DPAQ_SA.L.W */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200014bf, &NMD::DPSX_W_PH , 0, + 0xfc003fff, 0x200014bf, &DPSX_W_PH , 0, DSP_ }, /* DPSX.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200016bf, &NMD::DPSQ_SA_L_W , 0, + 0xfc003fff, 0x200016bf, &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, + 0xfc003fff, 0x20001abf, &MADDU_DSP_ , 0, DSP_ }, /* MADDU[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20001cbf, &NMD::MULTU_DSP_ , 0, + 0xfc003fff, 0x20001cbf, &MULTU_DSP_ , 0, DSP_ }, /* MULTU[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20001ebf, &NMD::EXTRV_R_W , 0, + 0xfc003fff, 0x20001ebf, &EXTRV_R_W , 0, DSP_ }, /* EXTRV_R.W */ }; -NMD::Pool NMD::POOL32Axf_2_DSP__16_23[8] = { +static const Pool POOL32Axf_2_DSP__16_23[8] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200020bf, &NMD::DPAU_H_QBL , 0, + 0xfc003fff, 0x200020bf, &DPAU_H_QBL , 0, DSP_ }, /* DPAU.H.QBL */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200022bf, &NMD::DPAQX_S_W_PH , 0, + 0xfc003fff, 0x200022bf, &DPAQX_S_W_PH , 0, DSP_ }, /* DPAQX_S.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200024bf, &NMD::DPSU_H_QBL , 0, + 0xfc003fff, 0x200024bf, &DPSU_H_QBL , 0, DSP_ }, /* DPSU.H.QBL */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200026bf, &NMD::DPSQX_S_W_PH , 0, + 0xfc003fff, 0x200026bf, &DPSQX_S_W_PH , 0, DSP_ }, /* DPSQX_S.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200028bf, &NMD::EXTPV , 0, + 0xfc003fff, 0x200028bf, &EXTPV , 0, DSP_ }, /* EXTPV */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20002abf, &NMD::MSUB_DSP_ , 0, + 0xfc003fff, 0x20002abf, &MSUB_DSP_ , 0, DSP_ }, /* MSUB[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20002cbf, &NMD::MULSA_W_PH , 0, + 0xfc003fff, 0x20002cbf, &MULSA_W_PH , 0, DSP_ }, /* MULSA.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20002ebf, &NMD::EXTRV_RS_W , 0, + 0xfc003fff, 0x20002ebf, &EXTRV_RS_W , 0, DSP_ }, /* EXTRV_RS.W */ }; -NMD::Pool NMD::POOL32Axf_2_DSP__24_31[8] = { +static const Pool POOL32Axf_2_DSP__24_31[8] = { { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200030bf, &NMD::DPAU_H_QBR , 0, + 0xfc003fff, 0x200030bf, &DPAU_H_QBR , 0, DSP_ }, /* DPAU.H.QBR */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200032bf, &NMD::DPAQX_SA_W_PH , 0, + 0xfc003fff, 0x200032bf, &DPAQX_SA_W_PH , 0, DSP_ }, /* DPAQX_SA.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200034bf, &NMD::DPSU_H_QBR , 0, + 0xfc003fff, 0x200034bf, &DPSU_H_QBR , 0, DSP_ }, /* DPSU.H.QBR */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200036bf, &NMD::DPSQX_SA_W_PH , 0, + 0xfc003fff, 0x200036bf, &DPSQX_SA_W_PH , 0, DSP_ }, /* DPSQX_SA.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x200038bf, &NMD::EXTPDPV , 0, + 0xfc003fff, 0x200038bf, &EXTPDPV , 0, DSP_ }, /* EXTPDPV */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20003abf, &NMD::MSUBU_DSP_ , 0, + 0xfc003fff, 0x20003abf, &MSUBU_DSP_ , 0, DSP_ }, /* MSUBU[DSP] */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20003cbf, &NMD::MULSAQ_S_W_PH , 0, + 0xfc003fff, 0x20003cbf, &MULSAQ_S_W_PH , 0, DSP_ }, /* MULSAQ_S.W.PH */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0x20003ebf, &NMD::EXTRV_S_H , 0, + 0xfc003fff, 0x20003ebf, &EXTRV_S_H , 0, DSP_ }, /* EXTRV_S.H */ }; -NMD::Pool NMD::POOL32Axf_2[4] = { +static const Pool POOL32Axf_2[4] = { { pool , POOL32Axf_2_DSP__0_7, 8 , 32, 0xfc0031ff, 0x200000bf, 0 , 0, 0x0 }, /* POOL32Axf_2(DSP)_0_7 */ @@ -18183,12 +17691,12 @@ NMD::Pool NMD::POOL32Axf_2[4] = { }; -NMD::Pool NMD::POOL32Axf_4[128] = { +static const Pool POOL32Axf_4[128] = { { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000013f, &NMD::ABSQ_S_QB , 0, + 0xfc00ffff, 0x2000013f, &ABSQ_S_QB , 0, DSP_ }, /* ABSQ_S.QB */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000033f, &NMD::REPLV_PH , 0, + 0xfc00ffff, 0x2000033f, &REPLV_PH , 0, DSP_ }, /* REPLV.PH */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000053f, 0 , 0, @@ -18209,10 +17717,10 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x20000f3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(7) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000113f, &NMD::ABSQ_S_PH , 0, + 0xfc00ffff, 0x2000113f, &ABSQ_S_PH , 0, DSP_ }, /* ABSQ_S.PH */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000133f, &NMD::REPLV_QB , 0, + 0xfc00ffff, 0x2000133f, &REPLV_QB , 0, DSP_ }, /* REPLV.QB */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000153f, 0 , 0, @@ -18233,7 +17741,7 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x20001f3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(15) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000213f, &NMD::ABSQ_S_W , 0, + 0xfc00ffff, 0x2000213f, &ABSQ_S_W , 0, DSP_ }, /* ABSQ_S.W */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000233f, 0 , 0, @@ -18281,7 +17789,7 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x20003f3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(31) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000413f, &NMD::INSV , 0, + 0xfc00ffff, 0x2000413f, &INSV , 0, DSP_ }, /* INSV */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000433f, 0 , 0, @@ -18296,16 +17804,16 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x2000493f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(36) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20004b3f, &NMD::CLO , 0, + 0xfc00ffff, 0x20004b3f, &CLO , 0, XMMS_ }, /* CLO */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20004d3f, &NMD::MFC2 , 0, + 0xfc00ffff, 0x20004d3f, &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, + 0xfc00ffff, 0x2000513f, &PRECEQ_W_PHL , 0, DSP_ }, /* PRECEQ.W.PHL */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000533f, 0 , 0, @@ -18320,16 +17828,16 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x2000593f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(44) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20005b3f, &NMD::CLZ , 0, + 0xfc00ffff, 0x20005b3f, &CLZ , 0, XMMS_ }, /* CLZ */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20005d3f, &NMD::MTC2 , 0, + 0xfc00ffff, 0x20005d3f, &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, + 0xfc00ffff, 0x2000613f, &PRECEQ_W_PHR , 0, DSP_ }, /* PRECEQ.W.PHR */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000633f, 0 , 0, @@ -18347,16 +17855,16 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x20006b3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(53) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20006d3f, &NMD::DMFC2 , 0, + 0xfc00ffff, 0x20006d3f, &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, + 0xfc00ffff, 0x2000713f, &PRECEQU_PH_QBL , 0, DSP_ }, /* PRECEQU.PH.QBL */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000733f, &NMD::PRECEQU_PH_QBLA , 0, + 0xfc00ffff, 0x2000733f, &PRECEQU_PH_QBLA , 0, DSP_ }, /* PRECEQU.PH.QBLA */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000753f, 0 , 0, @@ -18371,7 +17879,7 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x20007b3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(61) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20007d3f, &NMD::DMTC2 , 0, + 0xfc00ffff, 0x20007d3f, &DMTC2 , 0, CP2_ }, /* DMTC2 */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x20007f3f, 0 , 0, @@ -18395,16 +17903,16 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x20008b3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(69) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20008d3f, &NMD::MFHC2 , 0, + 0xfc00ffff, 0x20008d3f, &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, + 0xfc00ffff, 0x2000913f, &PRECEQU_PH_QBR , 0, DSP_ }, /* PRECEQU.PH.QBR */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000933f, &NMD::PRECEQU_PH_QBRA , 0, + 0xfc00ffff, 0x2000933f, &PRECEQU_PH_QBRA , 0, DSP_ }, /* PRECEQU.PH.QBRA */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000953f, 0 , 0, @@ -18419,7 +17927,7 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x20009b3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(77) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x20009d3f, &NMD::MTHC2 , 0, + 0xfc00ffff, 0x20009d3f, &MTHC2 , 0, CP2_ }, /* MTHC2 */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x20009f3f, 0 , 0, @@ -18449,10 +17957,10 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x2000af3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(87) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000b13f, &NMD::PRECEU_PH_QBL , 0, + 0xfc00ffff, 0x2000b13f, &PRECEU_PH_QBL , 0, DSP_ }, /* PRECEU.PH.QBL */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000b33f, &NMD::PRECEU_PH_QBLA , 0, + 0xfc00ffff, 0x2000b33f, &PRECEU_PH_QBLA , 0, DSP_ }, /* PRECEU.PH.QBLA */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000b53f, 0 , 0, @@ -18491,16 +17999,16 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x2000cb3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(101) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000cd3f, &NMD::CFC2 , 0, + 0xfc00ffff, 0x2000cd3f, &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, + 0xfc00ffff, 0x2000d13f, &PRECEU_PH_QBR , 0, DSP_ }, /* PRECEU.PH.QBR */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000d33f, &NMD::PRECEU_PH_QBRA , 0, + 0xfc00ffff, 0x2000d33f, &PRECEU_PH_QBRA , 0, DSP_ }, /* PRECEU.PH.QBRA */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000d53f, 0 , 0, @@ -18515,7 +18023,7 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x2000db3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(109) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000dd3f, &NMD::CTC2 , 0, + 0xfc00ffff, 0x2000dd3f, &CTC2 , 0, CP2_ }, /* CTC2 */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000df3f, 0 , 0, @@ -18545,7 +18053,7 @@ NMD::Pool NMD::POOL32Axf_4[128] = { 0xfc00ffff, 0x2000ef3f, 0 , 0, 0x0 }, /* POOL32Axf_4~*(119) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000f13f, &NMD::RADDU_W_QB , 0, + 0xfc00ffff, 0x2000f13f, &RADDU_W_QB , 0, DSP_ }, /* RADDU.W.QB */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000f33f, 0 , 0, @@ -18571,18 +18079,18 @@ NMD::Pool NMD::POOL32Axf_4[128] = { }; -NMD::Pool NMD::POOL32Axf_5_group0[32] = { +static const Pool POOL32Axf_5_group0[32] = { { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000017f, &NMD::TLBGP , 0, + 0xfc00ffff, 0x2000017f, &TLBGP , 0, CP0_ | VZ_ | TLB_ }, /* TLBGP */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000037f, &NMD::TLBP , 0, + 0xfc00ffff, 0x2000037f, &TLBP , 0, CP0_ | TLB_ }, /* TLBP */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000057f, &NMD::TLBGINV , 0, + 0xfc00ffff, 0x2000057f, &TLBGINV , 0, CP0_ | VZ_ | TLB_ | TLBINV_}, /* TLBGINV */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000077f, &NMD::TLBINV , 0, + 0xfc00ffff, 0x2000077f, &TLBINV , 0, CP0_ | TLB_ | TLBINV_}, /* TLBINV */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000097f, 0 , 0, @@ -18597,16 +18105,16 @@ NMD::Pool NMD::POOL32Axf_5_group0[32] = { 0xfc00ffff, 0x20000f7f, 0 , 0, 0x0 }, /* POOL32Axf_5_group0~*(7) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000117f, &NMD::TLBGR , 0, + 0xfc00ffff, 0x2000117f, &TLBGR , 0, CP0_ | VZ_ | TLB_ }, /* TLBGR */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000137f, &NMD::TLBR , 0, + 0xfc00ffff, 0x2000137f, &TLBR , 0, CP0_ | TLB_ }, /* TLBR */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000157f, &NMD::TLBGINVF , 0, + 0xfc00ffff, 0x2000157f, &TLBGINVF , 0, CP0_ | VZ_ | TLB_ | TLBINV_}, /* TLBGINVF */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000177f, &NMD::TLBINVF , 0, + 0xfc00ffff, 0x2000177f, &TLBINVF , 0, CP0_ | TLB_ | TLBINV_}, /* TLBINVF */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000197f, 0 , 0, @@ -18621,10 +18129,10 @@ NMD::Pool NMD::POOL32Axf_5_group0[32] = { 0xfc00ffff, 0x20001f7f, 0 , 0, 0x0 }, /* POOL32Axf_5_group0~*(15) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000217f, &NMD::TLBGWI , 0, + 0xfc00ffff, 0x2000217f, &TLBGWI , 0, CP0_ | VZ_ | TLB_ }, /* TLBGWI */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000237f, &NMD::TLBWI , 0, + 0xfc00ffff, 0x2000237f, &TLBWI , 0, CP0_ | TLB_ }, /* TLBWI */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000257f, 0 , 0, @@ -18645,10 +18153,10 @@ NMD::Pool NMD::POOL32Axf_5_group0[32] = { 0xfc00ffff, 0x20002f7f, 0 , 0, 0x0 }, /* POOL32Axf_5_group0~*(23) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000317f, &NMD::TLBGWR , 0, + 0xfc00ffff, 0x2000317f, &TLBGWR , 0, CP0_ | VZ_ | TLB_ }, /* TLBGWR */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000337f, &NMD::TLBWR , 0, + 0xfc00ffff, 0x2000337f, &TLBWR , 0, CP0_ | TLB_ }, /* TLBWR */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000357f, 0 , 0, @@ -18671,7 +18179,7 @@ NMD::Pool NMD::POOL32Axf_5_group0[32] = { }; -NMD::Pool NMD::POOL32Axf_5_group1[32] = { +static const Pool POOL32Axf_5_group1[32] = { { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000417f, 0 , 0, 0x0 }, /* POOL32Axf_5_group1~*(0) */ @@ -18682,7 +18190,7 @@ NMD::Pool NMD::POOL32Axf_5_group1[32] = { 0xfc00ffff, 0x2000457f, 0 , 0, 0x0 }, /* POOL32Axf_5_group1~*(2) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000477f, &NMD::DI , 0, + 0xfc00ffff, 0x2000477f, &DI , 0, 0x0 }, /* DI */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000497f, 0 , 0, @@ -18706,7 +18214,7 @@ NMD::Pool NMD::POOL32Axf_5_group1[32] = { 0xfc00ffff, 0x2000557f, 0 , 0, 0x0 }, /* POOL32Axf_5_group1~*(10) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000577f, &NMD::EI , 0, + 0xfc00ffff, 0x2000577f, &EI , 0, 0x0 }, /* EI */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000597f, 0 , 0, @@ -18771,22 +18279,22 @@ NMD::Pool NMD::POOL32Axf_5_group1[32] = { }; -NMD::Pool NMD::ERETx[2] = { +static const Pool ERETx[2] = { { instruction , 0 , 0 , 32, - 0xfc01ffff, 0x2000f37f, &NMD::ERET , 0, + 0xfc01ffff, 0x2000f37f, &ERET , 0, 0x0 }, /* ERET */ { instruction , 0 , 0 , 32, - 0xfc01ffff, 0x2001f37f, &NMD::ERETNC , 0, + 0xfc01ffff, 0x2001f37f, &ERETNC , 0, 0x0 }, /* ERETNC */ }; -NMD::Pool NMD::POOL32Axf_5_group3[32] = { +static const Pool 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, + 0xfc00ffff, 0x2000c37f, &WAIT , 0, 0x0 }, /* WAIT */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000c57f, 0 , 0, @@ -18810,7 +18318,7 @@ NMD::Pool NMD::POOL32Axf_5_group3[32] = { 0xfc00ffff, 0x2000d17f, 0 , 0, 0x0 }, /* POOL32Axf_5_group3~*(8) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000d37f, &NMD::IRET , 0, + 0xfc00ffff, 0x2000d37f, &IRET , 0, MCU_ }, /* IRET */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000d57f, 0 , 0, @@ -18831,10 +18339,10 @@ NMD::Pool NMD::POOL32Axf_5_group3[32] = { 0xfc00ffff, 0x2000df7f, 0 , 0, 0x0 }, /* POOL32Axf_5_group3~*(15) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000e17f, &NMD::RDPGPR , 0, + 0xfc00ffff, 0x2000e17f, &RDPGPR , 0, CP0_ }, /* RDPGPR */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000e37f, &NMD::DERET , 0, + 0xfc00ffff, 0x2000e37f, &DERET , 0, EJTAG_ }, /* DERET */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0x2000e57f, 0 , 0, @@ -18855,7 +18363,7 @@ NMD::Pool NMD::POOL32Axf_5_group3[32] = { 0xfc00ffff, 0x2000ef7f, 0 , 0, 0x0 }, /* POOL32Axf_5_group3~*(23) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0x2000f17f, &NMD::WRPGPR , 0, + 0xfc00ffff, 0x2000f17f, &WRPGPR , 0, CP0_ }, /* WRPGPR */ { pool , ERETx , 2 , 32, 0xfc00ffff, 0x2000f37f, 0 , 0, @@ -18881,7 +18389,7 @@ NMD::Pool NMD::POOL32Axf_5_group3[32] = { }; -NMD::Pool NMD::POOL32Axf_5[4] = { +static const Pool POOL32Axf_5[4] = { { pool , POOL32Axf_5_group0 , 32 , 32, 0xfc00c1ff, 0x2000017f, 0 , 0, 0x0 }, /* POOL32Axf_5_group0 */ @@ -18897,25 +18405,25 @@ NMD::Pool NMD::POOL32Axf_5[4] = { }; -NMD::Pool NMD::SHRA__R__QB[2] = { +static const Pool SHRA__R__QB[2] = { { instruction , 0 , 0 , 32, - 0xfc001fff, 0x200001ff, &NMD::SHRA_QB , 0, + 0xfc001fff, 0x200001ff, &SHRA_QB , 0, DSP_ }, /* SHRA.QB */ { instruction , 0 , 0 , 32, - 0xfc001fff, 0x200011ff, &NMD::SHRA_R_QB , 0, + 0xfc001fff, 0x200011ff, &SHRA_R_QB , 0, DSP_ }, /* SHRA_R.QB */ }; -NMD::Pool NMD::POOL32Axf_7[8] = { +static const Pool 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, + 0xfc000fff, 0x200003ff, &SHRL_PH , 0, DSP_ }, /* SHRL.PH */ { instruction , 0 , 0 , 32, - 0xfc000fff, 0x200005ff, &NMD::REPL_QB , 0, + 0xfc000fff, 0x200005ff, &REPL_QB , 0, DSP_ }, /* REPL.QB */ { reserved_block , 0 , 0 , 32, 0xfc000fff, 0x200007ff, 0 , 0, @@ -18935,7 +18443,7 @@ NMD::Pool NMD::POOL32Axf_7[8] = { }; -NMD::Pool NMD::POOL32Axf[8] = { +static const Pool POOL32Axf[8] = { { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0x2000003f, 0 , 0, 0x0 }, /* POOL32Axf~*(0) */ @@ -18963,18 +18471,18 @@ NMD::Pool NMD::POOL32Axf[8] = { }; -NMD::Pool NMD::_POOL32A7[8] = { +static const Pool _POOL32A7[8] = { { pool , P_LSX , 2 , 32, 0xfc00003f, 0x20000007, 0 , 0, 0x0 }, /* P.LSX */ { instruction , 0 , 0 , 32, - 0xfc00003f, 0x2000000f, &NMD::LSA , 0, + 0xfc00003f, 0x2000000f, &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, + 0xfc00003f, 0x2000001f, &EXTW , 0, 0x0 }, /* EXTW */ { reserved_block , 0 , 0 , 32, 0xfc00003f, 0x20000027, 0 , 0, @@ -18991,18 +18499,18 @@ NMD::Pool NMD::_POOL32A7[8] = { }; -NMD::Pool NMD::P32A[8] = { +static const Pool P32A[8] = { { pool , _POOL32A0 , 128 , 32, 0xfc000007, 0x20000000, 0 , 0, 0x0 }, /* _POOL32A0 */ { instruction , 0 , 0 , 32, - 0xfc000007, 0x20000001, &NMD::SPECIAL2 , 0, + 0xfc000007, 0x20000001, &SPECIAL2 , 0, UDI_ }, /* SPECIAL2 */ { instruction , 0 , 0 , 32, - 0xfc000007, 0x20000002, &NMD::COP2_1 , 0, + 0xfc000007, 0x20000002, &COP2_1 , 0, CP2_ }, /* COP2_1 */ { instruction , 0 , 0 , 32, - 0xfc000007, 0x20000003, &NMD::UDI , 0, + 0xfc000007, 0x20000003, &UDI , 0, UDI_ }, /* UDI */ { reserved_block , 0 , 0 , 32, 0xfc000007, 0x20000004, 0 , 0, @@ -19019,44 +18527,44 @@ NMD::Pool NMD::P32A[8] = { }; -NMD::Pool NMD::P_GP_D[2] = { +static const Pool P_GP_D[2] = { { instruction , 0 , 0 , 32, - 0xfc000007, 0x40000001, &NMD::LD_GP_ , 0, + 0xfc000007, 0x40000001, &LD_GP_ , 0, MIPS64_ }, /* LD[GP] */ { instruction , 0 , 0 , 32, - 0xfc000007, 0x40000005, &NMD::SD_GP_ , 0, + 0xfc000007, 0x40000005, &SD_GP_ , 0, MIPS64_ }, /* SD[GP] */ }; -NMD::Pool NMD::P_GP_W[4] = { +static const Pool P_GP_W[4] = { { instruction , 0 , 0 , 32, - 0xfc000003, 0x40000000, &NMD::ADDIU_GP_W_ , 0, + 0xfc000003, 0x40000000, &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, + 0xfc000003, 0x40000002, &LW_GP_ , 0, 0x0 }, /* LW[GP] */ { instruction , 0 , 0 , 32, - 0xfc000003, 0x40000003, &NMD::SW_GP_ , 0, + 0xfc000003, 0x40000003, &SW_GP_ , 0, 0x0 }, /* SW[GP] */ }; -NMD::Pool NMD::POOL48I[32] = { +static const Pool POOL48I[32] = { { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x600000000000ull, &NMD::LI_48_ , 0, + 0xfc1f00000000ull, 0x600000000000ull, &LI_48_ , 0, XMMS_ }, /* LI[48] */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x600100000000ull, &NMD::ADDIU_48_ , 0, + 0xfc1f00000000ull, 0x600100000000ull, &ADDIU_48_ , 0, XMMS_ }, /* ADDIU[48] */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x600200000000ull, &NMD::ADDIU_GP48_ , 0, + 0xfc1f00000000ull, 0x600200000000ull, &ADDIU_GP48_ , 0, XMMS_ }, /* ADDIU[GP48] */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x600300000000ull, &NMD::ADDIUPC_48_ , 0, + 0xfc1f00000000ull, 0x600300000000ull, &ADDIUPC_48_ , 0, XMMS_ }, /* ADDIUPC[48] */ { reserved_block , 0 , 0 , 48, 0xfc1f00000000ull, 0x600400000000ull, 0 , 0, @@ -19080,7 +18588,7 @@ NMD::Pool NMD::POOL48I[32] = { 0xfc1f00000000ull, 0x600a00000000ull, 0 , 0, 0x0 }, /* POOL48I~*(10) */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x600b00000000ull, &NMD::LWPC_48_ , 0, + 0xfc1f00000000ull, 0x600b00000000ull, &LWPC_48_ , 0, XMMS_ }, /* LWPC[48] */ { reserved_block , 0 , 0 , 48, 0xfc1f00000000ull, 0x600c00000000ull, 0 , 0, @@ -19092,13 +18600,13 @@ NMD::Pool NMD::POOL48I[32] = { 0xfc1f00000000ull, 0x600e00000000ull, 0 , 0, 0x0 }, /* POOL48I~*(14) */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x600f00000000ull, &NMD::SWPC_48_ , 0, + 0xfc1f00000000ull, 0x600f00000000ull, &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, + 0xfc1f00000000ull, 0x601100000000ull, &DADDIU_48_ , 0, MIPS64_ }, /* DADDIU[48] */ { reserved_block , 0 , 0 , 48, 0xfc1f00000000ull, 0x601200000000ull, 0 , 0, @@ -19107,7 +18615,7 @@ NMD::Pool NMD::POOL48I[32] = { 0xfc1f00000000ull, 0x601300000000ull, 0 , 0, 0x0 }, /* POOL48I~*(19) */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x601400000000ull, &NMD::DLUI_48_ , 0, + 0xfc1f00000000ull, 0x601400000000ull, &DLUI_48_ , 0, MIPS64_ }, /* DLUI[48] */ { reserved_block , 0 , 0 , 48, 0xfc1f00000000ull, 0x601500000000ull, 0 , 0, @@ -19128,7 +18636,7 @@ NMD::Pool NMD::POOL48I[32] = { 0xfc1f00000000ull, 0x601a00000000ull, 0 , 0, 0x0 }, /* POOL48I~*(26) */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x601b00000000ull, &NMD::LDPC_48_ , 0, + 0xfc1f00000000ull, 0x601b00000000ull, &LDPC_48_ , 0, MIPS64_ }, /* LDPC[48] */ { reserved_block , 0 , 0 , 48, 0xfc1f00000000ull, 0x601c00000000ull, 0 , 0, @@ -19140,33 +18648,33 @@ NMD::Pool NMD::POOL48I[32] = { 0xfc1f00000000ull, 0x601e00000000ull, 0 , 0, 0x0 }, /* POOL48I~*(30) */ { instruction , 0 , 0 , 48, - 0xfc1f00000000ull, 0x601f00000000ull, &NMD::SDPC_48_ , 0, + 0xfc1f00000000ull, 0x601f00000000ull, &SDPC_48_ , 0, MIPS64_ }, /* SDPC[48] */ }; -NMD::Pool NMD::PP_SR[4] = { +static const Pool PP_SR[4] = { { instruction , 0 , 0 , 32, - 0xfc10f003, 0x80003000, &NMD::SAVE_32_ , 0, + 0xfc10f003, 0x80003000, &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, + 0xfc10f003, 0x80003002, &RESTORE_32_ , 0, 0x0 }, /* RESTORE[32] */ { return_instruction , 0 , 0 , 32, - 0xfc10f003, 0x80003003, &NMD::RESTORE_JRC_32_ , 0, + 0xfc10f003, 0x80003003, &RESTORE_JRC_32_ , 0, 0x0 }, /* RESTORE.JRC[32] */ }; -NMD::Pool NMD::P_SR_F[8] = { +static const Pool P_SR_F[8] = { { instruction , 0 , 0 , 32, - 0xfc10f007, 0x80103000, &NMD::SAVEF , 0, + 0xfc10f007, 0x80103000, &SAVEF , 0, CP1_ }, /* SAVEF */ { instruction , 0 , 0 , 32, - 0xfc10f007, 0x80103001, &NMD::RESTOREF , 0, + 0xfc10f007, 0x80103001, &RESTOREF , 0, CP1_ }, /* RESTOREF */ { reserved_block , 0 , 0 , 32, 0xfc10f007, 0x80103002, 0 , 0, @@ -19189,7 +18697,7 @@ NMD::Pool NMD::P_SR_F[8] = { }; -NMD::Pool NMD::P_SR[2] = { +static const Pool P_SR[2] = { { pool , PP_SR , 4 , 32, 0xfc10f000, 0x80003000, 0 , 0, 0x0 }, /* PP.SR */ @@ -19199,26 +18707,26 @@ NMD::Pool NMD::P_SR[2] = { }; -NMD::Pool NMD::P_SLL[5] = { +static const Pool P_SLL[5] = { { instruction , 0 , 0 , 32, - 0xffe0f1ff, 0x8000c000, &NMD::NOP_32_ , 0, + 0xffe0f1ff, 0x8000c000, &NOP_32_ , 0, 0x0 }, /* NOP[32] */ { instruction , 0 , 0 , 32, - 0xffe0f1ff, 0x8000c003, &NMD::EHB , 0, + 0xffe0f1ff, 0x8000c003, &EHB , 0, 0x0 }, /* EHB */ { instruction , 0 , 0 , 32, - 0xffe0f1ff, 0x8000c005, &NMD::PAUSE , 0, + 0xffe0f1ff, 0x8000c005, &PAUSE , 0, 0x0 }, /* PAUSE */ { instruction , 0 , 0 , 32, - 0xffe0f1ff, 0x8000c006, &NMD::SYNC , 0, + 0xffe0f1ff, 0x8000c006, &SYNC , 0, 0x0 }, /* SYNC */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c000, &NMD::SLL_32_ , 0, + 0xfc00f1e0, 0x8000c000, &SLL_32_ , 0, 0x0 }, /* SLL[32] */ }; -NMD::Pool NMD::P_SHIFT[16] = { +static const Pool P_SHIFT[16] = { { pool , P_SLL , 5 , 32, 0xfc00f1e0, 0x8000c000, 0 , 0, 0x0 }, /* P.SLL */ @@ -19226,53 +18734,53 @@ NMD::Pool NMD::P_SHIFT[16] = { 0xfc00f1e0, 0x8000c020, 0 , 0, 0x0 }, /* P.SHIFT~*(1) */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c040, &NMD::SRL_32_ , 0, + 0xfc00f1e0, 0x8000c040, &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, + 0xfc00f1e0, 0x8000c080, &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, + 0xfc00f1e0, 0x8000c0c0, &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, + 0xfc00f1e0, 0x8000c100, &DSLL , 0, MIPS64_ }, /* DSLL */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c120, &NMD::DSLL32 , 0, + 0xfc00f1e0, 0x8000c120, &DSLL32 , 0, MIPS64_ }, /* DSLL32 */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c140, &NMD::DSRL , 0, + 0xfc00f1e0, 0x8000c140, &DSRL , 0, MIPS64_ }, /* DSRL */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c160, &NMD::DSRL32 , 0, + 0xfc00f1e0, 0x8000c160, &DSRL32 , 0, MIPS64_ }, /* DSRL32 */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c180, &NMD::DSRA , 0, + 0xfc00f1e0, 0x8000c180, &DSRA , 0, MIPS64_ }, /* DSRA */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c1a0, &NMD::DSRA32 , 0, + 0xfc00f1e0, 0x8000c1a0, &DSRA32 , 0, MIPS64_ }, /* DSRA32 */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c1c0, &NMD::DROTR , 0, + 0xfc00f1e0, 0x8000c1c0, &DROTR , 0, MIPS64_ }, /* DROTR */ { instruction , 0 , 0 , 32, - 0xfc00f1e0, 0x8000c1e0, &NMD::DROTR32 , 0, + 0xfc00f1e0, 0x8000c1e0, &DROTR32 , 0, MIPS64_ }, /* DROTR32 */ }; -NMD::Pool NMD::P_ROTX[4] = { +static const Pool P_ROTX[4] = { { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000d000, &NMD::ROTX , 0, + 0xfc00f820, 0x8000d000, &ROTX , 0, XMMS_ }, /* ROTX */ { reserved_block , 0 , 0 , 32, 0xfc00f820, 0x8000d020, 0 , 0, @@ -19286,74 +18794,74 @@ NMD::Pool NMD::P_ROTX[4] = { }; -NMD::Pool NMD::P_INS[4] = { +static const Pool P_INS[4] = { { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000e000, &NMD::INS , 0, + 0xfc00f820, 0x8000e000, &INS , 0, XMMS_ }, /* INS */ { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000e020, &NMD::DINSU , 0, + 0xfc00f820, 0x8000e020, &DINSU , 0, MIPS64_ }, /* DINSU */ { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000e800, &NMD::DINSM , 0, + 0xfc00f820, 0x8000e800, &DINSM , 0, MIPS64_ }, /* DINSM */ { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000e820, &NMD::DINS , 0, + 0xfc00f820, 0x8000e820, &DINS , 0, MIPS64_ }, /* DINS */ }; -NMD::Pool NMD::P_EXT[4] = { +static const Pool P_EXT[4] = { { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000f000, &NMD::EXT , 0, + 0xfc00f820, 0x8000f000, &EXT , 0, XMMS_ }, /* EXT */ { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000f020, &NMD::DEXTU , 0, + 0xfc00f820, 0x8000f020, &DEXTU , 0, MIPS64_ }, /* DEXTU */ { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000f800, &NMD::DEXTM , 0, + 0xfc00f820, 0x8000f800, &DEXTM , 0, MIPS64_ }, /* DEXTM */ { instruction , 0 , 0 , 32, - 0xfc00f820, 0x8000f820, &NMD::DEXT , 0, + 0xfc00f820, 0x8000f820, &DEXT , 0, MIPS64_ }, /* DEXT */ }; -NMD::Pool NMD::P_U12[16] = { +static const Pool P_U12[16] = { { instruction , 0 , 0 , 32, - 0xfc00f000, 0x80000000, &NMD::ORI , 0, + 0xfc00f000, 0x80000000, &ORI , 0, 0x0 }, /* ORI */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x80001000, &NMD::XORI , 0, + 0xfc00f000, 0x80001000, &XORI , 0, 0x0 }, /* XORI */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x80002000, &NMD::ANDI_32_ , 0, + 0xfc00f000, 0x80002000, &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, + 0xfc00f000, 0x80004000, &SLTI , 0, 0x0 }, /* SLTI */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x80005000, &NMD::SLTIU , 0, + 0xfc00f000, 0x80005000, &SLTIU , 0, 0x0 }, /* SLTIU */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x80006000, &NMD::SEQI , 0, + 0xfc00f000, 0x80006000, &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, + 0xfc00f000, 0x80008000, &ADDIU_NEG_ , 0, 0x0 }, /* ADDIU[NEG] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x80009000, &NMD::DADDIU_U12_ , 0, + 0xfc00f000, 0x80009000, &DADDIU_U12_ , 0, MIPS64_ }, /* DADDIU[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8000a000, &NMD::DADDIU_NEG_ , 0, + 0xfc00f000, 0x8000a000, &DADDIU_NEG_ , 0, MIPS64_ }, /* DADDIU[NEG] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8000b000, &NMD::DROTX , 0, + 0xfc00f000, 0x8000b000, &DROTX , 0, MIPS64_ }, /* DROTX */ { pool , P_SHIFT , 16 , 32, 0xfc00f000, 0x8000c000, 0 , 0, @@ -19370,19 +18878,19 @@ NMD::Pool NMD::P_U12[16] = { }; -NMD::Pool NMD::RINT_fmt[2] = { +static const Pool RINT_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000020, &NMD::RINT_S , 0, + 0xfc0003ff, 0xa0000020, &RINT_S , 0, CP1_ }, /* RINT.S */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000220, &NMD::RINT_D , 0, + 0xfc0003ff, 0xa0000220, &RINT_D , 0, CP1_ }, /* RINT.D */ }; -NMD::Pool NMD::ADD_fmt0[2] = { +static const Pool ADD_fmt0[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000030, &NMD::ADD_S , 0, + 0xfc0003ff, 0xa0000030, &ADD_S , 0, CP1_ }, /* ADD.S */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa0000230, 0 , 0, @@ -19390,29 +18898,29 @@ NMD::Pool NMD::ADD_fmt0[2] = { }; -NMD::Pool NMD::SELEQZ_fmt[2] = { +static const Pool SELEQZ_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000038, &NMD::SELEQZ_S , 0, + 0xfc0003ff, 0xa0000038, &SELEQZ_S , 0, CP1_ }, /* SELEQZ.S */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000238, &NMD::SELEQZ_D , 0, + 0xfc0003ff, 0xa0000238, &SELEQZ_D , 0, CP1_ }, /* SELEQZ.D */ }; -NMD::Pool NMD::CLASS_fmt[2] = { +static const Pool CLASS_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000060, &NMD::CLASS_S , 0, + 0xfc0003ff, 0xa0000060, &CLASS_S , 0, CP1_ }, /* CLASS.S */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000260, &NMD::CLASS_D , 0, + 0xfc0003ff, 0xa0000260, &CLASS_D , 0, CP1_ }, /* CLASS.D */ }; -NMD::Pool NMD::SUB_fmt0[2] = { +static const Pool SUB_fmt0[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000070, &NMD::SUB_S , 0, + 0xfc0003ff, 0xa0000070, &SUB_S , 0, CP1_ }, /* SUB.S */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa0000270, 0 , 0, @@ -19420,19 +18928,19 @@ NMD::Pool NMD::SUB_fmt0[2] = { }; -NMD::Pool NMD::SELNEZ_fmt[2] = { +static const Pool SELNEZ_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000078, &NMD::SELNEZ_S , 0, + 0xfc0003ff, 0xa0000078, &SELNEZ_S , 0, CP1_ }, /* SELNEZ.S */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000278, &NMD::SELNEZ_D , 0, + 0xfc0003ff, 0xa0000278, &SELNEZ_D , 0, CP1_ }, /* SELNEZ.D */ }; -NMD::Pool NMD::MUL_fmt0[2] = { +static const Pool MUL_fmt0[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00000b0, &NMD::MUL_S , 0, + 0xfc0003ff, 0xa00000b0, &MUL_S , 0, CP1_ }, /* MUL.S */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa00002b0, 0 , 0, @@ -19440,19 +18948,19 @@ NMD::Pool NMD::MUL_fmt0[2] = { }; -NMD::Pool NMD::SEL_fmt[2] = { +static const Pool SEL_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00000b8, &NMD::SEL_S , 0, + 0xfc0003ff, 0xa00000b8, &SEL_S , 0, CP1_ }, /* SEL.S */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00002b8, &NMD::SEL_D , 0, + 0xfc0003ff, 0xa00002b8, &SEL_D , 0, CP1_ }, /* SEL.D */ }; -NMD::Pool NMD::DIV_fmt0[2] = { +static const Pool DIV_fmt0[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00000f0, &NMD::DIV_S , 0, + 0xfc0003ff, 0xa00000f0, &DIV_S , 0, CP1_ }, /* DIV.S */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa00002f0, 0 , 0, @@ -19460,9 +18968,9 @@ NMD::Pool NMD::DIV_fmt0[2] = { }; -NMD::Pool NMD::ADD_fmt1[2] = { +static const Pool ADD_fmt1[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000130, &NMD::ADD_D , 0, + 0xfc0003ff, 0xa0000130, &ADD_D , 0, CP1_ }, /* ADD.D */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa0000330, 0 , 0, @@ -19470,9 +18978,9 @@ NMD::Pool NMD::ADD_fmt1[2] = { }; -NMD::Pool NMD::SUB_fmt1[2] = { +static const Pool SUB_fmt1[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa0000170, &NMD::SUB_D , 0, + 0xfc0003ff, 0xa0000170, &SUB_D , 0, CP1_ }, /* SUB.D */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa0000370, 0 , 0, @@ -19480,9 +18988,9 @@ NMD::Pool NMD::SUB_fmt1[2] = { }; -NMD::Pool NMD::MUL_fmt1[2] = { +static const Pool MUL_fmt1[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00001b0, &NMD::MUL_D , 0, + 0xfc0003ff, 0xa00001b0, &MUL_D , 0, CP1_ }, /* MUL.D */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa00003b0, 0 , 0, @@ -19490,19 +18998,19 @@ NMD::Pool NMD::MUL_fmt1[2] = { }; -NMD::Pool NMD::MADDF_fmt[2] = { +static const Pool MADDF_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00001b8, &NMD::MADDF_S , 0, + 0xfc0003ff, 0xa00001b8, &MADDF_S , 0, CP1_ }, /* MADDF.S */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00003b8, &NMD::MADDF_D , 0, + 0xfc0003ff, 0xa00003b8, &MADDF_D , 0, CP1_ }, /* MADDF.D */ }; -NMD::Pool NMD::DIV_fmt1[2] = { +static const Pool DIV_fmt1[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00001f0, &NMD::DIV_D , 0, + 0xfc0003ff, 0xa00001f0, &DIV_D , 0, CP1_ }, /* DIV.D */ { reserved_block , 0 , 0 , 32, 0xfc0003ff, 0xa00003f0, 0 , 0, @@ -19510,17 +19018,17 @@ NMD::Pool NMD::DIV_fmt1[2] = { }; -NMD::Pool NMD::MSUBF_fmt[2] = { +static const Pool MSUBF_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00001f8, &NMD::MSUBF_S , 0, + 0xfc0003ff, 0xa00001f8, &MSUBF_S , 0, CP1_ }, /* MSUBF.S */ { instruction , 0 , 0 , 32, - 0xfc0003ff, 0xa00003f8, &NMD::MSUBF_D , 0, + 0xfc0003ff, 0xa00003f8, &MSUBF_D , 0, CP1_ }, /* MSUBF.D */ }; -NMD::Pool NMD::POOL32F_0[64] = { +static const Pool POOL32F_0[64] = { { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xa0000000, 0 , 0, CP1_ }, /* POOL32F_0~*(0) */ @@ -19716,177 +19224,177 @@ NMD::Pool NMD::POOL32F_0[64] = { }; -NMD::Pool NMD::MIN_fmt[2] = { +static const Pool MIN_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa0000003, &NMD::MIN_S , 0, + 0xfc00023f, 0xa0000003, &MIN_S , 0, CP1_ }, /* MIN.S */ { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa0000203, &NMD::MIN_D , 0, + 0xfc00023f, 0xa0000203, &MIN_D , 0, CP1_ }, /* MIN.D */ }; -NMD::Pool NMD::MAX_fmt[2] = { +static const Pool MAX_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa000000b, &NMD::MAX_S , 0, + 0xfc00023f, 0xa000000b, &MAX_S , 0, CP1_ }, /* MAX.S */ { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa000020b, &NMD::MAX_D , 0, + 0xfc00023f, 0xa000020b, &MAX_D , 0, CP1_ }, /* MAX.D */ }; -NMD::Pool NMD::MINA_fmt[2] = { +static const Pool MINA_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa0000023, &NMD::MINA_S , 0, + 0xfc00023f, 0xa0000023, &MINA_S , 0, CP1_ }, /* MINA.S */ { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa0000223, &NMD::MINA_D , 0, + 0xfc00023f, 0xa0000223, &MINA_D , 0, CP1_ }, /* MINA.D */ }; -NMD::Pool NMD::MAXA_fmt[2] = { +static const Pool MAXA_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa000002b, &NMD::MAXA_S , 0, + 0xfc00023f, 0xa000002b, &MAXA_S , 0, CP1_ }, /* MAXA.S */ { instruction , 0 , 0 , 32, - 0xfc00023f, 0xa000022b, &NMD::MAXA_D , 0, + 0xfc00023f, 0xa000022b, &MAXA_D , 0, CP1_ }, /* MAXA.D */ }; -NMD::Pool NMD::CVT_L_fmt[2] = { +static const Pool CVT_L_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000013b, &NMD::CVT_L_S , 0, + 0xfc007fff, 0xa000013b, &CVT_L_S , 0, CP1_ }, /* CVT.L.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000413b, &NMD::CVT_L_D , 0, + 0xfc007fff, 0xa000413b, &CVT_L_D , 0, CP1_ }, /* CVT.L.D */ }; -NMD::Pool NMD::RSQRT_fmt[2] = { +static const Pool RSQRT_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000023b, &NMD::RSQRT_S , 0, + 0xfc007fff, 0xa000023b, &RSQRT_S , 0, CP1_ }, /* RSQRT.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000423b, &NMD::RSQRT_D , 0, + 0xfc007fff, 0xa000423b, &RSQRT_D , 0, CP1_ }, /* RSQRT.D */ }; -NMD::Pool NMD::FLOOR_L_fmt[2] = { +static const Pool FLOOR_L_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000033b, &NMD::FLOOR_L_S , 0, + 0xfc007fff, 0xa000033b, &FLOOR_L_S , 0, CP1_ }, /* FLOOR.L.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000433b, &NMD::FLOOR_L_D , 0, + 0xfc007fff, 0xa000433b, &FLOOR_L_D , 0, CP1_ }, /* FLOOR.L.D */ }; -NMD::Pool NMD::CVT_W_fmt[2] = { +static const Pool CVT_W_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000093b, &NMD::CVT_W_S , 0, + 0xfc007fff, 0xa000093b, &CVT_W_S , 0, CP1_ }, /* CVT.W.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000493b, &NMD::CVT_W_D , 0, + 0xfc007fff, 0xa000493b, &CVT_W_D , 0, CP1_ }, /* CVT.W.D */ }; -NMD::Pool NMD::SQRT_fmt[2] = { +static const Pool SQRT_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0000a3b, &NMD::SQRT_S , 0, + 0xfc007fff, 0xa0000a3b, &SQRT_S , 0, CP1_ }, /* SQRT.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0004a3b, &NMD::SQRT_D , 0, + 0xfc007fff, 0xa0004a3b, &SQRT_D , 0, CP1_ }, /* SQRT.D */ }; -NMD::Pool NMD::FLOOR_W_fmt[2] = { +static const Pool FLOOR_W_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0000b3b, &NMD::FLOOR_W_S , 0, + 0xfc007fff, 0xa0000b3b, &FLOOR_W_S , 0, CP1_ }, /* FLOOR.W.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0004b3b, &NMD::FLOOR_W_D , 0, + 0xfc007fff, 0xa0004b3b, &FLOOR_W_D , 0, CP1_ }, /* FLOOR.W.D */ }; -NMD::Pool NMD::RECIP_fmt[2] = { +static const Pool RECIP_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000123b, &NMD::RECIP_S , 0, + 0xfc007fff, 0xa000123b, &RECIP_S , 0, CP1_ }, /* RECIP.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000523b, &NMD::RECIP_D , 0, + 0xfc007fff, 0xa000523b, &RECIP_D , 0, CP1_ }, /* RECIP.D */ }; -NMD::Pool NMD::CEIL_L_fmt[2] = { +static const Pool CEIL_L_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000133b, &NMD::CEIL_L_S , 0, + 0xfc007fff, 0xa000133b, &CEIL_L_S , 0, CP1_ }, /* CEIL.L.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000533b, &NMD::CEIL_L_D , 0, + 0xfc007fff, 0xa000533b, &CEIL_L_D , 0, CP1_ }, /* CEIL.L.D */ }; -NMD::Pool NMD::CEIL_W_fmt[2] = { +static const Pool CEIL_W_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0001b3b, &NMD::CEIL_W_S , 0, + 0xfc007fff, 0xa0001b3b, &CEIL_W_S , 0, CP1_ }, /* CEIL.W.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0005b3b, &NMD::CEIL_W_D , 0, + 0xfc007fff, 0xa0005b3b, &CEIL_W_D , 0, CP1_ }, /* CEIL.W.D */ }; -NMD::Pool NMD::TRUNC_L_fmt[2] = { +static const Pool TRUNC_L_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000233b, &NMD::TRUNC_L_S , 0, + 0xfc007fff, 0xa000233b, &TRUNC_L_S , 0, CP1_ }, /* TRUNC.L.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000633b, &NMD::TRUNC_L_D , 0, + 0xfc007fff, 0xa000633b, &TRUNC_L_D , 0, CP1_ }, /* TRUNC.L.D */ }; -NMD::Pool NMD::TRUNC_W_fmt[2] = { +static const Pool TRUNC_W_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0002b3b, &NMD::TRUNC_W_S , 0, + 0xfc007fff, 0xa0002b3b, &TRUNC_W_S , 0, CP1_ }, /* TRUNC.W.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0006b3b, &NMD::TRUNC_W_D , 0, + 0xfc007fff, 0xa0006b3b, &TRUNC_W_D , 0, CP1_ }, /* TRUNC.W.D */ }; -NMD::Pool NMD::ROUND_L_fmt[2] = { +static const Pool ROUND_L_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000333b, &NMD::ROUND_L_S , 0, + 0xfc007fff, 0xa000333b, &ROUND_L_S , 0, CP1_ }, /* ROUND.L.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000733b, &NMD::ROUND_L_D , 0, + 0xfc007fff, 0xa000733b, &ROUND_L_D , 0, CP1_ }, /* ROUND.L.D */ }; -NMD::Pool NMD::ROUND_W_fmt[2] = { +static const Pool ROUND_W_fmt[2] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0003b3b, &NMD::ROUND_W_S , 0, + 0xfc007fff, 0xa0003b3b, &ROUND_W_S , 0, CP1_ }, /* ROUND.W.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0007b3b, &NMD::ROUND_W_D , 0, + 0xfc007fff, 0xa0007b3b, &ROUND_W_D , 0, CP1_ }, /* ROUND.W.D */ }; -NMD::Pool NMD::POOL32Fxf_0[64] = { +static const Pool POOL32Fxf_0[64] = { { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa000003b, 0 , 0, CP1_ }, /* POOL32Fxf_0~*(0) */ @@ -19936,7 +19444,7 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa0000f3b, 0 , 0, CP1_ }, /* POOL32Fxf_0~*(15) */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000103b, &NMD::CFC1 , 0, + 0xfc003fff, 0xa000103b, &CFC1 , 0, CP1_ }, /* CFC1 */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa000113b, 0 , 0, @@ -19960,7 +19468,7 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa000173b, 0 , 0, CP1_ }, /* POOL32Fxf_0~*(23) */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000183b, &NMD::CTC1 , 0, + 0xfc003fff, 0xa000183b, &CTC1 , 0, CP1_ }, /* CTC1 */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa000193b, 0 , 0, @@ -19984,10 +19492,10 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa0001f3b, 0 , 0, CP1_ }, /* POOL32Fxf_0~*(31) */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000203b, &NMD::MFC1 , 0, + 0xfc003fff, 0xa000203b, &MFC1 , 0, CP1_ }, /* MFC1 */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000213b, &NMD::CVT_S_PL , 0, + 0xfc003fff, 0xa000213b, &CVT_S_PL , 0, CP1_ }, /* CVT.S.PL */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa000223b, 0 , 0, @@ -19996,7 +19504,7 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa000233b, 0 , 0, CP1_ }, /* TRUNC.L.fmt */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000243b, &NMD::DMFC1 , 0, + 0xfc003fff, 0xa000243b, &DMFC1 , 0, CP1_ | MIPS64_ }, /* DMFC1 */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa000253b, 0 , 0, @@ -20008,10 +19516,10 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa000273b, 0 , 0, CP1_ }, /* POOL32Fxf_0~*(39) */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000283b, &NMD::MTC1 , 0, + 0xfc003fff, 0xa000283b, &MTC1 , 0, CP1_ }, /* MTC1 */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000293b, &NMD::CVT_S_PU , 0, + 0xfc003fff, 0xa000293b, &CVT_S_PU , 0, CP1_ }, /* CVT.S.PU */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa0002a3b, 0 , 0, @@ -20020,7 +19528,7 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa0002b3b, 0 , 0, CP1_ }, /* TRUNC.W.fmt */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa0002c3b, &NMD::DMTC1 , 0, + 0xfc003fff, 0xa0002c3b, &DMTC1 , 0, CP1_ | MIPS64_ }, /* DMTC1 */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa0002d3b, 0 , 0, @@ -20032,7 +19540,7 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa0002f3b, 0 , 0, CP1_ }, /* POOL32Fxf_0~*(47) */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000303b, &NMD::MFHC1 , 0, + 0xfc003fff, 0xa000303b, &MFHC1 , 0, CP1_ }, /* MFHC1 */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa000313b, 0 , 0, @@ -20056,7 +19564,7 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { 0xfc003fff, 0xa000373b, 0 , 0, CP1_ }, /* POOL32Fxf_0~*(55) */ { instruction , 0 , 0 , 32, - 0xfc003fff, 0xa000383b, &NMD::MTHC1 , 0, + 0xfc003fff, 0xa000383b, &MTHC1 , 0, CP1_ }, /* MTHC1 */ { reserved_block , 0 , 0 , 32, 0xfc003fff, 0xa000393b, 0 , 0, @@ -20082,12 +19590,12 @@ NMD::Pool NMD::POOL32Fxf_0[64] = { }; -NMD::Pool NMD::MOV_fmt[4] = { +static const Pool MOV_fmt[4] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000007b, &NMD::MOV_S , 0, + 0xfc007fff, 0xa000007b, &MOV_S , 0, CP1_ }, /* MOV.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000207b, &NMD::MOV_D , 0, + 0xfc007fff, 0xa000207b, &MOV_D , 0, CP1_ }, /* MOV.D */ { reserved_block , 0 , 0 , 32, 0xfc007fff, 0xa000407b, 0 , 0, @@ -20098,12 +19606,12 @@ NMD::Pool NMD::MOV_fmt[4] = { }; -NMD::Pool NMD::ABS_fmt[4] = { +static const Pool ABS_fmt[4] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000037b, &NMD::ABS_S , 0, + 0xfc007fff, 0xa000037b, &ABS_S , 0, CP1_ }, /* ABS.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000237b, &NMD::ABS_D , 0, + 0xfc007fff, 0xa000237b, &ABS_D , 0, CP1_ }, /* ABS.D */ { reserved_block , 0 , 0 , 32, 0xfc007fff, 0xa000437b, 0 , 0, @@ -20114,12 +19622,12 @@ NMD::Pool NMD::ABS_fmt[4] = { }; -NMD::Pool NMD::NEG_fmt[4] = { +static const Pool NEG_fmt[4] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0000b7b, &NMD::NEG_S , 0, + 0xfc007fff, 0xa0000b7b, &NEG_S , 0, CP1_ }, /* NEG.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0002b7b, &NMD::NEG_D , 0, + 0xfc007fff, 0xa0002b7b, &NEG_D , 0, CP1_ }, /* NEG.D */ { reserved_block , 0 , 0 , 32, 0xfc007fff, 0xa0004b7b, 0 , 0, @@ -20130,15 +19638,15 @@ NMD::Pool NMD::NEG_fmt[4] = { }; -NMD::Pool NMD::CVT_D_fmt[4] = { +static const Pool CVT_D_fmt[4] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000137b, &NMD::CVT_D_S , 0, + 0xfc007fff, 0xa000137b, &CVT_D_S , 0, CP1_ }, /* CVT.D.S */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000337b, &NMD::CVT_D_W , 0, + 0xfc007fff, 0xa000337b, &CVT_D_W , 0, CP1_ }, /* CVT.D.W */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa000537b, &NMD::CVT_D_L , 0, + 0xfc007fff, 0xa000537b, &CVT_D_L , 0, CP1_ }, /* CVT.D.L */ { reserved_block , 0 , 0 , 32, 0xfc007fff, 0xa000737b, 0 , 0, @@ -20146,15 +19654,15 @@ NMD::Pool NMD::CVT_D_fmt[4] = { }; -NMD::Pool NMD::CVT_S_fmt[4] = { +static const Pool CVT_S_fmt[4] = { { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0001b7b, &NMD::CVT_S_D , 0, + 0xfc007fff, 0xa0001b7b, &CVT_S_D , 0, CP1_ }, /* CVT.S.D */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0003b7b, &NMD::CVT_S_W , 0, + 0xfc007fff, 0xa0003b7b, &CVT_S_W , 0, CP1_ }, /* CVT.S.W */ { instruction , 0 , 0 , 32, - 0xfc007fff, 0xa0005b7b, &NMD::CVT_S_L , 0, + 0xfc007fff, 0xa0005b7b, &CVT_S_L , 0, CP1_ }, /* CVT.S.L */ { reserved_block , 0 , 0 , 32, 0xfc007fff, 0xa0007b7b, 0 , 0, @@ -20162,7 +19670,7 @@ NMD::Pool NMD::CVT_S_fmt[4] = { }; -NMD::Pool NMD::POOL32Fxf_1[32] = { +static const Pool POOL32Fxf_1[32] = { { pool , MOV_fmt , 4 , 32, 0xfc001fff, 0xa000007b, 0 , 0, CP1_ }, /* MOV.fmt */ @@ -20262,7 +19770,7 @@ NMD::Pool NMD::POOL32Fxf_1[32] = { }; -NMD::Pool NMD::POOL32Fxf[4] = { +static const Pool POOL32Fxf[4] = { { pool , POOL32Fxf_0 , 64 , 32, 0xfc0000ff, 0xa000003b, 0 , 0, CP1_ }, /* POOL32Fxf_0 */ @@ -20278,7 +19786,7 @@ NMD::Pool NMD::POOL32Fxf[4] = { }; -NMD::Pool NMD::POOL32F_3[8] = { +static const Pool POOL32F_3[8] = { { pool , MIN_fmt , 2 , 32, 0xfc00003f, 0xa0000003, 0 , 0, CP1_ }, /* MIN.fmt */ @@ -20306,66 +19814,66 @@ NMD::Pool NMD::POOL32F_3[8] = { }; -NMD::Pool NMD::CMP_condn_S[32] = { +static const Pool CMP_condn_S[32] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000005, &NMD::CMP_AF_S , 0, + 0xfc0007ff, 0xa0000005, &CMP_AF_S , 0, CP1_ }, /* CMP.AF.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000045, &NMD::CMP_UN_S , 0, + 0xfc0007ff, 0xa0000045, &CMP_UN_S , 0, CP1_ }, /* CMP.UN.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000085, &NMD::CMP_EQ_S , 0, + 0xfc0007ff, 0xa0000085, &CMP_EQ_S , 0, CP1_ }, /* CMP.EQ.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00000c5, &NMD::CMP_UEQ_S , 0, + 0xfc0007ff, 0xa00000c5, &CMP_UEQ_S , 0, CP1_ }, /* CMP.UEQ.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000105, &NMD::CMP_LT_S , 0, + 0xfc0007ff, 0xa0000105, &CMP_LT_S , 0, CP1_ }, /* CMP.LT.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000145, &NMD::CMP_ULT_S , 0, + 0xfc0007ff, 0xa0000145, &CMP_ULT_S , 0, CP1_ }, /* CMP.ULT.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000185, &NMD::CMP_LE_S , 0, + 0xfc0007ff, 0xa0000185, &CMP_LE_S , 0, CP1_ }, /* CMP.LE.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00001c5, &NMD::CMP_ULE_S , 0, + 0xfc0007ff, 0xa00001c5, &CMP_ULE_S , 0, CP1_ }, /* CMP.ULE.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000205, &NMD::CMP_SAF_S , 0, + 0xfc0007ff, 0xa0000205, &CMP_SAF_S , 0, CP1_ }, /* CMP.SAF.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000245, &NMD::CMP_SUN_S , 0, + 0xfc0007ff, 0xa0000245, &CMP_SUN_S , 0, CP1_ }, /* CMP.SUN.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000285, &NMD::CMP_SEQ_S , 0, + 0xfc0007ff, 0xa0000285, &CMP_SEQ_S , 0, CP1_ }, /* CMP.SEQ.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00002c5, &NMD::CMP_SUEQ_S , 0, + 0xfc0007ff, 0xa00002c5, &CMP_SUEQ_S , 0, CP1_ }, /* CMP.SUEQ.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000305, &NMD::CMP_SLT_S , 0, + 0xfc0007ff, 0xa0000305, &CMP_SLT_S , 0, CP1_ }, /* CMP.SLT.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000345, &NMD::CMP_SULT_S , 0, + 0xfc0007ff, 0xa0000345, &CMP_SULT_S , 0, CP1_ }, /* CMP.SULT.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000385, &NMD::CMP_SLE_S , 0, + 0xfc0007ff, 0xa0000385, &CMP_SLE_S , 0, CP1_ }, /* CMP.SLE.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00003c5, &NMD::CMP_SULE_S , 0, + 0xfc0007ff, 0xa00003c5, &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, + 0xfc0007ff, 0xa0000445, &CMP_OR_S , 0, CP1_ }, /* CMP.OR.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000485, &NMD::CMP_UNE_S , 0, + 0xfc0007ff, 0xa0000485, &CMP_UNE_S , 0, CP1_ }, /* CMP.UNE.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00004c5, &NMD::CMP_NE_S , 0, + 0xfc0007ff, 0xa00004c5, &CMP_NE_S , 0, CP1_ }, /* CMP.NE.S */ { reserved_block , 0 , 0 , 32, 0xfc0007ff, 0xa0000505, 0 , 0, @@ -20383,13 +19891,13 @@ NMD::Pool NMD::CMP_condn_S[32] = { 0xfc0007ff, 0xa0000605, 0 , 0, CP1_ }, /* CMP.condn.S~*(24) */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000645, &NMD::CMP_SOR_S , 0, + 0xfc0007ff, 0xa0000645, &CMP_SOR_S , 0, CP1_ }, /* CMP.SOR.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000685, &NMD::CMP_SUNE_S , 0, + 0xfc0007ff, 0xa0000685, &CMP_SUNE_S , 0, CP1_ }, /* CMP.SUNE.S */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00006c5, &NMD::CMP_SNE_S , 0, + 0xfc0007ff, 0xa00006c5, &CMP_SNE_S , 0, CP1_ }, /* CMP.SNE.S */ { reserved_block , 0 , 0 , 32, 0xfc0007ff, 0xa0000705, 0 , 0, @@ -20406,66 +19914,66 @@ NMD::Pool NMD::CMP_condn_S[32] = { }; -NMD::Pool NMD::CMP_condn_D[32] = { +static const Pool CMP_condn_D[32] = { { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000015, &NMD::CMP_AF_D , 0, + 0xfc0007ff, 0xa0000015, &CMP_AF_D , 0, CP1_ }, /* CMP.AF.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000055, &NMD::CMP_UN_D , 0, + 0xfc0007ff, 0xa0000055, &CMP_UN_D , 0, CP1_ }, /* CMP.UN.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000095, &NMD::CMP_EQ_D , 0, + 0xfc0007ff, 0xa0000095, &CMP_EQ_D , 0, CP1_ }, /* CMP.EQ.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00000d5, &NMD::CMP_UEQ_D , 0, + 0xfc0007ff, 0xa00000d5, &CMP_UEQ_D , 0, CP1_ }, /* CMP.UEQ.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000115, &NMD::CMP_LT_D , 0, + 0xfc0007ff, 0xa0000115, &CMP_LT_D , 0, CP1_ }, /* CMP.LT.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000155, &NMD::CMP_ULT_D , 0, + 0xfc0007ff, 0xa0000155, &CMP_ULT_D , 0, CP1_ }, /* CMP.ULT.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000195, &NMD::CMP_LE_D , 0, + 0xfc0007ff, 0xa0000195, &CMP_LE_D , 0, CP1_ }, /* CMP.LE.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00001d5, &NMD::CMP_ULE_D , 0, + 0xfc0007ff, 0xa00001d5, &CMP_ULE_D , 0, CP1_ }, /* CMP.ULE.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000215, &NMD::CMP_SAF_D , 0, + 0xfc0007ff, 0xa0000215, &CMP_SAF_D , 0, CP1_ }, /* CMP.SAF.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000255, &NMD::CMP_SUN_D , 0, + 0xfc0007ff, 0xa0000255, &CMP_SUN_D , 0, CP1_ }, /* CMP.SUN.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000295, &NMD::CMP_SEQ_D , 0, + 0xfc0007ff, 0xa0000295, &CMP_SEQ_D , 0, CP1_ }, /* CMP.SEQ.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00002d5, &NMD::CMP_SUEQ_D , 0, + 0xfc0007ff, 0xa00002d5, &CMP_SUEQ_D , 0, CP1_ }, /* CMP.SUEQ.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000315, &NMD::CMP_SLT_D , 0, + 0xfc0007ff, 0xa0000315, &CMP_SLT_D , 0, CP1_ }, /* CMP.SLT.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000355, &NMD::CMP_SULT_D , 0, + 0xfc0007ff, 0xa0000355, &CMP_SULT_D , 0, CP1_ }, /* CMP.SULT.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000395, &NMD::CMP_SLE_D , 0, + 0xfc0007ff, 0xa0000395, &CMP_SLE_D , 0, CP1_ }, /* CMP.SLE.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00003d5, &NMD::CMP_SULE_D , 0, + 0xfc0007ff, 0xa00003d5, &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, + 0xfc0007ff, 0xa0000455, &CMP_OR_D , 0, CP1_ }, /* CMP.OR.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000495, &NMD::CMP_UNE_D , 0, + 0xfc0007ff, 0xa0000495, &CMP_UNE_D , 0, CP1_ }, /* CMP.UNE.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00004d5, &NMD::CMP_NE_D , 0, + 0xfc0007ff, 0xa00004d5, &CMP_NE_D , 0, CP1_ }, /* CMP.NE.D */ { reserved_block , 0 , 0 , 32, 0xfc0007ff, 0xa0000515, 0 , 0, @@ -20483,13 +19991,13 @@ NMD::Pool NMD::CMP_condn_D[32] = { 0xfc0007ff, 0xa0000615, 0 , 0, CP1_ }, /* CMP.condn.D~*(24) */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000655, &NMD::CMP_SOR_D , 0, + 0xfc0007ff, 0xa0000655, &CMP_SOR_D , 0, CP1_ }, /* CMP.SOR.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa0000695, &NMD::CMP_SUNE_D , 0, + 0xfc0007ff, 0xa0000695, &CMP_SUNE_D , 0, CP1_ }, /* CMP.SUNE.D */ { instruction , 0 , 0 , 32, - 0xfc0007ff, 0xa00006d5, &NMD::CMP_SNE_D , 0, + 0xfc0007ff, 0xa00006d5, &CMP_SNE_D , 0, CP1_ }, /* CMP.SNE.D */ { reserved_block , 0 , 0 , 32, 0xfc0007ff, 0xa0000715, 0 , 0, @@ -20506,7 +20014,7 @@ NMD::Pool NMD::CMP_condn_D[32] = { }; -NMD::Pool NMD::POOL32F_5[8] = { +static const Pool POOL32F_5[8] = { { pool , CMP_condn_S , 32 , 32, 0xfc00003f, 0xa0000005, 0 , 0, CP1_ }, /* CMP.condn.S */ @@ -20534,7 +20042,7 @@ NMD::Pool NMD::POOL32F_5[8] = { }; -NMD::Pool NMD::POOL32F[8] = { +static const Pool POOL32F[8] = { { pool , POOL32F_0 , 64 , 32, 0xfc000007, 0xa0000000, 0 , 0, CP1_ }, /* POOL32F_0 */ @@ -20562,18 +20070,18 @@ NMD::Pool NMD::POOL32F[8] = { }; -NMD::Pool NMD::POOL32S_0[64] = { +static const Pool 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, + 0xfc0001ff, 0xc0000008, &DLSA , 0, MIPS64_ }, /* DLSA */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000010, &NMD::DSLLV , 0, + 0xfc0001ff, 0xc0000010, &DSLLV , 0, MIPS64_ }, /* DSLLV */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000018, &NMD::DMUL , 0, + 0xfc0001ff, 0xc0000018, &DMUL , 0, MIPS64_ }, /* DMUL */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc0000020, 0 , 0, @@ -20594,10 +20102,10 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc0000048, 0 , 0, 0x0 }, /* POOL32S_0~*(9) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000050, &NMD::DSRLV , 0, + 0xfc0001ff, 0xc0000050, &DSRLV , 0, MIPS64_ }, /* DSRLV */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000058, &NMD::DMUH , 0, + 0xfc0001ff, 0xc0000058, &DMUH , 0, MIPS64_ }, /* DMUH */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc0000060, 0 , 0, @@ -20618,10 +20126,10 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc0000088, 0 , 0, 0x0 }, /* POOL32S_0~*(17) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000090, &NMD::DSRAV , 0, + 0xfc0001ff, 0xc0000090, &DSRAV , 0, MIPS64_ }, /* DSRAV */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000098, &NMD::DMULU , 0, + 0xfc0001ff, 0xc0000098, &DMULU , 0, MIPS64_ }, /* DMULU */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc00000a0, 0 , 0, @@ -20642,10 +20150,10 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc00000c8, 0 , 0, 0x0 }, /* POOL32S_0~*(25) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc00000d0, &NMD::DROTRV , 0, + 0xfc0001ff, 0xc00000d0, &DROTRV , 0, MIPS64_ }, /* DROTRV */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc00000d8, &NMD::DMUHU , 0, + 0xfc0001ff, 0xc00000d8, &DMUHU , 0, MIPS64_ }, /* DMUHU */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc00000e0, 0 , 0, @@ -20666,10 +20174,10 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc0000108, 0 , 0, 0x0 }, /* POOL32S_0~*(33) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000110, &NMD::DADD , 0, + 0xfc0001ff, 0xc0000110, &DADD , 0, MIPS64_ }, /* DADD */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000118, &NMD::DDIV , 0, + 0xfc0001ff, 0xc0000118, &DDIV , 0, MIPS64_ }, /* DDIV */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc0000120, 0 , 0, @@ -20690,10 +20198,10 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc0000148, 0 , 0, 0x0 }, /* POOL32S_0~*(41) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000150, &NMD::DADDU , 0, + 0xfc0001ff, 0xc0000150, &DADDU , 0, MIPS64_ }, /* DADDU */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000158, &NMD::DMOD , 0, + 0xfc0001ff, 0xc0000158, &DMOD , 0, MIPS64_ }, /* DMOD */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc0000160, 0 , 0, @@ -20714,10 +20222,10 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc0000188, 0 , 0, 0x0 }, /* POOL32S_0~*(49) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000190, &NMD::DSUB , 0, + 0xfc0001ff, 0xc0000190, &DSUB , 0, MIPS64_ }, /* DSUB */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc0000198, &NMD::DDIVU , 0, + 0xfc0001ff, 0xc0000198, &DDIVU , 0, MIPS64_ }, /* DDIVU */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc00001a0, 0 , 0, @@ -20738,10 +20246,10 @@ NMD::Pool NMD::POOL32S_0[64] = { 0xfc0001ff, 0xc00001c8, 0 , 0, 0x0 }, /* POOL32S_0~*(57) */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc00001d0, &NMD::DSUBU , 0, + 0xfc0001ff, 0xc00001d0, &DSUBU , 0, MIPS64_ }, /* DSUBU */ { instruction , 0 , 0 , 32, - 0xfc0001ff, 0xc00001d8, &NMD::DMODU , 0, + 0xfc0001ff, 0xc00001d8, &DMODU , 0, MIPS64_ }, /* DMODU */ { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc00001e0, 0 , 0, @@ -20758,7 +20266,7 @@ NMD::Pool NMD::POOL32S_0[64] = { }; -NMD::Pool NMD::POOL32Sxf_4[128] = { +static const Pool POOL32Sxf_4[128] = { { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0xc000013c, 0 , 0, 0x0 }, /* POOL32Sxf_4~*(0) */ @@ -20871,7 +20379,7 @@ NMD::Pool NMD::POOL32Sxf_4[128] = { 0xfc00ffff, 0xc000493c, 0 , 0, 0x0 }, /* POOL32Sxf_4~*(36) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0xc0004b3c, &NMD::DCLO , 0, + 0xfc00ffff, 0xc0004b3c, &DCLO , 0, MIPS64_ }, /* DCLO */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0xc0004d3c, 0 , 0, @@ -20895,7 +20403,7 @@ NMD::Pool NMD::POOL32Sxf_4[128] = { 0xfc00ffff, 0xc000593c, 0 , 0, 0x0 }, /* POOL32Sxf_4~*(44) */ { instruction , 0 , 0 , 32, - 0xfc00ffff, 0xc0005b3c, &NMD::DCLZ , 0, + 0xfc00ffff, 0xc0005b3c, &DCLZ , 0, MIPS64_ }, /* DCLZ */ { reserved_block , 0 , 0 , 32, 0xfc00ffff, 0xc0005d3c, 0 , 0, @@ -21146,7 +20654,7 @@ NMD::Pool NMD::POOL32Sxf_4[128] = { }; -NMD::Pool NMD::POOL32Sxf[8] = { +static const Pool POOL32Sxf[8] = { { reserved_block , 0 , 0 , 32, 0xfc0001ff, 0xc000003c, 0 , 0, 0x0 }, /* POOL32Sxf~*(0) */ @@ -21174,12 +20682,12 @@ NMD::Pool NMD::POOL32Sxf[8] = { }; -NMD::Pool NMD::POOL32S_4[8] = { +static const Pool POOL32S_4[8] = { { instruction , 0 , 0 , 32, - 0xfc00003f, 0xc0000004, &NMD::EXTD , 0, + 0xfc00003f, 0xc0000004, &EXTD , 0, MIPS64_ }, /* EXTD */ { instruction , 0 , 0 , 32, - 0xfc00003f, 0xc000000c, &NMD::EXTD32 , 0, + 0xfc00003f, 0xc000000c, &EXTD32 , 0, MIPS64_ }, /* EXTD32 */ { reserved_block , 0 , 0 , 32, 0xfc00003f, 0xc0000014, 0 , 0, @@ -21202,7 +20710,7 @@ NMD::Pool NMD::POOL32S_4[8] = { }; -NMD::Pool NMD::POOL32S[8] = { +static const Pool POOL32S[8] = { { pool , POOL32S_0 , 64 , 32, 0xfc000007, 0xc0000000, 0 , 0, 0x0 }, /* POOL32S_0 */ @@ -21230,29 +20738,29 @@ NMD::Pool NMD::POOL32S[8] = { }; -NMD::Pool NMD::P_LUI[2] = { +static const Pool P_LUI[2] = { { instruction , 0 , 0 , 32, - 0xfc000002, 0xe0000000, &NMD::LUI , 0, + 0xfc000002, 0xe0000000, &LUI , 0, 0x0 }, /* LUI */ { instruction , 0 , 0 , 32, - 0xfc000002, 0xe0000002, &NMD::ALUIPC , 0, + 0xfc000002, 0xe0000002, &ALUIPC , 0, 0x0 }, /* ALUIPC */ }; -NMD::Pool NMD::P_GP_LH[2] = { +static const Pool P_GP_LH[2] = { { instruction , 0 , 0 , 32, - 0xfc1c0001, 0x44100000, &NMD::LH_GP_ , 0, + 0xfc1c0001, 0x44100000, &LH_GP_ , 0, 0x0 }, /* LH[GP] */ { instruction , 0 , 0 , 32, - 0xfc1c0001, 0x44100001, &NMD::LHU_GP_ , 0, + 0xfc1c0001, 0x44100001, &LHU_GP_ , 0, 0x0 }, /* LHU[GP] */ }; -NMD::Pool NMD::P_GP_SH[2] = { +static const Pool P_GP_SH[2] = { { instruction , 0 , 0 , 32, - 0xfc1c0001, 0x44140000, &NMD::SH_GP_ , 0, + 0xfc1c0001, 0x44140000, &SH_GP_ , 0, 0x0 }, /* SH[GP] */ { reserved_block , 0 , 0 , 32, 0xfc1c0001, 0x44140001, 0 , 0, @@ -21260,25 +20768,25 @@ NMD::Pool NMD::P_GP_SH[2] = { }; -NMD::Pool NMD::P_GP_CP1[4] = { +static const Pool P_GP_CP1[4] = { { instruction , 0 , 0 , 32, - 0xfc1c0003, 0x44180000, &NMD::LWC1_GP_ , 0, + 0xfc1c0003, 0x44180000, &LWC1_GP_ , 0, CP1_ }, /* LWC1[GP] */ { instruction , 0 , 0 , 32, - 0xfc1c0003, 0x44180001, &NMD::SWC1_GP_ , 0, + 0xfc1c0003, 0x44180001, &SWC1_GP_ , 0, CP1_ }, /* SWC1[GP] */ { instruction , 0 , 0 , 32, - 0xfc1c0003, 0x44180002, &NMD::LDC1_GP_ , 0, + 0xfc1c0003, 0x44180002, &LDC1_GP_ , 0, CP1_ }, /* LDC1[GP] */ { instruction , 0 , 0 , 32, - 0xfc1c0003, 0x44180003, &NMD::SDC1_GP_ , 0, + 0xfc1c0003, 0x44180003, &SDC1_GP_ , 0, CP1_ }, /* SDC1[GP] */ }; -NMD::Pool NMD::P_GP_M64[4] = { +static const Pool P_GP_M64[4] = { { instruction , 0 , 0 , 32, - 0xfc1c0003, 0x441c0000, &NMD::LWU_GP_ , 0, + 0xfc1c0003, 0x441c0000, &LWU_GP_ , 0, MIPS64_ }, /* LWU[GP] */ { reserved_block , 0 , 0 , 32, 0xfc1c0003, 0x441c0001, 0 , 0, @@ -21292,18 +20800,18 @@ NMD::Pool NMD::P_GP_M64[4] = { }; -NMD::Pool NMD::P_GP_BH[8] = { +static const Pool P_GP_BH[8] = { { instruction , 0 , 0 , 32, - 0xfc1c0000, 0x44000000, &NMD::LB_GP_ , 0, + 0xfc1c0000, 0x44000000, &LB_GP_ , 0, 0x0 }, /* LB[GP] */ { instruction , 0 , 0 , 32, - 0xfc1c0000, 0x44040000, &NMD::SB_GP_ , 0, + 0xfc1c0000, 0x44040000, &SB_GP_ , 0, 0x0 }, /* SB[GP] */ { instruction , 0 , 0 , 32, - 0xfc1c0000, 0x44080000, &NMD::LBU_GP_ , 0, + 0xfc1c0000, 0x44080000, &LBU_GP_ , 0, 0x0 }, /* LBU[GP] */ { instruction , 0 , 0 , 32, - 0xfc1c0000, 0x440c0000, &NMD::ADDIU_GP_B_ , 0, + 0xfc1c0000, 0x440c0000, &ADDIU_GP_B_ , 0, 0x0 }, /* ADDIU[GP.B] */ { pool , P_GP_LH , 2 , 32, 0xfc1c0000, 0x44100000, 0 , 0, @@ -21320,136 +20828,136 @@ NMD::Pool NMD::P_GP_BH[8] = { }; -NMD::Pool NMD::P_LS_U12[16] = { +static const Pool P_LS_U12[16] = { { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84000000, &NMD::LB_U12_ , 0, + 0xfc00f000, 0x84000000, &LB_U12_ , 0, 0x0 }, /* LB[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84001000, &NMD::SB_U12_ , 0, + 0xfc00f000, 0x84001000, &SB_U12_ , 0, 0x0 }, /* SB[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84002000, &NMD::LBU_U12_ , 0, + 0xfc00f000, 0x84002000, &LBU_U12_ , 0, 0x0 }, /* LBU[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84003000, &NMD::PREF_U12_ , 0, + 0xfc00f000, 0x84003000, &PREF_U12_ , 0, 0x0 }, /* PREF[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84004000, &NMD::LH_U12_ , 0, + 0xfc00f000, 0x84004000, &LH_U12_ , 0, 0x0 }, /* LH[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84005000, &NMD::SH_U12_ , 0, + 0xfc00f000, 0x84005000, &SH_U12_ , 0, 0x0 }, /* SH[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84006000, &NMD::LHU_U12_ , 0, + 0xfc00f000, 0x84006000, &LHU_U12_ , 0, 0x0 }, /* LHU[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84007000, &NMD::LWU_U12_ , 0, + 0xfc00f000, 0x84007000, &LWU_U12_ , 0, MIPS64_ }, /* LWU[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84008000, &NMD::LW_U12_ , 0, + 0xfc00f000, 0x84008000, &LW_U12_ , 0, 0x0 }, /* LW[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x84009000, &NMD::SW_U12_ , 0, + 0xfc00f000, 0x84009000, &SW_U12_ , 0, 0x0 }, /* SW[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8400a000, &NMD::LWC1_U12_ , 0, + 0xfc00f000, 0x8400a000, &LWC1_U12_ , 0, CP1_ }, /* LWC1[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8400b000, &NMD::SWC1_U12_ , 0, + 0xfc00f000, 0x8400b000, &SWC1_U12_ , 0, CP1_ }, /* SWC1[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8400c000, &NMD::LD_U12_ , 0, + 0xfc00f000, 0x8400c000, &LD_U12_ , 0, MIPS64_ }, /* LD[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8400d000, &NMD::SD_U12_ , 0, + 0xfc00f000, 0x8400d000, &SD_U12_ , 0, MIPS64_ }, /* SD[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8400e000, &NMD::LDC1_U12_ , 0, + 0xfc00f000, 0x8400e000, &LDC1_U12_ , 0, CP1_ }, /* LDC1[U12] */ { instruction , 0 , 0 , 32, - 0xfc00f000, 0x8400f000, &NMD::SDC1_U12_ , 0, + 0xfc00f000, 0x8400f000, &SDC1_U12_ , 0, CP1_ }, /* SDC1[U12] */ }; -NMD::Pool NMD::P_PREF_S9_[2] = { +static const Pool P_PREF_S9_[2] = { { instruction , 0 , 0 , 32, - 0xffe07f00, 0xa7e01800, &NMD::SYNCI , 0, + 0xffe07f00, 0xa7e01800, &SYNCI , 0, 0x0 }, /* SYNCI */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4001800, &NMD::PREF_S9_ , &NMD::PREF_S9__cond , + 0xfc007f00, 0xa4001800, &PREF_S9_ , &PREF_S9__cond , 0x0 }, /* PREF[S9] */ }; -NMD::Pool NMD::P_LS_S0[16] = { +static const Pool P_LS_S0[16] = { { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4000000, &NMD::LB_S9_ , 0, + 0xfc007f00, 0xa4000000, &LB_S9_ , 0, 0x0 }, /* LB[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4000800, &NMD::SB_S9_ , 0, + 0xfc007f00, 0xa4000800, &SB_S9_ , 0, 0x0 }, /* SB[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4001000, &NMD::LBU_S9_ , 0, + 0xfc007f00, 0xa4001000, &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, + 0xfc007f00, 0xa4002000, &LH_S9_ , 0, 0x0 }, /* LH[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4002800, &NMD::SH_S9_ , 0, + 0xfc007f00, 0xa4002800, &SH_S9_ , 0, 0x0 }, /* SH[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4003000, &NMD::LHU_S9_ , 0, + 0xfc007f00, 0xa4003000, &LHU_S9_ , 0, 0x0 }, /* LHU[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4003800, &NMD::LWU_S9_ , 0, + 0xfc007f00, 0xa4003800, &LWU_S9_ , 0, MIPS64_ }, /* LWU[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4004000, &NMD::LW_S9_ , 0, + 0xfc007f00, 0xa4004000, &LW_S9_ , 0, 0x0 }, /* LW[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4004800, &NMD::SW_S9_ , 0, + 0xfc007f00, 0xa4004800, &SW_S9_ , 0, 0x0 }, /* SW[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4005000, &NMD::LWC1_S9_ , 0, + 0xfc007f00, 0xa4005000, &LWC1_S9_ , 0, CP1_ }, /* LWC1[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4005800, &NMD::SWC1_S9_ , 0, + 0xfc007f00, 0xa4005800, &SWC1_S9_ , 0, CP1_ }, /* SWC1[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4006000, &NMD::LD_S9_ , 0, + 0xfc007f00, 0xa4006000, &LD_S9_ , 0, MIPS64_ }, /* LD[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4006800, &NMD::SD_S9_ , 0, + 0xfc007f00, 0xa4006800, &SD_S9_ , 0, MIPS64_ }, /* SD[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4007000, &NMD::LDC1_S9_ , 0, + 0xfc007f00, 0xa4007000, &LDC1_S9_ , 0, CP1_ }, /* LDC1[S9] */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4007800, &NMD::SDC1_S9_ , 0, + 0xfc007f00, 0xa4007800, &SDC1_S9_ , 0, CP1_ }, /* SDC1[S9] */ }; -NMD::Pool NMD::ASET_ACLR[2] = { +static const Pool ASET_ACLR[2] = { { instruction , 0 , 0 , 32, - 0xfe007f00, 0xa4001100, &NMD::ASET , 0, + 0xfe007f00, 0xa4001100, &ASET , 0, MCU_ }, /* ASET */ { instruction , 0 , 0 , 32, - 0xfe007f00, 0xa6001100, &NMD::ACLR , 0, + 0xfe007f00, 0xa6001100, &ACLR , 0, MCU_ }, /* ACLR */ }; -NMD::Pool NMD::P_LL[4] = { +static const Pool P_LL[4] = { { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005100, &NMD::LL , 0, + 0xfc007f03, 0xa4005100, &LL , 0, 0x0 }, /* LL */ { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005101, &NMD::LLWP , 0, + 0xfc007f03, 0xa4005101, &LLWP , 0, XNP_ }, /* LLWP */ { reserved_block , 0 , 0 , 32, 0xfc007f03, 0xa4005102, 0 , 0, @@ -21460,12 +20968,12 @@ NMD::Pool NMD::P_LL[4] = { }; -NMD::Pool NMD::P_SC[4] = { +static const Pool P_SC[4] = { { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005900, &NMD::SC , 0, + 0xfc007f03, 0xa4005900, &SC , 0, 0x0 }, /* SC */ { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005901, &NMD::SCWP , 0, + 0xfc007f03, 0xa4005901, &SCWP , 0, XNP_ }, /* SCWP */ { reserved_block , 0 , 0 , 32, 0xfc007f03, 0xa4005902, 0 , 0, @@ -21476,12 +20984,12 @@ NMD::Pool NMD::P_SC[4] = { }; -NMD::Pool NMD::P_LLD[8] = { +static const Pool P_LLD[8] = { { instruction , 0 , 0 , 32, - 0xfc007f07, 0xa4007100, &NMD::LLD , 0, + 0xfc007f07, 0xa4007100, &LLD , 0, MIPS64_ }, /* LLD */ { instruction , 0 , 0 , 32, - 0xfc007f07, 0xa4007101, &NMD::LLDP , 0, + 0xfc007f07, 0xa4007101, &LLDP , 0, MIPS64_ }, /* LLDP */ { reserved_block , 0 , 0 , 32, 0xfc007f07, 0xa4007102, 0 , 0, @@ -21504,12 +21012,12 @@ NMD::Pool NMD::P_LLD[8] = { }; -NMD::Pool NMD::P_SCD[8] = { +static const Pool P_SCD[8] = { { instruction , 0 , 0 , 32, - 0xfc007f07, 0xa4007900, &NMD::SCD , 0, + 0xfc007f07, 0xa4007900, &SCD , 0, MIPS64_ }, /* SCD */ { instruction , 0 , 0 , 32, - 0xfc007f07, 0xa4007901, &NMD::SCDP , 0, + 0xfc007f07, 0xa4007901, &SCDP , 0, MIPS64_ }, /* SCDP */ { reserved_block , 0 , 0 , 32, 0xfc007f07, 0xa4007902, 0 , 0, @@ -21532,7 +21040,7 @@ NMD::Pool NMD::P_SCD[8] = { }; -NMD::Pool NMD::P_LS_S1[16] = { +static const Pool P_LS_S1[16] = { { reserved_block , 0 , 0 , 32, 0xfc007f00, 0xa4000100, 0 , 0, 0x0 }, /* P.LS.S1~*(0) */ @@ -21546,22 +21054,22 @@ NMD::Pool NMD::P_LS_S1[16] = { 0xfc007f00, 0xa4001900, 0 , 0, 0x0 }, /* P.LS.S1~*(3) */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4002100, &NMD::UALH , 0, + 0xfc007f00, 0xa4002100, &UALH , 0, XMMS_ }, /* UALH */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4002900, &NMD::UASH , 0, + 0xfc007f00, 0xa4002900, &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, + 0xfc007f00, 0xa4003900, &CACHE , 0, CP0_ }, /* CACHE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4004100, &NMD::LWC2 , 0, + 0xfc007f00, 0xa4004100, &LWC2 , 0, CP2_ }, /* LWC2 */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4004900, &NMD::SWC2 , 0, + 0xfc007f00, 0xa4004900, &SWC2 , 0, CP2_ }, /* SWC2 */ { pool , P_LL , 4 , 32, 0xfc007f00, 0xa4005100, 0 , 0, @@ -21570,10 +21078,10 @@ NMD::Pool NMD::P_LS_S1[16] = { 0xfc007f00, 0xa4005900, 0 , 0, 0x0 }, /* P.SC */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4006100, &NMD::LDC2 , 0, + 0xfc007f00, 0xa4006100, &LDC2 , 0, CP2_ }, /* LDC2 */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4006900, &NMD::SDC2 , 0, + 0xfc007f00, 0xa4006900, &SDC2 , 0, CP2_ }, /* SDC2 */ { pool , P_LLD , 8 , 32, 0xfc007f00, 0xa4007100, 0 , 0, @@ -21584,22 +21092,22 @@ NMD::Pool NMD::P_LS_S1[16] = { }; -NMD::Pool NMD::P_PREFE[2] = { +static const Pool P_PREFE[2] = { { instruction , 0 , 0 , 32, - 0xffe07f00, 0xa7e01a00, &NMD::SYNCIE , 0, + 0xffe07f00, 0xa7e01a00, &SYNCIE , 0, CP0_ | EVA_ }, /* SYNCIE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4001a00, &NMD::PREFE , &NMD::PREFE_cond , + 0xfc007f00, 0xa4001a00, &PREFE , &PREFE_cond , CP0_ | EVA_ }, /* PREFE */ }; -NMD::Pool NMD::P_LLE[4] = { +static const Pool P_LLE[4] = { { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005200, &NMD::LLE , 0, + 0xfc007f03, 0xa4005200, &LLE , 0, CP0_ | EVA_ }, /* LLE */ { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005201, &NMD::LLWPE , 0, + 0xfc007f03, 0xa4005201, &LLWPE , 0, CP0_ | EVA_ }, /* LLWPE */ { reserved_block , 0 , 0 , 32, 0xfc007f03, 0xa4005202, 0 , 0, @@ -21610,12 +21118,12 @@ NMD::Pool NMD::P_LLE[4] = { }; -NMD::Pool NMD::P_SCE[4] = { +static const Pool P_SCE[4] = { { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005a00, &NMD::SCE , 0, + 0xfc007f03, 0xa4005a00, &SCE , 0, CP0_ | EVA_ }, /* SCE */ { instruction , 0 , 0 , 32, - 0xfc007f03, 0xa4005a01, &NMD::SCWPE , 0, + 0xfc007f03, 0xa4005a01, &SCWPE , 0, CP0_ | EVA_ }, /* SCWPE */ { reserved_block , 0 , 0 , 32, 0xfc007f03, 0xa4005a02, 0 , 0, @@ -21626,36 +21134,36 @@ NMD::Pool NMD::P_SCE[4] = { }; -NMD::Pool NMD::P_LS_E0[16] = { +static const Pool P_LS_E0[16] = { { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4000200, &NMD::LBE , 0, + 0xfc007f00, 0xa4000200, &LBE , 0, CP0_ | EVA_ }, /* LBE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4000a00, &NMD::SBE , 0, + 0xfc007f00, 0xa4000a00, &SBE , 0, CP0_ | EVA_ }, /* SBE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4001200, &NMD::LBUE , 0, + 0xfc007f00, 0xa4001200, &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, + 0xfc007f00, 0xa4002200, &LHE , 0, CP0_ | EVA_ }, /* LHE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4002a00, &NMD::SHE , 0, + 0xfc007f00, 0xa4002a00, &SHE , 0, CP0_ | EVA_ }, /* SHE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4003200, &NMD::LHUE , 0, + 0xfc007f00, 0xa4003200, &LHUE , 0, CP0_ | EVA_ }, /* LHUE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4003a00, &NMD::CACHEE , 0, + 0xfc007f00, 0xa4003a00, &CACHEE , 0, CP0_ | EVA_ }, /* CACHEE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4004200, &NMD::LWE , 0, + 0xfc007f00, 0xa4004200, &LWE , 0, CP0_ | EVA_ }, /* LWE */ { instruction , 0 , 0 , 32, - 0xfc007f00, 0xa4004a00, &NMD::SWE , 0, + 0xfc007f00, 0xa4004a00, &SWE , 0, CP0_ | EVA_ }, /* SWE */ { pool , P_LLE , 4 , 32, 0xfc007f00, 0xa4005200, 0 , 0, @@ -21678,47 +21186,47 @@ NMD::Pool NMD::P_LS_E0[16] = { }; -NMD::Pool NMD::P_LS_WM[2] = { +static const Pool P_LS_WM[2] = { { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000400, &NMD::LWM , 0, + 0xfc000f00, 0xa4000400, &LWM , 0, XMMS_ }, /* LWM */ { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000c00, &NMD::SWM , 0, + 0xfc000f00, 0xa4000c00, &SWM , 0, XMMS_ }, /* SWM */ }; -NMD::Pool NMD::P_LS_UAWM[2] = { +static const Pool P_LS_UAWM[2] = { { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000500, &NMD::UALWM , 0, + 0xfc000f00, 0xa4000500, &UALWM , 0, XMMS_ }, /* UALWM */ { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000d00, &NMD::UASWM , 0, + 0xfc000f00, 0xa4000d00, &UASWM , 0, XMMS_ }, /* UASWM */ }; -NMD::Pool NMD::P_LS_DM[2] = { +static const Pool P_LS_DM[2] = { { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000600, &NMD::LDM , 0, + 0xfc000f00, 0xa4000600, &LDM , 0, MIPS64_ }, /* LDM */ { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000e00, &NMD::SDM , 0, + 0xfc000f00, 0xa4000e00, &SDM , 0, MIPS64_ }, /* SDM */ }; -NMD::Pool NMD::P_LS_UADM[2] = { +static const Pool P_LS_UADM[2] = { { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000700, &NMD::UALDM , 0, + 0xfc000f00, 0xa4000700, &UALDM , 0, MIPS64_ }, /* UALDM */ { instruction , 0 , 0 , 32, - 0xfc000f00, 0xa4000f00, &NMD::UASDM , 0, + 0xfc000f00, 0xa4000f00, &UASDM , 0, MIPS64_ }, /* UASDM */ }; -NMD::Pool NMD::P_LS_S9[8] = { +static const Pool P_LS_S9[8] = { { pool , P_LS_S0 , 16 , 32, 0xfc000700, 0xa4000000, 0 , 0, 0x0 }, /* P.LS.S0 */ @@ -21746,32 +21254,32 @@ NMD::Pool NMD::P_LS_S9[8] = { }; -NMD::Pool NMD::P_BAL[2] = { +static const Pool P_BAL[2] = { { branch_instruction , 0 , 0 , 32, - 0xfe000000, 0x28000000, &NMD::BC_32_ , 0, + 0xfe000000, 0x28000000, &BC_32_ , 0, 0x0 }, /* BC[32] */ { call_instruction , 0 , 0 , 32, - 0xfe000000, 0x2a000000, &NMD::BALC_32_ , 0, + 0xfe000000, 0x2a000000, &BALC_32_ , 0, 0x0 }, /* BALC[32] */ }; -NMD::Pool NMD::P_BALRSC[2] = { +static const Pool P_BALRSC[2] = { { branch_instruction , 0 , 0 , 32, - 0xffe0f000, 0x48008000, &NMD::BRSC , 0, + 0xffe0f000, 0x48008000, &BRSC , 0, 0x0 }, /* BRSC */ { call_instruction , 0 , 0 , 32, - 0xfc00f000, 0x48008000, &NMD::BALRSC , &NMD::BALRSC_cond , + 0xfc00f000, 0x48008000, &BALRSC , &BALRSC_cond , 0x0 }, /* BALRSC */ }; -NMD::Pool NMD::P_J[16] = { +static const Pool P_J[16] = { { call_instruction , 0 , 0 , 32, - 0xfc00f000, 0x48000000, &NMD::JALRC_32_ , 0, + 0xfc00f000, 0x48000000, &JALRC_32_ , 0, 0x0 }, /* JALRC[32] */ { call_instruction , 0 , 0 , 32, - 0xfc00f000, 0x48001000, &NMD::JALRC_HB , 0, + 0xfc00f000, 0x48001000, &JALRC_HB , 0, 0x0 }, /* JALRC.HB */ { reserved_block , 0 , 0 , 32, 0xfc00f000, 0x48002000, 0 , 0, @@ -21818,21 +21326,21 @@ NMD::Pool NMD::P_J[16] = { }; -NMD::Pool NMD::P_BR3A[32] = { +static const Pool P_BR3A[32] = { { branch_instruction , 0 , 0 , 32, - 0xfc1fc000, 0x88004000, &NMD::BC1EQZC , 0, + 0xfc1fc000, 0x88004000, &BC1EQZC , 0, CP1_ }, /* BC1EQZC */ { branch_instruction , 0 , 0 , 32, - 0xfc1fc000, 0x88014000, &NMD::BC1NEZC , 0, + 0xfc1fc000, 0x88014000, &BC1NEZC , 0, CP1_ }, /* BC1NEZC */ { branch_instruction , 0 , 0 , 32, - 0xfc1fc000, 0x88024000, &NMD::BC2EQZC , 0, + 0xfc1fc000, 0x88024000, &BC2EQZC , 0, CP2_ }, /* BC2EQZC */ { branch_instruction , 0 , 0 , 32, - 0xfc1fc000, 0x88034000, &NMD::BC2NEZC , 0, + 0xfc1fc000, 0x88034000, &BC2NEZC , 0, CP2_ }, /* BC2NEZC */ { branch_instruction , 0 , 0 , 32, - 0xfc1fc000, 0x88044000, &NMD::BPOSGE32C , 0, + 0xfc1fc000, 0x88044000, &BPOSGE32C , 0, DSP_ }, /* BPOSGE32C */ { reserved_block , 0 , 0 , 32, 0xfc1fc000, 0x88054000, 0 , 0, @@ -21918,67 +21426,67 @@ NMD::Pool NMD::P_BR3A[32] = { }; -NMD::Pool NMD::P_BR1[4] = { +static const Pool P_BR1[4] = { { branch_instruction , 0 , 0 , 32, - 0xfc00c000, 0x88000000, &NMD::BEQC_32_ , 0, + 0xfc00c000, 0x88000000, &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, + 0xfc00c000, 0x88008000, &BGEC , 0, 0x0 }, /* BGEC */ { branch_instruction , 0 , 0 , 32, - 0xfc00c000, 0x8800c000, &NMD::BGEUC , 0, + 0xfc00c000, 0x8800c000, &BGEUC , 0, 0x0 }, /* BGEUC */ }; -NMD::Pool NMD::P_BR2[4] = { +static const Pool P_BR2[4] = { { branch_instruction , 0 , 0 , 32, - 0xfc00c000, 0xa8000000, &NMD::BNEC_32_ , 0, + 0xfc00c000, 0xa8000000, &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, + 0xfc00c000, 0xa8008000, &BLTC , 0, 0x0 }, /* BLTC */ { branch_instruction , 0 , 0 , 32, - 0xfc00c000, 0xa800c000, &NMD::BLTUC , 0, + 0xfc00c000, 0xa800c000, &BLTUC , 0, 0x0 }, /* BLTUC */ }; -NMD::Pool NMD::P_BRI[8] = { +static const Pool P_BRI[8] = { { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc8000000, &NMD::BEQIC , 0, + 0xfc1c0000, 0xc8000000, &BEQIC , 0, 0x0 }, /* BEQIC */ { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc8040000, &NMD::BBEQZC , 0, + 0xfc1c0000, 0xc8040000, &BBEQZC , 0, XMMS_ }, /* BBEQZC */ { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc8080000, &NMD::BGEIC , 0, + 0xfc1c0000, 0xc8080000, &BGEIC , 0, 0x0 }, /* BGEIC */ { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc80c0000, &NMD::BGEIUC , 0, + 0xfc1c0000, 0xc80c0000, &BGEIUC , 0, 0x0 }, /* BGEIUC */ { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc8100000, &NMD::BNEIC , 0, + 0xfc1c0000, 0xc8100000, &BNEIC , 0, 0x0 }, /* BNEIC */ { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc8140000, &NMD::BBNEZC , 0, + 0xfc1c0000, 0xc8140000, &BBNEZC , 0, XMMS_ }, /* BBNEZC */ { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc8180000, &NMD::BLTIC , 0, + 0xfc1c0000, 0xc8180000, &BLTIC , 0, 0x0 }, /* BLTIC */ { branch_instruction , 0 , 0 , 32, - 0xfc1c0000, 0xc81c0000, &NMD::BLTIUC , 0, + 0xfc1c0000, 0xc81c0000, &BLTIUC , 0, 0x0 }, /* BLTIUC */ }; -NMD::Pool NMD::P32[32] = { +static const Pool P32[32] = { { pool , P_ADDIU , 2 , 32, 0xfc000000, 0x00000000, 0 , 0, 0x0 }, /* P.ADDIU */ @@ -22004,7 +21512,7 @@ NMD::Pool NMD::P32[32] = { 0xfc000000, 0xe0000000, 0 , 0, 0x0 }, /* P.LUI */ { instruction , 0 , 0 , 32, - 0xfc000000, 0x04000000, &NMD::ADDIUPC_32_ , 0, + 0xfc000000, 0x04000000, &ADDIUPC_32_ , 0, 0x0 }, /* ADDIUPC[32] */ { reserved_block , 0 , 0 , 32, 0xfc000000, 0x24000000, 0 , 0, @@ -22028,7 +21536,7 @@ NMD::Pool NMD::P32[32] = { 0xfc000000, 0xe4000000, 0 , 0, 0x0 }, /* P32~*(29) */ { call_instruction , 0 , 0 , 32, - 0xfc000000, 0x08000000, &NMD::MOVE_BALC , 0, + 0xfc000000, 0x08000000, &MOVE_BALC , 0, XMMS_ }, /* MOVE.BALC */ { pool , P_BAL , 2 , 32, 0xfc000000, 0x28000000, 0 , 0, @@ -22078,17 +21586,17 @@ NMD::Pool NMD::P32[32] = { }; -NMD::Pool NMD::P16_SYSCALL[2] = { +static const Pool P16_SYSCALL[2] = { { instruction , 0 , 0 , 16, - 0xfffc , 0x1008 , &NMD::SYSCALL_16_ , 0, + 0xfffc , 0x1008 , &SYSCALL_16_ , 0, 0x0 }, /* SYSCALL[16] */ { instruction , 0 , 0 , 16, - 0xfffc , 0x100c , &NMD::HYPCALL_16_ , 0, + 0xfffc , 0x100c , &HYPCALL_16_ , 0, CP0_ | VZ_ }, /* HYPCALL[16] */ }; -NMD::Pool NMD::P16_RI[4] = { +static const Pool P16_RI[4] = { { reserved_block , 0 , 0 , 16, 0xfff8 , 0x1000 , 0 , 0, 0x0 }, /* P16.RI~*(0) */ @@ -22096,51 +21604,51 @@ NMD::Pool NMD::P16_RI[4] = { 0xfff8 , 0x1008 , 0 , 0, 0x0 }, /* P16.SYSCALL */ { instruction , 0 , 0 , 16, - 0xfff8 , 0x1010 , &NMD::BREAK_16_ , 0, + 0xfff8 , 0x1010 , &BREAK_16_ , 0, 0x0 }, /* BREAK[16] */ { instruction , 0 , 0 , 16, - 0xfff8 , 0x1018 , &NMD::SDBBP_16_ , 0, + 0xfff8 , 0x1018 , &SDBBP_16_ , 0, EJTAG_ }, /* SDBBP[16] */ }; -NMD::Pool NMD::P16_MV[2] = { +static const Pool 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 , + 0xfc00 , 0x1000 , &MOVE , &MOVE_cond , 0x0 }, /* MOVE */ }; -NMD::Pool NMD::P16_SHIFT[2] = { +static const Pool P16_SHIFT[2] = { { instruction , 0 , 0 , 16, - 0xfc08 , 0x3000 , &NMD::SLL_16_ , 0, + 0xfc08 , 0x3000 , &SLL_16_ , 0, 0x0 }, /* SLL[16] */ { instruction , 0 , 0 , 16, - 0xfc08 , 0x3008 , &NMD::SRL_16_ , 0, + 0xfc08 , 0x3008 , &SRL_16_ , 0, 0x0 }, /* SRL[16] */ }; -NMD::Pool NMD::POOL16C_00[4] = { +static const Pool POOL16C_00[4] = { { instruction , 0 , 0 , 16, - 0xfc0f , 0x5000 , &NMD::NOT_16_ , 0, + 0xfc0f , 0x5000 , &NOT_16_ , 0, 0x0 }, /* NOT[16] */ { instruction , 0 , 0 , 16, - 0xfc0f , 0x5004 , &NMD::XOR_16_ , 0, + 0xfc0f , 0x5004 , &XOR_16_ , 0, 0x0 }, /* XOR[16] */ { instruction , 0 , 0 , 16, - 0xfc0f , 0x5008 , &NMD::AND_16_ , 0, + 0xfc0f , 0x5008 , &AND_16_ , 0, 0x0 }, /* AND[16] */ { instruction , 0 , 0 , 16, - 0xfc0f , 0x500c , &NMD::OR_16_ , 0, + 0xfc0f , 0x500c , &OR_16_ , 0, 0x0 }, /* OR[16] */ }; -NMD::Pool NMD::POOL16C_0[2] = { +static const Pool POOL16C_0[2] = { { pool , POOL16C_00 , 4 , 16, 0xfc03 , 0x5000 , 0 , 0, 0x0 }, /* POOL16C_00 */ @@ -22150,39 +21658,39 @@ NMD::Pool NMD::POOL16C_0[2] = { }; -NMD::Pool NMD::P16C[2] = { +static const Pool P16C[2] = { { pool , POOL16C_0 , 2 , 16, 0xfc01 , 0x5000 , 0 , 0, 0x0 }, /* POOL16C_0 */ { instruction , 0 , 0 , 16, - 0xfc01 , 0x5001 , &NMD::LWXS_16_ , 0, + 0xfc01 , 0x5001 , &LWXS_16_ , 0, 0x0 }, /* LWXS[16] */ }; -NMD::Pool NMD::P16_A1[2] = { +static const Pool 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, + 0xfc40 , 0x7040 , &ADDIU_R1_SP_ , 0, 0x0 }, /* ADDIU[R1.SP] */ }; -NMD::Pool NMD::P_ADDIU_RS5_[2] = { +static const Pool P_ADDIU_RS5_[2] = { { instruction , 0 , 0 , 16, - 0xffe8 , 0x9008 , &NMD::NOP_16_ , 0, + 0xffe8 , 0x9008 , &NOP_16_ , 0, 0x0 }, /* NOP[16] */ { instruction , 0 , 0 , 16, - 0xfc08 , 0x9008 , &NMD::ADDIU_RS5_ , &NMD::ADDIU_RS5__cond , + 0xfc08 , 0x9008 , &ADDIU_RS5_ , &ADDIU_RS5__cond , 0x0 }, /* ADDIU[RS5] */ }; -NMD::Pool NMD::P16_A2[2] = { +static const Pool P16_A2[2] = { { instruction , 0 , 0 , 16, - 0xfc08 , 0x9000 , &NMD::ADDIU_R2_ , 0, + 0xfc08 , 0x9000 , &ADDIU_R2_ , 0, 0x0 }, /* ADDIU[R2] */ { pool , P_ADDIU_RS5_ , 2 , 16, 0xfc08 , 0x9008 , 0 , 0, @@ -22190,62 +21698,62 @@ NMD::Pool NMD::P16_A2[2] = { }; -NMD::Pool NMD::P16_ADDU[2] = { +static const Pool P16_ADDU[2] = { { instruction , 0 , 0 , 16, - 0xfc01 , 0xb000 , &NMD::ADDU_16_ , 0, + 0xfc01 , 0xb000 , &ADDU_16_ , 0, 0x0 }, /* ADDU[16] */ { instruction , 0 , 0 , 16, - 0xfc01 , 0xb001 , &NMD::SUBU_16_ , 0, + 0xfc01 , 0xb001 , &SUBU_16_ , 0, 0x0 }, /* SUBU[16] */ }; -NMD::Pool NMD::P16_JRC[2] = { +static const Pool P16_JRC[2] = { { branch_instruction , 0 , 0 , 16, - 0xfc1f , 0xd800 , &NMD::JRC , 0, + 0xfc1f , 0xd800 , &JRC , 0, 0x0 }, /* JRC */ { call_instruction , 0 , 0 , 16, - 0xfc1f , 0xd810 , &NMD::JALRC_16_ , 0, + 0xfc1f , 0xd810 , &JALRC_16_ , 0, 0x0 }, /* JALRC[16] */ }; -NMD::Pool NMD::P16_BR1[2] = { +static const Pool P16_BR1[2] = { { branch_instruction , 0 , 0 , 16, - 0xfc00 , 0xd800 , &NMD::BEQC_16_ , &NMD::BEQC_16__cond , + 0xfc00 , 0xd800 , &BEQC_16_ , &BEQC_16__cond , XMMS_ }, /* BEQC[16] */ { branch_instruction , 0 , 0 , 16, - 0xfc00 , 0xd800 , &NMD::BNEC_16_ , &NMD::BNEC_16__cond , + 0xfc00 , 0xd800 , &BNEC_16_ , &BNEC_16__cond , XMMS_ }, /* BNEC[16] */ }; -NMD::Pool NMD::P16_BR[2] = { +static const Pool 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 , + 0xfc00 , 0xd800 , 0 , &P16_BR1_cond , 0x0 }, /* P16.BR1 */ }; -NMD::Pool NMD::P16_SR[2] = { +static const Pool P16_SR[2] = { { instruction , 0 , 0 , 16, - 0xfd00 , 0x1c00 , &NMD::SAVE_16_ , 0, + 0xfd00 , 0x1c00 , &SAVE_16_ , 0, 0x0 }, /* SAVE[16] */ { return_instruction , 0 , 0 , 16, - 0xfd00 , 0x1d00 , &NMD::RESTORE_JRC_16_ , 0, + 0xfd00 , 0x1d00 , &RESTORE_JRC_16_ , 0, 0x0 }, /* RESTORE.JRC[16] */ }; -NMD::Pool NMD::P16_4X4[4] = { +static const Pool P16_4X4[4] = { { instruction , 0 , 0 , 16, - 0xfd08 , 0x3c00 , &NMD::ADDU_4X4_ , 0, + 0xfd08 , 0x3c00 , &ADDU_4X4_ , 0, XMMS_ }, /* ADDU[4X4] */ { instruction , 0 , 0 , 16, - 0xfd08 , 0x3c08 , &NMD::MUL_4X4_ , 0, + 0xfd08 , 0x3c08 , &MUL_4X4_ , 0, XMMS_ }, /* MUL[4X4] */ { reserved_block , 0 , 0 , 16, 0xfd08 , 0x3d00 , 0 , 0, @@ -22256,15 +21764,15 @@ NMD::Pool NMD::P16_4X4[4] = { }; -NMD::Pool NMD::P16_LB[4] = { +static const Pool P16_LB[4] = { { instruction , 0 , 0 , 16, - 0xfc0c , 0x5c00 , &NMD::LB_16_ , 0, + 0xfc0c , 0x5c00 , &LB_16_ , 0, 0x0 }, /* LB[16] */ { instruction , 0 , 0 , 16, - 0xfc0c , 0x5c04 , &NMD::SB_16_ , 0, + 0xfc0c , 0x5c04 , &SB_16_ , 0, 0x0 }, /* SB[16] */ { instruction , 0 , 0 , 16, - 0xfc0c , 0x5c08 , &NMD::LBU_16_ , 0, + 0xfc0c , 0x5c08 , &LBU_16_ , 0, 0x0 }, /* LBU[16] */ { reserved_block , 0 , 0 , 16, 0xfc0c , 0x5c0c , 0 , 0, @@ -22272,15 +21780,15 @@ NMD::Pool NMD::P16_LB[4] = { }; -NMD::Pool NMD::P16_LH[4] = { +static const Pool P16_LH[4] = { { instruction , 0 , 0 , 16, - 0xfc09 , 0x7c00 , &NMD::LH_16_ , 0, + 0xfc09 , 0x7c00 , &LH_16_ , 0, 0x0 }, /* LH[16] */ { instruction , 0 , 0 , 16, - 0xfc09 , 0x7c01 , &NMD::SH_16_ , 0, + 0xfc09 , 0x7c01 , &SH_16_ , 0, 0x0 }, /* SH[16] */ { instruction , 0 , 0 , 16, - 0xfc09 , 0x7c08 , &NMD::LHU_16_ , 0, + 0xfc09 , 0x7c08 , &LHU_16_ , 0, 0x0 }, /* LHU[16] */ { reserved_block , 0 , 0 , 16, 0xfc09 , 0x7c09 , 0 , 0, @@ -22288,7 +21796,7 @@ NMD::Pool NMD::P16_LH[4] = { }; -NMD::Pool NMD::P16[32] = { +static const Pool P16[32] = { { pool , P16_MV , 2 , 16, 0xfc00 , 0x1000 , 0 , 0, 0x0 }, /* P16.MV */ @@ -22308,40 +21816,40 @@ NMD::Pool NMD::P16[32] = { 0xfc00 , 0xb000 , 0 , 0, 0x0 }, /* P16.ADDU */ { instruction , 0 , 0 , 16, - 0xfc00 , 0xd000 , &NMD::LI_16_ , 0, + 0xfc00 , 0xd000 , &LI_16_ , 0, 0x0 }, /* LI[16] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0xf000 , &NMD::ANDI_16_ , 0, + 0xfc00 , 0xf000 , &ANDI_16_ , 0, 0x0 }, /* ANDI[16] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0x1400 , &NMD::LW_16_ , 0, + 0xfc00 , 0x1400 , &LW_16_ , 0, 0x0 }, /* LW[16] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0x3400 , &NMD::LW_SP_ , 0, + 0xfc00 , 0x3400 , &LW_SP_ , 0, 0x0 }, /* LW[SP] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0x5400 , &NMD::LW_GP16_ , 0, + 0xfc00 , 0x5400 , &LW_GP16_ , 0, 0x0 }, /* LW[GP16] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0x7400 , &NMD::LW_4X4_ , 0, + 0xfc00 , 0x7400 , &LW_4X4_ , 0, XMMS_ }, /* LW[4X4] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0x9400 , &NMD::SW_16_ , 0, + 0xfc00 , 0x9400 , &SW_16_ , 0, 0x0 }, /* SW[16] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0xb400 , &NMD::SW_SP_ , 0, + 0xfc00 , 0xb400 , &SW_SP_ , 0, 0x0 }, /* SW[SP] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0xd400 , &NMD::SW_GP16_ , 0, + 0xfc00 , 0xd400 , &SW_GP16_ , 0, 0x0 }, /* SW[GP16] */ { instruction , 0 , 0 , 16, - 0xfc00 , 0xf400 , &NMD::SW_4X4_ , 0, + 0xfc00 , 0xf400 , &SW_4X4_ , 0, XMMS_ }, /* SW[4X4] */ { branch_instruction , 0 , 0 , 16, - 0xfc00 , 0x1800 , &NMD::BC_16_ , 0, + 0xfc00 , 0x1800 , &BC_16_ , 0, 0x0 }, /* BC[16] */ { call_instruction , 0 , 0 , 16, - 0xfc00 , 0x3800 , &NMD::BALC_16_ , 0, + 0xfc00 , 0x3800 , &BALC_16_ , 0, 0x0 }, /* BALC[16] */ { reserved_block , 0 , 0 , 16, 0xfc00 , 0x5800 , 0 , 0, @@ -22350,10 +21858,10 @@ NMD::Pool NMD::P16[32] = { 0xfc00 , 0x7800 , 0 , 0, 0x0 }, /* P16~*(14) */ { branch_instruction , 0 , 0 , 16, - 0xfc00 , 0x9800 , &NMD::BEQZC_16_ , 0, + 0xfc00 , 0x9800 , &BEQZC_16_ , 0, 0x0 }, /* BEQZC[16] */ { branch_instruction , 0 , 0 , 16, - 0xfc00 , 0xb800 , &NMD::BNEZC_16_ , 0, + 0xfc00 , 0xb800 , &BNEZC_16_ , 0, 0x0 }, /* BNEZC[16] */ { pool , P16_BR , 2 , 16, 0xfc00 , 0xd800 , 0 , 0, @@ -22377,18 +21885,18 @@ NMD::Pool NMD::P16[32] = { 0xfc00 , 0x9c00 , 0 , 0, 0x0 }, /* P16~*(19) */ { instruction , 0 , 0 , 16, - 0xfc00 , 0xbc00 , &NMD::MOVEP , 0, + 0xfc00 , 0xbc00 , &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, + 0xfc00 , 0xfc00 , &MOVEP_REV_ , 0, XMMS_ }, /* MOVEP[REV] */ }; -NMD::Pool NMD::MAJOR[2] = { +static const Pool MAJOR[2] = { { pool , P32 , 32 , 32, 0x10000000, 0x00000000, 0 , 0, 0x0 }, /* P32 */ @@ -22396,3 +21904,105 @@ NMD::Pool NMD::MAJOR[2] = { 0x1000 , 0x1000 , 0 , 0, 0x0 }, /* P16 */ }; + +static int nanomips_dis(char **buf, + Dis_info *info, + unsigned short one, + unsigned short two, + unsigned short three) +{ + uint16 bits[3] = {one, two, three}; + + TABLE_ENTRY_TYPE type; + int size = Disassemble(bits, buf, &type, MAJOR, 2, info); + 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; + g_autofree char *buf = NULL; + + 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; + + Dis_info disassm_info; + disassm_info.m_pc = memaddr; + disassm_info.fprintf_func = info->fprintf_func; + disassm_info.stream = info->stream; + + 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, " "); + } + + /* Handle runtime errors. */ + if (sigsetjmp(disassm_info.buf, 0) != 0) { + info->insn_type = dis_noninsn; + return insn3 ? 6 : insn2 ? 4 : 2; + } + + int length = nanomips_dis(&buf, &disassm_info, insn1, insn2, insn3); + + /* FIXME: Should probably use a hash table on the major opcode here. */ + + (*info->fprintf_func) (info->stream, "%s", buf); + if (length > 0) { + return length / 8; + } + + info->insn_type = dis_noninsn; + + return insn3 ? 6 : insn2 ? 4 : 2; +} diff --git a/disas/nanomips.h b/disas/nanomips.h deleted file mode 100644 index a0a2225301..0000000000 --- a/disas/nanomips.h +++ /dev/null @@ -1,1076 +0,0 @@ -/* - * Header file for nanoMIPS disassembler component of QEMU - * - * Copyright (C) 2018 Wave Computing, Inc. - * Copyright (C) 2018 Matthew Fortune <matthew.fortune@mips.com> - * Copyright (C) 2018 Aleksandar Markovic <amarkovic@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 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - */ - -#ifndef DISAS_NANOMIPS_H -#define DISAS_NANOMIPS_H - -#include <string> - -typedef int64_t int64; -typedef uint64_t uint64; -typedef uint32_t uint32; -typedef uint16_t uint16; - -namespace img -{ - typedef uint64_t 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 decode_gpr_gpr4(uint64 d); - uint64 decode_gpr_gpr4_zero(uint64 d); - uint64 decode_gpr_gpr3(uint64 d); - uint64 decode_gpr_gpr3_src_store(uint64 d); - uint64 decode_gpr_gpr2_reg1(uint64 d); - uint64 decode_gpr_gpr2_reg2(uint64 d); - uint64 decode_gpr_gpr1(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__se3_4_2_1_0(uint64 instruction); - int64 extract_s__se7_0_6_5_4_3_2_1_s1(uint64 instruction); - int64 extract_s__se8_15_7_6_5_4_3_s3(uint64 instruction); - int64 extract_s__se8_15_7_6_5_4_3_2_s2(uint64 instruction); - int64 extract_s__se8_15_7_6_5_4_3_2_1_0(uint64 instruction); - int64 extract_s__se9_20_19_18_17_16_15_14_13_12_11(uint64 instruction); - int64 extract_s__se10_0_9_8_7_6_5_4_3_2_1_s1(uint64 instruction); - int64 extract_s__se11_0_10_9_8_7_6_5_4_3_2_1_0_s1(uint64 instruction); - int64 extract_s__se14_0_13_to_1_s1(uint64 instruction); - int64 extract_s__se21_0_20_to_1_s1(uint64 instruction); - int64 extract_s__se25_0_24_to_1_s1(uint64 instruction); - int64 extract_s__se31_15_to_0_31_to_16(uint64 instruction); - int64 extract_s__se31_0_11_to_2_20_to_12_s12(uint64 instruction); - int64 extract_shift__se5_21_20_19_18_17_16(uint64 instruction); - - uint64 extract_ac_15_14(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_15_14_13_12_11(uint64 instruction); - uint64 extract_fs_20_19_18_17_16(uint64 instruction); - uint64 extract_ft_15_14_13_12_11(uint64 instruction); - uint64 extract_ft_25_24_23_22_21(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_15_14_13_12_11(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 extract_shiftx_10_9_8_7__s1(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 extract_u_3_2_1_0__s1(uint64 instruction); - uint64 extract_u_2_1_0__s2(uint64 instruction); - uint64 extract_u_3_2_1_0__s2(uint64 instruction); - uint64 extract_u_4_3_2_1_0__s2(uint64 instruction); - uint64 extract_u_5_4_3_2_1_0__s2(uint64 instruction); - uint64 extract_u_6_5_4_3_2_1_0__s2(uint64 instruction); - uint64 extract_u_31_to_0__s32(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 extract_u_17_to_1__s1(uint64 instruction); - uint64 extract_u_2_1__s1(uint64 instruction); - uint64 extract_u_17_to_2__s2(uint64 instruction); - uint64 extract_u_20_to_2__s2(uint64 instruction); - uint64 extract_u_20_to_3__s3(uint64 instruction); - uint64 extract_u_3_8__s2(uint64 instruction); - uint64 extract_u_11_10_9_8_7_6_5_4_3__s3(uint64 instruction); - uint64 extract_u_7_6_5_4__s4(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/docs/devel/multiple-iothreads.txt b/docs/devel/multiple-iothreads.txt index aeb997bed5..343120f2ef 100644 --- a/docs/devel/multiple-iothreads.txt +++ b/docs/devel/multiple-iothreads.txt @@ -109,7 +109,7 @@ The AioContext originates from the QEMU block layer, even though nowadays AioContext is a generic event loop that can be used by any QEMU subsystem. The block layer has support for AioContext integrated. Each BlockDriverState -is associated with an AioContext using bdrv_try_set_aio_context() and +is associated with an AioContext using bdrv_try_change_aio_context() and bdrv_get_aio_context(). This allows block layer code to process I/O inside the right AioContext. Other subsystems may wish to follow a similar approach. @@ -134,5 +134,5 @@ Long-running jobs (usually in the form of coroutines) are best scheduled in the BlockDriverState's AioContext to avoid the need to acquire/release around each bdrv_*() call. The functions bdrv_add/remove_aio_context_notifier, or alternatively blk_add/remove_aio_context_notifier if you use BlockBackends, -can be used to get a notification whenever bdrv_try_set_aio_context() moves a +can be used to get a notification whenever bdrv_try_change_aio_context() moves a BlockDriverState to a different AioContext. diff --git a/docs/system/ppc/ppce500.rst b/docs/system/ppc/ppce500.rst index ba6bcb7314..fa40e57d18 100644 --- a/docs/system/ppc/ppce500.rst +++ b/docs/system/ppc/ppce500.rst @@ -113,7 +113,7 @@ To boot the 32-bit Linux kernel: .. code-block:: bash - $ qemu-system-ppc{64|32} -M ppce500 -cpu e500mc -smp 4 -m 2G \ + $ qemu-system-ppc64 -M ppce500 -cpu e500mc -smp 4 -m 2G \ -display none -serial stdio \ -kernel vmlinux \ -initrd /path/to/rootfs.cpio \ @@ -154,10 +154,10 @@ interface at PCI address 0.1.0, but we can switch that to an e1000 NIC by: .. code-block:: bash - $ qemu-system-ppc -M ppce500 -smp 4 -m 2G \ - -display none -serial stdio \ - -bios u-boot \ - -nic tap,ifname=tap0,script=no,downscript=no,model=e1000 + $ qemu-system-ppc64 -M ppce500 -smp 4 -m 2G \ + -display none -serial stdio \ + -bios u-boot \ + -nic tap,ifname=tap0,script=no,downscript=no,model=e1000 The QEMU ``ppce500`` machine can also dynamically instantiate an eTSEC device if “-device eTSEC” is given to QEMU: @@ -165,3 +165,18 @@ if “-device eTSEC” is given to QEMU: .. code-block:: bash -netdev tap,ifname=tap0,script=no,downscript=no,id=net0 -device eTSEC,netdev=net0 + +Root file system on flash drive +------------------------------- + +Rather than using a root file system on ram disk, it is possible to have it on +CFI flash. Given an ext2 image whose size must be a power of two, it can be used +as follows: + +.. code-block:: bash + + $ qemu-system-ppc64 -M ppce500 -cpu e500mc -smp 4 -m 2G \ + -display none -serial stdio \ + -kernel vmlinux \ + -drive if=pflash,file=/path/to/rootfs.ext2,format=raw \ + -append "rootwait root=/dev/mtdblock0" diff --git a/hmp-commands.hx b/hmp-commands.hx index 12b6d4e2dc..673e39a697 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1276,7 +1276,7 @@ ERST { .name = "netdev_add", .args_type = "netdev:O", - .params = "[user|tap|socket|vde|bridge|hubport|netmap|vhost-user" + .params = "[user|tap|socket|stream|dgram|vde|bridge|hubport|netmap|vhost-user" #ifdef CONFIG_VMNET "|vmnet-host|vmnet-shared|vmnet-bridged" #endif diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c index f4349eba83..c502c8c62a 100644 --- a/hw/alpha/dp264.c +++ b/hw/alpha/dp264.c @@ -20,8 +20,6 @@ #include "qemu/datadir.h" #include "net/net.h" -#define MAX_IDE_BUS 2 - static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr) { if (((addr >> 41) & 3) == 2) { diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 0cbc2fb4cb..9c235bf66e 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -690,7 +690,7 @@ static const MemoryRegionOps pflash_cfi01_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl) +static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl, Error **errp) { uint64_t blocks_per_device, sector_len_per_device, device_len; int num_devices; @@ -708,6 +708,10 @@ static void pflash_cfi01_fill_cfi_table(PFlashCFI01 *pfl) sector_len_per_device = pfl->sector_len / num_devices; } device_len = sector_len_per_device * blocks_per_device; + if (!is_power_of_2(device_len)) { + error_setg(errp, "Device size must be a power of two."); + return; + } /* Hardcoded CFI table */ /* Standard "QRY" string */ @@ -865,7 +869,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp) */ pfl->cmd = 0x00; pfl->status = 0x80; /* WSM ready */ - pflash_cfi01_fill_cfi_table(pfl); + pflash_cfi01_fill_cfi_table(pfl, errp); } static void pflash_cfi01_system_reset(DeviceState *dev) diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index 2a99b286b0..ff2fe154c1 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -880,6 +880,11 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp) return; } + if (!is_power_of_2(pfl->chip_len)) { + error_setg(errp, "Device size must be a power of two."); + return; + } + memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl), &pflash_cfi02_ops, pfl, pfl->name, pfl->chip_len, errp); diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index 84902dde17..13bf5cc47a 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -97,6 +97,10 @@ static int vhost_user_blk_handle_config_change(struct vhost_dev *dev) VHostUserBlk *s = VHOST_USER_BLK(dev->vdev); Error *local_err = NULL; + if (!dev->started) { + return 0; + } + ret = vhost_dev_get_config(dev, (uint8_t *)&blkcfg, vdev->config_len, &local_err); if (ret < 0) { diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index 19ea7c2c66..de1cc7ab71 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -30,8 +30,6 @@ #include "qemu/log.h" #include "net/net.h" -#define MAX_IDE_BUS 2 - #define MIN_SEABIOS_HPPA_VERSION 6 /* require at least this fw version */ #define HPA_POWER_BUTTON (FIRMWARE_END - 0x10) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 3e86083db3..ef14da5094 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -47,7 +47,6 @@ #include "multiboot.h" #include "hw/rtc/mc146818rtc.h" #include "hw/intc/i8259.h" -#include "hw/dma/i8257.h" #include "hw/timer/i8254.h" #include "hw/input/i8042.h" #include "hw/irq.h" @@ -1320,8 +1319,6 @@ void pc_basic_device_init(struct PCMachineState *pcms, pcspk_init(pcms->pcspk, isa_bus, pit); } - i8257_dma_init(isa_bus, 0); - /* Super I/O */ pc_superio_init(isa_bus, create_fdctrl, pcms->i8042_enabled, pcms->vmport != ON_OFF_AUTO_ON); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 0b1a79c0fa..0ad0ed1603 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -26,6 +26,7 @@ #include CONFIG_DEVICES #include "qemu/units.h" +#include "hw/dma/i8257.h" #include "hw/loader.h" #include "hw/i386/x86.h" #include "hw/i386/pc.h" @@ -39,6 +40,7 @@ #include "hw/usb.h" #include "net/net.h" #include "hw/ide/pci.h" +#include "hw/ide/piix.h" #include "hw/irq.h" #include "sysemu/kvm.h" #include "hw/kvm/clock.h" @@ -225,6 +227,7 @@ static void pc_init1(MachineState *machine, pci_bus = NULL; isa_bus = isa_bus_new(NULL, get_system_memory(), system_io, &error_abort); + i8257_dma_init(isa_bus, 0); pcms->hpet_enabled = false; } isa_bus_irqs(isa_bus, x86ms->gsi); @@ -257,7 +260,7 @@ static void pc_init1(MachineState *machine, if (pcmc->pci_enabled) { PCIDevice *dev; - dev = pci_create_simple(pci_bus, piix3_devfn + 1, "piix3-ide"); + dev = pci_create_simple(pci_bus, piix3_devfn + 1, TYPE_PIIX3_IDE); pci_ide_create_devs(dev); idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0"); idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1"); diff --git a/hw/ide/piix.c b/hw/ide/piix.c index de1f4f0efb..267dbf37db 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -36,6 +36,7 @@ #include "sysemu/blockdev.h" #include "sysemu/dma.h" +#include "hw/ide/piix.h" #include "hw/ide/pci.h" #include "trace.h" @@ -202,7 +203,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data) } static const TypeInfo piix3_ide_info = { - .name = "piix3-ide", + .name = TYPE_PIIX3_IDE, .parent = TYPE_PCI_IDE, .class_init = piix3_ide_class_init, }; @@ -224,7 +225,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data) } static const TypeInfo piix4_ide_info = { - .name = "piix4-ide", + .name = TYPE_PIIX4_IDE, .parent = TYPE_PCI_IDE, .class_init = piix4_ide_class_init, }; diff --git a/hw/ide/via.c b/hw/ide/via.c index 82def819c4..e1a429405d 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -230,7 +230,7 @@ static void via_ide_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_ide_info = { - .name = "via-ide", + .name = TYPE_VIA_IDE, .parent = TYPE_PCI_IDE, .class_init = via_ide_class_init, }; diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig index d42143a991..18b5c6bf3f 100644 --- a/hw/isa/Kconfig +++ b/hw/isa/Kconfig @@ -33,13 +33,20 @@ config PC87312 config PIIX3 bool + select I8257 select ISA_BUS config PIIX4 bool # For historical reasons, SuperIO devices are created in the board # for PIIX4. + select ACPI_PIIX4 + select I8254 + select I8257 + select I8259 + select IDE_PIIX select ISA_BUS + select MC146818RTC select USB_UHCI config VT82C686 @@ -53,6 +60,7 @@ config VT82C686 select I8254 select I8257 select I8259 + select IDE_VIA select MC146818RTC select PARALLEL @@ -67,6 +75,7 @@ config LPC_ICH9 bool # For historical reasons, SuperIO devices are created in the board # for ICH9. + select I8257 select ISA_BUS select ACPI_SMBUS select ACPI_X86_ICH diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 4553b5925b..8694e58b21 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -34,6 +34,7 @@ #include "qapi/error.h" #include "qapi/visitor.h" #include "qemu/range.h" +#include "hw/dma/i8257.h" #include "hw/isa/isa.h" #include "migration/vmstate.h" #include "hw/irq.h" @@ -722,6 +723,8 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp) qdev_init_gpio_out_named(dev, lpc->gsi, ICH9_GPIO_GSI, GSI_NUM_PINS); isa_bus_irqs(isa_bus, lpc->gsi); + + i8257_dma_init(isa_bus, 0); } static bool ich9_rst_cnt_needed(void *opaque) diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c index 48f9ab1096..808fd4eadf 100644 --- a/hw/isa/piix3.c +++ b/hw/isa/piix3.c @@ -25,12 +25,11 @@ #include "qemu/osdep.h" #include "qemu/range.h" #include "qapi/error.h" +#include "hw/dma/i8257.h" #include "hw/southbridge/piix.h" #include "hw/irq.h" #include "hw/isa/isa.h" #include "hw/xen/xen.h" -#include "sysemu/xen.h" -#include "sysemu/reset.h" #include "sysemu/runstate.h" #include "migration/vmstate.h" #include "hw/acpi/acpi_aml_interface.h" @@ -155,9 +154,9 @@ static void piix3_write_config_xen(PCIDevice *dev, piix3_write_config(dev, address, val, len); } -static void piix3_reset(void *opaque) +static void piix3_reset(DeviceState *dev) { - PIIX3State *d = opaque; + PIIX3State *d = PIIX3_PCI_DEVICE(dev); uint8_t *pci_conf = d->dev.config; pci_conf[0x04] = 0x07; /* master, memory and I/O */ @@ -289,15 +288,21 @@ static uint64_t rcr_read(void *opaque, hwaddr addr, unsigned len) static const MemoryRegionOps rcr_ops = { .read = rcr_read, .write = rcr_write, - .endianness = DEVICE_LITTLE_ENDIAN + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, }; static void pci_piix3_realize(PCIDevice *dev, Error **errp) { PIIX3State *d = PIIX3_PCI_DEVICE(dev); + ISABus *isa_bus; - if (!isa_bus_new(DEVICE(d), get_system_memory(), - pci_address_space_io(dev), errp)) { + isa_bus = isa_bus_new(DEVICE(d), pci_address_space(dev), + pci_address_space_io(dev), errp); + if (!isa_bus) { return; } @@ -306,7 +311,7 @@ static void pci_piix3_realize(PCIDevice *dev, Error **errp) memory_region_add_subregion_overlap(pci_address_space_io(dev), PIIX_RCR_IOPORT, &d->rcr_mem, 1); - qemu_register_reset(piix3_reset, d); + i8257_dma_init(isa_bus, 0); } static void build_pci_isa_aml(AcpiDevAmlIf *adev, Aml *scope) @@ -328,6 +333,7 @@ static void pci_piix3_class_init(ObjectClass *klass, void *data) PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass); + dc->reset = piix3_reset; dc->desc = "ISA bridge"; dc->vmsd = &vmstate_piix3; dc->hotpluggable = false; @@ -370,7 +376,7 @@ static void piix3_realize(PCIDevice *dev, Error **errp) pci_bus_irqs(pci_bus, piix3_set_irq, pci_slot_get_pirq, piix3, PIIX_NUM_PIRQS); pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq); -}; +} static void piix3_class_init(ObjectClass *klass, void *data) { @@ -405,7 +411,7 @@ static void piix3_xen_realize(PCIDevice *dev, Error **errp) */ pci_bus_irqs(pci_bus, xen_piix3_set_irq, xen_pci_slot_get_pirq, piix3, XEN_PIIX_NUM_PIRQS); -}; +} static void piix3_xen_class_init(ObjectClass *klass, void *data) { @@ -413,7 +419,7 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data) k->config_write = piix3_write_config_xen; k->realize = piix3_xen_realize; -}; +} static const TypeInfo piix3_xen_info = { .name = TYPE_PIIX3_XEN_DEVICE, diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index 15f344dbb7..8fc1db6dc9 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -28,6 +28,7 @@ #include "hw/irq.h" #include "hw/southbridge/piix.h" #include "hw/pci/pci.h" +#include "hw/ide/piix.h" #include "hw/isa/isa.h" #include "hw/intc/i8259.h" #include "hw/dma/i8257.h" @@ -139,9 +140,11 @@ static void piix4_isa_reset(DeviceState *dev) pci_conf[0xab] = 0x00; pci_conf[0xac] = 0x00; pci_conf[0xae] = 0x00; + + d->rcr = 0; } -static int piix4_ide_post_load(void *opaque, int version_id) +static int piix4_post_load(void *opaque, int version_id) { PIIX4State *s = opaque; @@ -156,7 +159,7 @@ static const VMStateDescription vmstate_piix4 = { .name = "PIIX4", .version_id = 3, .minimum_version_id = 2, - .post_load = piix4_ide_post_load, + .post_load = piix4_post_load, .fields = (VMStateField[]) { VMSTATE_PCI_DEVICE(dev, PIIX4State), VMSTATE_UINT8_V(rcr, PIIX4State, 3), @@ -254,7 +257,6 @@ static void piix4_realize(PCIDevice *dev, Error **errp) if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) { return; } - pci_ide_create_devs(PCI_DEVICE(&s->ide)); /* USB */ qdev_prop_set_int32(DEVICE(&s->uhci), "addr", dev->devfn + 2); @@ -277,7 +279,7 @@ static void piix4_init(Object *obj) PIIX4State *s = PIIX4_PCI_DEVICE(obj); object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC); - object_initialize_child(obj, "ide", &s->ide, "piix4-ide"); + object_initialize_child(obj, "ide", &s->ide, TYPE_PIIX4_IDE); object_initialize_child(obj, "uhci", &s->uhci, "piix4-usb-uhci"); object_initialize_child(obj, "pm", &s->pm, TYPE_PIIX4_PM); diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 8f656251b8..3f9bd0c04d 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -17,11 +17,13 @@ #include "hw/isa/vt82c686.h" #include "hw/pci/pci.h" #include "hw/qdev-properties.h" +#include "hw/ide/pci.h" #include "hw/isa/isa.h" #include "hw/isa/superio.h" #include "hw/intc/i8259.h" #include "hw/irq.h" #include "hw/dma/i8257.h" +#include "hw/usb/hcd-uhci.h" #include "hw/timer/i8254.h" #include "hw/rtc/mc146818rtc.h" #include "migration/vmstate.h" @@ -248,6 +250,8 @@ static const ViaPMInitInfo vt82c686b_pm_init_info = { .device_id = PCI_DEVICE_ID_VIA_82C686B_PM, }; +#define TYPE_VT82C686B_PM "vt82c686b-pm" + static const TypeInfo vt82c686b_pm_info = { .name = TYPE_VT82C686B_PM, .parent = TYPE_VIA_PM, @@ -259,6 +263,8 @@ static const ViaPMInitInfo vt8231_pm_init_info = { .device_id = PCI_DEVICE_ID_VIA_8231_PM, }; +#define TYPE_VT8231_PM "vt8231-pm" + static const TypeInfo vt8231_pm_info = { .name = TYPE_VT8231_PM, .parent = TYPE_VIA_PM, @@ -543,8 +549,13 @@ struct ViaISAState { PCIDevice dev; qemu_irq cpu_intr; qemu_irq *isa_irqs; - ISABus *isa_bus; - ViaSuperIOState *via_sio; + ViaSuperIOState via_sio; + RTCState rtc; + PCIIDEState ide; + UHCIState uhci[2]; + ViaPMState pm; + PCIDevice ac97; + PCIDevice mc97; }; static const VMStateDescription vmstate_via = { @@ -557,10 +568,23 @@ static const VMStateDescription vmstate_via = { } }; +static void via_isa_init(Object *obj) +{ + ViaISAState *s = VIA_ISA(obj); + + object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC); + object_initialize_child(obj, "ide", &s->ide, TYPE_VIA_IDE); + object_initialize_child(obj, "uhci1", &s->uhci[0], TYPE_VT82C686B_USB_UHCI); + object_initialize_child(obj, "uhci2", &s->uhci[1], TYPE_VT82C686B_USB_UHCI); + object_initialize_child(obj, "ac97", &s->ac97, TYPE_VIA_AC97); + object_initialize_child(obj, "mc97", &s->mc97, TYPE_VIA_MC97); +} + static const TypeInfo via_isa_info = { .name = TYPE_VIA_ISA, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(ViaISAState), + .instance_init = via_isa_init, .abstract = true, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, @@ -584,24 +608,74 @@ static void via_isa_realize(PCIDevice *d, Error **errp) { ViaISAState *s = VIA_ISA(d); DeviceState *dev = DEVICE(d); + PCIBus *pci_bus = pci_get_bus(d); qemu_irq *isa_irq; + ISABus *isa_bus; int i; qdev_init_gpio_out(dev, &s->cpu_intr, 1); isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1); - s->isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d), - &error_fatal); - s->isa_irqs = i8259_init(s->isa_bus, *isa_irq); - isa_bus_irqs(s->isa_bus, s->isa_irqs); - i8254_pit_init(s->isa_bus, 0x40, 0, NULL); - i8257_dma_init(s->isa_bus, 0); - mc146818_rtc_init(s->isa_bus, 2000, NULL); + isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d), + errp); + + if (!isa_bus) { + return; + } + + s->isa_irqs = i8259_init(isa_bus, *isa_irq); + isa_bus_irqs(isa_bus, s->isa_irqs); + i8254_pit_init(isa_bus, 0x40, 0, NULL); + i8257_dma_init(isa_bus, 0); + + /* RTC */ + qdev_prop_set_int32(DEVICE(&s->rtc), "base_year", 2000); + if (!qdev_realize(DEVICE(&s->rtc), BUS(isa_bus), errp)) { + return; + } + isa_connect_gpio_out(ISA_DEVICE(&s->rtc), 0, s->rtc.isairq); for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) { if (i < PCI_COMMAND || i >= PCI_REVISION_ID) { d->wmask[i] = 0; } } + + /* Super I/O */ + if (!qdev_realize(DEVICE(&s->via_sio), BUS(isa_bus), errp)) { + return; + } + + /* Function 1: IDE */ + qdev_prop_set_int32(DEVICE(&s->ide), "addr", d->devfn + 1); + if (!qdev_realize(DEVICE(&s->ide), BUS(pci_bus), errp)) { + return; + } + + /* Functions 2-3: USB Ports */ + for (i = 0; i < ARRAY_SIZE(s->uhci); i++) { + qdev_prop_set_int32(DEVICE(&s->uhci[i]), "addr", d->devfn + 2 + i); + if (!qdev_realize(DEVICE(&s->uhci[i]), BUS(pci_bus), errp)) { + return; + } + } + + /* Function 4: Power Management */ + qdev_prop_set_int32(DEVICE(&s->pm), "addr", d->devfn + 4); + if (!qdev_realize(DEVICE(&s->pm), BUS(pci_bus), errp)) { + return; + } + + /* Function 5: AC97 Audio */ + qdev_prop_set_int32(DEVICE(&s->ac97), "addr", d->devfn + 5); + if (!qdev_realize(DEVICE(&s->ac97), BUS(pci_bus), errp)) { + return; + } + + /* Function 6: MC97 Modem */ + qdev_prop_set_int32(DEVICE(&s->mc97), "addr", d->devfn + 6); + if (!qdev_realize(DEVICE(&s->mc97), BUS(pci_bus), errp)) { + return; + } } /* TYPE_VT82C686B_ISA */ @@ -615,7 +689,7 @@ static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, pci_default_write_config(d, addr, val, len); if (addr == 0x85) { /* BIT(1): enable or disable superio config io ports */ - via_superio_io_enable(s->via_sio, val & BIT(1)); + via_superio_io_enable(&s->via_sio, val & BIT(1)); } } @@ -639,13 +713,12 @@ static void vt82c686b_isa_reset(DeviceState *dev) pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */ } -static void vt82c686b_realize(PCIDevice *d, Error **errp) +static void vt82c686b_init(Object *obj) { - ViaISAState *s = VIA_ISA(d); + ViaISAState *s = VIA_ISA(obj); - via_isa_realize(d, errp); - s->via_sio = VIA_SUPERIO(isa_create_simple(s->isa_bus, - TYPE_VT82C686B_SUPERIO)); + object_initialize_child(obj, "sio", &s->via_sio, TYPE_VT82C686B_SUPERIO); + object_initialize_child(obj, "pm", &s->pm, TYPE_VT82C686B_PM); } static void vt82c686b_class_init(ObjectClass *klass, void *data) @@ -653,7 +726,7 @@ static void vt82c686b_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - k->realize = vt82c686b_realize; + k->realize = via_isa_realize; k->config_write = vt82c686b_write_config; k->vendor_id = PCI_VENDOR_ID_VIA; k->device_id = PCI_DEVICE_ID_VIA_82C686B_ISA; @@ -670,6 +743,7 @@ static const TypeInfo vt82c686b_isa_info = { .name = TYPE_VT82C686B_ISA, .parent = TYPE_VIA_ISA, .instance_size = sizeof(ViaISAState), + .instance_init = vt82c686b_init, .class_init = vt82c686b_class_init, }; @@ -684,7 +758,7 @@ static void vt8231_write_config(PCIDevice *d, uint32_t addr, pci_default_write_config(d, addr, val, len); if (addr == 0x50) { /* BIT(2): enable or disable superio config io ports */ - via_superio_io_enable(s->via_sio, val & BIT(2)); + via_superio_io_enable(&s->via_sio, val & BIT(2)); } } @@ -703,13 +777,12 @@ static void vt8231_isa_reset(DeviceState *dev) pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */ } -static void vt8231_realize(PCIDevice *d, Error **errp) +static void vt8231_init(Object *obj) { - ViaISAState *s = VIA_ISA(d); + ViaISAState *s = VIA_ISA(obj); - via_isa_realize(d, errp); - s->via_sio = VIA_SUPERIO(isa_create_simple(s->isa_bus, - TYPE_VT8231_SUPERIO)); + object_initialize_child(obj, "sio", &s->via_sio, TYPE_VT8231_SUPERIO); + object_initialize_child(obj, "pm", &s->pm, TYPE_VT8231_PM); } static void vt8231_class_init(ObjectClass *klass, void *data) @@ -717,7 +790,7 @@ static void vt8231_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - k->realize = vt8231_realize; + k->realize = via_isa_realize; k->config_write = vt8231_write_config; k->vendor_id = PCI_VENDOR_ID_VIA; k->device_id = PCI_DEVICE_ID_VIA_8231_ISA; @@ -734,6 +807,7 @@ static const TypeInfo vt8231_isa_info = { .name = TYPE_VT8231_ISA, .parent = TYPE_VIA_ISA, .instance_size = sizeof(ViaISAState), + .instance_init = vt8231_init, .class_init = vt8231_class_init, }; diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c index 7c7d777781..31080c22c9 100644 --- a/hw/mem/nvdimm.c +++ b/hw/mem/nvdimm.c @@ -149,7 +149,7 @@ static void nvdimm_prepare_memory_region(NVDIMMDevice *nvdimm, Error **errp) if (!nvdimm->unarmed && memory_region_is_rom(mr)) { HostMemoryBackend *hostmem = dimm->hostmem; - error_setg(errp, "'unarmed' property must be off since memdev %s " + error_setg(errp, "'unarmed' property must be 'on' since memdev %s " "is read-only", object_get_canonical_path_component(OBJECT(hostmem))); return; diff --git a/hw/mips/bootloader.c b/hw/mips/bootloader.c index 99991f8b2b..f5f42f2bf2 100644 --- a/hw/mips/bootloader.c +++ b/hw/mips/bootloader.c @@ -165,15 +165,29 @@ void bl_gen_jump_to(uint32_t **p, target_ulong jump_addr) bl_gen_nop(p); /* delay slot */ } -void bl_gen_jump_kernel(uint32_t **p, target_ulong sp, target_ulong a0, - target_ulong a1, target_ulong a2, target_ulong a3, +void bl_gen_jump_kernel(uint32_t **p, + bool set_sp, target_ulong sp, + bool set_a0, target_ulong a0, + bool set_a1, target_ulong a1, + bool set_a2, target_ulong a2, + bool set_a3, target_ulong a3, target_ulong kernel_addr) { - bl_gen_load_ulong(p, BL_REG_SP, sp); - bl_gen_load_ulong(p, BL_REG_A0, a0); - bl_gen_load_ulong(p, BL_REG_A1, a1); - bl_gen_load_ulong(p, BL_REG_A2, a2); - bl_gen_load_ulong(p, BL_REG_A3, a3); + if (set_sp) { + bl_gen_load_ulong(p, BL_REG_SP, sp); + } + if (set_a0) { + bl_gen_load_ulong(p, BL_REG_A0, a0); + } + if (set_a1) { + bl_gen_load_ulong(p, BL_REG_A1, a1); + } + if (set_a2) { + bl_gen_load_ulong(p, BL_REG_A2, a2); + } + if (set_a3) { + bl_gen_load_ulong(p, BL_REG_A3, a3); + } bl_gen_jump_to(p, kernel_addr); } diff --git a/hw/mips/boston.c b/hw/mips/boston.c index cab63f43bf..edda87e23c 100644 --- a/hw/mips/boston.c +++ b/hw/mips/boston.c @@ -352,7 +352,10 @@ static void gen_firmware(uint32_t *p, hwaddr kernel_entry, hwaddr fdt_addr) * a2/$6 = 0 * a3/$7 = 0 */ - bl_gen_jump_kernel(&p, 0, (int32_t)-2, fdt_addr, 0, 0, kernel_entry); + bl_gen_jump_kernel(&p, + true, 0, true, (int32_t)-2, + true, fdt_addr, true, 0, true, 0, + kernel_entry); } static const void *boston_fdt_filter(void *opaque, const void *fdt_orig, @@ -425,7 +428,7 @@ static inline XilinxPCIEHost * xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr, hwaddr cfg_base, uint64_t cfg_size, hwaddr mmio_base, uint64_t mmio_size, - qemu_irq irq, bool link_up) + qemu_irq irq) { DeviceState *dev; MemoryRegion *cfg, *mmio; @@ -437,7 +440,6 @@ xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr, qdev_prop_set_uint64(dev, "cfg_size", cfg_size); qdev_prop_set_uint64(dev, "mmio_base", mmio_base); qdev_prop_set_uint64(dev, "mmio_size", mmio_size); - qdev_prop_set_bit(dev, "link_up", link_up); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); @@ -730,21 +732,21 @@ static void boston_mach_init(MachineState *machine) boston_memmap[BOSTON_PCIE0].size, boston_memmap[BOSTON_PCIE0_MMIO].base, boston_memmap[BOSTON_PCIE0_MMIO].size, - get_cps_irq(&s->cps, 2), false); + get_cps_irq(&s->cps, 2)); xilinx_pcie_init(sys_mem, 1, boston_memmap[BOSTON_PCIE1].base, boston_memmap[BOSTON_PCIE1].size, boston_memmap[BOSTON_PCIE1_MMIO].base, boston_memmap[BOSTON_PCIE1_MMIO].size, - get_cps_irq(&s->cps, 1), false); + get_cps_irq(&s->cps, 1)); pcie2 = xilinx_pcie_init(sys_mem, 2, boston_memmap[BOSTON_PCIE2].base, boston_memmap[BOSTON_PCIE2].size, boston_memmap[BOSTON_PCIE2_MMIO].base, boston_memmap[BOSTON_PCIE2_MMIO].size, - get_cps_irq(&s->cps, 0), true); + get_cps_irq(&s->cps, 0)); platreg = g_new(MemoryRegion, 1); memory_region_init_io(platreg, NULL, &boston_platreg_ops, s, diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 5ee546f5f6..34befa5dd5 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -49,7 +49,6 @@ /* Fuloong 2e has a 512k flash: Winbond W39L040AP70Z */ #define BIOS_SIZE (512 * KiB) -#define MAX_IDE_BUS 2 /* * PMON is not part of qemu and released with BSD license, anyone @@ -180,8 +179,12 @@ static void write_bootloader(CPUMIPSState *env, uint8_t *base, /* Second part of the bootloader */ p = (uint32_t *)(base + 0x040); - bl_gen_jump_kernel(&p, ENVP_VADDR - 64, 2, ENVP_VADDR, ENVP_VADDR + 8, - loaderparams.ram_size, kernel_addr); + bl_gen_jump_kernel(&p, + true, ENVP_VADDR - 64, + true, 2, true, ENVP_VADDR, + true, ENVP_VADDR + 8, + true, loaderparams.ram_size, + kernel_addr); } static void main_cpu_reset(void *opaque) @@ -196,29 +199,6 @@ static void main_cpu_reset(void *opaque) } } -static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, - I2CBus **i2c_bus) -{ - PCIDevice *dev; - - dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(slot, 0), true, - TYPE_VT82C686B_ISA); - qdev_connect_gpio_out(DEVICE(dev), 0, intc); - - dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 1), "via-ide"); - pci_ide_create_devs(dev); - - pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci"); - pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), "vt82c686b-usb-uhci"); - - dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 4), TYPE_VT82C686B_PM); - *i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c")); - - /* Audio support */ - pci_create_simple(pci_bus, PCI_DEVFN(slot, 5), TYPE_VIA_AC97); - pci_create_simple(pci_bus, PCI_DEVFN(slot, 6), TYPE_VIA_MC97); -} - /* Network support */ static void network_init(PCIBus *pci_bus) { @@ -315,8 +295,20 @@ static void mips_fuloong2e_init(MachineState *machine) pci_bus = bonito_init((qemu_irq *)&(env->irq[2])); /* South bridge -> IP5 */ - vt82c686b_southbridge_init(pci_bus, FULOONG2E_VIA_SLOT, env->irq[5], - &smbus); + pci_dev = pci_create_simple_multifunction(pci_bus, + PCI_DEVFN(FULOONG2E_VIA_SLOT, 0), + true, TYPE_VT82C686B_ISA); + object_property_add_alias(OBJECT(machine), "rtc-time", + object_resolve_path_component(OBJECT(pci_dev), + "rtc"), + "date"); + qdev_connect_gpio_out(DEVICE(pci_dev), 0, env->irq[5]); + + dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "ide")); + pci_ide_create_devs(PCI_DEVICE(dev)); + + dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "pm")); + smbus = I2C_BUS(qdev_get_child_bus(dev, "i2c")); /* GPU */ if (vga_interface_type != VGA_NONE) { diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 7c3ad0974b..c0a2e0ab04 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -36,11 +36,12 @@ #include "hw/i2c/smbus_eeprom.h" #include "hw/block/flash.h" #include "hw/mips/mips.h" +#include "hw/mips/bootloader.h" #include "hw/mips/cpudevs.h" #include "hw/pci/pci.h" #include "qemu/log.h" #include "hw/mips/bios.h" -#include "hw/ide.h" +#include "hw/ide/pci.h" #include "hw/irq.h" #include "hw/loader.h" #include "elf.h" @@ -70,8 +71,6 @@ #define FLASH_SIZE 0x400000 -#define MAX_IDE_BUS 2 - typedef struct { MemoryRegion iomem; MemoryRegion iomem_lo; /* 0 - 0x900 */ @@ -867,88 +866,63 @@ static void write_bootloader(uint8_t *base, uint64_t run_addr, /* Second part of the bootloader */ p = (uint32_t *) (base + 0x580); - if (semihosting_get_argc()) { - /* Preserve a0 content as arguments have been passed */ - stl_p(p++, 0x00000000); /* nop */ - } else { - stl_p(p++, 0x24040002); /* addiu a0, zero, 2 */ - } - - /* lui sp, high(ENVP_VADDR) */ - stl_p(p++, 0x3c1d0000 | (((ENVP_VADDR - 64) >> 16) & 0xffff)); - /* ori sp, sp, low(ENVP_VADDR) */ - stl_p(p++, 0x37bd0000 | ((ENVP_VADDR - 64) & 0xffff)); - /* lui a1, high(ENVP_VADDR) */ - stl_p(p++, 0x3c050000 | ((ENVP_VADDR >> 16) & 0xffff)); - /* ori a1, a1, low(ENVP_VADDR) */ - stl_p(p++, 0x34a50000 | (ENVP_VADDR & 0xffff)); - /* lui a2, high(ENVP_VADDR + 8) */ - stl_p(p++, 0x3c060000 | (((ENVP_VADDR + 8) >> 16) & 0xffff)); - /* ori a2, a2, low(ENVP_VADDR + 8) */ - stl_p(p++, 0x34c60000 | ((ENVP_VADDR + 8) & 0xffff)); - /* lui a3, high(ram_low_size) */ - stl_p(p++, 0x3c070000 | (loaderparams.ram_low_size >> 16)); - /* ori a3, a3, low(ram_low_size) */ - stl_p(p++, 0x34e70000 | (loaderparams.ram_low_size & 0xffff)); - - /* Load BAR registers as done by YAMON */ - stl_p(p++, 0x3c09b400); /* lui t1, 0xb400 */ - -#if TARGET_BIG_ENDIAN - stl_p(p++, 0x3c08df00); /* lui t0, 0xdf00 */ -#else - stl_p(p++, 0x340800df); /* ori t0, r0, 0x00df */ -#endif - stl_p(p++, 0xad280068); /* sw t0, 0x0068(t1) */ - - stl_p(p++, 0x3c09bbe0); /* lui t1, 0xbbe0 */ - -#if TARGET_BIG_ENDIAN - stl_p(p++, 0x3c08c000); /* lui t0, 0xc000 */ -#else - stl_p(p++, 0x340800c0); /* ori t0, r0, 0x00c0 */ -#endif - stl_p(p++, 0xad280048); /* sw t0, 0x0048(t1) */ -#if TARGET_BIG_ENDIAN - stl_p(p++, 0x3c084000); /* lui t0, 0x4000 */ -#else - stl_p(p++, 0x34080040); /* ori t0, r0, 0x0040 */ -#endif - stl_p(p++, 0xad280050); /* sw t0, 0x0050(t1) */ - -#if TARGET_BIG_ENDIAN - stl_p(p++, 0x3c088000); /* lui t0, 0x8000 */ -#else - stl_p(p++, 0x34080080); /* ori t0, r0, 0x0080 */ -#endif - stl_p(p++, 0xad280058); /* sw t0, 0x0058(t1) */ -#if TARGET_BIG_ENDIAN - stl_p(p++, 0x3c083f00); /* lui t0, 0x3f00 */ -#else - stl_p(p++, 0x3408003f); /* ori t0, r0, 0x003f */ -#endif - stl_p(p++, 0xad280060); /* sw t0, 0x0060(t1) */ + /* + * Load BAR registers as done by YAMON: + * + * - set up PCI0 I/O BARs from 0x18000000 to 0x181fffff + * - set up PCI0 MEM0 at 0x10000000, size 0x7e00000 + * - set up PCI0 MEM1 at 0x18200000, size 0xbc00000 + * + */ + /* Bus endianess is always reversed */ #if TARGET_BIG_ENDIAN - stl_p(p++, 0x3c08c100); /* lui t0, 0xc100 */ +#define cpu_to_gt32 cpu_to_le32 #else - stl_p(p++, 0x340800c1); /* ori t0, r0, 0x00c1 */ +#define cpu_to_gt32 cpu_to_be32 #endif - stl_p(p++, 0xad280080); /* sw t0, 0x0080(t1) */ -#if TARGET_BIG_ENDIAN - stl_p(p++, 0x3c085e00); /* lui t0, 0x5e00 */ -#else - stl_p(p++, 0x3408005e); /* ori t0, r0, 0x005e */ -#endif - stl_p(p++, 0xad280088); /* sw t0, 0x0088(t1) */ - /* Jump to kernel code */ - stl_p(p++, 0x3c1f0000 | - ((kernel_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */ - stl_p(p++, 0x37ff0000 | - (kernel_entry & 0xffff)); /* ori ra, ra, low(kernel_entry) */ - stl_p(p++, 0x03e00009); /* jalr ra */ - stl_p(p++, 0x00000000); /* nop */ + /* move GT64120 registers from 0x14000000 to 0x1be00000 */ + bl_gen_write_u32(&p, /* GT_ISD */ + cpu_mips_phys_to_kseg1(NULL, 0x14000000 + 0x68), + cpu_to_gt32(0x1be00000 << 3)); + + /* setup MEM-to-PCI0 mapping */ + /* setup PCI0 io window to 0x18000000-0x181fffff */ + bl_gen_write_u32(&p, /* GT_PCI0IOLD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x48), + cpu_to_gt32(0x18000000 << 3)); + bl_gen_write_u32(&p, /* GT_PCI0IOHD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x50), + cpu_to_gt32(0x08000000 << 3)); + /* setup PCI0 mem windows */ + bl_gen_write_u32(&p, /* GT_PCI0M0LD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x58), + cpu_to_gt32(0x10000000 << 3)); + bl_gen_write_u32(&p, /* GT_PCI0M0HD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x60), + cpu_to_gt32(0x07e00000 << 3)); + + bl_gen_write_u32(&p, /* GT_PCI0M1LD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x80), + cpu_to_gt32(0x18200000 << 3)); + bl_gen_write_u32(&p, /* GT_PCI0M1HD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x88), + cpu_to_gt32(0x0bc00000 << 3)); + +#undef cpu_to_gt32 + + bl_gen_jump_kernel(&p, + true, ENVP_VADDR - 64, + /* + * If semihosting is used, arguments have already been + * passed, so we preserve $a0. + */ + !semihosting_get_argc(), 2, + true, ENVP_VADDR, + true, ENVP_VADDR + 8, + true, loaderparams.ram_low_size, + kernel_entry); /* YAMON subroutines */ p = (uint32_t *) (base + 0x800); @@ -1266,7 +1240,6 @@ void mips_malta_init(MachineState *machine) MaltaState *s; PCIDevice *piix4; DeviceState *dev; - DeviceState *pm_dev; s = MIPS_MALTA(qdev_new(TYPE_MIPS_MALTA)); sysbus_realize_and_unref(SYS_BUS_DEVICE(s), &error_fatal); @@ -1430,15 +1403,17 @@ void mips_malta_init(MachineState *machine) /* Southbridge */ piix4 = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0), true, TYPE_PIIX4_PCI_DEVICE); - dev = DEVICE(piix4); - isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0")); - pm_dev = DEVICE(object_resolve_path_component(OBJECT(dev), "pm")); - smbus = I2C_BUS(qdev_get_child_bus(pm_dev, "i2c")); + isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix4), "isa.0")); + + dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "ide")); + pci_ide_create_devs(PCI_DEVICE(dev)); /* Interrupt controller */ - qdev_connect_gpio_out_named(dev, "intr", 0, i8259_irq); + qdev_connect_gpio_out_named(DEVICE(piix4), "intr", 0, i8259_irq); /* generate SPD EEPROM data */ + dev = DEVICE(object_resolve_path_component(OBJECT(piix4), "pm")); + smbus = I2C_BUS(qdev_get_child_bus(dev, "i2c")); generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size); generate_eeprom_serial(&smbus_eeprom_buf[6 * 256]); smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size); diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h index ae99f58bab..9d423f6c09 100644 --- a/hw/net/e1000_regs.h +++ b/hw/net/e1000_regs.h @@ -793,6 +793,7 @@ #define E1000_CTRL_EXT_ASDCHK 0x00001000 /* auto speed detection check */ #define E1000_CTRL_EXT_EE_RST 0x00002000 /* EEPROM reset */ #define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external LINK_0 and LINK_1 pins */ +#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */ #define E1000_CTRL_EXT_EIAME 0x01000000 #define E1000_CTRL_EXT_IAME 0x08000000 /* Int ACK Auto-mask */ #define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */ diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index e9f696b4cf..b6903aea54 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -2526,6 +2526,7 @@ static void virtio_net_tx_complete(NetClientState *nc, ssize_t len) VirtIONet *n = qemu_get_nic_opaque(nc); VirtIONetQueue *q = virtio_net_get_subqueue(nc); VirtIODevice *vdev = VIRTIO_DEVICE(n); + int ret; virtqueue_push(q->tx_vq, q->async_tx.elem, 0); virtio_notify(vdev, q->tx_vq); @@ -2534,7 +2535,22 @@ static void virtio_net_tx_complete(NetClientState *nc, ssize_t len) q->async_tx.elem = NULL; virtio_queue_set_notification(q->tx_vq, 1); - virtio_net_flush_tx(q); + ret = virtio_net_flush_tx(q); + if (ret >= n->tx_burst) { + /* + * the flush has been stopped by tx_burst + * we will not receive notification for the + * remainining part, so re-schedule + */ + virtio_queue_set_notification(q->tx_vq, 0); + if (q->tx_bh) { + qemu_bh_schedule(q->tx_bh); + } else { + timer_mod(q->tx_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); + } + q->tx_waiting = 1; + } } /* TX */ @@ -2633,6 +2649,8 @@ drop: return num_packets; } +static void virtio_net_tx_timer(void *opaque); + static void virtio_net_handle_tx_timer(VirtIODevice *vdev, VirtQueue *vq) { VirtIONet *n = VIRTIO_NET(vdev); @@ -2650,15 +2668,13 @@ static void virtio_net_handle_tx_timer(VirtIODevice *vdev, VirtQueue *vq) } if (q->tx_waiting) { - virtio_queue_set_notification(vq, 1); + /* We already have queued packets, immediately flush */ timer_del(q->tx_timer); - q->tx_waiting = 0; - if (virtio_net_flush_tx(q) == -EINVAL) { - return; - } + virtio_net_tx_timer(q); } else { + /* re-arm timer to flush it (and more) on next tick */ timer_mod(q->tx_timer, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); q->tx_waiting = 1; virtio_queue_set_notification(vq, 0); } @@ -2691,6 +2707,8 @@ static void virtio_net_tx_timer(void *opaque) VirtIONetQueue *q = opaque; VirtIONet *n = q->n; VirtIODevice *vdev = VIRTIO_DEVICE(n); + int ret; + /* This happens when device was stopped but BH wasn't. */ if (!vdev->vm_running) { /* Make sure tx waiting is set, so we'll run when restarted. */ @@ -2705,8 +2723,33 @@ static void virtio_net_tx_timer(void *opaque) return; } + ret = virtio_net_flush_tx(q); + if (ret == -EBUSY || ret == -EINVAL) { + return; + } + /* + * If we flush a full burst of packets, assume there are + * more coming and immediately rearm + */ + if (ret >= n->tx_burst) { + q->tx_waiting = 1; + timer_mod(q->tx_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); + return; + } + /* + * If less than a full burst, re-enable notification and flush + * anything that may have come in while we weren't looking. If + * we find something, assume the guest is still active and rearm + */ virtio_queue_set_notification(q->tx_vq, 1); - virtio_net_flush_tx(q); + ret = virtio_net_flush_tx(q); + if (ret > 0) { + virtio_queue_set_notification(q->tx_vq, 0); + q->tx_waiting = 1; + timer_mod(q->tx_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout); + } } static void virtio_net_tx_bh(void *opaque) diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c index 5c815b4f0c..7d92c2d022 100644 --- a/hw/net/xen_nic.c +++ b/hw/net/xen_nic.c @@ -296,9 +296,8 @@ static int net_init(struct XenLegacyDevice *xendev) netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf, "xen", NULL, netdev); - snprintf(qemu_get_queue(netdev->nic)->info_str, - sizeof(qemu_get_queue(netdev->nic)->info_str), - "nic: xenbus vif macaddr=%s", netdev->mac); + qemu_set_info_str(qemu_get_queue(netdev->nic), + "nic: xenbus vif macaddr=%s", netdev->mac); /* fill info */ xenstore_write_be_int(&netdev->xendev, "feature-rx-copy", 1); diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index 791fe78a50..b8d2522f45 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -74,7 +74,6 @@ config PEGASOS2 imply ATI_VGA select MV64361 select VT82C686 - select IDE_VIA select SMBUS_EEPROM select VOF # This should come with VT82C686 @@ -126,6 +125,7 @@ config E500 select ETSEC select GPIO_MPC8XXX select OPENPIC + select PFLASH_CFI01 select PLATFORM_BUS select PPCE500_PCI select SERIAL diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 3e950ea3ba..2fe496677c 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -23,8 +23,10 @@ #include "e500-ccsr.h" #include "net/net.h" #include "qemu/config-file.h" +#include "hw/block/flash.h" #include "hw/char/serial.h" #include "hw/pci/pci.h" +#include "sysemu/block-backend-io.h" #include "sysemu/sysemu.h" #include "sysemu/kvm.h" #include "sysemu/reset.h" @@ -267,6 +269,31 @@ static void sysbus_device_create_devtree(SysBusDevice *sbdev, void *opaque) } } +static void create_devtree_flash(SysBusDevice *sbdev, + PlatformDevtreeData *data) +{ + g_autofree char *name = NULL; + uint64_t num_blocks = object_property_get_uint(OBJECT(sbdev), + "num-blocks", + &error_fatal); + uint64_t sector_length = object_property_get_uint(OBJECT(sbdev), + "sector-length", + &error_fatal); + uint64_t bank_width = object_property_get_uint(OBJECT(sbdev), + "width", + &error_fatal); + hwaddr flashbase = 0; + hwaddr flashsize = num_blocks * sector_length; + void *fdt = data->fdt; + + name = g_strdup_printf("%s/nor@%" PRIx64, data->node, flashbase); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop_string(fdt, name, "compatible", "cfi-flash"); + qemu_fdt_setprop_sized_cells(fdt, name, "reg", + 1, flashbase, 1, flashsize); + qemu_fdt_setprop_cell(fdt, name, "bank-width", bank_width); +} + static void platform_bus_create_devtree(PPCE500MachineState *pms, void *fdt, const char *mpic) { @@ -276,6 +303,8 @@ static void platform_bus_create_devtree(PPCE500MachineState *pms, uint64_t addr = pmc->platform_bus_base; uint64_t size = pmc->platform_bus_size; int irq_start = pmc->platform_bus_first_irq; + SysBusDevice *sbdev; + bool ambiguous; /* Create a /platform node that we can put all devices into */ @@ -302,6 +331,13 @@ static void platform_bus_create_devtree(PPCE500MachineState *pms, /* Loop through all dynamic sysbus devices and create nodes for them */ foreach_dynamic_sysbus_device(sysbus_device_create_devtree, &data); + sbdev = SYS_BUS_DEVICE(object_resolve_path_type("", TYPE_PFLASH_CFI01, + &ambiguous)); + if (sbdev) { + assert(!ambiguous); + create_devtree_flash(sbdev, &data); + } + g_free(node); } @@ -856,6 +892,7 @@ void ppce500_init(MachineState *machine) unsigned int pci_irq_nrs[PCI_NUM_PINS] = {1, 2, 3, 4}; IrqLines *irqs; DeviceState *dev, *mpicdev; + DriveInfo *dinfo; CPUPPCState *firstenv = NULL; MemoryRegion *ccsr_addr_space; SysBusDevice *s; @@ -1024,6 +1061,48 @@ void ppce500_init(MachineState *machine) pmc->platform_bus_base, &pms->pbus_dev->mmio); + dinfo = drive_get(IF_PFLASH, 0, 0); + if (dinfo) { + BlockBackend *blk = blk_by_legacy_dinfo(dinfo); + BlockDriverState *bs = blk_bs(blk); + uint64_t mmio_size = memory_region_size(&pms->pbus_dev->mmio); + uint64_t size = bdrv_getlength(bs); + uint32_t sector_len = 64 * KiB; + + if (!is_power_of_2(size)) { + error_report("Size of pflash file must be a power of two."); + exit(1); + } + + if (size > mmio_size) { + error_report("Size of pflash file must not be bigger than %" PRIu64 + " bytes.", mmio_size); + exit(1); + } + + if (!QEMU_IS_ALIGNED(size, sector_len)) { + error_report("Size of pflash file must be a multiple of %" PRIu32 + ".", sector_len); + exit(1); + } + + dev = qdev_new(TYPE_PFLASH_CFI01); + qdev_prop_set_drive(dev, "drive", blk); + qdev_prop_set_uint32(dev, "num-blocks", size / sector_len); + qdev_prop_set_uint64(dev, "sector-length", sector_len); + qdev_prop_set_uint8(dev, "width", 2); + qdev_prop_set_bit(dev, "big-endian", true); + qdev_prop_set_uint16(dev, "id0", 0x89); + qdev_prop_set_uint16(dev, "id1", 0x18); + qdev_prop_set_uint16(dev, "id2", 0x0000); + qdev_prop_set_uint16(dev, "id3", 0x0); + qdev_prop_set_string(dev, "name", "e500.flash"); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + + memory_region_add_subregion(&pms->pbus_dev->mmio, 0, + pflash_cfi01_get_memory(PFLASH_CFI01(dev))); + } + /* * Smart firmware defaults ahead! * diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build index 32babc9b48..c927337da0 100644 --- a/hw/ppc/meson.build +++ b/hw/ppc/meson.build @@ -59,8 +59,9 @@ ppc_ss.add(when: 'CONFIG_PPC440', if_true: files( 'ppc440_bamboo.c', 'ppc440_pcix.c', 'ppc440_uc.c')) ppc_ss.add(when: 'CONFIG_PPC4XX', if_true: files( + 'ppc4xx_devs.c', 'ppc4xx_pci.c', - 'ppc4xx_devs.c')) + 'ppc4xx_sdram.c')) ppc_ss.add(when: 'CONFIG_SAM460EX', if_true: files('sam460ex.c')) # PReP ppc_ss.add(when: 'CONFIG_PREP', if_true: files('prep.c')) diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index bb4d008ba9..f46d4bf51d 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -102,7 +102,7 @@ static void pegasos2_init(MachineState *machine) CPUPPCState *env; MemoryRegion *rom = g_new(MemoryRegion, 1); PCIBus *pci_bus; - PCIDevice *dev; + PCIDevice *dev, *via; I2CBus *i2c_bus; const char *fwname = machine->firmware ?: PROM_FILENAME; char *filename; @@ -159,30 +159,23 @@ static void pegasos2_init(MachineState *machine) pci_bus = mv64361_get_pci_bus(pm->mv, 1); /* VIA VT8231 South Bridge (multifunction PCI device) */ - /* VT8231 function 0: PCI-to-ISA Bridge */ - dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true, + via = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true, TYPE_VT8231_ISA); - qdev_connect_gpio_out(DEVICE(dev), 0, + object_property_add_alias(OBJECT(machine), "rtc-time", + object_resolve_path_component(OBJECT(via), + "rtc"), + "date"); + qdev_connect_gpio_out(DEVICE(via), 0, qdev_get_gpio_in_named(pm->mv, "gpp", 31)); - /* VT8231 function 1: IDE Controller */ - dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 1), "via-ide"); + dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "ide")); pci_ide_create_devs(dev); - /* VT8231 function 2-3: USB Ports */ - pci_create_simple(pci_bus, PCI_DEVFN(12, 2), "vt82c686b-usb-uhci"); - pci_create_simple(pci_bus, PCI_DEVFN(12, 3), "vt82c686b-usb-uhci"); - - /* VT8231 function 4: Power Management Controller */ - dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 4), TYPE_VT8231_PM); + dev = PCI_DEVICE(object_resolve_path_component(OBJECT(via), "pm")); i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c")); spd_data = spd_data_generate(DDR, machine->ram_size); smbus_eeprom_init_one(i2c_bus, 0x57, spd_data); - /* VT8231 function 5-6: AC97 Audio & Modem */ - pci_create_simple(pci_bus, PCI_DEVFN(12, 5), TYPE_VIA_AC97); - pci_create_simple(pci_bus, PCI_DEVFN(12, 6), TYPE_VIA_MC97); - /* other PC hardware */ pci_vga_init(pci_bus); diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 19e8eb885f..9ee79192dd 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -58,6 +58,7 @@ static void pnv_core_cpu_reset(PnvCore *pc, PowerPCCPU *cpu) env->msr |= MSR_HVB; /* Hypervisor mode */ env->spr[SPR_HRMOR] = pc->hrmor; hreg_compute_hflags(env); + ppc_maybe_interrupt(env); pcc->intc_reset(pc->chip, cpu); } diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 690f448cb9..dc86c1c7db 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -40,9 +40,8 @@ static void cpu_ppc_tb_stop (CPUPPCState *env); static void cpu_ppc_tb_start (CPUPPCState *env); -void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level) +void ppc_set_irq(PowerPCCPU *cpu, int irq, int level) { - CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; unsigned int old_pending; bool locked = false; @@ -56,21 +55,17 @@ void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level) old_pending = env->pending_interrupts; if (level) { - env->pending_interrupts |= 1 << n_IRQ; - cpu_interrupt(cs, CPU_INTERRUPT_HARD); + env->pending_interrupts |= irq; } else { - env->pending_interrupts &= ~(1 << n_IRQ); - if (env->pending_interrupts == 0) { - cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); - } + env->pending_interrupts &= ~irq; } if (old_pending != env->pending_interrupts) { - kvmppc_set_interrupt(cpu, n_IRQ, level); + ppc_maybe_interrupt(env); + kvmppc_set_interrupt(cpu, irq, level); } - - trace_ppc_irq_set_exit(env, n_IRQ, level, env->pending_interrupts, + trace_ppc_irq_set_exit(env, irq, level, env->pending_interrupts, CPU(cpu)->interrupt_request); if (locked) { diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c index 5fbf44009e..651263926e 100644 --- a/hw/ppc/ppc440_uc.c +++ b/hw/ppc/ppc440_uc.c @@ -10,21 +10,14 @@ #include "qemu/osdep.h" #include "qemu/units.h" -#include "qemu/error-report.h" #include "qapi/error.h" #include "qemu/log.h" -#include "qemu/module.h" #include "hw/irq.h" -#include "exec/memory.h" -#include "cpu.h" #include "hw/ppc/ppc4xx.h" #include "hw/qdev-properties.h" #include "hw/pci/pci.h" -#include "sysemu/block-backend.h" #include "sysemu/reset.h" #include "ppc440.h" -#include "qom/object.h" -#include "trace.h" /*****************************************************************************/ /* L2 Cache as SRAM */ @@ -479,331 +472,6 @@ void ppc4xx_sdr_init(CPUPPCState *env) } /*****************************************************************************/ -/* SDRAM controller */ -enum { - SDRAM0_CFGADDR = 0x10, - SDRAM0_CFGDATA, - SDRAM_R0BAS = 0x40, - SDRAM_R1BAS, - SDRAM_R2BAS, - SDRAM_R3BAS, - SDRAM_CONF1HB = 0x45, - SDRAM_PLBADDULL = 0x4a, - SDRAM_CONF1LL = 0x4b, - SDRAM_CONFPATHB = 0x4f, - SDRAM_PLBADDUHB = 0x50, -}; - -static uint32_t sdram_ddr2_bcr(hwaddr ram_base, hwaddr ram_size) -{ - uint32_t bcr; - - switch (ram_size) { - case 8 * MiB: - bcr = 0xffc0; - break; - case 16 * MiB: - bcr = 0xff80; - break; - case 32 * MiB: - bcr = 0xff00; - break; - case 64 * MiB: - bcr = 0xfe00; - break; - case 128 * MiB: - bcr = 0xfc00; - break; - case 256 * MiB: - bcr = 0xf800; - break; - case 512 * MiB: - bcr = 0xf000; - break; - case 1 * GiB: - bcr = 0xe000; - break; - case 2 * GiB: - bcr = 0xc000; - break; - case 4 * GiB: - bcr = 0x8000; - break; - default: - error_report("invalid RAM size " TARGET_FMT_plx, ram_size); - return 0; - } - bcr |= ram_base >> 2 & 0xffe00000; - bcr |= 1; - - return bcr; -} - -static inline hwaddr sdram_ddr2_base(uint32_t bcr) -{ - return (bcr & 0xffe00000) << 2; -} - -static uint64_t sdram_ddr2_size(uint32_t bcr) -{ - uint64_t size; - int sh; - - sh = 1024 - ((bcr >> 6) & 0x3ff); - size = 8 * MiB * sh; - - return size; -} - -static void sdram_bank_map(Ppc4xxSdramBank *bank) -{ - memory_region_init(&bank->container, NULL, "sdram-container", bank->size); - memory_region_add_subregion(&bank->container, 0, &bank->ram); - memory_region_add_subregion(get_system_memory(), bank->base, - &bank->container); -} - -static void sdram_bank_unmap(Ppc4xxSdramBank *bank) -{ - memory_region_del_subregion(get_system_memory(), &bank->container); - memory_region_del_subregion(&bank->container, &bank->ram); - object_unparent(OBJECT(&bank->container)); -} - -static void sdram_ddr2_set_bcr(Ppc4xxSdramDdr2State *sdram, int i, - uint32_t bcr, int enabled) -{ - if (sdram->bank[i].bcr & 1) { - /* First unmap RAM if enabled */ - trace_ppc4xx_sdram_unmap(sdram_ddr2_base(sdram->bank[i].bcr), - sdram_ddr2_size(sdram->bank[i].bcr)); - sdram_bank_unmap(&sdram->bank[i]); - } - sdram->bank[i].bcr = bcr & 0xffe0ffc1; - if (enabled && (bcr & 1)) { - trace_ppc4xx_sdram_map(sdram_ddr2_base(bcr), sdram_ddr2_size(bcr)); - sdram_bank_map(&sdram->bank[i]); - } -} - -static void sdram_ddr2_map_bcr(Ppc4xxSdramDdr2State *sdram) -{ - int i; - - for (i = 0; i < sdram->nbanks; i++) { - if (sdram->bank[i].size) { - sdram_ddr2_set_bcr(sdram, i, - sdram_ddr2_bcr(sdram->bank[i].base, - sdram->bank[i].size), 1); - } else { - sdram_ddr2_set_bcr(sdram, i, 0, 0); - } - } -} - -static void sdram_ddr2_unmap_bcr(Ppc4xxSdramDdr2State *sdram) -{ - int i; - - for (i = 0; i < sdram->nbanks; i++) { - if (sdram->bank[i].size) { - sdram_ddr2_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0); - } - } -} - -static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn) -{ - Ppc4xxSdramDdr2State *sdram = opaque; - uint32_t ret = 0; - - switch (dcrn) { - case SDRAM_R0BAS: - case SDRAM_R1BAS: - case SDRAM_R2BAS: - case SDRAM_R3BAS: - if (sdram->bank[dcrn - SDRAM_R0BAS].size) { - ret = sdram_ddr2_bcr(sdram->bank[dcrn - SDRAM_R0BAS].base, - sdram->bank[dcrn - SDRAM_R0BAS].size); - } - break; - case SDRAM_CONF1HB: - case SDRAM_CONF1LL: - case SDRAM_CONFPATHB: - case SDRAM_PLBADDULL: - case SDRAM_PLBADDUHB: - break; - case SDRAM0_CFGADDR: - ret = sdram->addr; - break; - case SDRAM0_CFGDATA: - switch (sdram->addr) { - case 0x14: /* SDRAM_MCSTAT (405EX) */ - case 0x1F: - ret = 0x80000000; - break; - case 0x21: /* SDRAM_MCOPT2 */ - ret = sdram->mcopt2; - break; - case 0x40: /* SDRAM_MB0CF */ - ret = 0x00008001; - break; - case 0x7A: /* SDRAM_DLCR */ - ret = 0x02000000; - break; - case 0xE1: /* SDR0_DDR0 */ - ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1; - break; - default: - break; - } - break; - default: - break; - } - - return ret; -} - -#define SDRAM_DDR2_MCOPT2_DCEN BIT(27) - -static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val) -{ - Ppc4xxSdramDdr2State *sdram = opaque; - - switch (dcrn) { - case SDRAM_R0BAS: - case SDRAM_R1BAS: - case SDRAM_R2BAS: - case SDRAM_R3BAS: - case SDRAM_CONF1HB: - case SDRAM_CONF1LL: - case SDRAM_CONFPATHB: - case SDRAM_PLBADDULL: - case SDRAM_PLBADDUHB: - break; - case SDRAM0_CFGADDR: - sdram->addr = val; - break; - case SDRAM0_CFGDATA: - switch (sdram->addr) { - case 0x00: /* B0CR */ - break; - case 0x21: /* SDRAM_MCOPT2 */ - if (!(sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && - (val & SDRAM_DDR2_MCOPT2_DCEN)) { - trace_ppc4xx_sdram_enable("enable"); - /* validate all RAM mappings */ - sdram_ddr2_map_bcr(sdram); - sdram->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN; - } else if ((sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && - !(val & SDRAM_DDR2_MCOPT2_DCEN)) { - trace_ppc4xx_sdram_enable("disable"); - /* invalidate all RAM mappings */ - sdram_ddr2_unmap_bcr(sdram); - sdram->mcopt2 &= ~SDRAM_DDR2_MCOPT2_DCEN; - } - break; - default: - break; - } - break; - default: - break; - } -} - -static void ppc4xx_sdram_ddr2_reset(DeviceState *dev) -{ - Ppc4xxSdramDdr2State *sdram = PPC4xx_SDRAM_DDR2(dev); - - sdram->addr = 0; - sdram->mcopt2 = 0; -} - -static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp) -{ - Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev); - Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); - /* - * SoC also has 4 GiB but that causes problem with 32 bit - * builds (4*GiB overflows the 32 bit ram_addr_t). - */ - const ram_addr_t valid_bank_sizes[] = { - 2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, - 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0 - }; - - if (s->nbanks < 1 || s->nbanks > 4) { - error_setg(errp, "Invalid number of RAM banks"); - return; - } - if (!s->dram_mr) { - error_setg(errp, "Missing dram memory region"); - return; - } - ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes); - - ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - - ppc4xx_dcr_register(dcr, SDRAM_R0BAS, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_R1BAS, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_R2BAS, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_R3BAS, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_CONF1HB, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_PLBADDULL, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_CONF1LL, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_CONFPATHB, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM_PLBADDUHB, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); -} - -static Property ppc4xx_sdram_ddr2_props[] = { - DEFINE_PROP_LINK("dram", Ppc4xxSdramDdr2State, dram_mr, TYPE_MEMORY_REGION, - MemoryRegion *), - DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdr2State, nbanks, 4), - DEFINE_PROP_END_OF_LIST(), -}; - -static void ppc4xx_sdram_ddr2_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = ppc4xx_sdram_ddr2_realize; - dc->reset = ppc4xx_sdram_ddr2_reset; - /* Reason: only works as function of a ppc4xx SoC */ - dc->user_creatable = false; - device_class_set_props(dc, ppc4xx_sdram_ddr2_props); -} - -void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s) -{ - sdram_ddr2_dcr_write(s, SDRAM0_CFGADDR, 0x21); - sdram_ddr2_dcr_write(s, SDRAM0_CFGDATA, 0x08000000); -} - -static const TypeInfo ppc4xx_types[] = { - { - .name = TYPE_PPC4xx_SDRAM_DDR2, - .parent = TYPE_PPC4xx_DCR_DEVICE, - .instance_size = sizeof(Ppc4xxSdramDdr2State), - .class_init = ppc4xx_sdram_ddr2_class_init, - } -}; -DEFINE_TYPES(ppc4xx_types) - -/*****************************************************************************/ /* PLB to AHB bridge */ enum { AHB_TOP = 0xA4, diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c index 12af90f244..c1d111465d 100644 --- a/hw/ppc/ppc4xx_devs.c +++ b/hw/ppc/ppc4xx_devs.c @@ -23,419 +23,10 @@ */ #include "qemu/osdep.h" -#include "qemu/units.h" -#include "sysemu/reset.h" #include "cpu.h" -#include "hw/irq.h" -#include "hw/ppc/ppc.h" #include "hw/ppc/ppc4xx.h" #include "hw/qdev-properties.h" -#include "qemu/log.h" -#include "exec/address-spaces.h" -#include "qemu/error-report.h" #include "qapi/error.h" -#include "trace.h" - -/*****************************************************************************/ -/* SDRAM controller */ -enum { - SDRAM0_CFGADDR = 0x010, - SDRAM0_CFGDATA = 0x011, -}; - -/* - * XXX: TOFIX: some patches have made this code become inconsistent: - * there are type inconsistencies, mixing hwaddr, target_ulong - * and uint32_t - */ -static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size) -{ - uint32_t bcr; - - switch (ram_size) { - case 4 * MiB: - bcr = 0; - break; - case 8 * MiB: - bcr = 0x20000; - break; - case 16 * MiB: - bcr = 0x40000; - break; - case 32 * MiB: - bcr = 0x60000; - break; - case 64 * MiB: - bcr = 0x80000; - break; - case 128 * MiB: - bcr = 0xA0000; - break; - case 256 * MiB: - bcr = 0xC0000; - break; - default: - qemu_log_mask(LOG_GUEST_ERROR, - "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__, - ram_size); - return 0; - } - bcr |= ram_base & 0xFF800000; - bcr |= 1; - - return bcr; -} - -static inline hwaddr sdram_ddr_base(uint32_t bcr) -{ - return bcr & 0xFF800000; -} - -static target_ulong sdram_ddr_size(uint32_t bcr) -{ - target_ulong size; - int sh; - - sh = (bcr >> 17) & 0x7; - if (sh == 7) { - size = -1; - } else { - size = (4 * MiB) << sh; - } - - return size; -} - -static void sdram_ddr_set_bcr(Ppc4xxSdramDdrState *sdram, int i, - uint32_t bcr, int enabled) -{ - if (sdram->bank[i].bcr & 1) { - /* Unmap RAM */ - trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr), - sdram_ddr_size(sdram->bank[i].bcr)); - memory_region_del_subregion(get_system_memory(), - &sdram->bank[i].container); - memory_region_del_subregion(&sdram->bank[i].container, - &sdram->bank[i].ram); - object_unparent(OBJECT(&sdram->bank[i].container)); - } - sdram->bank[i].bcr = bcr & 0xFFDEE001; - if (enabled && (bcr & 1)) { - trace_ppc4xx_sdram_map(sdram_ddr_base(bcr), sdram_ddr_size(bcr)); - memory_region_init(&sdram->bank[i].container, NULL, "sdram-container", - sdram_ddr_size(bcr)); - memory_region_add_subregion(&sdram->bank[i].container, 0, - &sdram->bank[i].ram); - memory_region_add_subregion(get_system_memory(), - sdram_ddr_base(bcr), - &sdram->bank[i].container); - } -} - -static void sdram_ddr_map_bcr(Ppc4xxSdramDdrState *sdram) -{ - int i; - - for (i = 0; i < sdram->nbanks; i++) { - if (sdram->bank[i].size != 0) { - sdram_ddr_set_bcr(sdram, i, sdram_ddr_bcr(sdram->bank[i].base, - sdram->bank[i].size), 1); - } else { - sdram_ddr_set_bcr(sdram, i, 0, 0); - } - } -} - -static void sdram_ddr_unmap_bcr(Ppc4xxSdramDdrState *sdram) -{ - int i; - - for (i = 0; i < sdram->nbanks; i++) { - trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr), - sdram_ddr_size(sdram->bank[i].bcr)); - memory_region_del_subregion(get_system_memory(), - &sdram->bank[i].ram); - } -} - -static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn) -{ - Ppc4xxSdramDdrState *sdram = opaque; - uint32_t ret; - - switch (dcrn) { - case SDRAM0_CFGADDR: - ret = sdram->addr; - break; - case SDRAM0_CFGDATA: - switch (sdram->addr) { - case 0x00: /* SDRAM_BESR0 */ - ret = sdram->besr0; - break; - case 0x08: /* SDRAM_BESR1 */ - ret = sdram->besr1; - break; - case 0x10: /* SDRAM_BEAR */ - ret = sdram->bear; - break; - case 0x20: /* SDRAM_CFG */ - ret = sdram->cfg; - break; - case 0x24: /* SDRAM_STATUS */ - ret = sdram->status; - break; - case 0x30: /* SDRAM_RTR */ - ret = sdram->rtr; - break; - case 0x34: /* SDRAM_PMIT */ - ret = sdram->pmit; - break; - case 0x40: /* SDRAM_B0CR */ - ret = sdram->bank[0].bcr; - break; - case 0x44: /* SDRAM_B1CR */ - ret = sdram->bank[1].bcr; - break; - case 0x48: /* SDRAM_B2CR */ - ret = sdram->bank[2].bcr; - break; - case 0x4C: /* SDRAM_B3CR */ - ret = sdram->bank[3].bcr; - break; - case 0x80: /* SDRAM_TR */ - ret = -1; /* ? */ - break; - case 0x94: /* SDRAM_ECCCFG */ - ret = sdram->ecccfg; - break; - case 0x98: /* SDRAM_ECCESR */ - ret = sdram->eccesr; - break; - default: /* Error */ - ret = -1; - break; - } - break; - default: - /* Avoid gcc warning */ - ret = 0; - break; - } - - return ret; -} - -static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val) -{ - Ppc4xxSdramDdrState *sdram = opaque; - - switch (dcrn) { - case SDRAM0_CFGADDR: - sdram->addr = val; - break; - case SDRAM0_CFGDATA: - switch (sdram->addr) { - case 0x00: /* SDRAM_BESR0 */ - sdram->besr0 &= ~val; - break; - case 0x08: /* SDRAM_BESR1 */ - sdram->besr1 &= ~val; - break; - case 0x10: /* SDRAM_BEAR */ - sdram->bear = val; - break; - case 0x20: /* SDRAM_CFG */ - val &= 0xFFE00000; - if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) { - trace_ppc4xx_sdram_enable("enable"); - /* validate all RAM mappings */ - sdram_ddr_map_bcr(sdram); - sdram->status &= ~0x80000000; - } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) { - trace_ppc4xx_sdram_enable("disable"); - /* invalidate all RAM mappings */ - sdram_ddr_unmap_bcr(sdram); - sdram->status |= 0x80000000; - } - if (!(sdram->cfg & 0x40000000) && (val & 0x40000000)) { - sdram->status |= 0x40000000; - } else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000)) { - sdram->status &= ~0x40000000; - } - sdram->cfg = val; - break; - case 0x24: /* SDRAM_STATUS */ - /* Read-only register */ - break; - case 0x30: /* SDRAM_RTR */ - sdram->rtr = val & 0x3FF80000; - break; - case 0x34: /* SDRAM_PMIT */ - sdram->pmit = (val & 0xF8000000) | 0x07C00000; - break; - case 0x40: /* SDRAM_B0CR */ - sdram_ddr_set_bcr(sdram, 0, val, sdram->cfg & 0x80000000); - break; - case 0x44: /* SDRAM_B1CR */ - sdram_ddr_set_bcr(sdram, 1, val, sdram->cfg & 0x80000000); - break; - case 0x48: /* SDRAM_B2CR */ - sdram_ddr_set_bcr(sdram, 2, val, sdram->cfg & 0x80000000); - break; - case 0x4C: /* SDRAM_B3CR */ - sdram_ddr_set_bcr(sdram, 3, val, sdram->cfg & 0x80000000); - break; - case 0x80: /* SDRAM_TR */ - sdram->tr = val & 0x018FC01F; - break; - case 0x94: /* SDRAM_ECCCFG */ - sdram->ecccfg = val & 0x00F00000; - break; - case 0x98: /* SDRAM_ECCESR */ - val &= 0xFFF0F000; - if (sdram->eccesr == 0 && val != 0) { - qemu_irq_raise(sdram->irq); - } else if (sdram->eccesr != 0 && val == 0) { - qemu_irq_lower(sdram->irq); - } - sdram->eccesr = val; - break; - default: /* Error */ - break; - } - break; - } -} - -static void ppc4xx_sdram_ddr_reset(DeviceState *dev) -{ - Ppc4xxSdramDdrState *sdram = PPC4xx_SDRAM_DDR(dev); - - sdram->addr = 0; - sdram->bear = 0; - sdram->besr0 = 0; /* No error */ - sdram->besr1 = 0; /* No error */ - sdram->cfg = 0; - sdram->ecccfg = 0; /* No ECC */ - sdram->eccesr = 0; /* No error */ - sdram->pmit = 0x07C00000; - sdram->rtr = 0x05F00000; - sdram->tr = 0x00854009; - /* We pre-initialize RAM banks */ - sdram->status = 0; - sdram->cfg = 0x00800000; -} - -static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp) -{ - Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev); - Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); - const ram_addr_t valid_bank_sizes[] = { - 256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0 - }; - - if (s->nbanks < 1 || s->nbanks > 4) { - error_setg(errp, "Invalid number of RAM banks"); - return; - } - if (!s->dram_mr) { - error_setg(errp, "Missing dram memory region"); - return; - } - ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes); - - sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); - - ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR, - s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write); - ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA, - s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write); -} - -static Property ppc4xx_sdram_ddr_props[] = { - DEFINE_PROP_LINK("dram", Ppc4xxSdramDdrState, dram_mr, TYPE_MEMORY_REGION, - MemoryRegion *), - DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdrState, nbanks, 4), - DEFINE_PROP_END_OF_LIST(), -}; - -static void ppc4xx_sdram_ddr_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = ppc4xx_sdram_ddr_realize; - dc->reset = ppc4xx_sdram_ddr_reset; - /* Reason: only works as function of a ppc4xx SoC */ - dc->user_creatable = false; - device_class_set_props(dc, ppc4xx_sdram_ddr_props); -} - -void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState *s) -{ - sdram_ddr_dcr_write(s, SDRAM0_CFGADDR, 0x20); - sdram_ddr_dcr_write(s, SDRAM0_CFGDATA, 0x80000000); -} - -/* - * Split RAM between SDRAM banks. - * - * sdram_bank_sizes[] must be in descending order, that is sizes[i] > sizes[i+1] - * and must be 0-terminated. - * - * The 4xx SDRAM controller supports a small number of banks, and each bank - * must be one of a small set of sizes. The number of banks and the supported - * sizes varies by SoC. - */ -void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks, - Ppc4xxSdramBank ram_banks[], - const ram_addr_t sdram_bank_sizes[]) -{ - ram_addr_t size_left = memory_region_size(ram); - ram_addr_t base = 0; - ram_addr_t bank_size; - int i; - int j; - - for (i = 0; i < nr_banks; i++) { - for (j = 0; sdram_bank_sizes[j] != 0; j++) { - bank_size = sdram_bank_sizes[j]; - if (bank_size <= size_left) { - char name[32]; - - ram_banks[i].base = base; - ram_banks[i].size = bank_size; - base += bank_size; - size_left -= bank_size; - snprintf(name, sizeof(name), "ppc4xx.sdram%d", i); - memory_region_init_alias(&ram_banks[i].ram, NULL, name, ram, - ram_banks[i].base, ram_banks[i].size); - break; - } - } - if (!size_left) { - /* No need to use the remaining banks. */ - break; - } - } - - if (size_left) { - ram_addr_t used_size = memory_region_size(ram) - size_left; - GString *s = g_string_new(NULL); - - for (i = 0; sdram_bank_sizes[i]; i++) { - g_string_append_printf(s, "%" PRIi64 "%s", - sdram_bank_sizes[i] / MiB, - sdram_bank_sizes[i + 1] ? ", " : ""); - } - error_report("at most %d bank%s of %s MiB each supported", - nr_banks, nr_banks == 1 ? "" : "s", s->str); - error_printf("Possible valid RAM size: %" PRIi64 " MiB\n", - used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB); - - g_string_free(s, true); - exit(EXIT_FAILURE); - } -} /*****************************************************************************/ /* MAL */ @@ -963,11 +554,6 @@ static void ppc4xx_dcr_class_init(ObjectClass *oc, void *data) static const TypeInfo ppc4xx_types[] = { { - .name = TYPE_PPC4xx_SDRAM_DDR, - .parent = TYPE_PPC4xx_DCR_DEVICE, - .instance_size = sizeof(Ppc4xxSdramDdrState), - .class_init = ppc4xx_sdram_ddr_class_init, - }, { .name = TYPE_PPC4xx_MAL, .parent = TYPE_PPC4xx_DCR_DEVICE, .instance_size = sizeof(Ppc4xxMalState), diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c new file mode 100644 index 0000000000..8d7137faf3 --- /dev/null +++ b/hw/ppc/ppc4xx_sdram.c @@ -0,0 +1,757 @@ +/* + * QEMU PowerPC 4xx embedded processors SDRAM controller emulation + * + * DDR SDRAM controller: + * Copyright (c) 2007 Jocelyn Mayer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * DDR2 SDRAM controller: + * Copyright (c) 2012 François Revol + * Copyright (c) 2016-2019 BALATON Zoltan + * + * This work is licensed under the GNU GPL license version 2 or later. + */ + +#include "qemu/osdep.h" +#include "qemu/units.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "exec/address-spaces.h" /* get_system_memory() */ +#include "hw/irq.h" +#include "hw/qdev-properties.h" +#include "hw/ppc/ppc4xx.h" +#include "trace.h" + +/*****************************************************************************/ +/* Shared functions */ + +/* + * Split RAM between SDRAM banks. + * + * sdram_bank_sizes[] must be in descending order, that is sizes[i] > sizes[i+1] + * and must be 0-terminated. + * + * The 4xx SDRAM controller supports a small number of banks, and each bank + * must be one of a small set of sizes. The number of banks and the supported + * sizes varies by SoC. + */ +static bool ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks, + Ppc4xxSdramBank ram_banks[], + const ram_addr_t sdram_bank_sizes[], + Error **errp) +{ + ERRP_GUARD(); + ram_addr_t size_left = memory_region_size(ram); + ram_addr_t base = 0; + ram_addr_t bank_size; + int i; + int j; + + for (i = 0; i < nr_banks; i++) { + for (j = 0; sdram_bank_sizes[j] != 0; j++) { + bank_size = sdram_bank_sizes[j]; + if (bank_size <= size_left) { + char name[32]; + + ram_banks[i].base = base; + ram_banks[i].size = bank_size; + base += bank_size; + size_left -= bank_size; + snprintf(name, sizeof(name), "ppc4xx.sdram%d", i); + memory_region_init_alias(&ram_banks[i].ram, NULL, name, ram, + ram_banks[i].base, ram_banks[i].size); + break; + } + } + if (!size_left) { + /* No need to use the remaining banks. */ + break; + } + } + + if (size_left) { + ram_addr_t used_size = memory_region_size(ram) - size_left; + GString *s = g_string_new(NULL); + + for (i = 0; sdram_bank_sizes[i]; i++) { + g_string_append_printf(s, "%" PRIi64 "%s", + sdram_bank_sizes[i] / MiB, + sdram_bank_sizes[i + 1] ? ", " : ""); + } + error_setg(errp, "Invalid SDRAM banks"); + error_append_hint(errp, "at most %d bank%s of %s MiB each supported\n", + nr_banks, nr_banks == 1 ? "" : "s", s->str); + error_append_hint(errp, "Possible valid RAM size: %" PRIi64 " MiB\n", + used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB); + + g_string_free(s, true); + return false; + } + return true; +} + +static void sdram_bank_map(Ppc4xxSdramBank *bank) +{ + trace_ppc4xx_sdram_map(bank->base, bank->size); + memory_region_init(&bank->container, NULL, "sdram-container", bank->size); + memory_region_add_subregion(&bank->container, 0, &bank->ram); + memory_region_add_subregion(get_system_memory(), bank->base, + &bank->container); +} + +static void sdram_bank_unmap(Ppc4xxSdramBank *bank) +{ + trace_ppc4xx_sdram_unmap(bank->base, bank->size); + memory_region_del_subregion(get_system_memory(), &bank->container); + memory_region_del_subregion(&bank->container, &bank->ram); + object_unparent(OBJECT(&bank->container)); +} + +static void sdram_bank_set_bcr(Ppc4xxSdramBank *bank, uint32_t bcr, + hwaddr base, hwaddr size, int enabled) +{ + if (memory_region_is_mapped(&bank->container)) { + sdram_bank_unmap(bank); + } + bank->bcr = bcr; + bank->base = base; + bank->size = size; + if (enabled && (bcr & 1)) { + sdram_bank_map(bank); + } +} + +enum { + SDRAM0_CFGADDR = 0x010, + SDRAM0_CFGDATA = 0x011, +}; + +/*****************************************************************************/ +/* DDR SDRAM controller */ +#define SDRAM_DDR_BCR_MASK 0xFFDEE001 + +static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size) +{ + uint32_t bcr; + + switch (ram_size) { + case 4 * MiB: + bcr = 0; + break; + case 8 * MiB: + bcr = 0x20000; + break; + case 16 * MiB: + bcr = 0x40000; + break; + case 32 * MiB: + bcr = 0x60000; + break; + case 64 * MiB: + bcr = 0x80000; + break; + case 128 * MiB: + bcr = 0xA0000; + break; + case 256 * MiB: + bcr = 0xC0000; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__, + ram_size); + return 0; + } + bcr |= ram_base & 0xFF800000; + bcr |= 1; + + return bcr; +} + +static inline hwaddr sdram_ddr_base(uint32_t bcr) +{ + return bcr & 0xFF800000; +} + +static hwaddr sdram_ddr_size(uint32_t bcr) +{ + hwaddr size; + int sh; + + sh = (bcr >> 17) & 0x7; + if (sh == 7) { + size = -1; + } else { + size = (4 * MiB) << sh; + } + + return size; +} + +static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn) +{ + Ppc4xxSdramDdrState *s = opaque; + uint32_t ret; + + switch (dcrn) { + case SDRAM0_CFGADDR: + ret = s->addr; + break; + case SDRAM0_CFGDATA: + switch (s->addr) { + case 0x00: /* SDRAM_BESR0 */ + ret = s->besr0; + break; + case 0x08: /* SDRAM_BESR1 */ + ret = s->besr1; + break; + case 0x10: /* SDRAM_BEAR */ + ret = s->bear; + break; + case 0x20: /* SDRAM_CFG */ + ret = s->cfg; + break; + case 0x24: /* SDRAM_STATUS */ + ret = s->status; + break; + case 0x30: /* SDRAM_RTR */ + ret = s->rtr; + break; + case 0x34: /* SDRAM_PMIT */ + ret = s->pmit; + break; + case 0x40: /* SDRAM_B0CR */ + ret = s->bank[0].bcr; + break; + case 0x44: /* SDRAM_B1CR */ + ret = s->bank[1].bcr; + break; + case 0x48: /* SDRAM_B2CR */ + ret = s->bank[2].bcr; + break; + case 0x4C: /* SDRAM_B3CR */ + ret = s->bank[3].bcr; + break; + case 0x80: /* SDRAM_TR */ + ret = -1; /* ? */ + break; + case 0x94: /* SDRAM_ECCCFG */ + ret = s->ecccfg; + break; + case 0x98: /* SDRAM_ECCESR */ + ret = s->eccesr; + break; + default: /* Error */ + ret = -1; + break; + } + break; + default: + /* Avoid gcc warning */ + ret = 0; + break; + } + + return ret; +} + +static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val) +{ + Ppc4xxSdramDdrState *s = opaque; + int i; + + switch (dcrn) { + case SDRAM0_CFGADDR: + s->addr = val; + break; + case SDRAM0_CFGDATA: + switch (s->addr) { + case 0x00: /* SDRAM_BESR0 */ + s->besr0 &= ~val; + break; + case 0x08: /* SDRAM_BESR1 */ + s->besr1 &= ~val; + break; + case 0x10: /* SDRAM_BEAR */ + s->bear = val; + break; + case 0x20: /* SDRAM_CFG */ + val &= 0xFFE00000; + if (!(s->cfg & 0x80000000) && (val & 0x80000000)) { + trace_ppc4xx_sdram_enable("enable"); + /* validate all RAM mappings */ + for (i = 0; i < s->nbanks; i++) { + if (s->bank[i].size) { + sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, + s->bank[i].base, s->bank[i].size, + 1); + } + } + s->status &= ~0x80000000; + } else if ((s->cfg & 0x80000000) && !(val & 0x80000000)) { + trace_ppc4xx_sdram_enable("disable"); + /* invalidate all RAM mappings */ + for (i = 0; i < s->nbanks; i++) { + if (s->bank[i].size) { + sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, + s->bank[i].base, s->bank[i].size, + 0); + } + } + s->status |= 0x80000000; + } + if (!(s->cfg & 0x40000000) && (val & 0x40000000)) { + s->status |= 0x40000000; + } else if ((s->cfg & 0x40000000) && !(val & 0x40000000)) { + s->status &= ~0x40000000; + } + s->cfg = val; + break; + case 0x24: /* SDRAM_STATUS */ + /* Read-only register */ + break; + case 0x30: /* SDRAM_RTR */ + s->rtr = val & 0x3FF80000; + break; + case 0x34: /* SDRAM_PMIT */ + s->pmit = (val & 0xF8000000) | 0x07C00000; + break; + case 0x40: /* SDRAM_B0CR */ + case 0x44: /* SDRAM_B1CR */ + case 0x48: /* SDRAM_B2CR */ + case 0x4C: /* SDRAM_B3CR */ + i = (s->addr - 0x40) / 4; + val &= SDRAM_DDR_BCR_MASK; + if (s->bank[i].size) { + sdram_bank_set_bcr(&s->bank[i], val, + sdram_ddr_base(val), sdram_ddr_size(val), + s->cfg & 0x80000000); + } + break; + case 0x80: /* SDRAM_TR */ + s->tr = val & 0x018FC01F; + break; + case 0x94: /* SDRAM_ECCCFG */ + s->ecccfg = val & 0x00F00000; + break; + case 0x98: /* SDRAM_ECCESR */ + val &= 0xFFF0F000; + if (s->eccesr == 0 && val != 0) { + qemu_irq_raise(s->irq); + } else if (s->eccesr != 0 && val == 0) { + qemu_irq_lower(s->irq); + } + s->eccesr = val; + break; + default: /* Error */ + break; + } + break; + } +} + +static void ppc4xx_sdram_ddr_reset(DeviceState *dev) +{ + Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev); + + s->addr = 0; + s->bear = 0; + s->besr0 = 0; /* No error */ + s->besr1 = 0; /* No error */ + s->cfg = 0; + s->ecccfg = 0; /* No ECC */ + s->eccesr = 0; /* No error */ + s->pmit = 0x07C00000; + s->rtr = 0x05F00000; + s->tr = 0x00854009; + /* We pre-initialize RAM banks */ + s->status = 0; + s->cfg = 0x00800000; +} + +static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp) +{ + Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev); + Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); + const ram_addr_t valid_bank_sizes[] = { + 256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0 + }; + int i; + + if (s->nbanks < 1 || s->nbanks > 4) { + error_setg(errp, "Invalid number of RAM banks"); + return; + } + if (!s->dram_mr) { + error_setg(errp, "Missing dram memory region"); + return; + } + if (!ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, + valid_bank_sizes, errp)) { + return; + } + for (i = 0; i < s->nbanks; i++) { + if (s->bank[i].size) { + s->bank[i].bcr = sdram_ddr_bcr(s->bank[i].base, s->bank[i].size); + sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, + s->bank[i].base, s->bank[i].size, 0); + } else { + sdram_bank_set_bcr(&s->bank[i], 0, 0, 0, 0); + } + trace_ppc4xx_sdram_init(sdram_ddr_base(s->bank[i].bcr), + sdram_ddr_size(s->bank[i].bcr), + s->bank[i].bcr); + } + + sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); + + ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR, + s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA, + s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write); +} + +static Property ppc4xx_sdram_ddr_props[] = { + DEFINE_PROP_LINK("dram", Ppc4xxSdramDdrState, dram_mr, TYPE_MEMORY_REGION, + MemoryRegion *), + DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdrState, nbanks, 4), + DEFINE_PROP_END_OF_LIST(), +}; + +static void ppc4xx_sdram_ddr_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + + dc->realize = ppc4xx_sdram_ddr_realize; + dc->reset = ppc4xx_sdram_ddr_reset; + /* Reason: only works as function of a ppc4xx SoC */ + dc->user_creatable = false; + device_class_set_props(dc, ppc4xx_sdram_ddr_props); +} + +void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState *s) +{ + sdram_ddr_dcr_write(s, SDRAM0_CFGADDR, 0x20); + sdram_ddr_dcr_write(s, SDRAM0_CFGDATA, 0x80000000); +} + +/*****************************************************************************/ +/* DDR2 SDRAM controller */ +#define SDRAM_DDR2_BCR_MASK 0xffe0ffc1 + +enum { + SDRAM_R0BAS = 0x40, + SDRAM_R1BAS, + SDRAM_R2BAS, + SDRAM_R3BAS, + SDRAM_CONF1HB = 0x45, + SDRAM_PLBADDULL = 0x4a, + SDRAM_CONF1LL = 0x4b, + SDRAM_CONFPATHB = 0x4f, + SDRAM_PLBADDUHB = 0x50, +}; + +static uint32_t sdram_ddr2_bcr(hwaddr ram_base, hwaddr ram_size) +{ + uint32_t bcr; + + switch (ram_size) { + case 8 * MiB: + bcr = 0xffc0; + break; + case 16 * MiB: + bcr = 0xff80; + break; + case 32 * MiB: + bcr = 0xff00; + break; + case 64 * MiB: + bcr = 0xfe00; + break; + case 128 * MiB: + bcr = 0xfc00; + break; + case 256 * MiB: + bcr = 0xf800; + break; + case 512 * MiB: + bcr = 0xf000; + break; + case 1 * GiB: + bcr = 0xe000; + break; + case 2 * GiB: + bcr = 0xc000; + break; + case 4 * GiB: + bcr = 0x8000; + break; + default: + error_report("invalid RAM size " TARGET_FMT_plx, ram_size); + return 0; + } + bcr |= ram_base >> 2 & 0xffe00000; + bcr |= 1; + + return bcr; +} + +static inline hwaddr sdram_ddr2_base(uint32_t bcr) +{ + return (bcr & 0xffe00000) << 2; +} + +static hwaddr sdram_ddr2_size(uint32_t bcr) +{ + hwaddr size; + int sh; + + sh = 1024 - ((bcr >> 6) & 0x3ff); + size = 8 * MiB * sh; + + return size; +} + +static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn) +{ + Ppc4xxSdramDdr2State *s = opaque; + uint32_t ret = 0; + + switch (dcrn) { + case SDRAM_R0BAS: + case SDRAM_R1BAS: + case SDRAM_R2BAS: + case SDRAM_R3BAS: + if (s->bank[dcrn - SDRAM_R0BAS].size) { + ret = sdram_ddr2_bcr(s->bank[dcrn - SDRAM_R0BAS].base, + s->bank[dcrn - SDRAM_R0BAS].size); + } + break; + case SDRAM_CONF1HB: + case SDRAM_CONF1LL: + case SDRAM_CONFPATHB: + case SDRAM_PLBADDULL: + case SDRAM_PLBADDUHB: + break; + case SDRAM0_CFGADDR: + ret = s->addr; + break; + case SDRAM0_CFGDATA: + switch (s->addr) { + case 0x14: /* SDRAM_MCSTAT (405EX) */ + case 0x1F: + ret = 0x80000000; + break; + case 0x21: /* SDRAM_MCOPT2 */ + ret = s->mcopt2; + break; + case 0x40: /* SDRAM_MB0CF */ + ret = 0x00008001; + break; + case 0x7A: /* SDRAM_DLCR */ + ret = 0x02000000; + break; + case 0xE1: /* SDR0_DDR0 */ + ret = SDR0_DDR0_DDRM_ENCODE(1) | SDR0_DDR0_DDRM_DDR1; + break; + default: + break; + } + break; + default: + break; + } + + return ret; +} + +#define SDRAM_DDR2_MCOPT2_DCEN BIT(27) + +static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val) +{ + Ppc4xxSdramDdr2State *s = opaque; + int i; + + switch (dcrn) { + case SDRAM_R0BAS: + case SDRAM_R1BAS: + case SDRAM_R2BAS: + case SDRAM_R3BAS: + case SDRAM_CONF1HB: + case SDRAM_CONF1LL: + case SDRAM_CONFPATHB: + case SDRAM_PLBADDULL: + case SDRAM_PLBADDUHB: + break; + case SDRAM0_CFGADDR: + s->addr = val; + break; + case SDRAM0_CFGDATA: + switch (s->addr) { + case 0x00: /* B0CR */ + break; + case 0x21: /* SDRAM_MCOPT2 */ + if (!(s->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && + (val & SDRAM_DDR2_MCOPT2_DCEN)) { + trace_ppc4xx_sdram_enable("enable"); + /* validate all RAM mappings */ + for (i = 0; i < s->nbanks; i++) { + if (s->bank[i].size) { + sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, + s->bank[i].base, s->bank[i].size, + 1); + } + } + s->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN; + } else if ((s->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) && + !(val & SDRAM_DDR2_MCOPT2_DCEN)) { + trace_ppc4xx_sdram_enable("disable"); + /* invalidate all RAM mappings */ + for (i = 0; i < s->nbanks; i++) { + if (s->bank[i].size) { + sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, + s->bank[i].base, s->bank[i].size, + 0); + } + } + s->mcopt2 &= ~SDRAM_DDR2_MCOPT2_DCEN; + } + break; + default: + break; + } + break; + default: + break; + } +} + +static void ppc4xx_sdram_ddr2_reset(DeviceState *dev) +{ + Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev); + + s->addr = 0; + s->mcopt2 = 0; +} + +static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp) +{ + Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev); + Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); + /* + * SoC also has 4 GiB but that causes problem with 32 bit + * builds (4*GiB overflows the 32 bit ram_addr_t). + */ + const ram_addr_t valid_bank_sizes[] = { + 2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, + 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0 + }; + int i; + + if (s->nbanks < 1 || s->nbanks > 4) { + error_setg(errp, "Invalid number of RAM banks"); + return; + } + if (!s->dram_mr) { + error_setg(errp, "Missing dram memory region"); + return; + } + if (!ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, + valid_bank_sizes, errp)) { + return; + } + for (i = 0; i < s->nbanks; i++) { + if (s->bank[i].size) { + s->bank[i].bcr = sdram_ddr2_bcr(s->bank[i].base, s->bank[i].size); + s->bank[i].bcr &= SDRAM_DDR2_BCR_MASK; + sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr, + s->bank[i].base, s->bank[i].size, 0); + } else { + sdram_bank_set_bcr(&s->bank[i], 0, 0, 0, 0); + } + trace_ppc4xx_sdram_init(sdram_ddr2_base(s->bank[i].bcr), + sdram_ddr2_size(s->bank[i].bcr), + s->bank[i].bcr); + } + + ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + + ppc4xx_dcr_register(dcr, SDRAM_R0BAS, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_R1BAS, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_R2BAS, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_R3BAS, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_CONF1HB, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_PLBADDULL, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_CONF1LL, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_CONFPATHB, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_PLBADDUHB, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); +} + +static Property ppc4xx_sdram_ddr2_props[] = { + DEFINE_PROP_LINK("dram", Ppc4xxSdramDdr2State, dram_mr, TYPE_MEMORY_REGION, + MemoryRegion *), + DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdr2State, nbanks, 4), + DEFINE_PROP_END_OF_LIST(), +}; + +static void ppc4xx_sdram_ddr2_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + + dc->realize = ppc4xx_sdram_ddr2_realize; + dc->reset = ppc4xx_sdram_ddr2_reset; + /* Reason: only works as function of a ppc4xx SoC */ + dc->user_creatable = false; + device_class_set_props(dc, ppc4xx_sdram_ddr2_props); +} + +void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s) +{ + sdram_ddr2_dcr_write(s, SDRAM0_CFGADDR, 0x21); + sdram_ddr2_dcr_write(s, SDRAM0_CFGDATA, 0x08000000); +} + +static const TypeInfo ppc4xx_sdram_types[] = { + { + .name = TYPE_PPC4xx_SDRAM_DDR, + .parent = TYPE_PPC4xx_DCR_DEVICE, + .instance_size = sizeof(Ppc4xxSdramDdrState), + .class_init = ppc4xx_sdram_ddr_class_init, + }, { + .name = TYPE_PPC4xx_SDRAM_DDR2, + .parent = TYPE_PPC4xx_DCR_DEVICE, + .instance_size = sizeof(Ppc4xxSdramDdr2State), + .class_init = ppc4xx_sdram_ddr2_class_init, + } +}; + +DEFINE_TYPES(ppc4xx_sdram_types) diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index f08714f2ec..fcbe4c5837 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -50,8 +50,6 @@ /* SMP is not enabled, for now */ #define MAX_CPUS 1 -#define MAX_IDE_BUS 2 - #define CFG_ADDR 0xf0000510 #define KERNEL_LOAD_ADDR 0x01000000 diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 891206e893..925ff523cc 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -490,6 +490,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr, env->msr |= (1ULL << MSR_EE); hreg_compute_hflags(env); + ppc_maybe_interrupt(env); if (spapr_cpu->prod) { spapr_cpu->prod = false; @@ -500,6 +501,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr, cs->halted = 1; cs->exception_index = EXCP_HLT; cs->exit_request = 1; + ppc_maybe_interrupt(env); } return H_SUCCESS; @@ -521,6 +523,7 @@ static target_ulong h_confer_self(PowerPCCPU *cpu) cs->halted = 1; cs->exception_index = EXCP_HALTED; cs->exit_request = 1; + ppc_maybe_interrupt(&cpu->env); return H_SUCCESS; } @@ -633,6 +636,7 @@ static target_ulong h_prod(PowerPCCPU *cpu, SpaprMachineState *spapr, spapr_cpu = spapr_cpu_state(tcpu); spapr_cpu->prod = true; cs->halted = 0; + ppc_maybe_interrupt(&cpu->env); qemu_cpu_kick(cs); return H_SUCCESS; @@ -1669,6 +1673,7 @@ static target_ulong h_enter_nested(PowerPCCPU *cpu, spapr_cpu->in_nested = true; hreg_compute_hflags(env); + ppc_maybe_interrupt(env); tlb_flush(cs); env->reserve_addr = -1; /* Reset the reservation */ @@ -1810,6 +1815,7 @@ out_restore_l1: spapr_cpu->in_nested = false; hreg_compute_hflags(env); + ppc_maybe_interrupt(env); tlb_flush(cs); env->reserve_addr = -1; /* Reset the reservation */ diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index d58b65e88f..3f664ea02c 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -214,9 +214,9 @@ static void rtas_stop_self(PowerPCCPU *cpu, SpaprMachineState *spapr, * guest. * For the same reason, set PSSCR_EC. */ - ppc_store_lpcr(cpu, env->spr[SPR_LPCR] & ~pcc->lpcr_pm); env->spr[SPR_PSSCR] |= PSSCR_EC; cs->halted = 1; + ppc_store_lpcr(cpu, env->spr[SPR_LPCR] & ~pcc->lpcr_pm); kvmppc_set_reg_ppc_online(cpu, 0); qemu_cpu_kick(cs); } diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events index a07d5aca0f..f670e8906c 100644 --- a/hw/ppc/trace-events +++ b/hw/ppc/trace-events @@ -127,7 +127,7 @@ ppc40x_set_tb_clk(uint32_t value) "new frequency %" PRIu32 ppc40x_timers_init(uint32_t value) "frequency %" PRIu32 ppc_irq_set(void *env, uint32_t pin, uint32_t level) "env [%p] pin %d level %d" -ppc_irq_set_exit(void *env, uint32_t n_IRQ, uint32_t level, uint32_t pending, uint32_t request) "env [%p] n_IRQ %d level %d => pending 0x%08" PRIx32 " req 0x%08" PRIx32 +ppc_irq_set_exit(void *env, uint32_t irq, uint32_t level, uint32_t pending, uint32_t request) "env [%p] irq 0x%05" PRIx32 " level %d => pending 0x%08" PRIx32 " req 0x%08" PRIx32 ppc_irq_set_state(const char *name, uint32_t level) "\"%s\" level %d" ppc_irq_reset(const char *name) "%s" ppc_irq_cpu(const char *action) "%s" @@ -179,3 +179,4 @@ ppc405ep_clocks_setup(const char *trace) "%s" ppc4xx_sdram_enable(const char *trace) "%s SDRAM controller" ppc4xx_sdram_unmap(uint64_t addr, uint64_t size) "Unmap RAM area 0x%" PRIx64 " size 0x%" PRIx64 ppc4xx_sdram_map(uint64_t addr, uint64_t size) "Map RAM area 0x%" PRIx64 " size 0x%" PRIx64 +ppc4xx_sdram_init(uint64_t base, uint64_t size, uint32_t bcr) "Init RAM area 0x%" PRIx64 " size 0x%" PRIx64 " bcr 0x%x" diff --git a/hw/s390x/pv.c b/hw/s390x/pv.c index 728ba24547..8dfe92d8df 100644 --- a/hw/s390x/pv.c +++ b/hw/s390x/pv.c @@ -50,7 +50,7 @@ static int __s390_pv_cmd(uint32_t cmd, const char *cmdname, void *data) * This macro lets us pass the command as a string to the function so * we can print it on an error. */ -#define s390_pv_cmd(cmd, data) __s390_pv_cmd(cmd, #cmd, data); +#define s390_pv_cmd(cmd, data) __s390_pv_cmd(cmd, #cmd, data) #define s390_pv_cmd_exit(cmd, data) \ { \ int rc; \ diff --git a/hw/s390x/tod-kvm.c b/hw/s390x/tod-kvm.c index 9d0cbfbce2..e2202dae2d 100644 --- a/hw/s390x/tod-kvm.c +++ b/hw/s390x/tod-kvm.c @@ -13,6 +13,7 @@ #include "qemu/module.h" #include "sysemu/runstate.h" #include "hw/s390x/tod.h" +#include "hw/s390x/pv.h" #include "kvm/kvm_s390x.h" static void kvm_s390_get_tod_raw(S390TOD *tod, Error **errp) @@ -84,6 +85,14 @@ static void kvm_s390_tod_vm_state_change(void *opaque, bool running, S390TODState *td = opaque; Error *local_err = NULL; + /* + * Under PV, the clock is under ultravisor control, hence we cannot restore + * it on resume. + */ + if (s390_is_pv()) { + return; + } + if (running && td->stopped) { /* Set the old TOD when running the VM - start the TOD clock. */ kvm_s390_set_tod_raw(&td->base, &local_err); diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h index e8c753d6d1..964570f8e8 100644 --- a/hw/sd/sdhci-internal.h +++ b/hw/sd/sdhci-internal.h @@ -288,26 +288,6 @@ enum { extern const VMStateDescription sdhci_vmstate; - -#define ESDHC_MIX_CTRL 0x48 - -#define ESDHC_VENDOR_SPEC 0xc0 -#define ESDHC_IMX_FRC_SDCLK_ON (1 << 8) - -#define ESDHC_DLL_CTRL 0x60 - -#define ESDHC_TUNING_CTRL 0xcc -#define ESDHC_TUNE_CTRL_STATUS 0x68 -#define ESDHC_WTMK_LVL 0x44 - -/* Undocumented register used by guests working around erratum ERR004536 */ -#define ESDHC_UNDOCUMENTED_REG27 0x6c - -#define ESDHC_CTRL_4BITBUS (0x1 << 1) -#define ESDHC_CTRL_8BITBUS (0x2 << 1) - -#define ESDHC_PRNSTS_SDSTB (1 << 3) - /* * Default SD/MMC host controller features information, which will be * presented in CAPABILITIES register of generic SD host controller at reset. diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index 0e5e988927..306070c872 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -1577,6 +1577,25 @@ static const TypeInfo sdhci_bus_info = { /* --- qdev i.MX eSDHC --- */ +#define USDHC_MIX_CTRL 0x48 + +#define USDHC_VENDOR_SPEC 0xc0 +#define USDHC_IMX_FRC_SDCLK_ON (1 << 8) + +#define USDHC_DLL_CTRL 0x60 + +#define USDHC_TUNING_CTRL 0xcc +#define USDHC_TUNE_CTRL_STATUS 0x68 +#define USDHC_WTMK_LVL 0x44 + +/* Undocumented register used by guests working around erratum ERR004536 */ +#define USDHC_UNDOCUMENTED_REG27 0x6c + +#define USDHC_CTRL_4BITBUS (0x1 << 1) +#define USDHC_CTRL_8BITBUS (0x2 << 1) + +#define USDHC_PRNSTS_SDSTB (1 << 3) + static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size) { SDHCIState *s = SYSBUS_SDHCI(opaque); @@ -1596,11 +1615,11 @@ static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size) hostctl1 = SDHC_DMA_TYPE(s->hostctl1) << (8 - 3); if (s->hostctl1 & SDHC_CTRL_8BITBUS) { - hostctl1 |= ESDHC_CTRL_8BITBUS; + hostctl1 |= USDHC_CTRL_8BITBUS; } if (s->hostctl1 & SDHC_CTRL_4BITBUS) { - hostctl1 |= ESDHC_CTRL_4BITBUS; + hostctl1 |= USDHC_CTRL_4BITBUS; } ret = hostctl1; @@ -1611,21 +1630,21 @@ static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size) case SDHC_PRNSTS: /* Add SDSTB (SD Clock Stable) bit to PRNSTS */ - ret = sdhci_read(opaque, offset, size) & ~ESDHC_PRNSTS_SDSTB; + ret = sdhci_read(opaque, offset, size) & ~USDHC_PRNSTS_SDSTB; if (s->clkcon & SDHC_CLOCK_INT_STABLE) { - ret |= ESDHC_PRNSTS_SDSTB; + ret |= USDHC_PRNSTS_SDSTB; } break; - case ESDHC_VENDOR_SPEC: + case USDHC_VENDOR_SPEC: ret = s->vendor_spec; break; - case ESDHC_DLL_CTRL: - case ESDHC_TUNE_CTRL_STATUS: - case ESDHC_UNDOCUMENTED_REG27: - case ESDHC_TUNING_CTRL: - case ESDHC_MIX_CTRL: - case ESDHC_WTMK_LVL: + case USDHC_DLL_CTRL: + case USDHC_TUNE_CTRL_STATUS: + case USDHC_UNDOCUMENTED_REG27: + case USDHC_TUNING_CTRL: + case USDHC_MIX_CTRL: + case USDHC_WTMK_LVL: ret = 0; break; } @@ -1641,18 +1660,18 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) uint32_t value = (uint32_t)val; switch (offset) { - case ESDHC_DLL_CTRL: - case ESDHC_TUNE_CTRL_STATUS: - case ESDHC_UNDOCUMENTED_REG27: - case ESDHC_TUNING_CTRL: - case ESDHC_WTMK_LVL: + case USDHC_DLL_CTRL: + case USDHC_TUNE_CTRL_STATUS: + case USDHC_UNDOCUMENTED_REG27: + case USDHC_TUNING_CTRL: + case USDHC_WTMK_LVL: break; - case ESDHC_VENDOR_SPEC: + case USDHC_VENDOR_SPEC: s->vendor_spec = value; switch (s->vendor) { case SDHCI_VENDOR_IMX: - if (value & ESDHC_IMX_FRC_SDCLK_ON) { + if (value & USDHC_IMX_FRC_SDCLK_ON) { s->prnsts &= ~SDHC_IMX_CLOCK_GATE_OFF; } else { s->prnsts |= SDHC_IMX_CLOCK_GATE_OFF; @@ -1721,12 +1740,12 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) * Second, split "Data Transfer Width" from bits 2 and 1 in to * bits 5 and 1 */ - if (value & ESDHC_CTRL_8BITBUS) { + if (value & USDHC_CTRL_8BITBUS) { hostctl1 |= SDHC_CTRL_8BITBUS; } - if (value & ESDHC_CTRL_4BITBUS) { - hostctl1 |= ESDHC_CTRL_4BITBUS; + if (value & USDHC_CTRL_4BITBUS) { + hostctl1 |= USDHC_CTRL_4BITBUS; } /* @@ -1749,7 +1768,7 @@ usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) sdhci_write(opaque, offset, value, size); break; - case ESDHC_MIX_CTRL: + case USDHC_MIX_CTRL: /* * So, when SD/MMC stack in Linux tries to write to "Transfer * Mode Register", ESDHC i.MX quirk code will translate it diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index 0e27715ac4..387181ff77 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -66,7 +66,6 @@ #define PBM_PCI_IO_BASE (PBM_SPECIAL_BASE + 0x02000000ULL) #define PROM_FILENAME "openbios-sparc64" #define NVRAM_SIZE 0x2000 -#define MAX_IDE_BUS 2 #define BIOS_CFG_IOPORT 0x510 #define FW_CFG_SPARC64_WIDTH (FW_CFG_ARCH_LOCAL + 0x00) #define FW_CFG_SPARC64_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01) diff --git a/hw/usb/vt82c686-uhci-pci.c b/hw/usb/vt82c686-uhci-pci.c index 0bf2b72ff0..46a901f56f 100644 --- a/hw/usb/vt82c686-uhci-pci.c +++ b/hw/usb/vt82c686-uhci-pci.c @@ -31,7 +31,7 @@ static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp) static UHCIInfo uhci_info[] = { { - .name = "vt82c686b-usb-uhci", + .name = TYPE_VT82C686B_USB_UHCI, .vendor_id = PCI_VENDOR_ID_VIA, .device_id = PCI_DEVICE_ID_VIA_UHCI, .revision = 0x01, @@ -45,7 +45,7 @@ static UHCIInfo uhci_info[] = { static const TypeInfo vt82c686b_usb_uhci_type_info = { .parent = TYPE_UHCI, - .name = "vt82c686b-usb-uhci", + .name = TYPE_VT82C686B_USB_UHCI, .class_init = uhci_data_class_init, .class_data = uhci_info, }; diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c index 596d4434d2..5bd14cad96 100644 --- a/hw/virtio/vhost-shadow-virtqueue.c +++ b/hw/virtio/vhost-shadow-virtqueue.c @@ -33,6 +33,7 @@ bool vhost_svq_valid_features(uint64_t features, Error **errp) ++b) { switch (b) { case VIRTIO_F_ANY_LAYOUT: + case VIRTIO_RING_F_EVENT_IDX: continue; case VIRTIO_F_ACCESS_PLATFORM: @@ -218,12 +219,22 @@ static bool vhost_svq_add_split(VhostShadowVirtqueue *svq, static void vhost_svq_kick(VhostShadowVirtqueue *svq) { + bool needs_kick; + /* * We need to expose the available array entries before checking the used * flags */ smp_mb(); - if (svq->vring.used->flags & VRING_USED_F_NO_NOTIFY) { + + if (virtio_vdev_has_feature(svq->vdev, VIRTIO_RING_F_EVENT_IDX)) { + uint16_t avail_event = *(uint16_t *)(&svq->vring.used->ring[svq->vring.num]); + needs_kick = vring_need_event(avail_event, svq->shadow_avail_idx, svq->shadow_avail_idx - 1); + } else { + needs_kick = !(svq->vring.used->flags & VRING_USED_F_NO_NOTIFY); + } + + if (!needs_kick) { return; } @@ -369,15 +380,27 @@ static bool vhost_svq_more_used(VhostShadowVirtqueue *svq) */ static bool vhost_svq_enable_notification(VhostShadowVirtqueue *svq) { - svq->vring.avail->flags &= ~cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT); - /* Make sure the flag is written before the read of used_idx */ + if (virtio_vdev_has_feature(svq->vdev, VIRTIO_RING_F_EVENT_IDX)) { + uint16_t *used_event = (uint16_t *)&svq->vring.avail->ring[svq->vring.num]; + *used_event = svq->shadow_used_idx; + } else { + svq->vring.avail->flags &= ~cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT); + } + + /* Make sure the event is enabled before the read of used_idx */ smp_mb(); return !vhost_svq_more_used(svq); } static void vhost_svq_disable_notification(VhostShadowVirtqueue *svq) { - svq->vring.avail->flags |= cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT); + /* + * No need to disable notification in the event idx case, since used event + * index is already an index too far away. + */ + if (!virtio_vdev_has_feature(svq->vdev, VIRTIO_RING_F_EVENT_IDX)) { + svq->vring.avail->flags |= cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT); + } } static uint16_t vhost_svq_last_desc_of_chain(const VhostShadowVirtqueue *svq, @@ -570,16 +593,16 @@ void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq, size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq) { size_t desc_size = sizeof(vring_desc_t) * svq->vring.num; - size_t avail_size = offsetof(vring_avail_t, ring) + - sizeof(uint16_t) * svq->vring.num; + size_t avail_size = offsetof(vring_avail_t, ring[svq->vring.num]) + + sizeof(uint16_t); return ROUND_UP(desc_size + avail_size, qemu_real_host_page_size()); } size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq) { - size_t used_size = offsetof(vring_used_t, ring) + - sizeof(vring_used_elem_t) * svq->vring.num; + size_t used_size = offsetof(vring_used_t, ring[svq->vring.num]) + + sizeof(uint16_t); return ROUND_UP(used_size, qemu_real_host_page_size()); } diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c index 30d03e987a..ed170def48 100644 --- a/hw/virtio/virtio-mem.c +++ b/hw/virtio/virtio-mem.c @@ -467,7 +467,7 @@ static int virtio_mem_set_block_state(VirtIOMEM *vmem, uint64_t start_gpa, int fd = memory_region_get_fd(&vmem->memdev->mr); Error *local_err = NULL; - os_mem_prealloc(fd, area, size, 1, &local_err); + qemu_prealloc_mem(fd, area, size, 1, NULL, &local_err); if (local_err) { static bool warned; diff --git a/include/block/block-common.h b/include/block/block-common.h index 061606e867..297704c1e9 100644 --- a/include/block/block-common.h +++ b/include/block/block-common.h @@ -322,6 +322,45 @@ enum { * * At least one of DATA, METADATA, FILTERED, or COW must be set for * every child. + * + * + * = Connection with bs->children, bs->file and bs->backing fields = + * + * 1. Filters + * + * Filter drivers have drv->is_filter = true. + * + * Filter node has exactly one FILTERED|PRIMARY child, and may have other + * children which must not have these bits (one example is the + * copy-before-write filter, which also has its target DATA child). + * + * Filter nodes never have COW children. + * + * For most filters, the filtered child is linked in bs->file, bs->backing is + * NULL. For some filters (as an exception), it is the other way around; those + * drivers will have drv->filtered_child_is_backing set to true (see that + * field’s documentation for what drivers this concerns) + * + * 2. "raw" driver (block/raw-format.c) + * + * Formally it's not a filter (drv->is_filter = false) + * + * bs->backing is always NULL + * + * Only has one child, linked in bs->file. Its role is either FILTERED|PRIMARY + * (like filter) or DATA|PRIMARY depending on options. + * + * 3. Other drivers + * + * Don't have any FILTERED children. + * + * May have at most one COW child. In this case it's linked in bs->backing. + * Otherwise bs->backing is NULL. COW child is never PRIMARY. + * + * May have at most one PRIMARY child. In this case it's linked in bs->file. + * Otherwise bs->file is NULL. + * + * May also have some other children that don't have the PRIMARY or COW bit set. */ enum BdrvChildRoleBits { /* diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h index eba4ed23b4..bb42ed9559 100644 --- a/include/block/block-global-state.h +++ b/include/block/block-global-state.h @@ -76,6 +76,9 @@ BdrvChild *bdrv_open_child(const char *filename, const BdrvChildClass *child_class, BdrvChildRole child_role, bool allow_none, Error **errp); +int bdrv_open_file_child(const char *filename, + QDict *options, const char *bdref_key, + BlockDriverState *parent, Error **errp); BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp); int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd, Error **errp); @@ -217,17 +220,12 @@ void coroutine_fn bdrv_co_lock(BlockDriverState *bs); */ void coroutine_fn bdrv_co_unlock(BlockDriverState *bs); -void bdrv_set_aio_context_ignore(BlockDriverState *bs, - AioContext *new_context, GSList **ignore); -int bdrv_try_set_aio_context(BlockDriverState *bs, AioContext *ctx, - Error **errp); -int bdrv_child_try_set_aio_context(BlockDriverState *bs, AioContext *ctx, - BdrvChild *ignore_child, Error **errp); -bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx, - GSList **ignore, Error **errp); -bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx, - GSList **ignore, Error **errp); AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c); +bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp); +int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx, + BdrvChild *ignore_child, Error **errp); int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz); int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo); diff --git a/include/block/block-hmp-cmds.h b/include/block/block-hmp-cmds.h index 50ce0247c3..ba0593c440 100644 --- a/include/block/block-hmp-cmds.h +++ b/include/block/block-hmp-cmds.h @@ -38,7 +38,7 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict); void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict); void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict); -void hmp_block_resize(Monitor *mon, const QDict *qdict); +void coroutine_fn hmp_block_resize(Monitor *mon, const QDict *qdict); void hmp_block_stream(Monitor *mon, const QDict *qdict); void hmp_block_passwd(Monitor *mon, const QDict *qdict); void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict); diff --git a/include/block/block-io.h b/include/block/block-io.h index 492f95fc05..770ddeb7c8 100644 --- a/include/block/block-io.h +++ b/include/block/block-io.h @@ -83,12 +83,13 @@ void bdrv_aio_cancel(BlockAIOCB *acb); void bdrv_aio_cancel_async(BlockAIOCB *acb); /* sg packet commands */ -int bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf); +int coroutine_fn bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf); /* Ensure contents are flushed to disk. */ int coroutine_fn bdrv_co_flush(BlockDriverState *bs); -int bdrv_co_pdiscard(BdrvChild *child, int64_t offset, int64_t bytes); +int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset, + int64_t bytes); bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs); int bdrv_block_status(BlockDriverState *bs, int64_t offset, int64_t bytes, int64_t *pnum, int64_t *map, diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index 9c569be162..5a2cc077a0 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -120,6 +120,20 @@ struct BlockDriver { */ bool is_filter; /* + * Only make sense for filter drivers, for others must be false. + * If true, filtered child is bs->backing. Otherwise it's bs->file. + * Two internal filters use bs->backing as filtered child and has this + * field set to true: mirror_top and commit_top. There also two such test + * filters in tests/unit/test-bdrv-graph-mod.c. + * + * Never create any more such filters! + * + * TODO: imagine how to deprecate this behavior and make all filters work + * similarly using bs->file as filtered child. + */ + bool filtered_child_is_backing; + + /* * Set to true if the BlockDriver is a format driver. Format nodes * generally do not expect their children to be other format nodes * (except for backing files), and so format probing is disabled @@ -734,13 +748,11 @@ struct BlockDriver { void coroutine_fn (*bdrv_co_drain_end)(BlockDriverState *bs); bool (*bdrv_supports_persistent_dirty_bitmap)(BlockDriverState *bs); - bool (*bdrv_co_can_store_new_dirty_bitmap)(BlockDriverState *bs, - const char *name, - uint32_t granularity, - Error **errp); - int (*bdrv_co_remove_persistent_dirty_bitmap)(BlockDriverState *bs, - const char *name, - Error **errp); + bool coroutine_fn (*bdrv_co_can_store_new_dirty_bitmap)( + BlockDriverState *bs, const char *name, uint32_t granularity, + Error **errp); + int coroutine_fn (*bdrv_co_remove_persistent_dirty_bitmap)( + BlockDriverState *bs, const char *name, Error **errp); }; static inline bool block_driver_can_compress(BlockDriver *drv) @@ -895,9 +907,9 @@ struct BdrvChildClass { int (*update_filename)(BdrvChild *child, BlockDriverState *new_base, const char *filename, Error **errp); - bool (*can_set_aio_ctx)(BdrvChild *child, AioContext *ctx, - GSList **ignore, Error **errp); - void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore); + bool (*change_aio_ctx)(BdrvChild *child, AioContext *ctx, + GHashTable *visited, Transaction *tran, + Error **errp); AioContext *(*get_parent_aio_context)(BdrvChild *child); @@ -1045,9 +1057,6 @@ struct BlockDriverState { QDict *full_open_options; char exact_filename[PATH_MAX]; - BdrvChild *backing; - BdrvChild *file; - /* I/O Limits */ BlockLimits bl; @@ -1106,7 +1115,19 @@ struct BlockDriverState { * parent node of this node. */ BlockDriverState *inherits_from; + + /* + * @backing and @file are some of @children or NULL. All these three fields + * (@file, @backing and @children) are modified only in + * bdrv_child_cb_attach() and bdrv_child_cb_detach(). + * + * See also comment in include/block/block.h, to learn how backing and file + * are connected with BdrvChildRole. + */ QLIST_HEAD(, BdrvChild) children; + BdrvChild *backing; + BdrvChild *file; + QLIST_HEAD(, BdrvChild) parents; QDict *options; @@ -1233,7 +1254,7 @@ static inline BlockDriverState *child_bs(BdrvChild *child) } int bdrv_check_request(int64_t offset, int64_t bytes, Error **errp); -int get_tmp_filename(char *filename, int size); +char *create_tmp_file(Error **errp); void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix, QDict *options); diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index f9b58773f7..8830546121 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -333,6 +333,7 @@ struct CPUState { struct QemuThread *thread; #ifdef _WIN32 HANDLE hThread; + QemuSemaphore sem; #endif int thread_id; bool running, has_waiter; diff --git a/include/hw/ide/piix.h b/include/hw/ide/piix.h new file mode 100644 index 0000000000..ef3ef3d62d --- /dev/null +++ b/include/hw/ide/piix.h @@ -0,0 +1,7 @@ +#ifndef HW_IDE_PIIX_H +#define HW_IDE_PIIX_H + +#define TYPE_PIIX3_IDE "piix3-ide" +#define TYPE_PIIX4_IDE "piix4-ide" + +#endif /* HW_IDE_PIIX_H */ diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h index 56ac141be3..eaa07881c5 100644 --- a/include/hw/isa/vt82c686.h +++ b/include/hw/isa/vt82c686.h @@ -4,10 +4,10 @@ #include "hw/pci/pci.h" #define TYPE_VT82C686B_ISA "vt82c686b-isa" -#define TYPE_VT82C686B_PM "vt82c686b-pm" +#define TYPE_VT82C686B_USB_UHCI "vt82c686b-usb-uhci" #define TYPE_VT8231_ISA "vt8231-isa" -#define TYPE_VT8231_PM "vt8231-pm" #define TYPE_VIA_AC97 "via-ac97" +#define TYPE_VIA_IDE "via-ide" #define TYPE_VIA_MC97 "via-mc97" void via_isa_set_irq(PCIDevice *d, int n, int level); diff --git a/include/hw/mips/bootloader.h b/include/hw/mips/bootloader.h index b5f48d71bb..fffb0b7da8 100644 --- a/include/hw/mips/bootloader.h +++ b/include/hw/mips/bootloader.h @@ -12,8 +12,12 @@ #include "exec/cpu-defs.h" void bl_gen_jump_to(uint32_t **p, target_ulong jump_addr); -void bl_gen_jump_kernel(uint32_t **p, target_ulong sp, target_ulong a0, - target_ulong a1, target_ulong a2, target_ulong a3, +void bl_gen_jump_kernel(uint32_t **p, + bool set_sp, target_ulong sp, + bool set_a0, target_ulong a0, + bool set_a1, target_ulong a1, + bool set_a2, target_ulong a2, + bool set_a3, target_ulong a3, target_ulong kernel_addr); void bl_gen_write_ulong(uint32_t **p, target_ulong addr, target_ulong val); void bl_gen_write_u32(uint32_t **p, target_ulong addr, uint32_t val); diff --git a/include/hw/ppc/ppc4xx.h b/include/hw/ppc/ppc4xx.h index 10c6dd535f..f8c86e09ec 100644 --- a/include/hw/ppc/ppc4xx.h +++ b/include/hw/ppc/ppc4xx.h @@ -29,18 +29,6 @@ #include "exec/memory.h" #include "hw/sysbus.h" -typedef struct { - MemoryRegion ram; - MemoryRegion container; /* used for clipping */ - hwaddr base; - hwaddr size; - uint32_t bcr; -} Ppc4xxSdramBank; - -void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks, - Ppc4xxSdramBank ram_banks[], - const ram_addr_t sdram_bank_sizes[]); - #define TYPE_PPC4xx_PCI_HOST_BRIDGE "ppc4xx-pcihost" /* @@ -111,6 +99,14 @@ struct Ppc4xxEbcState { }; /* SDRAM DDR controller */ +typedef struct { + MemoryRegion ram; + MemoryRegion container; /* used for clipping */ + hwaddr base; + hwaddr size; + uint32_t bcr; +} Ppc4xxSdramBank; + #define SDR0_DDR0_DDRM_ENCODE(n) ((((unsigned long)(n)) & 0x03) << 29) #define SDR0_DDR0_DDRM_DDR1 0x20000000 #define SDR0_DDR0_DDRM_DDR2 0x40000000 diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h index a9cf064ee8..dfbc0c9a2f 100644 --- a/include/monitor/hmp.h +++ b/include/monitor/hmp.h @@ -15,6 +15,7 @@ #define HMP_H #include "qemu/readline.h" +#include "qemu/coroutine.h" #include "qapi/qapi-types-common.h" bool hmp_handle_error(Monitor *mon, Error *err); @@ -81,7 +82,7 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict); void hmp_getfd(Monitor *mon, const QDict *qdict); void hmp_closefd(Monitor *mon, const QDict *qdict); void hmp_sendkey(Monitor *mon, const QDict *qdict); -void hmp_screendump(Monitor *mon, const QDict *qdict); +void coroutine_fn hmp_screendump(Monitor *mon, const QDict *qdict); void hmp_chardev_add(Monitor *mon, const QDict *qdict); void hmp_chardev_change(Monitor *mon, const QDict *qdict); void hmp_chardev_remove(Monitor *mon, const QDict *qdict); diff --git a/include/net/net.h b/include/net/net.h index 81d0b21def..3db75ff841 100644 --- a/include/net/net.h +++ b/include/net/net.h @@ -177,6 +177,7 @@ ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf, void qemu_purge_queued_packets(NetClientState *nc); void qemu_flush_queued_packets(NetClientState *nc); void qemu_flush_or_purge_queued_packets(NetClientState *nc, bool purge); +void qemu_set_info_str(NetClientState *nc, const char *fmt, ...); void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]); bool qemu_has_ufo(NetClientState *nc); bool qemu_has_vnet_hdr(NetClientState *nc); @@ -220,9 +221,11 @@ extern NICInfo nd_table[MAX_NICS]; extern const char *host_net_devices[]; /* from net.c */ -int net_client_parse(QemuOptsList *opts_list, const char *str); +bool netdev_is_modern(const char *optarg); +void netdev_parse_modern(const char *optarg); +void net_client_parse(QemuOptsList *opts_list, const char *str); void show_netdevs(void); -int net_init_clients(Error **errp); +void net_init_clients(void); void net_check_clients(void); void net_cleanup(void); void hmp_host_net_add(Monitor *mon, const QDict *qdict); diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h index 596fce0c54..87ca83b155 100644 --- a/include/qapi/qmp/qerror.h +++ b/include/qapi/qmp/qerror.h @@ -50,9 +50,6 @@ #define QERR_MISSING_PARAMETER \ "Parameter '%s' is missing" -#define QERR_PERMISSION_DENIED \ - "Insufficient permission to perform this operation" - #define QERR_PROPERTY_VALUE_BAD \ "Property '%s.%s' doesn't take value '%s'" diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index 608fe45dcf..89650a2d7f 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -287,7 +287,7 @@ void qemu_co_rwlock_init(CoRwlock *lock); * of a parallel writer, control is transferred to the caller of the current * coroutine. */ -void qemu_co_rwlock_rdlock(CoRwlock *lock); +void coroutine_fn qemu_co_rwlock_rdlock(CoRwlock *lock); /** * Write Locks the CoRwlock from a reader. This is a bit more efficient than @@ -296,7 +296,7 @@ void qemu_co_rwlock_rdlock(CoRwlock *lock); * to the caller of the current coroutine; another writer might run while * @qemu_co_rwlock_upgrade blocks. */ -void qemu_co_rwlock_upgrade(CoRwlock *lock); +void coroutine_fn qemu_co_rwlock_upgrade(CoRwlock *lock); /** * Downgrades a write-side critical section to a reader. Downgrading with @@ -304,20 +304,20 @@ void qemu_co_rwlock_upgrade(CoRwlock *lock); * followed by @qemu_co_rwlock_rdlock. This makes it more efficient, but * may also sometimes be necessary for correctness. */ -void qemu_co_rwlock_downgrade(CoRwlock *lock); +void coroutine_fn qemu_co_rwlock_downgrade(CoRwlock *lock); /** * Write Locks the mutex. If the lock cannot be taken immediately because * of a parallel reader, control is transferred to the caller of the current * coroutine. */ -void qemu_co_rwlock_wrlock(CoRwlock *lock); +void coroutine_fn qemu_co_rwlock_wrlock(CoRwlock *lock); /** * Unlocks the read/write lock and schedules the next coroutine that was * waiting for this lock to be run. */ -void qemu_co_rwlock_unlock(CoRwlock *lock); +void coroutine_fn qemu_co_rwlock_unlock(CoRwlock *lock); typedef struct QemuCoSleep { Coroutine *to_wake; @@ -389,8 +389,9 @@ void qemu_coroutine_dec_pool_size(unsigned int additional_pool_size); * The same interface as qemu_sendv_recvv(), with added yielding. * XXX should mark these as coroutine_fn */ -ssize_t qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt, - size_t offset, size_t bytes, bool do_send); +ssize_t coroutine_fn qemu_co_sendv_recvv(int sockfd, struct iovec *iov, + unsigned iov_cnt, size_t offset, + size_t bytes, bool do_send); #define qemu_co_recvv(sockfd, iov, iov_cnt, offset, bytes) \ qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, false) #define qemu_co_sendv(sockfd, iov, iov_cnt, offset, bytes) \ @@ -399,7 +400,8 @@ ssize_t qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt, /** * The same as above, but with just a single buffer */ -ssize_t qemu_co_send_recv(int sockfd, void *buf, size_t bytes, bool do_send); +ssize_t coroutine_fn qemu_co_send_recv(int sockfd, void *buf, size_t bytes, + bool do_send); #define qemu_co_recv(sockfd, buf, bytes) \ qemu_co_send_recv(sockfd, buf, bytes, false) #define qemu_co_send(sockfd, buf, bytes) \ diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 2276094729..b9c4307779 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -576,8 +576,23 @@ unsigned long qemu_getauxval(unsigned long type); void qemu_set_tty_echo(int fd, bool echo); -void os_mem_prealloc(int fd, char *area, size_t sz, int smp_cpus, - Error **errp); +typedef struct ThreadContext ThreadContext; + +/** + * qemu_prealloc_mem: + * @fd: the fd mapped into the area, -1 for anonymous memory + * @area: start address of the are to preallocate + * @sz: the size of the area to preallocate + * @max_threads: maximum number of threads to use + * @errp: returns an error if this function fails + * + * Preallocate memory (populate/prefault page tables writable) for the virtual + * memory area starting at @area with the size of @sz. After a successful call, + * each page in the area was faulted in writable at least once, for example, + * after allocating file blocks for mapped files. + */ +void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, + ThreadContext *tc, Error **errp); /** * qemu_get_pid_name: diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h index 036745e586..2b0698a7c9 100644 --- a/include/qemu/sockets.h +++ b/include/qemu/sockets.h @@ -33,6 +33,19 @@ int qemu_socketpair(int domain, int type, int protocol, int sv[2]); #endif int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +/* + * A variant of send(2) which handles partial send. + * + * Return the number of bytes transferred over the socket. + * Set errno if fewer than `count' bytes are sent. + * + * This function don't work with non-blocking socket's. + * Any of the possibilities with non-blocking socket's is bad: + * - return a short write (then name is wrong) + * - busy wait adding (errno == EAGAIN) to the loop + */ +ssize_t qemu_send_full(int s, const void *buf, size_t count) + G_GNUC_WARN_UNUSED_RESULT; int socket_set_cork(int fd, int v); int socket_set_nodelay(int fd); void qemu_socket_set_block(int fd); @@ -58,6 +71,7 @@ NetworkAddressFamily inet_netfamily(int family); int unix_listen(const char *path, Error **errp); int unix_connect(const char *path, Error **errp); +char *socket_uri(SocketAddress *addr); SocketAddress *socket_parse(const char *str, Error **errp); int socket_connect(SocketAddress *addr, Error **errp); int socket_listen(SocketAddress *addr, int num, Error **errp); @@ -65,6 +79,8 @@ void socket_listen_cleanup(int fd, Error **errp); int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp); /* Old, ipv4 only bits. Don't use for new code. */ +int convert_host_port(struct sockaddr_in *saddr, const char *host, + const char *port, Error **errp); int parse_host_port(struct sockaddr_in *saddr, const char *str, Error **errp); int socket_init(void); @@ -139,5 +155,4 @@ SocketAddress *socket_address_flatten(SocketAddressLegacy *addr); * Return 0 on success. */ int socket_address_parse_named_fd(SocketAddress *addr, Error **errp); - #endif /* QEMU_SOCKETS_H */ diff --git a/include/qemu/thread-context.h b/include/qemu/thread-context.h new file mode 100644 index 0000000000..2ebd6b7fe1 --- /dev/null +++ b/include/qemu/thread-context.h @@ -0,0 +1,57 @@ +/* + * QEMU Thread Context + * + * Copyright Red Hat Inc., 2022 + * + * Authors: + * David Hildenbrand <david@redhat.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef SYSEMU_THREAD_CONTEXT_H +#define SYSEMU_THREAD_CONTEXT_H + +#include "qapi/qapi-types-machine.h" +#include "qemu/thread.h" +#include "qom/object.h" + +#define TYPE_THREAD_CONTEXT "thread-context" +OBJECT_DECLARE_TYPE(ThreadContext, ThreadContextClass, + THREAD_CONTEXT) + +struct ThreadContextClass { + ObjectClass parent_class; +}; + +struct ThreadContext { + /* private */ + Object parent; + + /* private */ + unsigned int thread_id; + QemuThread thread; + + /* Semaphore to wait for context thread action. */ + QemuSemaphore sem; + /* Semaphore to wait for action in context thread. */ + QemuSemaphore sem_thread; + /* Mutex to synchronize requests. */ + QemuMutex mutex; + + /* Commands for the thread to execute. */ + int thread_cmd; + void *thread_cmd_data; + + /* CPU affinity bitmap used for initialization. */ + unsigned long *init_cpu_bitmap; + int init_cpu_nbits; +}; + +void thread_context_create_thread(ThreadContext *tc, QemuThread *thread, + const char *name, + void *(*start_routine)(void *), void *arg, + int mode); + +#endif /* SYSEMU_THREAD_CONTEXT_H */ diff --git a/include/qemu/thread.h b/include/qemu/thread.h index 20641e5844..7c6703bce3 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -185,6 +185,10 @@ void qemu_event_destroy(QemuEvent *ev); void qemu_thread_create(QemuThread *thread, const char *name, void *(*start_routine)(void *), void *arg, int mode); +int qemu_thread_set_affinity(QemuThread *thread, unsigned long *host_cpus, + unsigned long nbits); +int qemu_thread_get_affinity(QemuThread *thread, unsigned long **host_cpus, + unsigned long *nbits); void *qemu_thread_join(QemuThread *thread); void qemu_thread_get_self(QemuThread *thread); bool qemu_thread_is_self(QemuThread *thread); diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h index 9ff5c16963..39326f1d4f 100644 --- a/include/sysemu/hostmem.h +++ b/include/sysemu/hostmem.h @@ -18,6 +18,7 @@ #include "qom/object.h" #include "exec/memory.h" #include "qemu/bitmap.h" +#include "qemu/thread-context.h" #define TYPE_MEMORY_BACKEND "memory-backend" OBJECT_DECLARE_TYPE(HostMemoryBackend, HostMemoryBackendClass, @@ -66,6 +67,7 @@ struct HostMemoryBackend { bool merge, dump, use_canonical_path; bool prealloc, is_mapped, share, reserve; uint32_t prealloc_threads; + ThreadContext *prealloc_context; DECLARE_BITMAP(host_nodes, MAX_NODES + 1); HostMemPolicy policy; diff --git a/io/channel-watch.c b/io/channel-watch.c index 0289b3647c..ad7c568a84 100644 --- a/io/channel-watch.c +++ b/io/channel-watch.c @@ -115,28 +115,24 @@ static gboolean qio_channel_socket_source_check(GSource *source) { static struct timeval tv0; - QIOChannelSocketSource *ssource = (QIOChannelSocketSource *)source; - WSANETWORKEVENTS ev; fd_set rfds, wfds, xfds; if (!ssource->condition) { return 0; } - WSAEnumNetworkEvents(ssource->socket, ssource->ioc->event, &ev); - FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&xfds); if (ssource->condition & G_IO_IN) { - FD_SET((SOCKET)ssource->socket, &rfds); + FD_SET(ssource->socket, &rfds); } if (ssource->condition & G_IO_OUT) { - FD_SET((SOCKET)ssource->socket, &wfds); + FD_SET(ssource->socket, &wfds); } if (ssource->condition & G_IO_PRI) { - FD_SET((SOCKET)ssource->socket, &xfds); + FD_SET(ssource->socket, &xfds); } ssource->revents = 0; if (select(0, &rfds, &wfds, &xfds, &tv0) == 0) { @@ -285,11 +281,9 @@ GSource *qio_channel_create_socket_watch(QIOChannel *ioc, GSource *source; QIOChannelSocketSource *ssource; -#ifdef WIN32 WSAEventSelect(socket, ioc->event, FD_READ | FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_WRITE | FD_OOB); -#endif source = g_source_new(&qio_channel_socket_source_funcs, sizeof(QIOChannelSocketSource)); @@ -588,7 +588,7 @@ static void coroutine_fn job_do_yield_locked(Job *job, uint64_t ns) next_aio_context = job->aio_context; /* * Coroutine has resumed, but in the meanwhile the job AioContext - * might have changed via bdrv_try_set_aio_context(), so we need to move + * might have changed via bdrv_try_change_aio_context(), so we need to move * the coroutine too in the new aiocontext. */ while (qemu_get_current_aio_context() != next_aio_context) { diff --git a/meson.build b/meson.build index d0a186e7f5..1c1afcc9b8 100644 --- a/meson.build +++ b/meson.build @@ -636,10 +636,16 @@ if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h', endif seccomp = not_found +seccomp_has_sysrawrc = false if not get_option('seccomp').auto() or have_system or have_tools seccomp = dependency('libseccomp', version: '>=2.3.0', required: get_option('seccomp'), method: 'pkg-config', kwargs: static_kwargs) + if seccomp.found() + seccomp_has_sysrawrc = cc.has_header_symbol('seccomp.h', + 'SCMP_FLTATR_API_SYSRAWRC', + dependencies: seccomp) + endif endif libcap_ng = not_found @@ -1847,7 +1853,6 @@ config_host_data.set('CONFIG_LIBNFS', libnfs.found()) config_host_data.set('CONFIG_LIBSSH', libssh.found()) config_host_data.set('CONFIG_LINUX_AIO', libaio.found()) config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found()) -config_host_data.set('CONFIG_LIBURING_REGISTER_RING_FD', cc.has_function('io_uring_register_ring_fd', prefix: '#include <liburing.h>', dependencies:linux_io_uring)) config_host_data.set('CONFIG_LIBPMEM', libpmem.found()) config_host_data.set('CONFIG_NUMA', numa.found()) config_host_data.set('CONFIG_OPENGL', opengl.found()) @@ -1857,6 +1862,9 @@ config_host_data.set('CONFIG_RDMA', rdma.found()) config_host_data.set('CONFIG_SDL', sdl.found()) config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found()) config_host_data.set('CONFIG_SECCOMP', seccomp.found()) +if seccomp.found() + config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc) +endif config_host_data.set('CONFIG_SNAPPY', snappy.found()) config_host_data.set('CONFIG_TPM', have_tpm) config_host_data.set('CONFIG_USB_LIBUSB', libusb.found()) @@ -2122,7 +2130,23 @@ config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_pre pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); return 0; }''', dependencies: threads)) +config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + ''' + #include <pthread.h> + static void *f(void *p) { return NULL; } + int main(void) + { + int setsize = CPU_ALLOC_SIZE(64); + pthread_t thread; + cpu_set_t *cpuset; + pthread_create(&thread, 0, f, 0); + cpuset = CPU_ALLOC(64); + CPU_ZERO_S(setsize, cpuset); + pthread_setaffinity_np(thread, setsize, cpuset); + pthread_getaffinity_np(thread, setsize, cpuset); + CPU_FREE(cpuset); + return 0; + }''', dependencies: threads)) config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + ''' #include <sys/signalfd.h> #include <stddef.h> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index bab86c5537..01b789a79e 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -199,27 +199,6 @@ void hmp_info_mice(Monitor *mon, const QDict *qdict) qapi_free_MouseInfoList(mice_list); } -static char *SocketAddress_to_str(SocketAddress *addr) -{ - switch (addr->type) { - case SOCKET_ADDRESS_TYPE_INET: - return g_strdup_printf("tcp:%s:%s", - addr->u.inet.host, - addr->u.inet.port); - case SOCKET_ADDRESS_TYPE_UNIX: - return g_strdup_printf("unix:%s", - addr->u.q_unix.path); - case SOCKET_ADDRESS_TYPE_FD: - return g_strdup_printf("fd:%s", addr->u.fd.str); - case SOCKET_ADDRESS_TYPE_VSOCK: - return g_strdup_printf("tcp:%s:%s", - addr->u.vsock.cid, - addr->u.vsock.port); - default: - return g_strdup("unknown address type"); - } -} - void hmp_info_migrate(Monitor *mon, const QDict *qdict) { MigrationInfo *info; @@ -382,7 +361,7 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict) monitor_printf(mon, "socket address: [\n"); for (addr = info->socket_address; addr; addr = addr->next) { - char *s = SocketAddress_to_str(addr->value); + char *s = socket_uri(addr->value); monitor_printf(mon, "\t%s\n", s); g_free(s); } diff --git a/net/clients.h b/net/clients.h index c9157789f2..ed8bdfff1e 100644 --- a/net/clients.h +++ b/net/clients.h @@ -40,6 +40,12 @@ int net_init_hubport(const Netdev *netdev, const char *name, int net_init_socket(const Netdev *netdev, const char *name, NetClientState *peer, Error **errp); +int net_init_stream(const Netdev *netdev, const char *name, + NetClientState *peer, Error **errp); + +int net_init_dgram(const Netdev *netdev, const char *name, + NetClientState *peer, Error **errp); + int net_init_tap(const Netdev *netdev, const char *name, NetClientState *peer, Error **errp); diff --git a/net/dgram.c b/net/dgram.c new file mode 100644 index 0000000000..9f7bf38376 --- /dev/null +++ b/net/dgram.c @@ -0,0 +1,623 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * Copyright (c) 2022 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" + +#include "net/net.h" +#include "clients.h" +#include "monitor/monitor.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "qemu/option.h" +#include "qemu/sockets.h" +#include "qemu/iov.h" +#include "qemu/main-loop.h" +#include "qemu/cutils.h" + +typedef struct NetDgramState { + NetClientState nc; + int fd; + SocketReadState rs; + bool read_poll; /* waiting to receive data? */ + bool write_poll; /* waiting to transmit data? */ + /* contains destination iff connectionless */ + struct sockaddr *dest_addr; + socklen_t dest_len; +} NetDgramState; + +static void net_dgram_send(void *opaque); +static void net_dgram_writable(void *opaque); + +static void net_dgram_update_fd_handler(NetDgramState *s) +{ + qemu_set_fd_handler(s->fd, + s->read_poll ? net_dgram_send : NULL, + s->write_poll ? net_dgram_writable : NULL, + s); +} + +static void net_dgram_read_poll(NetDgramState *s, bool enable) +{ + s->read_poll = enable; + net_dgram_update_fd_handler(s); +} + +static void net_dgram_write_poll(NetDgramState *s, bool enable) +{ + s->write_poll = enable; + net_dgram_update_fd_handler(s); +} + +static void net_dgram_writable(void *opaque) +{ + NetDgramState *s = opaque; + + net_dgram_write_poll(s, false); + + qemu_flush_queued_packets(&s->nc); +} + +static ssize_t net_dgram_receive(NetClientState *nc, + const uint8_t *buf, size_t size) +{ + NetDgramState *s = DO_UPCAST(NetDgramState, nc, nc); + ssize_t ret; + + do { + if (s->dest_addr) { + ret = sendto(s->fd, buf, size, 0, s->dest_addr, s->dest_len); + } else { + ret = send(s->fd, buf, size, 0); + } + } while (ret == -1 && errno == EINTR); + + if (ret == -1 && errno == EAGAIN) { + net_dgram_write_poll(s, true); + return 0; + } + return ret; +} + +static void net_dgram_send_completed(NetClientState *nc, ssize_t len) +{ + NetDgramState *s = DO_UPCAST(NetDgramState, nc, nc); + + if (!s->read_poll) { + net_dgram_read_poll(s, true); + } +} + +static void net_dgram_rs_finalize(SocketReadState *rs) +{ + NetDgramState *s = container_of(rs, NetDgramState, rs); + + if (qemu_send_packet_async(&s->nc, rs->buf, + rs->packet_len, + net_dgram_send_completed) == 0) { + net_dgram_read_poll(s, false); + } +} + +static void net_dgram_send(void *opaque) +{ + NetDgramState *s = opaque; + int size; + + size = recv(s->fd, s->rs.buf, sizeof(s->rs.buf), 0); + if (size < 0) { + return; + } + if (size == 0) { + /* end of connection */ + net_dgram_read_poll(s, false); + net_dgram_write_poll(s, false); + return; + } + if (qemu_send_packet_async(&s->nc, s->rs.buf, size, + net_dgram_send_completed) == 0) { + net_dgram_read_poll(s, false); + } +} + +static int net_dgram_mcast_create(struct sockaddr_in *mcastaddr, + struct in_addr *localaddr, + Error **errp) +{ + struct ip_mreq imr; + int fd; + int val, ret; +#ifdef __OpenBSD__ + unsigned char loop; +#else + int loop; +#endif + + if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) { + error_setg(errp, "specified mcastaddr %s (0x%08x) " + "does not contain a multicast address", + inet_ntoa(mcastaddr->sin_addr), + (int)ntohl(mcastaddr->sin_addr.s_addr)); + return -1; + } + + fd = qemu_socket(PF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + error_setg_errno(errp, errno, "can't create datagram socket"); + return -1; + } + + /* + * Allow multiple sockets to bind the same multicast ip and port by setting + * SO_REUSEADDR. This is the only situation where SO_REUSEADDR should be set + * on windows. Use socket_set_fast_reuse otherwise as it sets SO_REUSEADDR + * only on posix systems. + */ + val = 1; + ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + if (ret < 0) { + error_setg_errno(errp, errno, "can't set socket option SO_REUSEADDR"); + goto fail; + } + + ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr)); + if (ret < 0) { + error_setg_errno(errp, errno, "can't bind ip=%s to socket", + inet_ntoa(mcastaddr->sin_addr)); + goto fail; + } + + /* Add host to multicast group */ + imr.imr_multiaddr = mcastaddr->sin_addr; + if (localaddr) { + imr.imr_interface = *localaddr; + } else { + imr.imr_interface.s_addr = htonl(INADDR_ANY); + } + + ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, + &imr, sizeof(struct ip_mreq)); + if (ret < 0) { + error_setg_errno(errp, errno, + "can't add socket to multicast group %s", + inet_ntoa(imr.imr_multiaddr)); + goto fail; + } + + /* Force mcast msgs to loopback (eg. several QEMUs in same host */ + loop = 1; + ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, + &loop, sizeof(loop)); + if (ret < 0) { + error_setg_errno(errp, errno, + "can't force multicast message to loopback"); + goto fail; + } + + /* If a bind address is given, only send packets from that address */ + if (localaddr != NULL) { + ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, + localaddr, sizeof(*localaddr)); + if (ret < 0) { + error_setg_errno(errp, errno, + "can't set the default network send interface"); + goto fail; + } + } + + qemu_socket_set_nonblock(fd); + return fd; +fail: + if (fd >= 0) { + closesocket(fd); + } + return -1; +} + +static void net_dgram_cleanup(NetClientState *nc) +{ + NetDgramState *s = DO_UPCAST(NetDgramState, nc, nc); + if (s->fd != -1) { + net_dgram_read_poll(s, false); + net_dgram_write_poll(s, false); + close(s->fd); + s->fd = -1; + } + g_free(s->dest_addr); + s->dest_addr = NULL; + s->dest_len = 0; +} + +static NetClientInfo net_dgram_socket_info = { + .type = NET_CLIENT_DRIVER_DGRAM, + .size = sizeof(NetDgramState), + .receive = net_dgram_receive, + .cleanup = net_dgram_cleanup, +}; + +static NetDgramState *net_dgram_fd_init(NetClientState *peer, + const char *model, + const char *name, + int fd, + Error **errp) +{ + NetClientState *nc; + NetDgramState *s; + + nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name); + + s = DO_UPCAST(NetDgramState, nc, nc); + + s->fd = fd; + net_socket_rs_init(&s->rs, net_dgram_rs_finalize, false); + net_dgram_read_poll(s, true); + + return s; +} + +static int net_dgram_mcast_init(NetClientState *peer, + const char *model, + const char *name, + SocketAddress *remote, + SocketAddress *local, + Error **errp) +{ + NetDgramState *s; + int fd, ret; + struct sockaddr_in *saddr; + + if (remote->type != SOCKET_ADDRESS_TYPE_INET) { + error_setg(errp, "multicast only support inet type"); + return -1; + } + + saddr = g_new(struct sockaddr_in, 1); + if (convert_host_port(saddr, remote->u.inet.host, remote->u.inet.port, + errp) < 0) { + g_free(saddr); + return -1; + } + + if (!local) { + fd = net_dgram_mcast_create(saddr, NULL, errp); + if (fd < 0) { + g_free(saddr); + return -1; + } + } else { + switch (local->type) { + case SOCKET_ADDRESS_TYPE_INET: { + struct in_addr localaddr; + + if (inet_aton(local->u.inet.host, &localaddr) == 0) { + g_free(saddr); + error_setg(errp, "localaddr '%s' is not a valid IPv4 address", + local->u.inet.host); + return -1; + } + + fd = net_dgram_mcast_create(saddr, &localaddr, errp); + if (fd < 0) { + g_free(saddr); + return -1; + } + break; + } + case SOCKET_ADDRESS_TYPE_FD: { + int newfd; + + fd = monitor_fd_param(monitor_cur(), local->u.fd.str, errp); + if (fd == -1) { + g_free(saddr); + return -1; + } + ret = qemu_socket_try_set_nonblock(fd); + if (ret < 0) { + g_free(saddr); + error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", + name, fd); + return -1; + } + + /* + * fd passed: multicast: "learn" dest_addr address from bound + * address and save it. Because this may be "shared" socket from a + * "master" process, datagrams would be recv() by ONLY ONE process: + * we must "clone" this dgram socket --jjo + */ + + saddr = g_new(struct sockaddr_in, 1); + + if (convert_host_port(saddr, local->u.inet.host, local->u.inet.port, + errp) < 0) { + g_free(saddr); + closesocket(fd); + return -1; + } + + /* must be bound */ + if (saddr->sin_addr.s_addr == 0) { + error_setg(errp, "can't setup multicast destination address"); + g_free(saddr); + closesocket(fd); + return -1; + } + /* clone dgram socket */ + newfd = net_dgram_mcast_create(saddr, NULL, errp); + if (newfd < 0) { + g_free(saddr); + closesocket(fd); + return -1; + } + /* clone newfd to fd, close newfd */ + dup2(newfd, fd); + close(newfd); + break; + } + default: + g_free(saddr); + error_setg(errp, "only support inet or fd type for local"); + return -1; + } + } + + s = net_dgram_fd_init(peer, model, name, fd, errp); + if (!s) { + g_free(saddr); + return -1; + } + + g_assert(s->dest_addr == NULL); + s->dest_addr = (struct sockaddr *)saddr; + s->dest_len = sizeof(*saddr); + + if (!local) { + qemu_set_info_str(&s->nc, "mcast=%s:%d", + inet_ntoa(saddr->sin_addr), + ntohs(saddr->sin_port)); + } else { + switch (local->type) { + case SOCKET_ADDRESS_TYPE_INET: + qemu_set_info_str(&s->nc, "mcast=%s:%d", + inet_ntoa(saddr->sin_addr), + ntohs(saddr->sin_port)); + break; + case SOCKET_ADDRESS_TYPE_FD: + qemu_set_info_str(&s->nc, "fd=%d (cloned mcast=%s:%d)", + fd, inet_ntoa(saddr->sin_addr), + ntohs(saddr->sin_port)); + break; + default: + g_assert_not_reached(); + } + } + + return 0; + +} + + +int net_init_dgram(const Netdev *netdev, const char *name, + NetClientState *peer, Error **errp) +{ + NetDgramState *s; + int fd, ret; + SocketAddress *remote, *local; + struct sockaddr *dest_addr; + struct sockaddr_in laddr_in, raddr_in; + struct sockaddr_un laddr_un, raddr_un; + socklen_t dest_len; + + assert(netdev->type == NET_CLIENT_DRIVER_DGRAM); + + remote = netdev->u.dgram.remote; + local = netdev->u.dgram.local; + + /* detect multicast address */ + if (remote && remote->type == SOCKET_ADDRESS_TYPE_INET) { + struct sockaddr_in mcastaddr; + + if (convert_host_port(&mcastaddr, remote->u.inet.host, + remote->u.inet.port, errp) < 0) { + return -1; + } + + if (IN_MULTICAST(ntohl(mcastaddr.sin_addr.s_addr))) { + return net_dgram_mcast_init(peer, "dram", name, remote, local, + errp); + } + } + + /* unicast address */ + if (!local) { + error_setg(errp, "dgram requires local= parameter"); + return -1; + } + + if (remote) { + if (local->type == SOCKET_ADDRESS_TYPE_FD) { + error_setg(errp, "don't set remote with local.fd"); + return -1; + } + if (remote->type != local->type) { + error_setg(errp, "remote and local types must be the same"); + return -1; + } + } else { + if (local->type != SOCKET_ADDRESS_TYPE_FD) { + error_setg(errp, + "type=inet or type=unix requires remote parameter"); + return -1; + } + } + + switch (local->type) { + case SOCKET_ADDRESS_TYPE_INET: + if (convert_host_port(&laddr_in, local->u.inet.host, local->u.inet.port, + errp) < 0) { + return -1; + } + + if (convert_host_port(&raddr_in, remote->u.inet.host, + remote->u.inet.port, errp) < 0) { + return -1; + } + + fd = qemu_socket(PF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + error_setg_errno(errp, errno, "can't create datagram socket"); + return -1; + } + + ret = socket_set_fast_reuse(fd); + if (ret < 0) { + error_setg_errno(errp, errno, + "can't set socket option SO_REUSEADDR"); + closesocket(fd); + return -1; + } + ret = bind(fd, (struct sockaddr *)&laddr_in, sizeof(laddr_in)); + if (ret < 0) { + error_setg_errno(errp, errno, "can't bind ip=%s to socket", + inet_ntoa(laddr_in.sin_addr)); + closesocket(fd); + return -1; + } + qemu_socket_set_nonblock(fd); + + dest_len = sizeof(raddr_in); + dest_addr = g_malloc(dest_len); + memcpy(dest_addr, &raddr_in, dest_len); + break; + case SOCKET_ADDRESS_TYPE_UNIX: + ret = unlink(local->u.q_unix.path); + if (ret < 0 && errno != ENOENT) { + error_setg_errno(errp, errno, "failed to unlink socket %s", + local->u.q_unix.path); + return -1; + } + + laddr_un.sun_family = PF_UNIX; + ret = snprintf(laddr_un.sun_path, sizeof(laddr_un.sun_path), "%s", + local->u.q_unix.path); + if (ret < 0 || ret >= sizeof(laddr_un.sun_path)) { + error_setg(errp, "UNIX socket path '%s' is too long", + local->u.q_unix.path); + error_append_hint(errp, "Path must be less than %zu bytes\n", + sizeof(laddr_un.sun_path)); + } + + raddr_un.sun_family = PF_UNIX; + ret = snprintf(raddr_un.sun_path, sizeof(raddr_un.sun_path), "%s", + remote->u.q_unix.path); + if (ret < 0 || ret >= sizeof(raddr_un.sun_path)) { + error_setg(errp, "UNIX socket path '%s' is too long", + remote->u.q_unix.path); + error_append_hint(errp, "Path must be less than %zu bytes\n", + sizeof(raddr_un.sun_path)); + } + + fd = qemu_socket(PF_UNIX, SOCK_DGRAM, 0); + if (fd < 0) { + error_setg_errno(errp, errno, "can't create datagram socket"); + return -1; + } + + ret = bind(fd, (struct sockaddr *)&laddr_un, sizeof(laddr_un)); + if (ret < 0) { + error_setg_errno(errp, errno, "can't bind unix=%s to socket", + laddr_un.sun_path); + closesocket(fd); + return -1; + } + qemu_socket_set_nonblock(fd); + + dest_len = sizeof(raddr_un); + dest_addr = g_malloc(dest_len); + memcpy(dest_addr, &raddr_un, dest_len); + break; + case SOCKET_ADDRESS_TYPE_FD: + fd = monitor_fd_param(monitor_cur(), local->u.fd.str, errp); + if (fd == -1) { + return -1; + } + ret = qemu_socket_try_set_nonblock(fd); + if (ret < 0) { + error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d", + name, fd); + return -1; + } + dest_addr = NULL; + dest_len = 0; + break; + default: + error_setg(errp, "only support inet or fd type for local"); + return -1; + } + + s = net_dgram_fd_init(peer, "dgram", name, fd, errp); + if (!s) { + return -1; + } + + if (remote) { + g_assert(s->dest_addr == NULL); + s->dest_addr = dest_addr; + s->dest_len = dest_len; + } + + switch (local->type) { + case SOCKET_ADDRESS_TYPE_INET: + qemu_set_info_str(&s->nc, "udp=%s:%d/%s:%d", + inet_ntoa(laddr_in.sin_addr), + ntohs(laddr_in.sin_port), + inet_ntoa(raddr_in.sin_addr), + ntohs(raddr_in.sin_port)); + break; + case SOCKET_ADDRESS_TYPE_UNIX: + qemu_set_info_str(&s->nc, "udp=%s:%s", + laddr_un.sun_path, raddr_un.sun_path); + break; + case SOCKET_ADDRESS_TYPE_FD: { + SocketAddress *sa; + SocketAddressType sa_type; + + sa = socket_local_address(fd, errp); + if (sa) { + sa_type = sa->type; + qapi_free_SocketAddress(sa); + + qemu_set_info_str(&s->nc, "fd=%d %s", fd, + SocketAddressType_str(sa_type)); + } else { + qemu_set_info_str(&s->nc, "fd=%d", fd); + } + break; + } + default: + g_assert_not_reached(); + } + + return 0; +} @@ -313,6 +313,8 @@ void net_hub_check_clients(void) case NET_CLIENT_DRIVER_USER: case NET_CLIENT_DRIVER_TAP: case NET_CLIENT_DRIVER_SOCKET: + case NET_CLIENT_DRIVER_STREAM: + case NET_CLIENT_DRIVER_DGRAM: case NET_CLIENT_DRIVER_VDE: case NET_CLIENT_DRIVER_VHOST_USER: has_host_dev = 1; diff --git a/net/l2tpv3.c b/net/l2tpv3.c index af373e5c30..350041a0d6 100644 --- a/net/l2tpv3.c +++ b/net/l2tpv3.c @@ -723,8 +723,7 @@ int net_init_l2tpv3(const Netdev *netdev, l2tpv3_read_poll(s, true); - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "l2tpv3: connected"); + qemu_set_info_str(&s->nc, "l2tpv3: connected"); return 0; outerr: qemu_del_net_client(nc); diff --git a/net/meson.build b/net/meson.build index d1be76daf3..6cd1e3dab3 100644 --- a/net/meson.build +++ b/net/meson.build @@ -13,6 +13,8 @@ softmmu_ss.add(files( 'net.c', 'queue.c', 'socket.c', + 'stream.c', + 'dgram.c', 'util.c', )) @@ -48,12 +48,14 @@ #include "qemu/qemu-print.h" #include "qemu/main-loop.h" #include "qemu/option.h" +#include "qemu/keyval.h" #include "qapi/error.h" #include "qapi/opts-visitor.h" #include "sysemu/runstate.h" #include "net/colo-compare.h" #include "net/filter.h" #include "qapi/string-output-visitor.h" +#include "qapi/qobject-input-visitor.h" /* Net bridge is currently not supported for W32. */ #if !defined(_WIN32) @@ -63,58 +65,70 @@ static VMChangeStateEntry *net_change_state_entry; static QTAILQ_HEAD(, NetClientState) net_clients; +typedef struct NetdevQueueEntry { + Netdev *nd; + Location loc; + QSIMPLEQ_ENTRY(NetdevQueueEntry) entry; +} NetdevQueueEntry; + +typedef QSIMPLEQ_HEAD(, NetdevQueueEntry) NetdevQueue; + +static NetdevQueue nd_queue = QSIMPLEQ_HEAD_INITIALIZER(nd_queue); + /***********************************************************/ /* network device redirectors */ -int parse_host_port(struct sockaddr_in *saddr, const char *str, - Error **errp) +int convert_host_port(struct sockaddr_in *saddr, const char *host, + const char *port, Error **errp) { - gchar **substrings; struct hostent *he; - const char *addr, *p, *r; - int port, ret = 0; + const char *r; + long p; memset(saddr, 0, sizeof(*saddr)); - substrings = g_strsplit(str, ":", 2); - if (!substrings || !substrings[0] || !substrings[1]) { - error_setg(errp, "host address '%s' doesn't contain ':' " - "separating host from port", str); - ret = -1; - goto out; - } - - addr = substrings[0]; - p = substrings[1]; - saddr->sin_family = AF_INET; - if (addr[0] == '\0') { + if (host[0] == '\0') { saddr->sin_addr.s_addr = 0; } else { - if (qemu_isdigit(addr[0])) { - if (!inet_aton(addr, &saddr->sin_addr)) { + if (qemu_isdigit(host[0])) { + if (!inet_aton(host, &saddr->sin_addr)) { error_setg(errp, "host address '%s' is not a valid " - "IPv4 address", addr); - ret = -1; - goto out; + "IPv4 address", host); + return -1; } } else { - he = gethostbyname(addr); + he = gethostbyname(host); if (he == NULL) { - error_setg(errp, "can't resolve host address '%s'", addr); - ret = -1; - goto out; + error_setg(errp, "can't resolve host address '%s'", host); + return -1; } saddr->sin_addr = *(struct in_addr *)he->h_addr; } } - port = strtol(p, (char **)&r, 0); - if (r == p) { - error_setg(errp, "port number '%s' is invalid", p); + if (qemu_strtol(port, &r, 0, &p) != 0) { + error_setg(errp, "port number '%s' is invalid", port); + return -1; + } + saddr->sin_port = htons(p); + return 0; +} + +int parse_host_port(struct sockaddr_in *saddr, const char *str, + Error **errp) +{ + gchar **substrings; + int ret; + + substrings = g_strsplit(str, ":", 2); + if (!substrings || !substrings[0] || !substrings[1]) { + error_setg(errp, "host address '%s' doesn't contain ':' " + "separating host from port", str); ret = -1; goto out; } - saddr->sin_port = htons(port); + + ret = convert_host_port(saddr, substrings[0], substrings[1], errp); out: g_strfreev(substrings); @@ -128,13 +142,20 @@ char *qemu_mac_strdup_printf(const uint8_t *macaddr) macaddr[3], macaddr[4], macaddr[5]); } +void qemu_set_info_str(NetClientState *nc, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vsnprintf(nc->info_str, sizeof(nc->info_str), fmt, ap); + va_end(ap); +} + void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]) { - snprintf(nc->info_str, sizeof(nc->info_str), - "model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x", - nc->model, - macaddr[0], macaddr[1], macaddr[2], - macaddr[3], macaddr[4], macaddr[5]); + qemu_set_info_str(nc, "model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x", + nc->model, macaddr[0], macaddr[1], macaddr[2], + macaddr[3], macaddr[4], macaddr[5]); } static int mac_table[256] = {0}; @@ -1001,6 +1022,8 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])( #endif [NET_CLIENT_DRIVER_TAP] = net_init_tap, [NET_CLIENT_DRIVER_SOCKET] = net_init_socket, + [NET_CLIENT_DRIVER_STREAM] = net_init_stream, + [NET_CLIENT_DRIVER_DGRAM] = net_init_dgram, #ifdef CONFIG_VDE [NET_CLIENT_DRIVER_VDE] = net_init_vde, #endif @@ -1036,19 +1059,23 @@ static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp) if (is_netdev) { if (netdev->type == NET_CLIENT_DRIVER_NIC || !net_client_init_fun[netdev->type]) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type", - "a netdev backend type"); + error_setg(errp, "network backend '%s' is not compiled into this binary", + NetClientDriver_str(netdev->type)); return -1; } } else { if (netdev->type == NET_CLIENT_DRIVER_NONE) { return 0; /* nothing to do */ } - if (netdev->type == NET_CLIENT_DRIVER_HUBPORT || - !net_client_init_fun[netdev->type]) { - error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "type", - "a net backend type (maybe it is not compiled " - "into this binary)"); + if (netdev->type == NET_CLIENT_DRIVER_HUBPORT) { + error_setg(errp, "network backend '%s' is only supported with -netdev/-nic", + NetClientDriver_str(netdev->type)); + return -1; + } + + if (!net_client_init_fun[netdev->type]) { + error_setg(errp, "network backend '%s' is not compiled into this binary", + NetClientDriver_str(netdev->type)); return -1; } @@ -1088,6 +1115,8 @@ void show_netdevs(void) int idx; const char *available_netdevs[] = { "socket", + "stream", + "dgram", "hubport", "tap", #ifdef CONFIG_SLIRP @@ -1560,36 +1589,97 @@ out: return ret; } -int net_init_clients(Error **errp) +static void netdev_init_modern(void) +{ + while (!QSIMPLEQ_EMPTY(&nd_queue)) { + NetdevQueueEntry *nd = QSIMPLEQ_FIRST(&nd_queue); + + QSIMPLEQ_REMOVE_HEAD(&nd_queue, entry); + loc_push_restore(&nd->loc); + net_client_init1(nd->nd, true, &error_fatal); + loc_pop(&nd->loc); + qapi_free_Netdev(nd->nd); + g_free(nd); + } +} + +void net_init_clients(void) { net_change_state_entry = qemu_add_vm_change_state_handler(net_vm_change_state_handler, NULL); QTAILQ_INIT(&net_clients); - if (qemu_opts_foreach(qemu_find_opts("netdev"), - net_init_netdev, NULL, errp)) { - return -1; - } + netdev_init_modern(); - if (qemu_opts_foreach(qemu_find_opts("nic"), net_param_nic, NULL, errp)) { - return -1; - } + qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, + &error_fatal); - if (qemu_opts_foreach(qemu_find_opts("net"), net_init_client, NULL, errp)) { - return -1; + qemu_opts_foreach(qemu_find_opts("nic"), net_param_nic, NULL, + &error_fatal); + + qemu_opts_foreach(qemu_find_opts("net"), net_init_client, NULL, + &error_fatal); +} + +/* + * Does this -netdev argument use modern rather than traditional syntax? + * Modern syntax is to be parsed with netdev_parse_modern(). + * Traditional syntax is to be parsed with net_client_parse(). + */ +bool netdev_is_modern(const char *optarg) +{ + QemuOpts *opts; + bool is_modern; + const char *type; + static QemuOptsList dummy_opts = { + .name = "netdev", + .implied_opt_name = "type", + .head = QTAILQ_HEAD_INITIALIZER(dummy_opts.head), + .desc = { { } }, + }; + + if (optarg[0] == '{') { + /* This is JSON, which means it's modern syntax */ + return true; } - return 0; + opts = qemu_opts_create(&dummy_opts, NULL, false, &error_abort); + qemu_opts_do_parse(opts, optarg, dummy_opts.implied_opt_name, + &error_abort); + type = qemu_opt_get(opts, "type"); + is_modern = !g_strcmp0(type, "stream") || !g_strcmp0(type, "dgram"); + + qemu_opts_reset(&dummy_opts); + + return is_modern; +} + +/* + * netdev_parse_modern() uses modern, more expressive syntax than + * net_client_parse(), but supports only the -netdev option. + * netdev_parse_modern() appends to @nd_queue, whereas net_client_parse() + * appends to @qemu_netdev_opts. + */ +void netdev_parse_modern(const char *optarg) +{ + Visitor *v; + NetdevQueueEntry *nd; + + v = qobject_input_visitor_new_str(optarg, "type", &error_fatal); + nd = g_new(NetdevQueueEntry, 1); + visit_type_Netdev(v, NULL, &nd->nd, &error_fatal); + visit_free(v); + loc_save(&nd->loc); + + QSIMPLEQ_INSERT_TAIL(&nd_queue, nd, entry); } -int net_client_parse(QemuOptsList *opts_list, const char *optarg) +void net_client_parse(QemuOptsList *opts_list, const char *optarg) { if (!qemu_opts_parse_noisily(opts_list, optarg, true)) { - return -1; + exit(1); } - - return 0; } /* From FreeBSD */ diff --git a/net/slirp.c b/net/slirp.c index 8679be6444..14a8d59277 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -611,9 +611,8 @@ static int net_slirp_init(NetClientState *peer, const char *model, nc = qemu_new_net_client(&net_slirp_info, peer, model, name); - snprintf(nc->info_str, sizeof(nc->info_str), - "net=%s,restrict=%s", inet_ntoa(net), - restricted ? "on" : "off"); + qemu_set_info_str(nc, "net=%s,restrict=%s", inet_ntoa(net), + restricted ? "on" : "off"); s = DO_UPCAST(SlirpState, nc, nc); diff --git a/net/socket.c b/net/socket.c index bfd8596250..4944bb70d5 100644 --- a/net/socket.c +++ b/net/socket.c @@ -179,7 +179,7 @@ static void net_socket_send(void *opaque) s->fd = -1; net_socket_rs_init(&s->rs, net_socket_rs_finalize, false); s->nc.link_down = true; - memset(s->nc.info_str, 0, sizeof(s->nc.info_str)); + qemu_set_info_str(&s->nc, ""); return; } @@ -387,16 +387,15 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer, /* mcast: save bound address as dst */ if (is_connected && mcast != NULL) { s->dgram_dst = saddr; - snprintf(nc->info_str, sizeof(nc->info_str), - "socket: fd=%d (cloned mcast=%s:%d)", - fd, inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); + qemu_set_info_str(nc, "socket: fd=%d (cloned mcast=%s:%d)", fd, + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); } else { if (sa_type == SOCKET_ADDRESS_TYPE_UNIX) { s->dgram_dst.sin_family = AF_UNIX; } - snprintf(nc->info_str, sizeof(nc->info_str), - "socket: fd=%d %s", fd, SocketAddressType_str(sa_type)); + qemu_set_info_str(nc, "socket: fd=%d %s", fd, + SocketAddressType_str(sa_type)); } return s; @@ -430,7 +429,7 @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer, nc = qemu_new_net_client(&net_socket_info, peer, model, name); - snprintf(nc->info_str, sizeof(nc->info_str), "socket: fd=%d", fd); + qemu_set_info_str(nc, "socket: fd=%d", fd); s = DO_UPCAST(NetSocketState, nc, nc); @@ -497,9 +496,8 @@ static void net_socket_accept(void *opaque) s->fd = fd; s->nc.link_down = false; net_socket_connect(s); - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "socket: connection from %s:%d", - inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); + qemu_set_info_str(&s->nc, "socket: connection from %s:%d", + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); } static int net_socket_listen_init(NetClientState *peer, @@ -579,8 +577,7 @@ static int net_socket_connect_init(NetClientState *peer, if (errno == EINTR || errno == EWOULDBLOCK) { /* continue */ } else if (errno == EINPROGRESS || - errno == EALREADY || - errno == EINVAL) { + errno == EALREADY) { break; } else { error_setg_errno(errp, errno, "can't connect socket"); @@ -597,9 +594,8 @@ static int net_socket_connect_init(NetClientState *peer, return -1; } - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "socket: connect to %s:%d", - inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); + qemu_set_info_str(&s->nc, "socket: connect to %s:%d", + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); return 0; } @@ -642,9 +638,8 @@ static int net_socket_mcast_init(NetClientState *peer, s->dgram_dst = saddr; - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "socket: mcast=%s:%d", - inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); + qemu_set_info_str(&s->nc, "socket: mcast=%s:%d", + inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); return 0; } @@ -697,9 +692,8 @@ static int net_socket_udp_init(NetClientState *peer, s->dgram_dst = raddr; - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "socket: udp=%s:%d", - inet_ntoa(raddr.sin_addr), ntohs(raddr.sin_port)); + qemu_set_info_str(&s->nc, "socket: udp=%s:%d", inet_ntoa(raddr.sin_addr), + ntohs(raddr.sin_port)); return 0; } diff --git a/net/stream.c b/net/stream.c new file mode 100644 index 0000000000..53b7040cc4 --- /dev/null +++ b/net/stream.c @@ -0,0 +1,386 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * Copyright (c) 2022 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" + +#include "net/net.h" +#include "clients.h" +#include "monitor/monitor.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "qemu/option.h" +#include "qemu/sockets.h" +#include "qemu/iov.h" +#include "qemu/main-loop.h" +#include "qemu/cutils.h" +#include "io/channel.h" +#include "io/channel-socket.h" +#include "io/net-listener.h" +#include "qapi/qapi-events-net.h" + +typedef struct NetStreamState { + NetClientState nc; + QIOChannel *listen_ioc; + QIONetListener *listener; + QIOChannel *ioc; + guint ioc_read_tag; + guint ioc_write_tag; + SocketReadState rs; + unsigned int send_index; /* number of bytes sent*/ +} NetStreamState; + +static void net_stream_listen(QIONetListener *listener, + QIOChannelSocket *cioc, + void *opaque); + +static gboolean net_stream_writable(QIOChannel *ioc, + GIOCondition condition, + gpointer data) +{ + NetStreamState *s = data; + + s->ioc_write_tag = 0; + + qemu_flush_queued_packets(&s->nc); + + return G_SOURCE_REMOVE; +} + +static ssize_t net_stream_receive(NetClientState *nc, const uint8_t *buf, + size_t size) +{ + NetStreamState *s = DO_UPCAST(NetStreamState, nc, nc); + uint32_t len = htonl(size); + struct iovec iov[] = { + { + .iov_base = &len, + .iov_len = sizeof(len), + }, { + .iov_base = (void *)buf, + .iov_len = size, + }, + }; + struct iovec local_iov[2]; + unsigned int nlocal_iov; + size_t remaining; + ssize_t ret; + + remaining = iov_size(iov, 2) - s->send_index; + nlocal_iov = iov_copy(local_iov, 2, iov, 2, s->send_index, remaining); + ret = qio_channel_writev(s->ioc, local_iov, nlocal_iov, NULL); + if (ret == QIO_CHANNEL_ERR_BLOCK) { + ret = 0; /* handled further down */ + } + if (ret == -1) { + s->send_index = 0; + return -errno; + } + if (ret < (ssize_t)remaining) { + s->send_index += ret; + s->ioc_write_tag = qio_channel_add_watch(s->ioc, G_IO_OUT, + net_stream_writable, s, NULL); + return 0; + } + s->send_index = 0; + return size; +} + +static gboolean net_stream_send(QIOChannel *ioc, + GIOCondition condition, + gpointer data); + +static void net_stream_send_completed(NetClientState *nc, ssize_t len) +{ + NetStreamState *s = DO_UPCAST(NetStreamState, nc, nc); + + if (!s->ioc_read_tag) { + s->ioc_read_tag = qio_channel_add_watch(s->ioc, G_IO_IN, + net_stream_send, s, NULL); + } +} + +static void net_stream_rs_finalize(SocketReadState *rs) +{ + NetStreamState *s = container_of(rs, NetStreamState, rs); + + if (qemu_send_packet_async(&s->nc, rs->buf, + rs->packet_len, + net_stream_send_completed) == 0) { + if (s->ioc_read_tag) { + g_source_remove(s->ioc_read_tag); + s->ioc_read_tag = 0; + } + } +} + +static gboolean net_stream_send(QIOChannel *ioc, + GIOCondition condition, + gpointer data) +{ + NetStreamState *s = data; + int size; + int ret; + char buf1[NET_BUFSIZE]; + const char *buf; + + size = qio_channel_read(s->ioc, buf1, sizeof(buf1), NULL); + if (size < 0) { + if (errno != EWOULDBLOCK) { + goto eoc; + } + } else if (size == 0) { + /* end of connection */ + eoc: + s->ioc_read_tag = 0; + if (s->ioc_write_tag) { + g_source_remove(s->ioc_write_tag); + s->ioc_write_tag = 0; + } + if (s->listener) { + qio_net_listener_set_client_func(s->listener, net_stream_listen, + s, NULL); + } + object_unref(OBJECT(s->ioc)); + s->ioc = NULL; + + net_socket_rs_init(&s->rs, net_stream_rs_finalize, false); + s->nc.link_down = true; + qemu_set_info_str(&s->nc, ""); + + qapi_event_send_netdev_stream_disconnected(s->nc.name); + + return G_SOURCE_REMOVE; + } + buf = buf1; + + ret = net_fill_rstate(&s->rs, (const uint8_t *)buf, size); + + if (ret == -1) { + goto eoc; + } + + return G_SOURCE_CONTINUE; +} + +static void net_stream_cleanup(NetClientState *nc) +{ + NetStreamState *s = DO_UPCAST(NetStreamState, nc, nc); + if (s->ioc) { + if (QIO_CHANNEL_SOCKET(s->ioc)->fd != -1) { + if (s->ioc_read_tag) { + g_source_remove(s->ioc_read_tag); + s->ioc_read_tag = 0; + } + if (s->ioc_write_tag) { + g_source_remove(s->ioc_write_tag); + s->ioc_write_tag = 0; + } + } + object_unref(OBJECT(s->ioc)); + s->ioc = NULL; + } + if (s->listen_ioc) { + if (s->listener) { + qio_net_listener_disconnect(s->listener); + object_unref(OBJECT(s->listener)); + s->listener = NULL; + } + object_unref(OBJECT(s->listen_ioc)); + s->listen_ioc = NULL; + } +} + +static NetClientInfo net_stream_info = { + .type = NET_CLIENT_DRIVER_STREAM, + .size = sizeof(NetStreamState), + .receive = net_stream_receive, + .cleanup = net_stream_cleanup, +}; + +static void net_stream_listen(QIONetListener *listener, + QIOChannelSocket *cioc, + void *opaque) +{ + NetStreamState *s = opaque; + SocketAddress *addr; + char *uri; + + object_ref(OBJECT(cioc)); + + qio_net_listener_set_client_func(s->listener, NULL, s, NULL); + + s->ioc = QIO_CHANNEL(cioc); + qio_channel_set_name(s->ioc, "stream-server"); + s->nc.link_down = false; + + s->ioc_read_tag = qio_channel_add_watch(s->ioc, G_IO_IN, net_stream_send, + s, NULL); + + if (cioc->localAddr.ss_family == AF_UNIX) { + addr = qio_channel_socket_get_local_address(cioc, NULL); + } else { + addr = qio_channel_socket_get_remote_address(cioc, NULL); + } + g_assert(addr != NULL); + uri = socket_uri(addr); + qemu_set_info_str(&s->nc, uri); + g_free(uri); + qapi_event_send_netdev_stream_connected(s->nc.name, addr); + qapi_free_SocketAddress(addr); +} + +static void net_stream_server_listening(QIOTask *task, gpointer opaque) +{ + NetStreamState *s = opaque; + QIOChannelSocket *listen_sioc = QIO_CHANNEL_SOCKET(s->listen_ioc); + SocketAddress *addr; + int ret; + + if (listen_sioc->fd < 0) { + qemu_set_info_str(&s->nc, "connection error"); + return; + } + + addr = qio_channel_socket_get_local_address(listen_sioc, NULL); + g_assert(addr != NULL); + ret = qemu_socket_try_set_nonblock(listen_sioc->fd); + if (addr->type == SOCKET_ADDRESS_TYPE_FD && ret < 0) { + qemu_set_info_str(&s->nc, "can't use file descriptor %s (errno %d)", + addr->u.fd.str, -ret); + return; + } + g_assert(ret == 0); + qapi_free_SocketAddress(addr); + + s->nc.link_down = true; + s->listener = qio_net_listener_new(); + + net_socket_rs_init(&s->rs, net_stream_rs_finalize, false); + qio_net_listener_set_client_func(s->listener, net_stream_listen, s, NULL); + qio_net_listener_add(s->listener, listen_sioc); +} + +static int net_stream_server_init(NetClientState *peer, + const char *model, + const char *name, + SocketAddress *addr, + Error **errp) +{ + NetClientState *nc; + NetStreamState *s; + QIOChannelSocket *listen_sioc = qio_channel_socket_new(); + + nc = qemu_new_net_client(&net_stream_info, peer, model, name); + s = DO_UPCAST(NetStreamState, nc, nc); + + s->listen_ioc = QIO_CHANNEL(listen_sioc); + qio_channel_socket_listen_async(listen_sioc, addr, 0, + net_stream_server_listening, s, + NULL, NULL); + + return 0; +} + +static void net_stream_client_connected(QIOTask *task, gpointer opaque) +{ + NetStreamState *s = opaque; + QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(s->ioc); + SocketAddress *addr; + gchar *uri; + int ret; + + if (sioc->fd < 0) { + qemu_set_info_str(&s->nc, "connection error"); + goto error; + } + + addr = qio_channel_socket_get_remote_address(sioc, NULL); + g_assert(addr != NULL); + uri = socket_uri(addr); + qemu_set_info_str(&s->nc, uri); + g_free(uri); + + ret = qemu_socket_try_set_nonblock(sioc->fd); + if (addr->type == SOCKET_ADDRESS_TYPE_FD && ret < 0) { + qemu_set_info_str(&s->nc, "can't use file descriptor %s (errno %d)", + addr->u.fd.str, -ret); + qapi_free_SocketAddress(addr); + goto error; + } + g_assert(ret == 0); + + net_socket_rs_init(&s->rs, net_stream_rs_finalize, false); + + /* Disable Nagle algorithm on TCP sockets to reduce latency */ + qio_channel_set_delay(s->ioc, false); + + s->ioc_read_tag = qio_channel_add_watch(s->ioc, G_IO_IN, net_stream_send, + s, NULL); + s->nc.link_down = false; + qapi_event_send_netdev_stream_connected(s->nc.name, addr); + qapi_free_SocketAddress(addr); + + return; +error: + object_unref(OBJECT(s->ioc)); + s->ioc = NULL; +} + +static int net_stream_client_init(NetClientState *peer, + const char *model, + const char *name, + SocketAddress *addr, + Error **errp) +{ + NetStreamState *s; + NetClientState *nc; + QIOChannelSocket *sioc = qio_channel_socket_new(); + + nc = qemu_new_net_client(&net_stream_info, peer, model, name); + s = DO_UPCAST(NetStreamState, nc, nc); + + s->ioc = QIO_CHANNEL(sioc); + s->nc.link_down = true; + + qio_channel_socket_connect_async(sioc, addr, + net_stream_client_connected, s, + NULL, NULL); + + return 0; +} + +int net_init_stream(const Netdev *netdev, const char *name, + NetClientState *peer, Error **errp) +{ + const NetdevStreamOptions *sock; + + assert(netdev->type == NET_CLIENT_DRIVER_STREAM); + sock = &netdev->u.stream; + + if (!sock->has_server || !sock->server) { + return net_stream_client_init(peer, "stream", name, sock->addr, errp); + } + return net_stream_server_init(peer, "stream", name, sock->addr, errp); +} diff --git a/net/tap-win32.c b/net/tap-win32.c index 7466f22e77..a49c28ba5d 100644 --- a/net/tap-win32.c +++ b/net/tap-win32.c @@ -789,8 +789,7 @@ static int tap_win32_init(NetClientState *peer, const char *model, s = DO_UPCAST(TAPState, nc, nc); - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "tap: ifname=%s", ifname); + qemu_set_info_str(&s->nc, "tap: ifname=%s", ifname); s->handle = handle; @@ -630,8 +630,7 @@ int net_init_bridge(const Netdev *netdev, const char *name, } s = net_tap_fd_init(peer, "bridge", name, fd, vnet_hdr); - snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s,br=%s", helper, - br); + qemu_set_info_str(&s->nc, "helper=%s,br=%s", helper, br); return 0; } @@ -690,14 +689,12 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, } if (tap->has_fd || tap->has_fds) { - snprintf(s->nc.info_str, sizeof(s->nc.info_str), "fd=%d", fd); + qemu_set_info_str(&s->nc, "fd=%d", fd); } else if (tap->has_helper) { - snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s", - tap->helper); + qemu_set_info_str(&s->nc, "helper=%s", tap->helper); } else { - snprintf(s->nc.info_str, sizeof(s->nc.info_str), - "ifname=%s,script=%s,downscript=%s", ifname, script, - downscript); + qemu_set_info_str(&s->nc, "ifname=%s,script=%s,downscript=%s", ifname, + script, downscript); if (strcmp(downscript, "no") != 0) { snprintf(s->down_script, sizeof(s->down_script), "%s", downscript); @@ -98,8 +98,7 @@ static int net_vde_init(NetClientState *peer, const char *model, nc = qemu_new_net_client(&net_vde_info, peer, model, name); - snprintf(nc->info_str, sizeof(nc->info_str), "sock=%s,fd=%d", - sock, vde_datafd(vde)); + qemu_set_info_str(nc, "sock=%s,fd=%d", sock, vde_datafd(vde)); s = DO_UPCAST(VDEState, nc, nc); diff --git a/net/vhost-user.c b/net/vhost-user.c index b1a0247b59..3a6b90da86 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -341,8 +341,7 @@ static int net_vhost_user_init(NetClientState *peer, const char *device, user = g_new0(struct VhostUserState, 1); for (i = 0; i < queues; i++) { nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name); - snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s", - i, chr->label); + qemu_set_info_str(nc, "vhost-user%d to %s", i, chr->label); nc->queue_index = i; if (!nc0) { nc0 = nc; diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c index 4bc3fd01a8..854ebd61ae 100644 --- a/net/vhost-vdpa.c +++ b/net/vhost-vdpa.c @@ -63,7 +63,6 @@ const int vdpa_feature_bits[] = { VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_RX_EXTRA, VIRTIO_NET_F_CTRL_VLAN, - VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_CTRL_MAC_ADDR, VIRTIO_NET_F_RSS, VIRTIO_NET_F_MQ, @@ -463,48 +462,6 @@ static NetClientInfo net_vhost_vdpa_cvq_info = { }; /** - * Do not forward commands not supported by SVQ. Otherwise, the device could - * accept it and qemu would not know how to update the device model. - */ -static bool vhost_vdpa_net_cvq_validate_cmd(const void *out_buf, size_t len) -{ - struct virtio_net_ctrl_hdr ctrl; - - if (unlikely(len < sizeof(ctrl))) { - qemu_log_mask(LOG_GUEST_ERROR, - "%s: invalid legnth of out buffer %zu\n", __func__, len); - return false; - } - - memcpy(&ctrl, out_buf, sizeof(ctrl)); - switch (ctrl.class) { - case VIRTIO_NET_CTRL_MAC: - switch (ctrl.cmd) { - case VIRTIO_NET_CTRL_MAC_ADDR_SET: - return true; - default: - qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid mac cmd %u\n", - __func__, ctrl.cmd); - }; - break; - case VIRTIO_NET_CTRL_MQ: - switch (ctrl.cmd) { - case VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET: - return true; - default: - qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid mq cmd %u\n", - __func__, ctrl.cmd); - }; - break; - default: - qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid control class %u\n", - __func__, ctrl.class); - }; - - return false; -} - -/** * Validate and copy control virtqueue commands. * * Following QEMU guidelines, we offer a copy of the buffers to the device to @@ -527,16 +484,10 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, .iov_len = sizeof(status), }; ssize_t dev_written = -EINVAL; - bool ok; out.iov_len = iov_to_buf(elem->out_sg, elem->out_num, 0, s->cvq_cmd_out_buffer, vhost_vdpa_net_cvq_cmd_len()); - ok = vhost_vdpa_net_cvq_validate_cmd(s->cvq_cmd_out_buffer, out.iov_len); - if (unlikely(!ok)) { - goto out; - } - dev_written = vhost_vdpa_net_cvq_add(s, out.iov_len, sizeof(status)); if (unlikely(dev_written < 0)) { goto out; @@ -593,7 +544,7 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, nc = qemu_new_net_control_client(&net_vhost_vdpa_cvq_info, peer, device, name); } - snprintf(nc->info_str, sizeof(nc->info_str), TYPE_VHOST_VDPA); + qemu_set_info_str(nc, TYPE_VHOST_VDPA); s = DO_UPCAST(VhostVDPAState, nc, nc); s->vhost_vdpa.device_fd = vdpa_device_fd; @@ -683,14 +634,29 @@ int net_init_vhost_vdpa(const Netdev *netdev, const char *name, assert(netdev->type == NET_CLIENT_DRIVER_VHOST_VDPA); opts = &netdev->u.vhost_vdpa; - if (!opts->vhostdev) { - error_setg(errp, "vdpa character device not specified with vhostdev"); + if (!opts->has_vhostdev && !opts->has_vhostfd) { + error_setg(errp, + "vhost-vdpa: neither vhostdev= nor vhostfd= was specified"); return -1; } - vdpa_device_fd = qemu_open(opts->vhostdev, O_RDWR, errp); - if (vdpa_device_fd == -1) { - return -errno; + if (opts->has_vhostdev && opts->has_vhostfd) { + error_setg(errp, + "vhost-vdpa: vhostdev= and vhostfd= are mutually exclusive"); + return -1; + } + + if (opts->has_vhostdev) { + vdpa_device_fd = qemu_open(opts->vhostdev, O_RDWR, errp); + if (vdpa_device_fd == -1) { + return -errno; + } + } else if (opts->has_vhostfd) { + vdpa_device_fd = monitor_fd_param(monitor_cur(), opts->vhostfd, errp); + if (vdpa_device_fd == -1) { + error_prepend(errp, "vhost-vdpa: unable to parse vhostfd: "); + return -1; + } } r = vhost_vdpa_get_features(vdpa_device_fd, &features, errp); diff --git a/qapi/net.json b/qapi/net.json index dd088c09c5..522ac582ed 100644 --- a/qapi/net.json +++ b/qapi/net.json @@ -7,6 +7,7 @@ ## { 'include': 'common.json' } +{ 'include': 'sockets.json' } ## # @set_link: @@ -442,6 +443,8 @@ # @vhostdev: path of vhost-vdpa device # (default:'/dev/vhost-vdpa-0') # +# @vhostfd: file descriptor of an already opened vhost vdpa device +# # @queues: number of queues to be created for multiqueue vhost-vdpa # (default: 1) # @@ -456,6 +459,7 @@ { 'struct': 'NetdevVhostVDPAOptions', 'data': { '*vhostdev': 'str', + '*vhostfd': 'str', '*queues': 'int', '*x-svq': {'type': 'bool', 'features' : [ 'unstable'] } } } @@ -574,6 +578,60 @@ 'if': 'CONFIG_VMNET' } ## +# @NetdevStreamOptions: +# +# Configuration info for stream socket netdev +# +# @addr: socket address to listen on (server=true) +# or connect to (server=false) +# @server: create server socket (default: false) +# +# Only SocketAddress types 'unix', 'inet' and 'fd' are supported. +# +# Since: 7.2 +## +{ 'struct': 'NetdevStreamOptions', + 'data': { + 'addr': 'SocketAddress', + '*server': 'bool' } } + +## +# @NetdevDgramOptions: +# +# Configuration info for datagram socket netdev. +# +# @remote: remote address +# @local: local address +# +# Only SocketAddress types 'unix', 'inet' and 'fd' are supported. +# +# If remote address is present and it's a multicast address, local address +# is optional. Otherwise local address is required and remote address is +# optional. +# +# .. table:: Valid parameters combination table +# :widths: auto +# +# ============= ======== ===== +# remote local okay? +# ============= ======== ===== +# absent absent no +# absent not fd no +# absent fd yes +# multicast absent yes +# multicast present yes +# not multicast absent no +# not multicast present yes +# ============= ======== ===== +# +# Since: 7.2 +## +{ 'struct': 'NetdevDgramOptions', + 'data': { + '*local': 'SocketAddress', + '*remote': 'SocketAddress' } } + +## # @NetClientDriver: # # Available netdev drivers. @@ -584,10 +642,13 @@ # @vmnet-host since 7.1 # @vmnet-shared since 7.1 # @vmnet-bridged since 7.1 +# @stream since 7.2 +# @dgram since 7.2 ## { 'enum': 'NetClientDriver', - 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'vde', - 'bridge', 'hubport', 'netmap', 'vhost-user', 'vhost-vdpa', + 'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'stream', + 'dgram', 'vde', 'bridge', 'hubport', 'netmap', 'vhost-user', + 'vhost-vdpa', { 'name': 'vmnet-host', 'if': 'CONFIG_VMNET' }, { 'name': 'vmnet-shared', 'if': 'CONFIG_VMNET' }, { 'name': 'vmnet-bridged', 'if': 'CONFIG_VMNET' }] } @@ -607,6 +668,8 @@ # 'vmnet-host' - since 7.1 # 'vmnet-shared' - since 7.1 # 'vmnet-bridged' - since 7.1 +# 'stream' since 7.2 +# 'dgram' since 7.2 ## { 'union': 'Netdev', 'base': { 'id': 'str', 'type': 'NetClientDriver' }, @@ -617,6 +680,8 @@ 'tap': 'NetdevTapOptions', 'l2tpv3': 'NetdevL2TPv3Options', 'socket': 'NetdevSocketOptions', + 'stream': 'NetdevStreamOptions', + 'dgram': 'NetdevDgramOptions', 'vde': 'NetdevVdeOptions', 'bridge': 'NetdevBridgeOptions', 'hubport': 'NetdevHubPortOptions', @@ -833,3 +898,52 @@ ## { 'event': 'FAILOVER_NEGOTIATED', 'data': {'device-id': 'str'} } + +## +# @NETDEV_STREAM_CONNECTED: +# +# Emitted when the netdev stream backend is connected +# +# @netdev-id: QEMU netdev id that is connected +# @addr: The destination address +# +# Since: 7.2 +# +# Example: +# +# <- { "event": "NETDEV_STREAM_CONNECTED", +# "data": { "netdev-id": "netdev0", +# "addr": { "port": "47666", "ipv6": true, +# "host": "::1", "type": "inet" } }, +# "timestamp": { "seconds": 1666269863, "microseconds": 311222 } } +# +# or +# +# <- { "event": "NETDEV_STREAM_CONNECTED", +# "data": { "netdev-id": "netdev0", +# "addr": { "path": "/tmp/qemu0", "type": "unix" } }, +# "timestamp": { "seconds": 1666269706, "microseconds": 413651 } } +# +## +{ 'event': 'NETDEV_STREAM_CONNECTED', + 'data': { 'netdev-id': 'str', + 'addr': 'SocketAddress' } } + +## +# @NETDEV_STREAM_DISCONNECTED: +# +# Emitted when the netdev stream backend is disconnected +# +# @netdev-id: QEMU netdev id that is disconnected +# +# Since: 7.2 +# +# Example: +# +# <- { 'event': 'NETDEV_STREAM_DISCONNECTED', +# 'data': {'netdev-id': 'netdev0'}, +# 'timestamp': {'seconds': 1663330937, 'microseconds': 526695} } +# +## +{ 'event': 'NETDEV_STREAM_DISCONNECTED', + 'data': { 'netdev-id': 'str' } } diff --git a/qapi/qom.json b/qapi/qom.json index 80dd419b39..87fcad2423 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -578,6 +578,9 @@ # # @prealloc-threads: number of CPU threads to use for prealloc (default: 1) # +# @prealloc-context: thread context to use for creation of preallocation threads +# (default: none) (since 7.2) +# # @share: if false, the memory is private to QEMU; if true, it is shared # (default: false) # @@ -608,6 +611,7 @@ '*policy': 'HostMemPolicy', '*prealloc': 'bool', '*prealloc-threads': 'uint32', + '*prealloc-context': 'str', '*share': 'bool', '*reserve': 'bool', 'size': 'size', @@ -831,6 +835,28 @@ '*kernel-hashes': 'bool' } } ## +# @ThreadContextProperties: +# +# Properties for thread context objects. +# +# @cpu-affinity: the list of host CPU numbers used as CPU affinity for all +# threads created in the thread context (default: QEMU main +# thread CPU affinity) +# +# @node-affinity: the list of host node numbers that will be resolved to a +# list of host CPU numbers used as CPU affinity. This is a +# shortcut for specifying the list of host CPU numbers +# belonging to the host nodes manually by setting +# @cpu-affinity. (default: QEMU main thread affinity) +# +# Since: 7.2 +## +{ 'struct': 'ThreadContextProperties', + 'data': { '*cpu-affinity': ['uint16'], + '*node-affinity': ['uint16'] } } + + +## # @ObjectType: # # Features: @@ -882,6 +908,7 @@ { 'name': 'secret_keyring', 'if': 'CONFIG_SECRET_KEYRING' }, 'sev-guest', + 'thread-context', 's390-pv-guest', 'throttle-group', 'tls-creds-anon', @@ -948,6 +975,7 @@ 'secret_keyring': { 'type': 'SecretKeyringProperties', 'if': 'CONFIG_SECRET_KEYRING' }, 'sev-guest': 'SevGuestProperties', + 'thread-context': 'ThreadContextProperties', 'throttle-group': 'ThrottleGroupProperties', 'tls-creds-anon': 'TlsCredsAnonProperties', 'tls-creds-psk': 'TlsCredsPskProperties', diff --git a/qemu-options.hx b/qemu-options.hx index eb38e5dc40..ceee0ddc25 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2772,6 +2772,20 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, "-netdev socket,id=str[,fd=h][,udp=host:port][,localaddr=host:port]\n" " configure a network backend to connect to another network\n" " using an UDP tunnel\n" + "-netdev stream,id=str[,server=on|off],addr.type=inet,addr.host=host,addr.port=port[,to=maxport][,numeric=on|off][,keep-alive=on|off][,mptcp=on|off][,addr.ipv4=on|off][,addr.ipv6=on|off]\n" + "-netdev stream,id=str[,server=on|off],addr.type=unix,addr.path=path[,abstract=on|off][,tight=on|off]\n" + "-netdev stream,id=str[,server=on|off],addr.type=fd,addr.str=file-descriptor\n" + " configure a network backend to connect to another network\n" + " using a socket connection in stream mode.\n" + "-netdev dgram,id=str,remote.type=inet,remote.host=maddr,remote.port=port[,local.type=inet,local.host=addr]\n" + "-netdev dgram,id=str,remote.type=inet,remote.host=maddr,remote.port=port[,local.type=fd,local.str=file-descriptor]\n" + " configure a network backend to connect to a multicast maddr and port\n" + " use ``local.host=addr`` to specify the host address to send packets from\n" + "-netdev dgram,id=str,local.type=inet,local.host=addr,local.port=port[,remote.type=inet,remote.host=addr,remote.port=port]\n" + "-netdev dgram,id=str,local.type=unix,local.path=path[,remote.type=unix,remote.path=path]\n" + "-netdev dgram,id=str,local.type=fd,local.str=file-descriptor\n" + " configure a network backend to connect to another network\n" + " using an UDP tunnel\n" #ifdef CONFIG_VDE "-netdev vde,id=str[,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n" " configure a network backend to connect to port 'n' of a vde switch\n" @@ -2790,8 +2804,10 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, " configure a vhost-user network, backed by a chardev 'dev'\n" #endif #ifdef __linux__ - "-netdev vhost-vdpa,id=str,vhostdev=/path/to/dev\n" + "-netdev vhost-vdpa,id=str[,vhostdev=/path/to/dev][,vhostfd=h]\n" " configure a vhost-vdpa network,Establish a vhost-vdpa netdev\n" + " use 'vhostdev=/path/to/dev' to open a vhost vdpa device\n" + " use 'vhostfd=h' to connect to an already opened vhost vdpa device\n" #endif #ifdef CONFIG_VMNET "-netdev vmnet-host,id=str[,isolated=on|off][,net-uuid=uuid]\n" @@ -3296,7 +3312,7 @@ SRST -netdev type=vhost-user,id=net0,chardev=chr0 \ -device virtio-net-pci,netdev=net0 -``-netdev vhost-vdpa,vhostdev=/path/to/dev`` +``-netdev vhost-vdpa[,vhostdev=/path/to/dev][,vhostfd=h]`` Establish a vhost-vdpa netdev. vDPA device is a device that uses a datapath which complies with diff --git a/qom/object.c b/qom/object.c index d34608558e..e5cef30f6d 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1383,7 +1383,8 @@ bool object_property_get(Object *obj, const char *name, Visitor *v, } if (!prop->get) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property '%s.%s' is not readable", + object_get_typename(obj), name); return false; } prop->get(obj, v, name, prop->opaque, &err); @@ -1402,7 +1403,8 @@ bool object_property_set(Object *obj, const char *name, Visitor *v, } if (!prop->set) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property '%s.%s' is not writable", + object_get_typename(obj), name); return false; } prop->set(obj, v, name, prop->opaque, errp); diff --git a/scripts/git-submodule.sh b/scripts/git-submodule.sh index e225d3a963..7be41f5948 100755 --- a/scripts/git-submodule.sh +++ b/scripts/git-submodule.sh @@ -51,6 +51,12 @@ validate_error() { exit 1 } +if test -n "$maybe_modules" && ! test -e ".git" +then + echo "$0: unexpectedly called with submodules but no git checkout exists" + exit 1 +fi + modules="" for m in $maybe_modules do @@ -63,12 +69,6 @@ do fi done -if test -n "$maybe_modules" && ! test -e ".git" -then - echo "$0: unexpectedly called with submodules but no git checkout exists" - exit 1 -fi - case "$command" in status|validate) if test -z "$maybe_modules" diff --git a/softmmu/cpus.c b/softmmu/cpus.c index 61b27ff59d..5a584a8d57 100644 --- a/softmmu/cpus.c +++ b/softmmu/cpus.c @@ -354,7 +354,7 @@ static void qemu_init_sigbus(void) /* * ALERT: when modifying this, take care that SIGBUS forwarding in - * os_mem_prealloc() will continue working as expected. + * qemu_prealloc_mem() will continue working as expected. */ memset(&action, 0, sizeof(action)); action.sa_flags = SA_SIGINFO; @@ -437,18 +437,19 @@ void qemu_wait_io_event(CPUState *cpu) void cpus_kick_thread(CPUState *cpu) { -#ifndef _WIN32 - int err; - if (cpu->thread_kicked) { return; } cpu->thread_kicked = true; - err = pthread_kill(cpu->thread->thread, SIG_IPI); + +#ifndef _WIN32 + int err = pthread_kill(cpu->thread->thread, SIG_IPI); if (err && err != ESRCH) { fprintf(stderr, "qemu:%s: %s", __func__, strerror(err)); exit(1); } +#else + qemu_sem_post(&cpu->sem); #endif } diff --git a/softmmu/qemu-seccomp.c b/softmmu/qemu-seccomp.c index deaf8a4ef5..d66a2a1226 100644 --- a/softmmu/qemu-seccomp.c +++ b/softmmu/qemu-seccomp.c @@ -312,6 +312,19 @@ static int seccomp_start(uint32_t seccomp_opts, Error **errp) goto seccomp_return; } +#if defined(CONFIG_SECCOMP_SYSRAWRC) + /* + * This must be the first seccomp_attr_set() call to have full + * error propagation from subsequent seccomp APIs. + */ + rc = seccomp_attr_set(ctx, SCMP_FLTATR_API_SYSRAWRC, 1); + if (rc != 0) { + error_setg_errno(errp, -rc, + "failed to set seccomp rawrc attribute"); + goto seccomp_return; + } +#endif + rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_TSYNC, 1); if (rc != 0) { error_setg_errno(errp, -rc, diff --git a/softmmu/qtest.c b/softmmu/qtest.c index f8acef2628..afea7693d0 100644 --- a/softmmu/qtest.c +++ b/softmmu/qtest.c @@ -977,7 +977,7 @@ static void qtest_set_log(Object *obj, const char *value, Error **errp) QTest *q = QTEST(obj); if (qtest == q) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property 'log' can not be set now"); } else { g_free(q->log); q->log = g_strdup(value); @@ -997,7 +997,7 @@ static void qtest_set_chardev(Object *obj, const char *value, Error **errp) Chardev *chr; if (qtest == q) { - error_setg(errp, QERR_PERMISSION_DENIED); + error_setg(errp, "Property 'chardev' can not be set now"); return; } diff --git a/softmmu/vl.c b/softmmu/vl.c index b464da25bc..5115221efe 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -1760,6 +1760,27 @@ static void object_option_parse(const char *optarg) } /* + * Very early object creation, before the sandbox options have been activated. + */ +static bool object_create_pre_sandbox(const char *type) +{ + /* + * Objects should in general not get initialized "too early" without + * a reason. If you add one, state the reason in a comment! + */ + + /* + * Reason: -sandbox on,resourcecontrol=deny disallows setting CPU + * affinity of threads. + */ + if (g_str_equal(type, "thread-context")) { + return true; + } + + return false; +} + +/* * Initial object creation happens before all other * QEMU data types are created. The majority of objects * can be created at this point. The rng-egd object @@ -1773,6 +1794,11 @@ static bool object_create_early(const char *type) * add one, state the reason in a comment! */ + /* Reason: already created. */ + if (object_create_pre_sandbox(type)) { + return false; + } + /* Reason: property "chardev" */ if (g_str_equal(type, "rng-egd") || g_str_equal(type, "qtest")) { @@ -1895,7 +1921,7 @@ static void qemu_create_early_backends(void) */ static bool object_create_late(const char *type) { - return !object_create_early(type); + return !object_create_early(type) && !object_create_pre_sandbox(type); } static void qemu_create_late_backends(void) @@ -1904,7 +1930,7 @@ static void qemu_create_late_backends(void) qtest_server_init(qtest_chrdev, qtest_log, &error_fatal); } - net_init_clients(&error_fatal); + net_init_clients(); object_option_foreach_add(object_create_late); @@ -2351,6 +2377,11 @@ static int process_runstate_actions(void *opaque, QemuOpts *opts, Error **errp) static void qemu_process_early_options(void) { + qemu_opts_foreach(qemu_find_opts("name"), + parse_name, NULL, &error_fatal); + + object_option_foreach_add(object_create_pre_sandbox); + #ifdef CONFIG_SECCOMP QemuOptsList *olist = qemu_find_opts_err("sandbox", NULL); if (olist) { @@ -2358,9 +2389,6 @@ static void qemu_process_early_options(void) } #endif - qemu_opts_foreach(qemu_find_opts("name"), - parse_name, NULL, &error_fatal); - if (qemu_opts_foreach(qemu_find_opts("action"), process_runstate_actions, NULL, &error_fatal)) { exit(1); @@ -2801,21 +2829,19 @@ void qemu_init(int argc, char **argv) break; case QEMU_OPTION_netdev: default_net = 0; - if (net_client_parse(qemu_find_opts("netdev"), optarg) == -1) { - exit(1); + if (netdev_is_modern(optarg)) { + netdev_parse_modern(optarg); + } else { + net_client_parse(qemu_find_opts("netdev"), optarg); } break; case QEMU_OPTION_nic: default_net = 0; - if (net_client_parse(qemu_find_opts("nic"), optarg) == -1) { - exit(1); - } + net_client_parse(qemu_find_opts("nic"), optarg); break; case QEMU_OPTION_net: default_net = 0; - if (net_client_parse(qemu_find_opts("net"), optarg) == -1) { - exit(1); - } + net_client_parse(qemu_find_opts("net"), optarg); break; #ifdef CONFIG_LIBISCSI case QEMU_OPTION_iscsi: diff --git a/target/ppc/cpu.c b/target/ppc/cpu.c index 0ebac04bc4..1a97b41c6b 100644 --- a/target/ppc/cpu.c +++ b/target/ppc/cpu.c @@ -73,6 +73,7 @@ void ppc_store_msr(CPUPPCState *env, target_ulong value) hreg_store_msr(env, value, 0); } +#if !defined(CONFIG_USER_ONLY) void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val) { PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); @@ -81,7 +82,10 @@ void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val) env->spr[SPR_LPCR] = val & pcc->lpcr_mask; /* The gtse bit affects hflags */ hreg_compute_hflags(env); + + ppc_maybe_interrupt(env); } +#endif static inline void fpscr_set_rounding_mode(CPUPPCState *env) { diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index cca6c4e51c..81d4263a07 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -696,7 +696,9 @@ enum { HFLAGS_PR = 14, /* MSR_PR */ HFLAGS_PMCC0 = 15, /* MMCR0 PMCC bit 0 */ HFLAGS_PMCC1 = 16, /* MMCR0 PMCC bit 1 */ - HFLAGS_INSN_CNT = 17, /* PMU instruction count enabled */ + HFLAGS_PMCJCE = 17, /* MMCR0 PMCjCE bit */ + HFLAGS_PMC_OTHER = 18, /* PMC other than PMC5-6 is enabled */ + HFLAGS_INSN_CNT = 19, /* PMU instruction count enabled */ HFLAGS_VSX = 23, /* MSR_VSX if cpu has VSX */ HFLAGS_VR = 25, /* MSR_VR if cpu has VRE */ @@ -1358,6 +1360,7 @@ int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs, int cpuid, DumpState *s); #ifndef CONFIG_USER_ONLY +void ppc_maybe_interrupt(CPUPPCState *env); void ppc_cpu_do_interrupt(CPUState *cpu); bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req); void ppc_cpu_do_system_reset(CPUState *cs); @@ -1370,9 +1373,9 @@ void ppc_translate_init(void); #if !defined(CONFIG_USER_ONLY) void ppc_store_sdr1(CPUPPCState *env, target_ulong value); +void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val); #endif /* !defined(CONFIG_USER_ONLY) */ void ppc_store_msr(CPUPPCState *env, target_ulong value); -void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val); void ppc_cpu_list(void); @@ -2416,27 +2419,27 @@ enum { /* Hardware exceptions definitions */ enum { /* External hardware exception sources */ - PPC_INTERRUPT_RESET = 0, /* Reset exception */ - PPC_INTERRUPT_WAKEUP, /* Wakeup exception */ - PPC_INTERRUPT_MCK, /* Machine check exception */ - PPC_INTERRUPT_EXT, /* External interrupt */ - PPC_INTERRUPT_SMI, /* System management interrupt */ - PPC_INTERRUPT_CEXT, /* Critical external interrupt */ - PPC_INTERRUPT_DEBUG, /* External debug exception */ - PPC_INTERRUPT_THERM, /* Thermal exception */ + PPC_INTERRUPT_RESET = 0x00001, /* Reset exception */ + PPC_INTERRUPT_WAKEUP = 0x00002, /* Wakeup exception */ + PPC_INTERRUPT_MCK = 0x00004, /* Machine check exception */ + PPC_INTERRUPT_EXT = 0x00008, /* External interrupt */ + PPC_INTERRUPT_SMI = 0x00010, /* System management interrupt */ + PPC_INTERRUPT_CEXT = 0x00020, /* Critical external interrupt */ + PPC_INTERRUPT_DEBUG = 0x00040, /* External debug exception */ + PPC_INTERRUPT_THERM = 0x00080, /* Thermal exception */ /* Internal hardware exception sources */ - PPC_INTERRUPT_DECR, /* Decrementer exception */ - PPC_INTERRUPT_HDECR, /* Hypervisor decrementer exception */ - PPC_INTERRUPT_PIT, /* Programmable interval timer interrupt */ - PPC_INTERRUPT_FIT, /* Fixed interval timer interrupt */ - PPC_INTERRUPT_WDT, /* Watchdog timer interrupt */ - PPC_INTERRUPT_CDOORBELL, /* Critical doorbell interrupt */ - PPC_INTERRUPT_DOORBELL, /* Doorbell interrupt */ - PPC_INTERRUPT_PERFM, /* Performance monitor interrupt */ - PPC_INTERRUPT_HMI, /* Hypervisor Maintenance interrupt */ - PPC_INTERRUPT_HDOORBELL, /* Hypervisor Doorbell interrupt */ - PPC_INTERRUPT_HVIRT, /* Hypervisor virtualization interrupt */ - PPC_INTERRUPT_EBB, /* Event-based Branch exception */ + PPC_INTERRUPT_DECR = 0x00100, /* Decrementer exception */ + PPC_INTERRUPT_HDECR = 0x00200, /* Hypervisor decrementer exception */ + PPC_INTERRUPT_PIT = 0x00400, /* Programmable interval timer int. */ + PPC_INTERRUPT_FIT = 0x00800, /* Fixed interval timer interrupt */ + PPC_INTERRUPT_WDT = 0x01000, /* Watchdog timer interrupt */ + PPC_INTERRUPT_CDOORBELL = 0x02000, /* Critical doorbell interrupt */ + PPC_INTERRUPT_DOORBELL = 0x04000, /* Doorbell interrupt */ + PPC_INTERRUPT_PERFM = 0x08000, /* Performance monitor interrupt */ + PPC_INTERRUPT_HMI = 0x10000, /* Hypervisor Maintenance interrupt */ + PPC_INTERRUPT_HDOORBELL = 0x20000, /* Hypervisor Doorbell interrupt */ + PPC_INTERRUPT_HVIRT = 0x40000, /* Hypervisor virtualization interrupt */ + PPC_INTERRUPT_EBB = 0x80000, /* Event-based Branch exception */ }; /* Processor Compatibility mask (PCR) */ diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 335351c226..32e94153d1 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -5960,46 +5960,10 @@ static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return true; } -static bool cpu_has_work_POWER7(CPUState *cs) -{ - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - if (cs->halted) { - if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { - return false; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { - return true; - } - if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { - return true; - } - return false; - } else { - return FIELD_EX64(env->msr, MSR, EE) && - (cs->interrupt_request & CPU_INTERRUPT_HARD); - } -} - POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - CPUClass *cc = CPU_CLASS(oc); dc->fw_name = "PowerPC,POWER7"; dc->desc = "POWER7"; @@ -6008,7 +5972,6 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER7; pcc->check_pow = check_pow_nocheck; - cc->has_work = cpu_has_work_POWER7; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -6133,54 +6096,10 @@ static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return true; } -static bool cpu_has_work_POWER8(CPUState *cs) -{ - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - if (cs->halted) { - if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { - return false; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) { - return true; - } - if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { - return true; - } - return false; - } else { - return FIELD_EX64(env->msr, MSR, EE) && - (cs->interrupt_request & CPU_INTERRUPT_HARD); - } -} - POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - CPUClass *cc = CPU_CLASS(oc); dc->fw_name = "PowerPC,POWER8"; dc->desc = "POWER8"; @@ -6189,7 +6108,6 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER8; pcc->check_pow = check_pow_nocheck; - cc->has_work = cpu_has_work_POWER8; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -6351,71 +6269,10 @@ static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return false; } -static bool cpu_has_work_POWER9(CPUState *cs) -{ - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - if (cs->halted) { - uint64_t psscr = env->spr[SPR_PSSCR]; - - if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { - return false; - } - - /* If EC is clear, just return true on any pending interrupt */ - if (!(psscr & PSSCR_EC)) { - return true; - } - /* External Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && - (env->spr[SPR_LPCR] & LPCR_EEE)) { - bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); - if (!heic || !FIELD_EX64_HV(env->msr) || - FIELD_EX64(env->msr, MSR, PR)) { - return true; - } - } - /* Decrementer Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && - (env->spr[SPR_LPCR] & LPCR_DEE)) { - return true; - } - /* Machine Check or Hypervisor Maintenance Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK | - 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) { - return true; - } - /* Privileged Doorbell Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) && - (env->spr[SPR_LPCR] & LPCR_PDEE)) { - return true; - } - /* Hypervisor Doorbell Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) && - (env->spr[SPR_LPCR] & LPCR_HDEE)) { - return true; - } - /* Hypervisor virtualization exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) && - (env->spr[SPR_LPCR] & LPCR_HVEE)) { - return true; - } - if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { - return true; - } - return false; - } else { - return FIELD_EX64(env->msr, MSR, EE) && - (cs->interrupt_request & CPU_INTERRUPT_HARD); - } -} - POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - CPUClass *cc = CPU_CLASS(oc); dc->fw_name = "PowerPC,POWER9"; dc->desc = "POWER9"; @@ -6425,7 +6282,6 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER9; pcc->check_pow = check_pow_nocheck; - cc->has_work = cpu_has_work_POWER9; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -6584,71 +6440,10 @@ static bool ppc_pvr_match_power10(PowerPCCPUClass *pcc, uint32_t pvr, bool best) return false; } -static bool cpu_has_work_POWER10(CPUState *cs) -{ - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - if (cs->halted) { - uint64_t psscr = env->spr[SPR_PSSCR]; - - if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { - return false; - } - - /* If EC is clear, just return true on any pending interrupt */ - if (!(psscr & PSSCR_EC)) { - return true; - } - /* External Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && - (env->spr[SPR_LPCR] & LPCR_EEE)) { - bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); - if (!heic || !FIELD_EX64_HV(env->msr) || - FIELD_EX64(env->msr, MSR, PR)) { - return true; - } - } - /* Decrementer Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && - (env->spr[SPR_LPCR] & LPCR_DEE)) { - return true; - } - /* Machine Check or Hypervisor Maintenance Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK | - 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) { - return true; - } - /* Privileged Doorbell Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) && - (env->spr[SPR_LPCR] & LPCR_PDEE)) { - return true; - } - /* Hypervisor Doorbell Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) && - (env->spr[SPR_LPCR] & LPCR_HDEE)) { - return true; - } - /* Hypervisor virtualization exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) && - (env->spr[SPR_LPCR] & LPCR_HVEE)) { - return true; - } - if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { - return true; - } - return false; - } else { - return FIELD_EX64(env->msr, MSR, EE) && - (cs->interrupt_request & CPU_INTERRUPT_HARD); - } -} - POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - CPUClass *cc = CPU_CLASS(oc); dc->fw_name = "PowerPC,POWER10"; dc->desc = "POWER10"; @@ -6659,7 +6454,6 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data) PCR_COMPAT_2_06 | PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER10; pcc->check_pow = check_pow_nocheck; - cc->has_work = cpu_has_work_POWER10; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -7232,11 +7026,7 @@ static void ppc_restore_state_to_opc(CPUState *cs, static bool ppc_cpu_has_work(CPUState *cs) { - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - return FIELD_EX64(env->msr, MSR, EE) && - (cs->interrupt_request & CPU_INTERRUPT_HARD); + return cs->interrupt_request & CPU_INTERRUPT_HARD; } static void ppc_cpu_reset(DeviceState *dev) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 43f2480e94..09a81561d4 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -23,6 +23,7 @@ #include "exec/exec-all.h" #include "internal.h" #include "helper_regs.h" +#include "hw/ppc/ppc.h" #include "trace.h" @@ -389,6 +390,7 @@ static void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector, env->nip = vector; env->msr = msr; hreg_compute_hflags(env); + ppc_maybe_interrupt(env); powerpc_reset_excp_state(cpu); @@ -1683,29 +1685,355 @@ void ppc_cpu_do_interrupt(CPUState *cs) powerpc_excp(cpu, cs->exception_index); } -static void ppc_hw_interrupt(CPUPPCState *env) +#if defined(TARGET_PPC64) +#define P7_UNUSED_INTERRUPTS \ + (PPC_INTERRUPT_RESET | PPC_INTERRUPT_HVIRT | PPC_INTERRUPT_CEXT | \ + PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | PPC_INTERRUPT_FIT | \ + PPC_INTERRUPT_PIT | PPC_INTERRUPT_DOORBELL | PPC_INTERRUPT_HDOORBELL | \ + PPC_INTERRUPT_THERM | PPC_INTERRUPT_EBB) + +static int p7_interrupt_powersave(CPUPPCState *env) +{ + if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) { + return PPC_INTERRUPT_EXT; + } + if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) { + return PPC_INTERRUPT_DECR; + } + if ((env->pending_interrupts & PPC_INTERRUPT_MCK) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { + return PPC_INTERRUPT_MCK; + } + if ((env->pending_interrupts & PPC_INTERRUPT_HMI) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { + return PPC_INTERRUPT_HMI; + } + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + return PPC_INTERRUPT_RESET; + } + return 0; +} + +static int p7_next_unmasked_interrupt(CPUPPCState *env) { PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = CPU(cpu); + /* Ignore MSR[EE] when coming out of some power management states */ + bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset; + + assert((env->pending_interrupts & P7_UNUSED_INTERRUPTS) == 0); + + if (cs->halted) { + /* LPCR[PECE] controls which interrupts can exit power-saving mode */ + return p7_interrupt_powersave(env); + } + + /* Machine check exception */ + if (env->pending_interrupts & PPC_INTERRUPT_MCK) { + return PPC_INTERRUPT_MCK; + } + + /* Hypervisor decrementer exception */ + if (env->pending_interrupts & PPC_INTERRUPT_HDECR) { + /* LPCR will be clear when not supported so this will work */ + bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); + if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) { + /* HDEC clears on delivery */ + return PPC_INTERRUPT_HDECR; + } + } + + /* External interrupt can ignore MSR:EE under some circumstances */ + if (env->pending_interrupts & PPC_INTERRUPT_EXT) { + bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); + bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + /* HEIC blocks delivery to the hypervisor */ + if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) && + !FIELD_EX64(env->msr, MSR, PR))) || + (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) { + return PPC_INTERRUPT_EXT; + } + } + if (msr_ee != 0) { + /* Decrementer exception */ + if (env->pending_interrupts & PPC_INTERRUPT_DECR) { + return PPC_INTERRUPT_DECR; + } + if (env->pending_interrupts & PPC_INTERRUPT_PERFM) { + return PPC_INTERRUPT_PERFM; + } + } + + return 0; +} + +#define P8_UNUSED_INTERRUPTS \ + (PPC_INTERRUPT_RESET | PPC_INTERRUPT_DEBUG | PPC_INTERRUPT_HVIRT | \ + PPC_INTERRUPT_CEXT | PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | \ + PPC_INTERRUPT_FIT | PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM) + +static int p8_interrupt_powersave(CPUPPCState *env) +{ + if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) { + return PPC_INTERRUPT_EXT; + } + if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) { + return PPC_INTERRUPT_DECR; + } + if ((env->pending_interrupts & PPC_INTERRUPT_MCK) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { + return PPC_INTERRUPT_MCK; + } + if ((env->pending_interrupts & PPC_INTERRUPT_HMI) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { + return PPC_INTERRUPT_HMI; + } + if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) { + return PPC_INTERRUPT_DOORBELL; + } + if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) { + return PPC_INTERRUPT_HDOORBELL; + } + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + return PPC_INTERRUPT_RESET; + } + return 0; +} + +static int p8_next_unmasked_interrupt(CPUPPCState *env) +{ + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = CPU(cpu); + /* Ignore MSR[EE] when coming out of some power management states */ + bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset; + + assert((env->pending_interrupts & P8_UNUSED_INTERRUPTS) == 0); + + if (cs->halted) { + /* LPCR[PECE] controls which interrupts can exit power-saving mode */ + return p8_interrupt_powersave(env); + } + + /* Machine check exception */ + if (env->pending_interrupts & PPC_INTERRUPT_MCK) { + return PPC_INTERRUPT_MCK; + } + + /* Hypervisor decrementer exception */ + if (env->pending_interrupts & PPC_INTERRUPT_HDECR) { + /* LPCR will be clear when not supported so this will work */ + bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); + if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) { + /* HDEC clears on delivery */ + return PPC_INTERRUPT_HDECR; + } + } + + /* External interrupt can ignore MSR:EE under some circumstances */ + if (env->pending_interrupts & PPC_INTERRUPT_EXT) { + bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); + bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + /* HEIC blocks delivery to the hypervisor */ + if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) && + !FIELD_EX64(env->msr, MSR, PR))) || + (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) { + return PPC_INTERRUPT_EXT; + } + } + if (msr_ee != 0) { + /* Decrementer exception */ + if (env->pending_interrupts & PPC_INTERRUPT_DECR) { + return PPC_INTERRUPT_DECR; + } + if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) { + return PPC_INTERRUPT_DOORBELL; + } + if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) { + return PPC_INTERRUPT_HDOORBELL; + } + if (env->pending_interrupts & PPC_INTERRUPT_PERFM) { + return PPC_INTERRUPT_PERFM; + } + /* EBB exception */ + if (env->pending_interrupts & PPC_INTERRUPT_EBB) { + /* + * EBB exception must be taken in problem state and + * with BESCR_GE set. + */ + if (FIELD_EX64(env->msr, MSR, PR) && + (env->spr[SPR_BESCR] & BESCR_GE)) { + return PPC_INTERRUPT_EBB; + } + } + } + + return 0; +} + +#define P9_UNUSED_INTERRUPTS \ + (PPC_INTERRUPT_RESET | PPC_INTERRUPT_DEBUG | PPC_INTERRUPT_CEXT | \ + PPC_INTERRUPT_WDT | PPC_INTERRUPT_CDOORBELL | PPC_INTERRUPT_FIT | \ + PPC_INTERRUPT_PIT | PPC_INTERRUPT_THERM) + +static int p9_interrupt_powersave(CPUPPCState *env) +{ + /* External Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_EXT) && + (env->spr[SPR_LPCR] & LPCR_EEE)) { + bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + if (!heic || !FIELD_EX64_HV(env->msr) || + FIELD_EX64(env->msr, MSR, PR)) { + return PPC_INTERRUPT_EXT; + } + } + /* Decrementer Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_DECR) && + (env->spr[SPR_LPCR] & LPCR_DEE)) { + return PPC_INTERRUPT_DECR; + } + /* Machine Check or Hypervisor Maintenance Exception */ + if (env->spr[SPR_LPCR] & LPCR_OEE) { + if (env->pending_interrupts & PPC_INTERRUPT_MCK) { + return PPC_INTERRUPT_MCK; + } + if (env->pending_interrupts & PPC_INTERRUPT_HMI) { + return PPC_INTERRUPT_HMI; + } + } + /* Privileged Doorbell Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_DOORBELL) && + (env->spr[SPR_LPCR] & LPCR_PDEE)) { + return PPC_INTERRUPT_DOORBELL; + } + /* Hypervisor Doorbell Exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) && + (env->spr[SPR_LPCR] & LPCR_HDEE)) { + return PPC_INTERRUPT_HDOORBELL; + } + /* Hypervisor virtualization exception */ + if ((env->pending_interrupts & PPC_INTERRUPT_HVIRT) && + (env->spr[SPR_LPCR] & LPCR_HVEE)) { + return PPC_INTERRUPT_HVIRT; + } + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + return PPC_INTERRUPT_RESET; + } + return 0; +} + +static int p9_next_unmasked_interrupt(CPUPPCState *env) +{ + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = CPU(cpu); + /* Ignore MSR[EE] when coming out of some power management states */ + bool msr_ee = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset; + + assert((env->pending_interrupts & P9_UNUSED_INTERRUPTS) == 0); + + if (cs->halted) { + if (env->spr[SPR_PSSCR] & PSSCR_EC) { + /* + * When PSSCR[EC] is set, LPCR[PECE] controls which interrupts can + * wakeup the processor + */ + return p9_interrupt_powersave(env); + } else { + /* + * When it's clear, any system-caused exception exits power-saving + * mode, even the ones that gate on MSR[EE]. + */ + msr_ee = true; + } + } + + /* Machine check exception */ + if (env->pending_interrupts & PPC_INTERRUPT_MCK) { + return PPC_INTERRUPT_MCK; + } + + /* Hypervisor decrementer exception */ + if (env->pending_interrupts & PPC_INTERRUPT_HDECR) { + /* LPCR will be clear when not supported so this will work */ + bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); + if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hdice) { + /* HDEC clears on delivery */ + return PPC_INTERRUPT_HDECR; + } + } + + /* Hypervisor virtualization interrupt */ + if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) { + /* LPCR will be clear when not supported so this will work */ + bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); + if ((msr_ee || !FIELD_EX64_HV(env->msr)) && hvice) { + return PPC_INTERRUPT_HVIRT; + } + } + + /* External interrupt can ignore MSR:EE under some circumstances */ + if (env->pending_interrupts & PPC_INTERRUPT_EXT) { + bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); + bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + /* HEIC blocks delivery to the hypervisor */ + if ((msr_ee && !(heic && FIELD_EX64_HV(env->msr) && + !FIELD_EX64(env->msr, MSR, PR))) || + (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) { + return PPC_INTERRUPT_EXT; + } + } + if (msr_ee != 0) { + /* Decrementer exception */ + if (env->pending_interrupts & PPC_INTERRUPT_DECR) { + return PPC_INTERRUPT_DECR; + } + if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) { + return PPC_INTERRUPT_DOORBELL; + } + if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) { + return PPC_INTERRUPT_HDOORBELL; + } + if (env->pending_interrupts & PPC_INTERRUPT_PERFM) { + return PPC_INTERRUPT_PERFM; + } + /* EBB exception */ + if (env->pending_interrupts & PPC_INTERRUPT_EBB) { + /* + * EBB exception must be taken in problem state and + * with BESCR_GE set. + */ + if (FIELD_EX64(env->msr, MSR, PR) && + (env->spr[SPR_BESCR] & BESCR_GE)) { + return PPC_INTERRUPT_EBB; + } + } + } + + return 0; +} +#endif + +static int ppc_next_unmasked_interrupt_generic(CPUPPCState *env) +{ bool async_deliver; /* External reset */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET); - powerpc_excp(cpu, POWERPC_EXCP_RESET); - return; + if (env->pending_interrupts & PPC_INTERRUPT_RESET) { + return PPC_INTERRUPT_RESET; } /* Machine check exception */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK); - powerpc_excp(cpu, POWERPC_EXCP_MCHECK); - return; + if (env->pending_interrupts & PPC_INTERRUPT_MCK) { + return PPC_INTERRUPT_MCK; } #if 0 /* TODO */ /* External debug exception */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG); - powerpc_excp(cpu, POWERPC_EXCP_DEBUG); - return; + if (env->pending_interrupts & PPC_INTERRUPT_DEBUG) { + return PPC_INTERRUPT_DEBUG; } #endif @@ -1718,129 +2046,246 @@ static void ppc_hw_interrupt(CPUPPCState *env) async_deliver = FIELD_EX64(env->msr, MSR, EE) || env->resume_as_sreset; /* Hypervisor decrementer exception */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) { + if (env->pending_interrupts & PPC_INTERRUPT_HDECR) { /* LPCR will be clear when not supported so this will work */ bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE); if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hdice) { /* HDEC clears on delivery */ - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR); - powerpc_excp(cpu, POWERPC_EXCP_HDECR); - return; + return PPC_INTERRUPT_HDECR; } } /* Hypervisor virtualization interrupt */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_HVIRT)) { + if (env->pending_interrupts & PPC_INTERRUPT_HVIRT) { /* LPCR will be clear when not supported so this will work */ bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); if ((async_deliver || !FIELD_EX64_HV(env->msr)) && hvice) { - powerpc_excp(cpu, POWERPC_EXCP_HVIRT); - return; + return PPC_INTERRUPT_HVIRT; } } /* External interrupt can ignore MSR:EE under some circumstances */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) { + if (env->pending_interrupts & PPC_INTERRUPT_EXT) { bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); /* HEIC blocks delivery to the hypervisor */ if ((async_deliver && !(heic && FIELD_EX64_HV(env->msr) && !FIELD_EX64(env->msr, MSR, PR))) || (env->has_hv_mode && !FIELD_EX64_HV(env->msr) && !lpes0)) { - if (books_vhyp_promotes_external_to_hvirt(cpu)) { - powerpc_excp(cpu, POWERPC_EXCP_HVIRT); - } else { - powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); - } - return; + return PPC_INTERRUPT_EXT; } } if (FIELD_EX64(env->msr, MSR, CE)) { /* External critical interrupt */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) { - powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); - return; + if (env->pending_interrupts & PPC_INTERRUPT_CEXT) { + return PPC_INTERRUPT_CEXT; } } if (async_deliver != 0) { /* Watchdog timer on embedded PowerPC */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT); - powerpc_excp(cpu, POWERPC_EXCP_WDT); - return; + if (env->pending_interrupts & PPC_INTERRUPT_WDT) { + return PPC_INTERRUPT_WDT; } - if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL); - powerpc_excp(cpu, POWERPC_EXCP_DOORCI); - return; + if (env->pending_interrupts & PPC_INTERRUPT_CDOORBELL) { + return PPC_INTERRUPT_CDOORBELL; } /* Fixed interval timer on embedded PowerPC */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT); - powerpc_excp(cpu, POWERPC_EXCP_FIT); - return; + if (env->pending_interrupts & PPC_INTERRUPT_FIT) { + return PPC_INTERRUPT_FIT; } /* Programmable interval timer on embedded PowerPC */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT); - powerpc_excp(cpu, POWERPC_EXCP_PIT); - return; + if (env->pending_interrupts & PPC_INTERRUPT_PIT) { + return PPC_INTERRUPT_PIT; } /* Decrementer exception */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) { - if (ppc_decr_clear_on_delivery(env)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR); - } - powerpc_excp(cpu, POWERPC_EXCP_DECR); - return; + if (env->pending_interrupts & PPC_INTERRUPT_DECR) { + return PPC_INTERRUPT_DECR; } - if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); - if (is_book3s_arch2x(env)) { - powerpc_excp(cpu, POWERPC_EXCP_SDOOR); - } else { - powerpc_excp(cpu, POWERPC_EXCP_DOORI); - } - return; + if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) { + return PPC_INTERRUPT_DOORBELL; } - if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); - powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); - return; + if (env->pending_interrupts & PPC_INTERRUPT_HDOORBELL) { + return PPC_INTERRUPT_HDOORBELL; } - if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM); - powerpc_excp(cpu, POWERPC_EXCP_PERFM); - return; + if (env->pending_interrupts & PPC_INTERRUPT_PERFM) { + return PPC_INTERRUPT_PERFM; } /* Thermal interrupt */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM); - powerpc_excp(cpu, POWERPC_EXCP_THERM); - return; + if (env->pending_interrupts & PPC_INTERRUPT_THERM) { + return PPC_INTERRUPT_THERM; } /* EBB exception */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_EBB)) { + if (env->pending_interrupts & PPC_INTERRUPT_EBB) { /* * EBB exception must be taken in problem state and * with BESCR_GE set. */ if (FIELD_EX64(env->msr, MSR, PR) && (env->spr[SPR_BESCR] & BESCR_GE)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EBB); + return PPC_INTERRUPT_EBB; + } + } + } - if (env->spr[SPR_BESCR] & BESCR_PMEO) { - powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB); - } else if (env->spr[SPR_BESCR] & BESCR_EEO) { - powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB); - } + return 0; +} - return; - } +static int ppc_next_unmasked_interrupt(CPUPPCState *env) +{ + switch (env->excp_model) { +#if defined(TARGET_PPC64) + case POWERPC_EXCP_POWER7: + return p7_next_unmasked_interrupt(env); + case POWERPC_EXCP_POWER8: + return p8_next_unmasked_interrupt(env); + case POWERPC_EXCP_POWER9: + case POWERPC_EXCP_POWER10: + return p9_next_unmasked_interrupt(env); +#endif + default: + return ppc_next_unmasked_interrupt_generic(env); + } +} + +/* + * Sets CPU_INTERRUPT_HARD if there is at least one unmasked interrupt to be + * delivered and clears CPU_INTERRUPT_HARD otherwise. + * + * This method is called by ppc_set_interrupt when an interrupt is raised or + * lowered, and should also be called whenever an interrupt masking condition + * is changed, e.g.: + * - When relevant bits of MSR are altered, like EE, HV, PR, etc.; + * - When relevant bits of LPCR are altered, like PECE, HDICE, HVICE, etc.; + * - When PSSCR[EC] or env->resume_as_sreset are changed; + * - When cs->halted is changed and the CPU has a different interrupt masking + * logic in power-saving mode (e.g., POWER7/8/9/10); + */ +void ppc_maybe_interrupt(CPUPPCState *env) +{ + CPUState *cs = env_cpu(env); + bool locked = false; + + if (!qemu_mutex_iothread_locked()) { + locked = true; + qemu_mutex_lock_iothread(); + } + + if (ppc_next_unmasked_interrupt(env)) { + cpu_interrupt(cs, CPU_INTERRUPT_HARD); + } else { + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); + } + + if (locked) { + qemu_mutex_unlock_iothread(); + } +} + +#if defined(TARGET_PPC64) +static void p7_deliver_interrupt(CPUPPCState *env, int interrupt) +{ + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = env_cpu(env); + + switch (interrupt) { + case PPC_INTERRUPT_MCK: /* Machine check exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_MCK; + powerpc_excp(cpu, POWERPC_EXCP_MCHECK); + break; + + case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */ + /* HDEC clears on delivery */ + env->pending_interrupts &= ~PPC_INTERRUPT_HDECR; + powerpc_excp(cpu, POWERPC_EXCP_HDECR); + break; + + case PPC_INTERRUPT_EXT: + if (books_vhyp_promotes_external_to_hvirt(cpu)) { + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); + } else { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); } + break; + + case PPC_INTERRUPT_DECR: /* Decrementer exception */ + powerpc_excp(cpu, POWERPC_EXCP_DECR); + break; + case PPC_INTERRUPT_PERFM: + env->pending_interrupts &= ~PPC_INTERRUPT_PERFM; + powerpc_excp(cpu, POWERPC_EXCP_PERFM); + break; + case 0: + /* + * This is a bug ! It means that has_work took us out of halt without + * anything to deliver while in a PM state that requires getting + * out via a 0x100 + * + * This means we will incorrectly execute past the power management + * instruction instead of triggering a reset. + * + * It generally means a discrepancy between the wakeup conditions in the + * processor has_work implementation and the logic in this function. + */ + assert(!env->resume_as_sreset); + break; + default: + cpu_abort(cs, "Invalid PowerPC interrupt %d. Aborting\n", interrupt); } +} - if (env->resume_as_sreset) { +static void p8_deliver_interrupt(CPUPPCState *env, int interrupt) +{ + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = env_cpu(env); + + switch (interrupt) { + case PPC_INTERRUPT_MCK: /* Machine check exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_MCK; + powerpc_excp(cpu, POWERPC_EXCP_MCHECK); + break; + + case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */ + /* HDEC clears on delivery */ + env->pending_interrupts &= ~PPC_INTERRUPT_HDECR; + powerpc_excp(cpu, POWERPC_EXCP_HDECR); + break; + + case PPC_INTERRUPT_EXT: + if (books_vhyp_promotes_external_to_hvirt(cpu)) { + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); + } else { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); + } + break; + + case PPC_INTERRUPT_DECR: /* Decrementer exception */ + powerpc_excp(cpu, POWERPC_EXCP_DECR); + break; + case PPC_INTERRUPT_DOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; + if (is_book3s_arch2x(env)) { + powerpc_excp(cpu, POWERPC_EXCP_SDOOR); + } else { + powerpc_excp(cpu, POWERPC_EXCP_DOORI); + } + break; + case PPC_INTERRUPT_HDOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL; + powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); + break; + case PPC_INTERRUPT_PERFM: + env->pending_interrupts &= ~PPC_INTERRUPT_PERFM; + powerpc_excp(cpu, POWERPC_EXCP_PERFM); + break; + case PPC_INTERRUPT_EBB: /* EBB exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_EBB; + if (env->spr[SPR_BESCR] & BESCR_PMEO) { + powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB); + } else if (env->spr[SPR_BESCR] & BESCR_EEO) { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB); + } + break; + case 0: /* * This is a bug ! It means that has_work took us out of halt without * anything to deliver while in a PM state that requires getting @@ -1852,8 +2297,214 @@ static void ppc_hw_interrupt(CPUPPCState *env) * It generally means a discrepancy between the wakeup conditions in the * processor has_work implementation and the logic in this function. */ - cpu_abort(env_cpu(env), - "Wakeup from PM state but interrupt Undelivered"); + assert(!env->resume_as_sreset); + break; + default: + cpu_abort(cs, "Invalid PowerPC interrupt %d. Aborting\n", interrupt); + } +} + +static void p9_deliver_interrupt(CPUPPCState *env, int interrupt) +{ + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = env_cpu(env); + + if (cs->halted && !(env->spr[SPR_PSSCR] & PSSCR_EC) && + !FIELD_EX64(env->msr, MSR, EE)) { + /* + * A pending interrupt took us out of power-saving, but MSR[EE] says + * that we should return to NIP+4 instead of delivering it. + */ + return; + } + + switch (interrupt) { + case PPC_INTERRUPT_MCK: /* Machine check exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_MCK; + powerpc_excp(cpu, POWERPC_EXCP_MCHECK); + break; + + case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */ + /* HDEC clears on delivery */ + env->pending_interrupts &= ~PPC_INTERRUPT_HDECR; + powerpc_excp(cpu, POWERPC_EXCP_HDECR); + break; + case PPC_INTERRUPT_HVIRT: /* Hypervisor virtualization interrupt */ + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); + break; + + case PPC_INTERRUPT_EXT: + if (books_vhyp_promotes_external_to_hvirt(cpu)) { + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); + } else { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); + } + break; + + case PPC_INTERRUPT_DECR: /* Decrementer exception */ + powerpc_excp(cpu, POWERPC_EXCP_DECR); + break; + case PPC_INTERRUPT_DOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; + powerpc_excp(cpu, POWERPC_EXCP_SDOOR); + break; + case PPC_INTERRUPT_HDOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL; + powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); + break; + case PPC_INTERRUPT_PERFM: + env->pending_interrupts &= ~PPC_INTERRUPT_PERFM; + powerpc_excp(cpu, POWERPC_EXCP_PERFM); + break; + case PPC_INTERRUPT_EBB: /* EBB exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_EBB; + if (env->spr[SPR_BESCR] & BESCR_PMEO) { + powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB); + } else if (env->spr[SPR_BESCR] & BESCR_EEO) { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB); + } + break; + case 0: + /* + * This is a bug ! It means that has_work took us out of halt without + * anything to deliver while in a PM state that requires getting + * out via a 0x100 + * + * This means we will incorrectly execute past the power management + * instruction instead of triggering a reset. + * + * It generally means a discrepancy between the wakeup conditions in the + * processor has_work implementation and the logic in this function. + */ + assert(!env->resume_as_sreset); + break; + default: + cpu_abort(cs, "Invalid PowerPC interrupt %d. Aborting\n", interrupt); + } +} +#endif + +static void ppc_deliver_interrupt_generic(CPUPPCState *env, int interrupt) +{ + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = env_cpu(env); + + switch (interrupt) { + case PPC_INTERRUPT_RESET: /* External reset */ + env->pending_interrupts &= ~PPC_INTERRUPT_RESET; + powerpc_excp(cpu, POWERPC_EXCP_RESET); + break; + case PPC_INTERRUPT_MCK: /* Machine check exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_MCK; + powerpc_excp(cpu, POWERPC_EXCP_MCHECK); + break; + + case PPC_INTERRUPT_HDECR: /* Hypervisor decrementer exception */ + /* HDEC clears on delivery */ + env->pending_interrupts &= ~PPC_INTERRUPT_HDECR; + powerpc_excp(cpu, POWERPC_EXCP_HDECR); + break; + case PPC_INTERRUPT_HVIRT: /* Hypervisor virtualization interrupt */ + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); + break; + + case PPC_INTERRUPT_EXT: + if (books_vhyp_promotes_external_to_hvirt(cpu)) { + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); + } else { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); + } + break; + case PPC_INTERRUPT_CEXT: /* External critical interrupt */ + powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); + break; + + case PPC_INTERRUPT_WDT: /* Watchdog timer on embedded PowerPC */ + env->pending_interrupts &= ~PPC_INTERRUPT_WDT; + powerpc_excp(cpu, POWERPC_EXCP_WDT); + break; + case PPC_INTERRUPT_CDOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_CDOORBELL; + powerpc_excp(cpu, POWERPC_EXCP_DOORCI); + break; + case PPC_INTERRUPT_FIT: /* Fixed interval timer on embedded PowerPC */ + env->pending_interrupts &= ~PPC_INTERRUPT_FIT; + powerpc_excp(cpu, POWERPC_EXCP_FIT); + break; + case PPC_INTERRUPT_PIT: /* Programmable interval timer on embedded ppc */ + env->pending_interrupts &= ~PPC_INTERRUPT_PIT; + powerpc_excp(cpu, POWERPC_EXCP_PIT); + break; + case PPC_INTERRUPT_DECR: /* Decrementer exception */ + if (ppc_decr_clear_on_delivery(env)) { + env->pending_interrupts &= ~PPC_INTERRUPT_DECR; + } + powerpc_excp(cpu, POWERPC_EXCP_DECR); + break; + case PPC_INTERRUPT_DOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_DOORBELL; + if (is_book3s_arch2x(env)) { + powerpc_excp(cpu, POWERPC_EXCP_SDOOR); + } else { + powerpc_excp(cpu, POWERPC_EXCP_DOORI); + } + break; + case PPC_INTERRUPT_HDOORBELL: + env->pending_interrupts &= ~PPC_INTERRUPT_HDOORBELL; + powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); + break; + case PPC_INTERRUPT_PERFM: + env->pending_interrupts &= ~PPC_INTERRUPT_PERFM; + powerpc_excp(cpu, POWERPC_EXCP_PERFM); + break; + case PPC_INTERRUPT_THERM: /* Thermal interrupt */ + env->pending_interrupts &= ~PPC_INTERRUPT_THERM; + powerpc_excp(cpu, POWERPC_EXCP_THERM); + break; + case PPC_INTERRUPT_EBB: /* EBB exception */ + env->pending_interrupts &= ~PPC_INTERRUPT_EBB; + if (env->spr[SPR_BESCR] & BESCR_PMEO) { + powerpc_excp(cpu, POWERPC_EXCP_PERFM_EBB); + } else if (env->spr[SPR_BESCR] & BESCR_EEO) { + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL_EBB); + } + break; + case 0: + /* + * This is a bug ! It means that has_work took us out of halt without + * anything to deliver while in a PM state that requires getting + * out via a 0x100 + * + * This means we will incorrectly execute past the power management + * instruction instead of triggering a reset. + * + * It generally means a discrepancy between the wakeup conditions in the + * processor has_work implementation and the logic in this function. + */ + assert(!env->resume_as_sreset); + break; + default: + cpu_abort(cs, "Invalid PowerPC interrupt %d. Aborting\n", interrupt); + } +} + +static void ppc_deliver_interrupt(CPUPPCState *env, int interrupt) +{ + switch (env->excp_model) { +#if defined(TARGET_PPC64) + case POWERPC_EXCP_POWER7: + p7_deliver_interrupt(env, interrupt); + break; + case POWERPC_EXCP_POWER8: + p8_deliver_interrupt(env, interrupt); + break; + case POWERPC_EXCP_POWER9: + case POWERPC_EXCP_POWER10: + p9_deliver_interrupt(env, interrupt); + break; +#endif + default: + ppc_deliver_interrupt_generic(env, interrupt); } } @@ -1889,15 +2540,22 @@ bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = &cpu->env; + int interrupt; - if (interrupt_request & CPU_INTERRUPT_HARD) { - ppc_hw_interrupt(env); - if (env->pending_interrupts == 0) { - cs->interrupt_request &= ~CPU_INTERRUPT_HARD; - } - return true; + if ((interrupt_request & CPU_INTERRUPT_HARD) == 0) { + return false; } - return false; + + interrupt = ppc_next_unmasked_interrupt(env); + if (interrupt == 0) { + return false; + } + + ppc_deliver_interrupt(env, interrupt); + if (env->pending_interrupts == 0) { + cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); + } + return true; } #endif /* !CONFIG_USER_ONLY */ @@ -1958,6 +2616,11 @@ void helper_store_msr(CPUPPCState *env, target_ulong val) } } +void helper_ppc_maybe_interrupt(CPUPPCState *env) +{ + ppc_maybe_interrupt(env); +} + #if defined(TARGET_PPC64) void helper_scv(CPUPPCState *env, uint32_t lev) { @@ -1978,6 +2641,8 @@ void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn) /* Condition for waking up at 0x100 */ env->resume_as_sreset = (insn != PPC_PM_STOP) || (env->spr[SPR_PSSCR] & PSSCR_EC); + + ppc_maybe_interrupt(env); } #endif /* defined(TARGET_PPC64) */ @@ -2086,7 +2751,6 @@ void helper_rfebb(CPUPPCState *env, target_ulong s) static void do_ebb(CPUPPCState *env, int ebb_excp) { PowerPCCPU *cpu = env_archcpu(env); - CPUState *cs = CPU(cpu); /* * FSCR_EBB and FSCR_IC_EBB are the same bits used with @@ -2104,8 +2768,7 @@ static void do_ebb(CPUPPCState *env, int ebb_excp) if (FIELD_EX64(env->msr, MSR, PR)) { powerpc_excp(cpu, ebb_excp); } else { - env->pending_interrupts |= 1 << PPC_INTERRUPT_EBB; - cpu_interrupt(cs, CPU_INTERRUPT_HARD); + ppc_set_irq(cpu, PPC_INTERRUPT_EBB, 1); } } @@ -2298,7 +2961,7 @@ void helper_msgclr(CPUPPCState *env, target_ulong rb) return; } - env->pending_interrupts &= ~(1 << irq); + ppc_set_irq(env_archcpu(env), irq, 0); } void helper_msgsnd(target_ulong rb) @@ -2317,8 +2980,7 @@ void helper_msgsnd(target_ulong rb) CPUPPCState *cenv = &cpu->env; if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) { - cenv->pending_interrupts |= 1 << irq; - cpu_interrupt(cs, CPU_INTERRUPT_HARD); + ppc_set_irq(cpu, irq, 1); } } qemu_mutex_unlock_iothread(); @@ -2342,7 +3004,7 @@ void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb) return; } - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); + ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_HDOORBELL, 0); } static void book3s_msgsnd_common(int pir, int irq) @@ -2356,8 +3018,7 @@ static void book3s_msgsnd_common(int pir, int irq) /* TODO: broadcast message to all threads of the same processor */ if (cenv->spr_cb[SPR_PIR].default_value == pir) { - cenv->pending_interrupts |= 1 << irq; - cpu_interrupt(cs, CPU_INTERRUPT_HARD); + ppc_set_irq(cpu, irq, 1); } } qemu_mutex_unlock_iothread(); @@ -2383,7 +3044,7 @@ void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb) return; } - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); + ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_HDOORBELL, 0); } /* diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index ae25f32d6e..a66e16c212 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -3241,93 +3241,82 @@ void helper_XVXSIGSP(ppc_vsr_t *xt, ppc_vsr_t *xb) *xt = t; } -/* - * VSX_TEST_DC - VSX floating point test data class - * op - instruction mnemonic - * nels - number of elements (1, 2 or 4) - * xbn - VSR register number - * tp - type (float32 or float64) - * fld - vsr_t field (VsrD(*) or VsrW(*)) - * tfld - target vsr_t field (VsrD(*) or VsrW(*)) - * fld_max - target field max - * scrf - set result in CR and FPCC - */ -#define VSX_TEST_DC(op, nels, xbn, tp, fld, tfld, fld_max, scrf) \ -void helper_##op(CPUPPCState *env, uint32_t opcode) \ +#define VSX_TSTDC(tp) \ +static int32_t tp##_tstdc(tp b, uint32_t dcmx) \ { \ - ppc_vsr_t *xt = &env->vsr[xT(opcode)]; \ - ppc_vsr_t *xb = &env->vsr[xbn]; \ - ppc_vsr_t t = { }; \ - uint32_t i, sign, dcmx; \ - uint32_t cc, match = 0; \ - \ - if (!scrf) { \ - dcmx = DCMX_XV(opcode); \ - } else { \ - t = *xt; \ - dcmx = DCMX(opcode); \ - } \ - \ - for (i = 0; i < nels; i++) { \ - sign = tp##_is_neg(xb->fld); \ - if (tp##_is_any_nan(xb->fld)) { \ - match = extract32(dcmx, 6, 1); \ - } else if (tp##_is_infinity(xb->fld)) { \ - match = extract32(dcmx, 4 + !sign, 1); \ - } else if (tp##_is_zero(xb->fld)) { \ - match = extract32(dcmx, 2 + !sign, 1); \ - } else if (tp##_is_zero_or_denormal(xb->fld)) { \ - match = extract32(dcmx, 0 + !sign, 1); \ - } \ - \ - if (scrf) { \ - cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT; \ - env->fpscr &= ~FP_FPCC; \ - env->fpscr |= cc << FPSCR_FPCC; \ - env->crf[BF(opcode)] = cc; \ - } else { \ - t.tfld = match ? fld_max : 0; \ - } \ - match = 0; \ - } \ - if (!scrf) { \ - *xt = t; \ + uint32_t match = 0; \ + uint32_t sign = tp##_is_neg(b); \ + if (tp##_is_any_nan(b)) { \ + match = extract32(dcmx, 6, 1); \ + } else if (tp##_is_infinity(b)) { \ + match = extract32(dcmx, 4 + !sign, 1); \ + } else if (tp##_is_zero(b)) { \ + match = extract32(dcmx, 2 + !sign, 1); \ + } else if (tp##_is_zero_or_denormal(b)) { \ + match = extract32(dcmx, 0 + !sign, 1); \ } \ + return (match != 0); \ } -VSX_TEST_DC(xvtstdcdp, 2, xB(opcode), float64, VsrD(i), VsrD(i), UINT64_MAX, 0) -VSX_TEST_DC(xvtstdcsp, 4, xB(opcode), float32, VsrW(i), VsrW(i), UINT32_MAX, 0) -VSX_TEST_DC(xststdcdp, 1, xB(opcode), float64, VsrD(0), VsrD(0), 0, 1) -VSX_TEST_DC(xststdcqp, 1, (rB(opcode) + 32), float128, f128, VsrD(0), 0, 1) +VSX_TSTDC(float32) +VSX_TSTDC(float64) +VSX_TSTDC(float128) +#undef VSX_TSTDC -void helper_xststdcsp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xb) +void helper_XVTSTDCDP(ppc_vsr_t *t, ppc_vsr_t *b, uint64_t dcmx, uint32_t v) { - uint32_t dcmx, sign, exp; - uint32_t cc, match = 0, not_sp = 0; - float64 arg = xb->VsrD(0); - float64 arg_sp; - - dcmx = DCMX(opcode); - exp = (arg >> 52) & 0x7FF; - sign = float64_is_neg(arg); + int i; + for (i = 0; i < 2; i++) { + t->s64[i] = (int64_t)-float64_tstdc(b->f64[i], dcmx); + } +} - if (float64_is_any_nan(arg)) { - match = extract32(dcmx, 6, 1); - } else if (float64_is_infinity(arg)) { - match = extract32(dcmx, 4 + !sign, 1); - } else if (float64_is_zero(arg)) { - match = extract32(dcmx, 2 + !sign, 1); - } else if (float64_is_zero_or_denormal(arg) || (exp > 0 && exp < 0x381)) { - match = extract32(dcmx, 0 + !sign, 1); +void helper_XVTSTDCSP(ppc_vsr_t *t, ppc_vsr_t *b, uint64_t dcmx, uint32_t v) +{ + int i; + for (i = 0; i < 4; i++) { + t->s32[i] = (int32_t)-float32_tstdc(b->f32[i], dcmx); } +} - arg_sp = helper_todouble(helper_tosingle(arg)); - not_sp = arg != arg_sp; +static bool not_SP_value(float64 val) +{ + return val != helper_todouble(helper_tosingle(val)); +} +/* + * VSX_XS_TSTDC - VSX Scalar Test Data Class + * NAME - instruction name + * FLD - vsr_t field (VsrD(0) or f128) + * TP - type (float64 or float128) + */ +#define VSX_XS_TSTDC(NAME, FLD, TP) \ + void helper_##NAME(CPUPPCState *env, uint32_t bf, \ + uint32_t dcmx, ppc_vsr_t *b) \ + { \ + uint32_t cc, match, sign = TP##_is_neg(b->FLD); \ + match = TP##_tstdc(b->FLD, dcmx); \ + cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT; \ + env->fpscr &= ~FP_FPCC; \ + env->fpscr |= cc << FPSCR_FPCC; \ + env->crf[bf] = cc; \ + } + +VSX_XS_TSTDC(XSTSTDCDP, VsrD(0), float64) +VSX_XS_TSTDC(XSTSTDCQP, f128, float128) +#undef VSX_XS_TSTDC + +void helper_XSTSTDCSP(CPUPPCState *env, uint32_t bf, + uint32_t dcmx, ppc_vsr_t *b) +{ + uint32_t cc, match, sign = float64_is_neg(b->VsrD(0)); + uint32_t exp = (b->VsrD(0) >> 52) & 0x7FF; + int not_sp = (int)not_SP_value(b->VsrD(0)); + match = float64_tstdc(b->VsrD(0), dcmx) || (exp > 0 && exp < 0x381); cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT | not_sp << CRF_SO_BIT; env->fpscr &= ~FP_FPCC; env->fpscr |= cc << FPSCR_FPCC; - env->crf[BF(opcode)] = cc; + env->crf[bf] = cc; } void helper_xsrqpi(CPUPPCState *env, uint32_t opcode, diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 57eee07256..8dd22a35e4 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -10,6 +10,7 @@ DEF_HELPER_4(HASHSTP, void, env, tl, tl, tl) DEF_HELPER_4(HASHCHKP, void, env, tl, tl, tl) #if !defined(CONFIG_USER_ONLY) DEF_HELPER_2(store_msr, void, env, tl) +DEF_HELPER_1(ppc_maybe_interrupt, void, env) DEF_HELPER_1(rfi, void, env) DEF_HELPER_1(40x_rfci, void, env) DEF_HELPER_1(rfci, void, env) @@ -29,6 +30,7 @@ DEF_HELPER_2(store_mmcr1, void, env, tl) DEF_HELPER_3(store_pmc, void, env, i32, i64) DEF_HELPER_2(read_pmc, tl, env, i32) DEF_HELPER_2(insns_inc, void, env, i32) +DEF_HELPER_1(handle_pmc5_overflow, void, env) #endif DEF_HELPER_1(check_tlb_flush_local, void, env) DEF_HELPER_1(check_tlb_flush_global, void, env) @@ -143,15 +145,15 @@ DEF_HELPER_FLAGS_1(ftsqrt, TCG_CALL_NO_RWG_SE, i32, i64) #define dh_ctype_acc ppc_acc_t * #define dh_typecode_acc dh_typecode_ptr -DEF_HELPER_FLAGS_3(vavgub, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vavguh, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vavguw, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vabsdub, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vabsduh, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vabsduw, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vavgsb, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vavgsh, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vavgsw, TCG_CALL_NO_RWG, void, avr, avr, avr) +DEF_HELPER_FLAGS_4(VAVGUB, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) +DEF_HELPER_FLAGS_4(VAVGUH, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) +DEF_HELPER_FLAGS_4(VAVGUW, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) +DEF_HELPER_FLAGS_4(VABSDUB, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) +DEF_HELPER_FLAGS_4(VABSDUH, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) +DEF_HELPER_FLAGS_4(VABSDUW, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) +DEF_HELPER_FLAGS_4(VAVGSB, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) +DEF_HELPER_FLAGS_4(VAVGSH, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) +DEF_HELPER_FLAGS_4(VAVGSW, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) DEF_HELPER_4(vcmpeqfp, void, env, avr, avr, avr) DEF_HELPER_4(vcmpgefp, void, env, avr, avr, avr) DEF_HELPER_4(vcmpgtfp, void, env, avr, avr, avr) @@ -193,11 +195,7 @@ DEF_HELPER_FLAGS_3(vslo, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vsro, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vsrv, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vslv, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vaddcuw, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_2(vprtybw, TCG_CALL_NO_RWG, void, avr, avr) -DEF_HELPER_FLAGS_2(vprtybd, TCG_CALL_NO_RWG, void, avr, avr) -DEF_HELPER_FLAGS_2(vprtybq, TCG_CALL_NO_RWG, void, avr, avr) -DEF_HELPER_FLAGS_3(vsubcuw, TCG_CALL_NO_RWG, void, avr, avr, avr) +DEF_HELPER_FLAGS_3(VPRTYBQ, TCG_CALL_NO_RWG, void, avr, avr, i32) DEF_HELPER_FLAGS_5(vaddsbs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vaddshs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vaddsws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) @@ -231,8 +229,6 @@ DEF_HELPER_FLAGS_2(VSTRIBL, TCG_CALL_NO_RWG, i32, avr, avr) DEF_HELPER_FLAGS_2(VSTRIBR, TCG_CALL_NO_RWG, i32, avr, avr) DEF_HELPER_FLAGS_2(VSTRIHL, TCG_CALL_NO_RWG, i32, avr, avr) DEF_HELPER_FLAGS_2(VSTRIHR, TCG_CALL_NO_RWG, i32, avr, avr) -DEF_HELPER_FLAGS_2(vnegw, TCG_CALL_NO_RWG, void, avr, avr) -DEF_HELPER_FLAGS_2(vnegd, TCG_CALL_NO_RWG, void, avr, avr) DEF_HELPER_FLAGS_2(vupkhpx, TCG_CALL_NO_RWG, void, avr, avr) DEF_HELPER_FLAGS_2(vupklpx, TCG_CALL_NO_RWG, void, avr, avr) DEF_HELPER_FLAGS_2(vupkhsb, TCG_CALL_NO_RWG, void, avr, avr) @@ -258,13 +254,13 @@ DEF_HELPER_4(vpkuhum, void, env, avr, avr, avr) DEF_HELPER_4(vpkuwum, void, env, avr, avr, avr) DEF_HELPER_4(vpkudum, void, env, avr, avr, avr) DEF_HELPER_FLAGS_3(vpkpx, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_5(vmhaddshs, void, env, avr, avr, avr, avr) -DEF_HELPER_5(vmhraddshs, void, env, avr, avr, avr, avr) +DEF_HELPER_5(VMHADDSHS, void, env, avr, avr, avr, avr) +DEF_HELPER_5(VMHRADDSHS, void, env, avr, avr, avr, avr) DEF_HELPER_FLAGS_4(VMSUMUHM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_5(VMSUMUHS, void, env, avr, avr, avr, avr) DEF_HELPER_FLAGS_4(VMSUMSHM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_5(VMSUMSHS, void, env, avr, avr, avr, avr) -DEF_HELPER_FLAGS_4(vmladduhm, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) +DEF_HELPER_FLAGS_5(VMLADDUHM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_2(mtvscr, TCG_CALL_NO_RWG, void, env, i32) DEF_HELPER_FLAGS_1(mfvscr, TCG_CALL_NO_RWG, i32, env) DEF_HELPER_3(lvebx, void, env, avr, tl) @@ -423,9 +419,9 @@ DEF_HELPER_3(xscvuxdsp, void, env, vsr, vsr) DEF_HELPER_3(xscvsxdsp, void, env, vsr, vsr) DEF_HELPER_4(xscvudqp, void, env, i32, vsr, vsr) DEF_HELPER_3(xscvuxddp, void, env, vsr, vsr) -DEF_HELPER_3(xststdcsp, void, env, i32, vsr) -DEF_HELPER_2(xststdcdp, void, env, i32) -DEF_HELPER_2(xststdcqp, void, env, i32) +DEF_HELPER_4(XSTSTDCSP, void, env, i32, i32, vsr) +DEF_HELPER_4(XSTSTDCDP, void, env, i32, i32, vsr) +DEF_HELPER_4(XSTSTDCQP, void, env, i32, i32, vsr) DEF_HELPER_3(xsrdpi, void, env, vsr, vsr) DEF_HELPER_3(xsrdpic, void, env, vsr, vsr) DEF_HELPER_3(xsrdpim, void, env, vsr, vsr) @@ -523,8 +519,8 @@ DEF_HELPER_3(xvcvsxdsp, void, env, vsr, vsr) DEF_HELPER_3(xvcvuxdsp, void, env, vsr, vsr) DEF_HELPER_3(xvcvsxwsp, void, env, vsr, vsr) DEF_HELPER_3(xvcvuxwsp, void, env, vsr, vsr) -DEF_HELPER_2(xvtstdcsp, void, env, i32) -DEF_HELPER_2(xvtstdcdp, void, env, i32) +DEF_HELPER_FLAGS_4(XVTSTDCSP, TCG_CALL_NO_RWG, void, vsr, vsr, i64, i32) +DEF_HELPER_FLAGS_4(XVTSTDCDP, TCG_CALL_NO_RWG, void, vsr, vsr, i64, i32) DEF_HELPER_3(xvrspi, void, env, vsr, vsr) DEF_HELPER_3(xvrspic, void, env, vsr, vsr) DEF_HELPER_3(xvrspim, void, env, vsr, vsr) diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c index 12235ea2e9..c0aee5855b 100644 --- a/target/ppc/helper_regs.c +++ b/target/ppc/helper_regs.c @@ -109,6 +109,9 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState *env) if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCC1) { hflags |= 1 << HFLAGS_PMCC1; } + if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE) { + hflags |= 1 << HFLAGS_PMCJCE; + } #ifndef CONFIG_USER_ONLY if (!env->has_hv_mode || (msr & (1ull << MSR_HV))) { @@ -119,6 +122,9 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState *env) if (env->pmc_ins_cnt) { hflags |= 1 << HFLAGS_INSN_CNT; } + if (env->pmc_ins_cnt & 0x1e) { + hflags |= 1 << HFLAGS_PMC_OTHER; + } #endif /* @@ -260,6 +266,8 @@ int hreg_store_msr(CPUPPCState *env, target_ulong value, int alter_hv) env->msr = value; hreg_compute_hflags(env); #if !defined(CONFIG_USER_ONLY) + ppc_maybe_interrupt(env); + if (unlikely(FIELD_EX64(env->msr, MSR, POW))) { if (!env->pending_interrupts && (*env->check_pow)(env)) { cs->halted = 1; diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index a5249ee32c..f8f589e9fd 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -199,6 +199,12 @@ @XX2_uim4 ...... ..... . uim:4 ..... ......... .. &XX2_uim xt=%xx_xt xb=%xx_xb +%xx_uim7 6:1 2:1 16:5 +@XX2_uim7 ...... ..... ..... ..... .... . ... . .. &XX2_uim xt=%xx_xt xb=%xx_xb uim=%xx_uim7 + +&XX2_bf_uim bf xb uim +@XX2_bf_uim ...... bf:3 uim:7 ..... ......... . . &XX2_bf_uim + &XX2_bf_xb bf xb @XX2_bf_xb ...... bf:3 .. ..... ..... ......... . . &XX2_bf_xb xb=%xx_xb @@ -519,6 +525,21 @@ VCMPNEZW 000100 ..... ..... ..... . 0110000111 @VC VCMPSQ 000100 ... -- ..... ..... 00101000001 @VX_bf VCMPUQ 000100 ... -- ..... ..... 00100000001 @VX_bf +## Vector Integer Average Instructions + +VAVGSB 000100 ..... ..... ..... 10100000010 @VX +VAVGSH 000100 ..... ..... ..... 10101000010 @VX +VAVGSW 000100 ..... ..... ..... 10110000010 @VX +VAVGUB 000100 ..... ..... ..... 10000000010 @VX +VAVGUH 000100 ..... ..... ..... 10001000010 @VX +VAVGUW 000100 ..... ..... ..... 10010000010 @VX + +## Vector Integer Absolute Difference Instructions + +VABSDUB 000100 ..... ..... ..... 10000000011 @VX +VABSDUH 000100 ..... ..... ..... 10001000011 @VX +VABSDUW 000100 ..... ..... ..... 10010000011 @VX + ## Vector Bit Manipulation Instruction VGNB 000100 ..... -- ... ..... 10011001100 @VX_n @@ -529,6 +550,10 @@ VCTZDM 000100 ..... ..... ..... 11111000100 @VX VPDEPD 000100 ..... ..... ..... 10111001101 @VX VPEXTD 000100 ..... ..... ..... 10110001101 @VX +VPRTYBD 000100 ..... 01001 ..... 11000000010 @VX_tb +VPRTYBQ 000100 ..... 01010 ..... 11000000010 @VX_tb +VPRTYBW 000100 ..... 01000 ..... 11000000010 @VX_tb + ## Vector Permute and Formatting Instruction VEXTDUBVLX 000100 ..... ..... ..... ..... 011000 @VA @@ -608,12 +633,14 @@ VRLQNM 000100 ..... ..... ..... 00101000101 @VX ## Vector Integer Arithmetic Instructions +VADDCUW 000100 ..... ..... ..... 00110000000 @VX VADDCUQ 000100 ..... ..... ..... 00101000000 @VX VADDUQM 000100 ..... ..... ..... 00100000000 @VX VADDEUQM 000100 ..... ..... ..... ..... 111100 @VA VADDECUQ 000100 ..... ..... ..... ..... 111101 @VA +VSUBCUW 000100 ..... ..... ..... 10110000000 @VX VSUBCUQ 000100 ..... ..... ..... 10101000000 @VX VSUBUQM 000100 ..... ..... ..... 10100000000 @VX @@ -627,6 +654,9 @@ VEXTSH2D 000100 ..... 11001 ..... 11000000010 @VX_tb VEXTSW2D 000100 ..... 11010 ..... 11000000010 @VX_tb VEXTSD2Q 000100 ..... 11011 ..... 11000000010 @VX_tb +VNEGD 000100 ..... 00111 ..... 11000000010 @VX_tb +VNEGW 000100 ..... 00110 ..... 11000000010 @VX_tb + ## Vector Mask Manipulation Instructions MTVSRBM 000100 ..... 10000 ..... 11001000010 @VX_tb @@ -693,6 +723,10 @@ VMSUMUHS 000100 ..... ..... ..... ..... 100111 @VA VMSUMCUD 000100 ..... ..... ..... ..... 010111 @VA VMSUMUDM 000100 ..... ..... ..... ..... 100011 @VA +VMLADDUHM 000100 ..... ..... ..... ..... 100010 @VA +VMHADDSHS 000100 ..... ..... ..... ..... 100000 @VA +VMHRADDSHS 000100 ..... ..... ..... ..... 100001 @VA + ## Vector String Instructions VSTRIBL 000100 ..... 00000 ..... . 0000001101 @VX_tb_rc @@ -726,6 +760,17 @@ STXVRHX 011111 ..... ..... ..... 0010101101 . @X_TSX STXVRWX 011111 ..... ..... ..... 0011001101 . @X_TSX STXVRDX 011111 ..... ..... ..... 0011101101 . @X_TSX +## VSX Vector Binary Floating-Point Sign Manipulation Instructions + +XVABSDP 111100 ..... 00000 ..... 111011001 .. @XX2 +XVABSSP 111100 ..... 00000 ..... 110011001 .. @XX2 +XVNABSDP 111100 ..... 00000 ..... 111101001 .. @XX2 +XVNABSSP 111100 ..... 00000 ..... 110101001 .. @XX2 +XVNEGDP 111100 ..... 00000 ..... 111111001 .. @XX2 +XVNEGSP 111100 ..... 00000 ..... 110111001 .. @XX2 +XVCPSGNDP 111100 ..... ..... ..... 11110000 ... @XX3 +XVCPSGNSP 111100 ..... ..... ..... 11010000 ... @XX3 + ## VSX Scalar Multiply-Add Instructions XSMADDADP 111100 ..... ..... ..... 00100001 . . . @XX3 @@ -809,6 +854,11 @@ XSCVSPDPN 111100 ..... ----- ..... 101001011 .. @XX2 ## VSX Binary Floating-Point Math Support Instructions XVXSIGSP 111100 ..... 01001 ..... 111011011 .. @XX2 +XVTSTDCDP 111100 ..... ..... ..... 1111 . 101 ... @XX2_uim7 +XVTSTDCSP 111100 ..... ..... ..... 1101 . 101 ... @XX2_uim7 +XSTSTDCSP 111100 ... ....... ..... 100101010 . - @XX2_bf_uim xb=%xx_xb +XSTSTDCDP 111100 ... ....... ..... 101101010 . - @XX2_bf_uim xb=%xx_xb +XSTSTDCQP 111111 ... ....... xb:5 1011000100 - @XX2_bf_uim ## VSX Vector Test Least-Significant Bit by Byte Instruction @@ -908,3 +958,11 @@ SLBSYNC 011111 ----- ----- ----- 0101010010 - TLBIE 011111 ..... - .. . . ..... 0100110010 - @X_tlbie TLBIEL 011111 ..... - .. . . ..... 0100010010 - @X_tlbie + +# Processor Control Instructions + +MSGCLR 011111 ----- ----- ..... 0011101110 - @X_rb +MSGSND 011111 ----- ----- ..... 0011001110 - @X_rb +MSGCLRP 011111 ----- ----- ..... 0010101110 - @X_rb +MSGSNDP 011111 ----- ----- ..... 0010001110 - @X_rb +MSGSYNC 011111 ----- ----- ----- 1101110110 - diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 696096100b..d97a7f1f28 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -492,40 +492,8 @@ static inline void set_vscr_sat(CPUPPCState *env) env->vscr_sat.u32[0] = 1; } -void helper_vaddcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(r->u32); i++) { - r->u32[i] = ~a->u32[i] < b->u32[i]; - } -} - -/* vprtybw */ -void helper_vprtybw(ppc_avr_t *r, ppc_avr_t *b) -{ - int i; - for (i = 0; i < ARRAY_SIZE(r->u32); i++) { - uint64_t res = b->u32[i] ^ (b->u32[i] >> 16); - res ^= res >> 8; - r->u32[i] = res & 1; - } -} - -/* vprtybd */ -void helper_vprtybd(ppc_avr_t *r, ppc_avr_t *b) -{ - int i; - for (i = 0; i < ARRAY_SIZE(r->u64); i++) { - uint64_t res = b->u64[i] ^ (b->u64[i] >> 32); - res ^= res >> 16; - res ^= res >> 8; - r->u64[i] = res & 1; - } -} - /* vprtybq */ -void helper_vprtybq(ppc_avr_t *r, ppc_avr_t *b) +void helper_VPRTYBQ(ppc_avr_t *r, ppc_avr_t *b, uint32_t v) { uint64_t res = b->u64[0] ^ b->u64[1]; res ^= res >> 32; @@ -602,29 +570,27 @@ VARITHSAT_UNSIGNED(w, u32, uint64_t, cvtsduw) #undef VARITHSAT_SIGNED #undef VARITHSAT_UNSIGNED -#define VAVG_DO(name, element, etype) \ - void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ - { \ - int i; \ - \ - for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ - etype x = (etype)a->element[i] + (etype)b->element[i] + 1; \ - r->element[i] = x >> 1; \ - } \ +#define VAVG(name, element, etype) \ + void helper_##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t v)\ + { \ + int i; \ + \ + for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ + etype x = (etype)a->element[i] + (etype)b->element[i] + 1; \ + r->element[i] = x >> 1; \ + } \ } -#define VAVG(type, signed_element, signed_type, unsigned_element, \ - unsigned_type) \ - VAVG_DO(avgs##type, signed_element, signed_type) \ - VAVG_DO(avgu##type, unsigned_element, unsigned_type) -VAVG(b, s8, int16_t, u8, uint16_t) -VAVG(h, s16, int32_t, u16, uint32_t) -VAVG(w, s32, int64_t, u32, uint64_t) -#undef VAVG_DO +VAVG(VAVGSB, s8, int16_t) +VAVG(VAVGUB, u8, uint16_t) +VAVG(VAVGSH, s16, int32_t) +VAVG(VAVGUH, u16, uint32_t) +VAVG(VAVGSW, s32, int64_t) +VAVG(VAVGUW, u32, uint64_t) #undef VAVG -#define VABSDU_DO(name, element) \ -void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ +#define VABSDU(name, element) \ +void helper_##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t v)\ { \ int i; \ \ @@ -640,12 +606,9 @@ void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ * name - instruction mnemonic suffix (b: byte, h: halfword, w: word) * element - element type to access from vector */ -#define VABSDU(type, element) \ - VABSDU_DO(absdu##type, element) -VABSDU(b, u8) -VABSDU(h, u16) -VABSDU(w, u32) -#undef VABSDU_DO +VABSDU(VABSDUB, u8) +VABSDU(VABSDUH, u16) +VABSDU(VABSDUW, u32) #undef VABSDU #define VCF(suffix, cvt, element) \ @@ -939,7 +902,7 @@ target_ulong helper_vctzlsbb(ppc_avr_t *r) return count; } -void helper_vmhaddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, +void helper_VMHADDSHS(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { int sat = 0; @@ -957,7 +920,7 @@ void helper_vmhaddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } } -void helper_vmhraddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, +void helper_VMHRADDSHS(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { int sat = 0; @@ -974,7 +937,8 @@ void helper_vmhraddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } } -void helper_vmladduhm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) +void helper_VMLADDUHM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c, + uint32_t v) { int i; @@ -1936,18 +1900,6 @@ XXBLEND(W, 32) XXBLEND(D, 64) #undef XXBLEND -#define VNEG(name, element) \ -void helper_##name(ppc_avr_t *r, ppc_avr_t *b) \ -{ \ - int i; \ - for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ - r->element[i] = -b->element[i]; \ - } \ -} -VNEG(vnegw, s32) -VNEG(vnegd, s64) -#undef VNEG - void helper_vsro(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { int sh = (b->VsrB(0xf) >> 3) & 0xf; @@ -1961,15 +1913,6 @@ void helper_vsro(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) #endif } -void helper_vsubcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(r->u32); i++) { - r->u32[i] = a->u32[i] >= b->u32[i]; - } -} - void helper_vsumsws(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { int64_t t; diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index b0a5e7ce76..a9bc1522e2 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -25,6 +25,7 @@ #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "mmu-book3s-v3.h" +#include "hw/ppc/ppc.h" #include "helper_regs.h" @@ -163,7 +164,7 @@ target_ulong helper_load_dpdes(CPUPPCState *env) helper_hfscr_facility_check(env, HFSCR_MSGP, "load DPDES", HFSCR_IC_MSGP); /* TODO: TCG supports only one thread */ - if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) { + if (env->pending_interrupts & PPC_INTERRUPT_DOORBELL) { dpdes = 1; } @@ -173,7 +174,6 @@ target_ulong helper_load_dpdes(CPUPPCState *env) void helper_store_dpdes(CPUPPCState *env, target_ulong val) { PowerPCCPU *cpu = env_archcpu(env); - CPUState *cs = CPU(cpu); helper_hfscr_facility_check(env, HFSCR_MSGP, "store DPDES", HFSCR_IC_MSGP); @@ -184,12 +184,7 @@ void helper_store_dpdes(CPUPPCState *env, target_ulong val) return; } - if (val & 0x1) { - env->pending_interrupts |= 1 << PPC_INTERRUPT_DOORBELL; - cpu_interrupt(cs, CPU_INTERRUPT_HARD); - } else { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); - } + ppc_set_irq(cpu, PPC_INTERRUPT_DOORBELL, val & 0x1); } #endif /* defined(TARGET_PPC64) */ diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c index 00f2e9fa2e..031efda0df 100644 --- a/target/ppc/mmu-radix64.c +++ b/target/ppc/mmu-radix64.c @@ -238,6 +238,8 @@ static void ppc_radix64_set_rc(PowerPCCPU *cpu, MMUAccessType access_type, static bool ppc_radix64_is_valid_level(int level, int psize, uint64_t nls) { + bool ret; + /* * Check if this is a valid level, according to POWER9 and POWER10 * Processor User's Manuals, sections 4.10.4.1 and 5.10.6.1, respectively: @@ -249,16 +251,25 @@ static bool ppc_radix64_is_valid_level(int level, int psize, uint64_t nls) */ switch (level) { case 0: /* Root Page Dir */ - return psize == 52 && nls == 13; + ret = psize == 52 && nls == 13; + break; case 1: case 2: - return nls == 9; + ret = nls == 9; + break; case 3: - return nls == 9 || nls == 5; + ret = nls == 9 || nls == 5; + break; default: - qemu_log_mask(LOG_GUEST_ERROR, "invalid radix level: %d\n", level); - return false; + ret = false; + } + + if (unlikely(!ret)) { + qemu_log_mask(LOG_GUEST_ERROR, "invalid radix configuration: " + "level %d size %d nls %"PRIu64"\n", + level, psize, nls); } + return ret; } static int ppc_radix64_next_level(AddressSpace *as, vaddr eaddr, @@ -519,11 +530,13 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, if (!ppc_radix64_is_valid_level(level++, *g_page_size, nls)) { fault_cause |= DSISR_R_BADCONFIG; - return 1; + ret = 1; + } else { + ret = ppc_radix64_next_level(cs->as, eaddr & R_EADDR_MASK, + &h_raddr, &nls, g_page_size, + &pte, &fault_cause); } - ret = ppc_radix64_next_level(cs->as, eaddr & R_EADDR_MASK, &h_raddr, - &nls, g_page_size, &pte, &fault_cause); if (ret) { /* No valid pte */ if (guest_visible) { diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c index beeab5c494..1381072b9e 100644 --- a/target/ppc/power8-pmu.c +++ b/target/ppc/power8-pmu.c @@ -22,8 +22,6 @@ #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) -#define PMC_COUNTER_NEGATIVE_VAL 0x80000000UL - static bool pmc_has_overflow_enabled(CPUPPCState *env, int sprn) { if (sprn == SPR_POWER_PMC1) { @@ -88,49 +86,47 @@ static bool pmu_increment_insns(CPUPPCState *env, uint32_t num_insns) bool overflow_triggered = false; target_ulong tmp; - if (unlikely(ins_cnt & 0x1e)) { - if (ins_cnt & (1 << 1)) { - tmp = env->spr[SPR_POWER_PMC1]; - tmp += num_insns; - if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMC1CE)) { - tmp = PMC_COUNTER_NEGATIVE_VAL; - overflow_triggered = true; - } - env->spr[SPR_POWER_PMC1] = tmp; + if (ins_cnt & (1 << 1)) { + tmp = env->spr[SPR_POWER_PMC1]; + tmp += num_insns; + if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMC1CE)) { + tmp = PMC_COUNTER_NEGATIVE_VAL; + overflow_triggered = true; } + env->spr[SPR_POWER_PMC1] = tmp; + } - if (ins_cnt & (1 << 2)) { - tmp = env->spr[SPR_POWER_PMC2]; - tmp += num_insns; - if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) { - tmp = PMC_COUNTER_NEGATIVE_VAL; - overflow_triggered = true; - } - env->spr[SPR_POWER_PMC2] = tmp; + if (ins_cnt & (1 << 2)) { + tmp = env->spr[SPR_POWER_PMC2]; + tmp += num_insns; + if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) { + tmp = PMC_COUNTER_NEGATIVE_VAL; + overflow_triggered = true; + } + env->spr[SPR_POWER_PMC2] = tmp; + } + + if (ins_cnt & (1 << 3)) { + tmp = env->spr[SPR_POWER_PMC3]; + tmp += num_insns; + if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) { + tmp = PMC_COUNTER_NEGATIVE_VAL; + overflow_triggered = true; } + env->spr[SPR_POWER_PMC3] = tmp; + } - if (ins_cnt & (1 << 3)) { - tmp = env->spr[SPR_POWER_PMC3]; + if (ins_cnt & (1 << 4)) { + target_ulong mmcr1 = env->spr[SPR_POWER_MMCR1]; + int sel = extract64(mmcr1, MMCR1_PMC4EVT_EXTR, MMCR1_EVT_SIZE); + if (sel == 0x02 || (env->spr[SPR_CTRL] & CTRL_RUN)) { + tmp = env->spr[SPR_POWER_PMC4]; tmp += num_insns; if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) { tmp = PMC_COUNTER_NEGATIVE_VAL; overflow_triggered = true; } - env->spr[SPR_POWER_PMC3] = tmp; - } - - if (ins_cnt & (1 << 4)) { - target_ulong mmcr1 = env->spr[SPR_POWER_MMCR1]; - int sel = extract64(mmcr1, MMCR1_PMC4EVT_EXTR, MMCR1_EVT_SIZE); - if (sel == 0x02 || (env->spr[SPR_CTRL] & CTRL_RUN)) { - tmp = env->spr[SPR_POWER_PMC4]; - tmp += num_insns; - if (tmp >= PMC_COUNTER_NEGATIVE_VAL && (mmcr0 & MMCR0_PMCjCE)) { - tmp = PMC_COUNTER_NEGATIVE_VAL; - overflow_triggered = true; - } - env->spr[SPR_POWER_PMC4] = tmp; - } + env->spr[SPR_POWER_PMC4] = tmp; } } @@ -310,6 +306,12 @@ static void fire_PMC_interrupt(PowerPCCPU *cpu) raise_ebb_perfm_exception(env); } +void helper_handle_pmc5_overflow(CPUPPCState *env) +{ + env->spr[SPR_POWER_PMC5] = PMC_COUNTER_NEGATIVE_VAL; + fire_PMC_interrupt(env_archcpu(env)); +} + /* This helper assumes that the PMC is running. */ void helper_insns_inc(CPUPPCState *env, uint32_t num_insns) { diff --git a/target/ppc/power8-pmu.h b/target/ppc/power8-pmu.h index 9692dd765e..c0093e2219 100644 --- a/target/ppc/power8-pmu.h +++ b/target/ppc/power8-pmu.h @@ -14,6 +14,9 @@ #define POWER8_PMU_H #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) + +#define PMC_COUNTER_NEGATIVE_VAL 0x80000000UL + void cpu_ppc_pmu_init(CPUPPCState *env); void pmu_update_summaries(CPUPPCState *env); #else diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 7228857e23..19c1d17cb0 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -36,6 +36,7 @@ #include "exec/log.h" #include "qemu/atomic128.h" #include "spr_common.h" +#include "power8-pmu.h" #include "qemu/qemu-print.h" #include "qapi/error.h" @@ -177,6 +178,8 @@ struct DisasContext { bool hr; bool mmcr0_pmcc0; bool mmcr0_pmcc1; + bool mmcr0_pmcjce; + bool pmc_other; bool pmu_insn_cnt; ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ int singlestep_enabled; @@ -305,6 +308,14 @@ static void gen_icount_io_start(DisasContext *ctx) } } +#if !defined(CONFIG_USER_ONLY) +static void gen_ppc_maybe_interrupt(DisasContext *ctx) +{ + gen_icount_io_start(ctx); + gen_helper_ppc_maybe_interrupt(cpu_env); +} +#endif + /* * Tells the caller what is the appropriate exception to generate and prepares * SPR registers for this exception. @@ -4261,6 +4272,9 @@ static void pmu_count_insns(DisasContext *ctx) } #if !defined(CONFIG_USER_ONLY) + TCGLabel *l; + TCGv t0; + /* * The PMU insns_inc() helper stops the internal PMU timer if a * counter overflows happens. In that case, if the guest is @@ -4269,8 +4283,26 @@ static void pmu_count_insns(DisasContext *ctx) */ gen_icount_io_start(ctx); - gen_helper_insns_inc(cpu_env, tcg_constant_i32(ctx->base.num_insns)); -#else + /* Avoid helper calls when only PMC5-6 are enabled. */ + if (!ctx->pmc_other) { + l = gen_new_label(); + t0 = tcg_temp_new(); + + gen_load_spr(t0, SPR_POWER_PMC5); + tcg_gen_addi_tl(t0, t0, ctx->base.num_insns); + gen_store_spr(SPR_POWER_PMC5, t0); + /* Check for overflow, if it's enabled */ + if (ctx->mmcr0_pmcjce) { + tcg_gen_brcondi_tl(TCG_COND_LT, t0, PMC_COUNTER_NEGATIVE_VAL, l); + gen_helper_handle_pmc5_overflow(cpu_env); + } + + gen_set_label(l); + tcg_temp_free(t0); + } else { + gen_helper_insns_inc(cpu_env, tcg_constant_i32(ctx->base.num_insns)); + } + #else /* * User mode can read (but not write) PMC5 and start/stop * the PMU via MMCR0_FC. In this case just increment @@ -4283,7 +4315,7 @@ static void pmu_count_insns(DisasContext *ctx) gen_store_spr(SPR_POWER_PMC5, t0); tcg_temp_free(t0); -#endif /* #if !defined(CONFIG_USER_ONLY) */ + #endif /* #if !defined(CONFIG_USER_ONLY) */ } #else static void pmu_count_insns(DisasContext *ctx) @@ -6161,7 +6193,6 @@ static void gen_tlbilx_booke206(DisasContext *ctx) #endif /* defined(CONFIG_USER_ONLY) */ } - /* wrtee */ static void gen_wrtee(DisasContext *ctx) { @@ -6175,6 +6206,7 @@ static void gen_wrtee(DisasContext *ctx) tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE)); tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE)); tcg_gen_or_tl(cpu_msr, cpu_msr, t0); + gen_ppc_maybe_interrupt(ctx); tcg_temp_free(t0); /* * Stop translation to have a chance to raise an exception if we @@ -6193,6 +6225,7 @@ static void gen_wrteei(DisasContext *ctx) CHK_SV(ctx); if (ctx->opcode & 0x00008000) { tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE)); + gen_ppc_maybe_interrupt(ctx); /* Stop translation to have a chance to raise an exception */ ctx->base.is_jmp = DISAS_EXIT_UPDATE; } else { @@ -6239,68 +6272,6 @@ static void gen_icbt_440(DisasContext *ctx) */ } -/* Embedded.Processor Control */ - -static void gen_msgclr(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_HV(ctx); - if (is_book3s_arch2x(ctx)) { - gen_helper_book3s_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]); - } else { - gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]); - } -#endif /* defined(CONFIG_USER_ONLY) */ -} - -static void gen_msgsnd(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_HV(ctx); - if (is_book3s_arch2x(ctx)) { - gen_helper_book3s_msgsnd(cpu_gpr[rB(ctx->opcode)]); - } else { - gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]); - } -#endif /* defined(CONFIG_USER_ONLY) */ -} - -#if defined(TARGET_PPC64) -static void gen_msgclrp(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_SV(ctx); - gen_helper_book3s_msgclrp(cpu_env, cpu_gpr[rB(ctx->opcode)]); -#endif /* defined(CONFIG_USER_ONLY) */ -} - -static void gen_msgsndp(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_SV(ctx); - gen_helper_book3s_msgsndp(cpu_env, cpu_gpr[rB(ctx->opcode)]); -#endif /* defined(CONFIG_USER_ONLY) */ -} -#endif - -static void gen_msgsync(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_HV(ctx); -#endif /* defined(CONFIG_USER_ONLY) */ - /* interpreted as no-op */ -} - #if defined(TARGET_PPC64) static void gen_maddld(DisasContext *ctx) { @@ -6545,12 +6516,12 @@ static int64_t dw_compose_ea(DisasContext *ctx, int x) } \ } while (0) -#define REQUIRE_HV(CTX) \ - do { \ - if (unlikely((CTX)->pr || !(CTX)->hv)) \ - gen_priv_opc(CTX); \ - return true; \ - } \ +#define REQUIRE_HV(CTX) \ + do { \ + if (unlikely((CTX)->pr || !(CTX)->hv)) { \ + gen_priv_opc(CTX); \ + return true; \ + } \ } while (0) #else #define REQUIRE_SV(CTX) do { gen_priv_opc(CTX); return true; } while (0) @@ -6628,6 +6599,8 @@ static bool resolve_PLS_D(DisasContext *ctx, arg_D *d, arg_PLS_D *a) #include "translate/branch-impl.c.inc" +#include "translate/processor-ctrl-impl.c.inc" + #include "translate/storage-ctrl-impl.c.inc" /* Handles lfdp */ @@ -6901,12 +6874,6 @@ GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001, PPC_NONE, PPC2_BOOKE206), GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001, PPC_NONE, PPC2_BOOKE206), -GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001, - PPC_NONE, PPC2_PRCNTL), -GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001, - PPC_NONE, PPC2_PRCNTL), -GEN_HANDLER2_E(msgsync, "msgsync", 0x1F, 0x16, 0x1B, 0x00000000, - PPC_NONE, PPC2_PRCNTL), GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE), GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE), GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC), @@ -6921,15 +6888,10 @@ GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC), GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC), GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC), GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC), -GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC), #if defined(TARGET_PPC64) GEN_HANDLER_E(maddhd_maddhdu, 0x04, 0x18, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E(maddld, 0x04, 0x19, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300), -GEN_HANDLER2_E(msgsndp, "msgsndp", 0x1F, 0x0E, 0x04, 0x03ff0001, - PPC_NONE, PPC2_ISA207S), -GEN_HANDLER2_E(msgclrp, "msgclrp", 0x1F, 0x0E, 0x05, 0x03ff0001, - PPC_NONE, PPC2_ISA207S), #endif #undef GEN_INT_ARITH_ADD @@ -7574,6 +7536,8 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->hr = (hflags >> HFLAGS_HR) & 1; ctx->mmcr0_pmcc0 = (hflags >> HFLAGS_PMCC0) & 1; ctx->mmcr0_pmcc1 = (hflags >> HFLAGS_PMCC1) & 1; + ctx->mmcr0_pmcjce = (hflags >> HFLAGS_PMCJCE) & 1; + ctx->pmc_other = (hflags >> HFLAGS_PMC_OTHER) & 1; ctx->pmu_insn_cnt = (hflags >> HFLAGS_INSN_CNT) & 1; ctx->singlestep_enabled = 0; diff --git a/target/ppc/translate/processor-ctrl-impl.c.inc b/target/ppc/translate/processor-ctrl-impl.c.inc new file mode 100644 index 0000000000..cc7a50d579 --- /dev/null +++ b/target/ppc/translate/processor-ctrl-impl.c.inc @@ -0,0 +1,105 @@ +/* + * Power ISA decode for Storage Control instructions + * + * Copyright (c) 2022 Instituto de Pesquisas Eldorado (eldorado.org.br) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Processor Control Instructions + */ + +static bool trans_MSGCLR(DisasContext *ctx, arg_X_rb *a) +{ + if (!(ctx->insns_flags2 & PPC2_ISA207S)) { + /* + * Before Power ISA 2.07, processor control instructions were only + * implemented in the "Embedded.Processor Control" category. + */ + REQUIRE_INSNS_FLAGS2(ctx, PRCNTL); + } + + REQUIRE_HV(ctx); + +#if !defined(CONFIG_USER_ONLY) + if (is_book3s_arch2x(ctx)) { + gen_helper_book3s_msgclr(cpu_env, cpu_gpr[a->rb]); + } else { + gen_helper_msgclr(cpu_env, cpu_gpr[a->rb]); + } +#else + qemu_build_not_reached(); +#endif + return true; +} + +static bool trans_MSGSND(DisasContext *ctx, arg_X_rb *a) +{ + if (!(ctx->insns_flags2 & PPC2_ISA207S)) { + /* + * Before Power ISA 2.07, processor control instructions were only + * implemented in the "Embedded.Processor Control" category. + */ + REQUIRE_INSNS_FLAGS2(ctx, PRCNTL); + } + + REQUIRE_HV(ctx); + +#if !defined(CONFIG_USER_ONLY) + if (is_book3s_arch2x(ctx)) { + gen_helper_book3s_msgsnd(cpu_gpr[a->rb]); + } else { + gen_helper_msgsnd(cpu_gpr[a->rb]); + } +#else + qemu_build_not_reached(); +#endif + return true; +} + +static bool trans_MSGCLRP(DisasContext *ctx, arg_X_rb *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_INSNS_FLAGS2(ctx, ISA207S); + REQUIRE_SV(ctx); +#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64) + gen_helper_book3s_msgclrp(cpu_env, cpu_gpr[a->rb]); +#else + qemu_build_not_reached(); +#endif + return true; +} + +static bool trans_MSGSNDP(DisasContext *ctx, arg_X_rb *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_INSNS_FLAGS2(ctx, ISA207S); + REQUIRE_SV(ctx); +#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64) + gen_helper_book3s_msgsndp(cpu_env, cpu_gpr[a->rb]); +#else + qemu_build_not_reached(); +#endif + return true; +} + +static bool trans_MSGSYNC(DisasContext *ctx, arg_MSGSYNC *a) +{ + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_HV(ctx); + + /* interpreted as no-op */ + return true; +} diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index e644ad3236..7741f2eb49 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -431,21 +431,6 @@ GEN_VXFORM_V(vminsb, MO_8, tcg_gen_gvec_smin, 1, 12); GEN_VXFORM_V(vminsh, MO_16, tcg_gen_gvec_smin, 1, 13); GEN_VXFORM_V(vminsw, MO_32, tcg_gen_gvec_smin, 1, 14); GEN_VXFORM_V(vminsd, MO_64, tcg_gen_gvec_smin, 1, 15); -GEN_VXFORM(vavgub, 1, 16); -GEN_VXFORM(vabsdub, 1, 16); -GEN_VXFORM_DUAL(vavgub, PPC_ALTIVEC, PPC_NONE, \ - vabsdub, PPC_NONE, PPC2_ISA300) -GEN_VXFORM(vavguh, 1, 17); -GEN_VXFORM(vabsduh, 1, 17); -GEN_VXFORM_DUAL(vavguh, PPC_ALTIVEC, PPC_NONE, \ - vabsduh, PPC_NONE, PPC2_ISA300) -GEN_VXFORM(vavguw, 1, 18); -GEN_VXFORM(vabsduw, 1, 18); -GEN_VXFORM_DUAL(vavguw, PPC_ALTIVEC, PPC_NONE, \ - vabsduw, PPC_NONE, PPC2_ISA300) -GEN_VXFORM(vavgsb, 1, 20); -GEN_VXFORM(vavgsh, 1, 21); -GEN_VXFORM(vavgsw, 1, 22); GEN_VXFORM(vmrghb, 6, 0); GEN_VXFORM(vmrghh, 6, 1); GEN_VXFORM(vmrghw, 6, 2); @@ -803,8 +788,6 @@ GEN_VXFORM(vsrv, 2, 28); GEN_VXFORM(vslv, 2, 29); GEN_VXFORM(vslo, 6, 16); GEN_VXFORM(vsro, 6, 17); -GEN_VXFORM(vaddcuw, 0, 6); -GEN_VXFORM(vsubcuw, 0, 22); static bool do_vector_gvec3_VX(DisasContext *ctx, arg_VX *a, int vece, void (*gen_gvec)(unsigned, uint32_t, uint32_t, @@ -1661,9 +1644,71 @@ GEN_VXFORM_NOA_ENV(vrfim, 5, 11); GEN_VXFORM_NOA_ENV(vrfin, 5, 8); GEN_VXFORM_NOA_ENV(vrfip, 5, 10); GEN_VXFORM_NOA_ENV(vrfiz, 5, 9); -GEN_VXFORM_NOA(vprtybw, 1, 24); -GEN_VXFORM_NOA(vprtybd, 1, 24); -GEN_VXFORM_NOA(vprtybq, 1, 24); + +static void gen_vprtyb_vec(unsigned vece, TCGv_vec t, TCGv_vec b) +{ + int i; + TCGv_vec tmp = tcg_temp_new_vec_matching(b); + /* MO_32 is 2, so 2 iteractions for MO_32 and 3 for MO_64 */ + for (i = 0; i < vece; i++) { + tcg_gen_shri_vec(vece, tmp, b, (4 << (vece - i))); + tcg_gen_xor_vec(vece, b, tmp, b); + } + tcg_gen_and_vec(vece, t, b, tcg_constant_vec_matching(t, vece, 1)); + tcg_temp_free_vec(tmp); +} + +/* vprtybw */ +static void gen_vprtyb_i32(TCGv_i32 t, TCGv_i32 b) +{ + tcg_gen_ctpop_i32(t, b); + tcg_gen_and_i32(t, t, tcg_constant_i32(1)); +} + +/* vprtybd */ +static void gen_vprtyb_i64(TCGv_i64 t, TCGv_i64 b) +{ + tcg_gen_ctpop_i64(t, b); + tcg_gen_and_i64(t, t, tcg_constant_i64(1)); +} + +static bool do_vx_vprtyb(DisasContext *ctx, arg_VX_tb *a, unsigned vece) +{ + static const TCGOpcode vecop_list[] = { + INDEX_op_shri_vec, 0 + }; + + static const GVecGen2 op[] = { + { + .fniv = gen_vprtyb_vec, + .fni4 = gen_vprtyb_i32, + .opt_opc = vecop_list, + .vece = MO_32 + }, + { + .fniv = gen_vprtyb_vec, + .fni8 = gen_vprtyb_i64, + .opt_opc = vecop_list, + .vece = MO_64 + }, + { + .fno = gen_helper_VPRTYBQ, + .vece = MO_128 + }, + }; + + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_VECTOR(ctx); + + tcg_gen_gvec_2(avr_full_offset(a->vrt), avr_full_offset(a->vrb), + 16, 16, &op[vece - MO_32]); + + return true; +} + +TRANS(VPRTYBW, do_vx_vprtyb, MO_32) +TRANS(VPRTYBD, do_vx_vprtyb, MO_64) +TRANS(VPRTYBQ, do_vx_vprtyb, MO_128) static void gen_vsplt(DisasContext *ctx, int vece) { @@ -2521,25 +2566,7 @@ static void glue(gen_, name0##_##name1)(DisasContext *ctx) \ tcg_temp_free_ptr(rd); \ } -GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16) - -static void gen_vmladduhm(DisasContext *ctx) -{ - TCGv_ptr ra, rb, rc, rd; - if (unlikely(!ctx->altivec_enabled)) { - gen_exception(ctx, POWERPC_EXCP_VPU); - return; - } - ra = gen_avr_ptr(rA(ctx->opcode)); - rb = gen_avr_ptr(rB(ctx->opcode)); - rc = gen_avr_ptr(rC(ctx->opcode)); - rd = gen_avr_ptr(rD(ctx->opcode)); - gen_helper_vmladduhm(rd, ra, rb, rc); - tcg_temp_free_ptr(ra); - tcg_temp_free_ptr(rb); - tcg_temp_free_ptr(rc); - tcg_temp_free_ptr(rd); -} +GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23) static bool do_va_helper(DisasContext *ctx, arg_VA *a, void (*gen_helper)(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr)) @@ -2569,6 +2596,36 @@ TRANS_FLAGS2(ALTIVEC_207, VSUBECUQ, do_va_helper, gen_helper_VSUBECUQ) TRANS_FLAGS(ALTIVEC, VPERM, do_va_helper, gen_helper_VPERM) TRANS_FLAGS2(ISA300, VPERMR, do_va_helper, gen_helper_VPERMR) +static void gen_vmladduhm_vec(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b, + TCGv_vec c) +{ + tcg_gen_mul_vec(vece, t, a, b); + tcg_gen_add_vec(vece, t, t, c); +} + +static bool trans_VMLADDUHM(DisasContext *ctx, arg_VA *a) +{ + static const TCGOpcode vecop_list[] = { + INDEX_op_add_vec, INDEX_op_mul_vec, 0 + }; + + static const GVecGen4 op = { + .fno = gen_helper_VMLADDUHM, + .fniv = gen_vmladduhm_vec, + .opt_opc = vecop_list, + .vece = MO_16 + }; + + REQUIRE_INSNS_FLAGS(ctx, ALTIVEC); + REQUIRE_VECTOR(ctx); + + tcg_gen_gvec_4(avr_full_offset(a->vrt), avr_full_offset(a->vra), + avr_full_offset(a->vrb), avr_full_offset(a->rc), + 16, 16, &op); + + return true; +} + static bool trans_VSEL(DisasContext *ctx, arg_VA *a) { REQUIRE_INSNS_FLAGS(ctx, ALTIVEC); @@ -2608,14 +2665,26 @@ static bool do_va_env_helper(DisasContext *ctx, arg_VA *a, TRANS_FLAGS(ALTIVEC, VMSUMUHS, do_va_env_helper, gen_helper_VMSUMUHS) TRANS_FLAGS(ALTIVEC, VMSUMSHS, do_va_env_helper, gen_helper_VMSUMSHS) -GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23) +TRANS_FLAGS(ALTIVEC, VMHADDSHS, do_va_env_helper, gen_helper_VMHADDSHS) +TRANS_FLAGS(ALTIVEC, VMHRADDSHS, do_va_env_helper, gen_helper_VMHRADDSHS) GEN_VXFORM_NOA(vclzb, 1, 28) GEN_VXFORM_NOA(vclzh, 1, 29) GEN_VXFORM_TRANS(vclzw, 1, 30) GEN_VXFORM_TRANS(vclzd, 1, 31) -GEN_VXFORM_NOA_2(vnegw, 1, 24, 6) -GEN_VXFORM_NOA_2(vnegd, 1, 24, 7) + +static bool do_vneg(DisasContext *ctx, arg_VX_tb *a, unsigned vece) +{ + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_VECTOR(ctx); + + tcg_gen_gvec_neg(vece, avr_full_offset(a->vrt), avr_full_offset(a->vrb), + 16, 16); + return true; +} + +TRANS(VNEGW, do_vneg, MO_32) +TRANS(VNEGD, do_vneg, MO_64) static void gen_vexts_i64(TCGv_i64 t, TCGv_i64 b, int64_t s) { @@ -2834,8 +2903,6 @@ static void gen_xpnd04_2(DisasContext *ctx) } -GEN_VXFORM_DUAL(vsubcuw, PPC_ALTIVEC, PPC_NONE, \ - xpnd04_1, PPC_NONE, PPC2_ISA300) GEN_VXFORM_DUAL(vsubsws, PPC_ALTIVEC, PPC_NONE, \ xpnd04_2, PPC_NONE, PPC2_ISA300) @@ -3097,6 +3164,63 @@ TRANS_FLAGS2(ALTIVEC_207, VPMSUMD, do_vx_helper, gen_helper_VPMSUMD) TRANS_FLAGS2(ALTIVEC_207, VSUBCUQ, do_vx_helper, gen_helper_VSUBCUQ) TRANS_FLAGS2(ALTIVEC_207, VSUBUQM, do_vx_helper, gen_helper_VSUBUQM) +static void gen_VADDCUW_vec(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b) +{ + tcg_gen_not_vec(vece, a, a); + tcg_gen_cmp_vec(TCG_COND_LTU, vece, t, a, b); + tcg_gen_and_vec(vece, t, t, tcg_constant_vec_matching(t, vece, 1)); +} + +static void gen_VADDCUW_i32(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b) +{ + tcg_gen_not_i32(a, a); + tcg_gen_setcond_i32(TCG_COND_LTU, t, a, b); +} + +static void gen_VSUBCUW_vec(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b) +{ + tcg_gen_cmp_vec(TCG_COND_GEU, vece, t, a, b); + tcg_gen_and_vec(vece, t, t, tcg_constant_vec_matching(t, vece, 1)); +} + +static void gen_VSUBCUW_i32(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b) +{ + tcg_gen_setcond_i32(TCG_COND_GEU, t, a, b); +} + +static bool do_vx_vaddsubcuw(DisasContext *ctx, arg_VX *a, int add) +{ + static const TCGOpcode vecop_list[] = { + INDEX_op_cmp_vec, 0 + }; + + static const GVecGen3 op[] = { + { + .fniv = gen_VSUBCUW_vec, + .fni4 = gen_VSUBCUW_i32, + .opt_opc = vecop_list, + .vece = MO_32 + }, + { + .fniv = gen_VADDCUW_vec, + .fni4 = gen_VADDCUW_i32, + .opt_opc = vecop_list, + .vece = MO_32 + }, + }; + + REQUIRE_INSNS_FLAGS(ctx, ALTIVEC); + REQUIRE_VECTOR(ctx); + + tcg_gen_gvec_3(avr_full_offset(a->vrt), avr_full_offset(a->vra), + avr_full_offset(a->vrb), 16, 16, &op[add]); + + return true; +} + +TRANS(VSUBCUW, do_vx_vaddsubcuw, 0) +TRANS(VADDCUW, do_vx_vaddsubcuw, 1) + static bool do_vx_vmuleo(DisasContext *ctx, arg_VX *a, bool even, void (*gen_mul)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64)) { @@ -3234,6 +3358,146 @@ TRANS(VMULHSD, do_vx_mulh, true , do_vx_vmulhd_i64) TRANS(VMULHUW, do_vx_mulh, false, do_vx_vmulhw_i64) TRANS(VMULHUD, do_vx_mulh, false, do_vx_vmulhd_i64) +static void do_vavg(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b, + void (*gen_shr_vec)(unsigned, TCGv_vec, TCGv_vec, int64_t)) +{ + TCGv_vec tmp = tcg_temp_new_vec_matching(t); + tcg_gen_or_vec(vece, tmp, a, b); + tcg_gen_and_vec(vece, tmp, tmp, tcg_constant_vec_matching(t, vece, 1)); + gen_shr_vec(vece, a, a, 1); + gen_shr_vec(vece, b, b, 1); + tcg_gen_add_vec(vece, t, a, b); + tcg_gen_add_vec(vece, t, t, tmp); + tcg_temp_free_vec(tmp); +} + +QEMU_FLATTEN +static void gen_vavgu(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b) +{ + do_vavg(vece, t, a, b, tcg_gen_shri_vec); +} + +QEMU_FLATTEN +static void gen_vavgs(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b) +{ + do_vavg(vece, t, a, b, tcg_gen_sari_vec); +} + +static bool do_vx_vavg(DisasContext *ctx, arg_VX *a, int sign, int vece) +{ + static const TCGOpcode vecop_list_s[] = { + INDEX_op_add_vec, INDEX_op_sari_vec, 0 + }; + static const TCGOpcode vecop_list_u[] = { + INDEX_op_add_vec, INDEX_op_shri_vec, 0 + }; + + static const GVecGen3 op[2][3] = { + { + { + .fniv = gen_vavgu, + .fno = gen_helper_VAVGUB, + .opt_opc = vecop_list_u, + .vece = MO_8 + }, + { + .fniv = gen_vavgu, + .fno = gen_helper_VAVGUH, + .opt_opc = vecop_list_u, + .vece = MO_16 + }, + { + .fniv = gen_vavgu, + .fno = gen_helper_VAVGUW, + .opt_opc = vecop_list_u, + .vece = MO_32 + }, + }, + { + { + .fniv = gen_vavgs, + .fno = gen_helper_VAVGSB, + .opt_opc = vecop_list_s, + .vece = MO_8 + }, + { + .fniv = gen_vavgs, + .fno = gen_helper_VAVGSH, + .opt_opc = vecop_list_s, + .vece = MO_16 + }, + { + .fniv = gen_vavgs, + .fno = gen_helper_VAVGSW, + .opt_opc = vecop_list_s, + .vece = MO_32 + }, + }, + }; + + REQUIRE_VECTOR(ctx); + + tcg_gen_gvec_3(avr_full_offset(a->vrt), avr_full_offset(a->vra), + avr_full_offset(a->vrb), 16, 16, &op[sign][vece]); + + + return true; +} + + +TRANS_FLAGS(ALTIVEC, VAVGSB, do_vx_vavg, 1, MO_8) +TRANS_FLAGS(ALTIVEC, VAVGSH, do_vx_vavg, 1, MO_16) +TRANS_FLAGS(ALTIVEC, VAVGSW, do_vx_vavg, 1, MO_32) +TRANS_FLAGS(ALTIVEC, VAVGUB, do_vx_vavg, 0, MO_8) +TRANS_FLAGS(ALTIVEC, VAVGUH, do_vx_vavg, 0, MO_16) +TRANS_FLAGS(ALTIVEC, VAVGUW, do_vx_vavg, 0, MO_32) + +static void gen_vabsdu(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b) +{ + tcg_gen_umax_vec(vece, t, a, b); + tcg_gen_umin_vec(vece, a, a, b); + tcg_gen_sub_vec(vece, t, t, a); +} + +static bool do_vabsdu(DisasContext *ctx, arg_VX *a, const int vece) +{ + static const TCGOpcode vecop_list[] = { + INDEX_op_umax_vec, INDEX_op_umin_vec, INDEX_op_sub_vec, 0 + }; + + static const GVecGen3 op[] = { + { + .fniv = gen_vabsdu, + .fno = gen_helper_VABSDUB, + .opt_opc = vecop_list, + .vece = MO_8 + }, + { + .fniv = gen_vabsdu, + .fno = gen_helper_VABSDUH, + .opt_opc = vecop_list, + .vece = MO_16 + }, + { + .fniv = gen_vabsdu, + .fno = gen_helper_VABSDUW, + .opt_opc = vecop_list, + .vece = MO_32 + }, + }; + + REQUIRE_VECTOR(ctx); + + tcg_gen_gvec_3(avr_full_offset(a->vrt), avr_full_offset(a->vra), + avr_full_offset(a->vrb), 16, 16, &op[vece]); + + return true; +} + +TRANS_FLAGS2(ISA300, VABSDUB, do_vabsdu, MO_8) +TRANS_FLAGS2(ISA300, VABSDUH, do_vabsdu, MO_16) +TRANS_FLAGS2(ISA300, VABSDUW, do_vabsdu, MO_32) + static bool do_vdiv_vmod(DisasContext *ctx, arg_VX *a, const int vece, void (*func_32)(TCGv_i32 t, TCGv_i32 a, TCGv_i32 b), void (*func_64)(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b)) diff --git a/target/ppc/translate/vmx-ops.c.inc b/target/ppc/translate/vmx-ops.c.inc index a3a0fd0650..33fec8aca4 100644 --- a/target/ppc/translate/vmx-ops.c.inc +++ b/target/ppc/translate/vmx-ops.c.inc @@ -83,12 +83,6 @@ GEN_VXFORM(vminsb, 1, 12), GEN_VXFORM(vminsh, 1, 13), GEN_VXFORM(vminsw, 1, 14), GEN_VXFORM_207(vminsd, 1, 15), -GEN_VXFORM_DUAL(vavgub, vabsdub, 1, 16, PPC_ALTIVEC, PPC_NONE), -GEN_VXFORM_DUAL(vavguh, vabsduh, 1, 17, PPC_ALTIVEC, PPC_NONE), -GEN_VXFORM_DUAL(vavguw, vabsduw, 1, 18, PPC_ALTIVEC, PPC_NONE), -GEN_VXFORM(vavgsb, 1, 20), -GEN_VXFORM(vavgsh, 1, 21), -GEN_VXFORM(vavgsw, 1, 22), GEN_VXFORM(vmrghb, 6, 0), GEN_VXFORM(vmrghh, 6, 1), GEN_VXFORM(vmrghw, 6, 2), @@ -106,12 +100,8 @@ GEN_VXFORM_300(vsrv, 2, 28), GEN_VXFORM_300(vslv, 2, 29), GEN_VXFORM(vslo, 6, 16), GEN_VXFORM(vsro, 6, 17), -GEN_VXFORM(vaddcuw, 0, 6), -GEN_HANDLER_E_2(vprtybw, 0x4, 0x1, 0x18, 8, 0, PPC_NONE, PPC2_ISA300), -GEN_HANDLER_E_2(vprtybd, 0x4, 0x1, 0x18, 9, 0, PPC_NONE, PPC2_ISA300), -GEN_HANDLER_E_2(vprtybq, 0x4, 0x1, 0x18, 10, 0, PPC_NONE, PPC2_ISA300), -GEN_VXFORM_DUAL(vsubcuw, xpnd04_1, 0, 22, PPC_ALTIVEC, PPC_NONE), +GEN_VXFORM(xpnd04_1, 0, 22), GEN_VXFORM_300(bcdsr, 0, 23), GEN_VXFORM_300(bcdsr, 0, 31), GEN_VXFORM_DUAL(vaddubs, vmul10uq, 0, 8, PPC_ALTIVEC, PPC_NONE), @@ -182,8 +172,6 @@ GEN_VXFORM_300_EXT(vextractd, 6, 11, 0x100000), GEN_VXFORM(vspltisb, 6, 12), GEN_VXFORM(vspltish, 6, 13), GEN_VXFORM(vspltisw, 6, 14), -GEN_VXFORM_300_EO(vnegw, 0x01, 0x18, 0x06), -GEN_VXFORM_300_EO(vnegd, 0x01, 0x18, 0x07), GEN_VXFORM_300_EO(vctzb, 0x01, 0x18, 0x1C), GEN_VXFORM_300_EO(vctzh, 0x01, 0x18, 0x1D), GEN_VXFORM_300_EO(vctzw, 0x01, 0x18, 0x1E), @@ -219,7 +207,6 @@ GEN_VXFORM_UIMM(vctsxs, 5, 15), #define GEN_VAFORM_PAIRED(name0, name1, opc2) \ GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC) -GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16), GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23), GEN_VXFORM_DUAL(vclzb, vpopcntb, 1, 28, PPC_NONE, PPC2_ALTIVEC_207), diff --git a/target/ppc/translate/vsx-impl.c.inc b/target/ppc/translate/vsx-impl.c.inc index e6e5c45ffd..4deb29ee42 100644 --- a/target/ppc/translate/vsx-impl.c.inc +++ b/target/ppc/translate/vsx-impl.c.inc @@ -630,6 +630,10 @@ static void gen_mtvsrws(DisasContext *ctx) #define OP_CPSGN 4 #define SGN_MASK_DP 0x8000000000000000ull #define SGN_MASK_SP 0x8000000080000000ull +#define EXP_MASK_DP 0x7FF0000000000000ull +#define EXP_MASK_SP 0x7F8000007F800000ull +#define FRC_MASK_DP (~(SGN_MASK_DP | EXP_MASK_DP)) +#define FRC_MASK_SP (~(SGN_MASK_SP | EXP_MASK_SP)) #define VSX_SCALAR_MOVE(name, op, sgn_mask) \ static void glue(gen_, name)(DisasContext *ctx) \ @@ -729,67 +733,125 @@ VSX_SCALAR_MOVE_QP(xsnabsqp, OP_NABS, SGN_MASK_DP) VSX_SCALAR_MOVE_QP(xsnegqp, OP_NEG, SGN_MASK_DP) VSX_SCALAR_MOVE_QP(xscpsgnqp, OP_CPSGN, SGN_MASK_DP) -#define VSX_VECTOR_MOVE(name, op, sgn_mask) \ -static void glue(gen_, name)(DisasContext *ctx) \ - { \ - TCGv_i64 xbh, xbl, sgm; \ - if (unlikely(!ctx->vsx_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_VSXU); \ - return; \ - } \ - xbh = tcg_temp_new_i64(); \ - xbl = tcg_temp_new_i64(); \ - sgm = tcg_temp_new_i64(); \ - get_cpu_vsr(xbh, xB(ctx->opcode), true); \ - get_cpu_vsr(xbl, xB(ctx->opcode), false); \ - tcg_gen_movi_i64(sgm, sgn_mask); \ - switch (op) { \ - case OP_ABS: { \ - tcg_gen_andc_i64(xbh, xbh, sgm); \ - tcg_gen_andc_i64(xbl, xbl, sgm); \ - break; \ - } \ - case OP_NABS: { \ - tcg_gen_or_i64(xbh, xbh, sgm); \ - tcg_gen_or_i64(xbl, xbl, sgm); \ - break; \ - } \ - case OP_NEG: { \ - tcg_gen_xor_i64(xbh, xbh, sgm); \ - tcg_gen_xor_i64(xbl, xbl, sgm); \ - break; \ - } \ - case OP_CPSGN: { \ - TCGv_i64 xah = tcg_temp_new_i64(); \ - TCGv_i64 xal = tcg_temp_new_i64(); \ - get_cpu_vsr(xah, xA(ctx->opcode), true); \ - get_cpu_vsr(xal, xA(ctx->opcode), false); \ - tcg_gen_and_i64(xah, xah, sgm); \ - tcg_gen_and_i64(xal, xal, sgm); \ - tcg_gen_andc_i64(xbh, xbh, sgm); \ - tcg_gen_andc_i64(xbl, xbl, sgm); \ - tcg_gen_or_i64(xbh, xbh, xah); \ - tcg_gen_or_i64(xbl, xbl, xal); \ - tcg_temp_free_i64(xah); \ - tcg_temp_free_i64(xal); \ - break; \ - } \ - } \ - set_cpu_vsr(xT(ctx->opcode), xbh, true); \ - set_cpu_vsr(xT(ctx->opcode), xbl, false); \ - tcg_temp_free_i64(xbh); \ - tcg_temp_free_i64(xbl); \ - tcg_temp_free_i64(sgm); \ - } - -VSX_VECTOR_MOVE(xvabsdp, OP_ABS, SGN_MASK_DP) -VSX_VECTOR_MOVE(xvnabsdp, OP_NABS, SGN_MASK_DP) -VSX_VECTOR_MOVE(xvnegdp, OP_NEG, SGN_MASK_DP) -VSX_VECTOR_MOVE(xvcpsgndp, OP_CPSGN, SGN_MASK_DP) -VSX_VECTOR_MOVE(xvabssp, OP_ABS, SGN_MASK_SP) -VSX_VECTOR_MOVE(xvnabssp, OP_NABS, SGN_MASK_SP) -VSX_VECTOR_MOVE(xvnegsp, OP_NEG, SGN_MASK_SP) -VSX_VECTOR_MOVE(xvcpsgnsp, OP_CPSGN, SGN_MASK_SP) +#define TCG_OP_IMM_i64(FUNC, OP, IMM) \ + static void FUNC(TCGv_i64 t, TCGv_i64 b) \ + { \ + OP(t, b, IMM); \ + } + +TCG_OP_IMM_i64(do_xvabssp_i64, tcg_gen_andi_i64, ~SGN_MASK_SP) +TCG_OP_IMM_i64(do_xvnabssp_i64, tcg_gen_ori_i64, SGN_MASK_SP) +TCG_OP_IMM_i64(do_xvnegsp_i64, tcg_gen_xori_i64, SGN_MASK_SP) +TCG_OP_IMM_i64(do_xvabsdp_i64, tcg_gen_andi_i64, ~SGN_MASK_DP) +TCG_OP_IMM_i64(do_xvnabsdp_i64, tcg_gen_ori_i64, SGN_MASK_DP) +TCG_OP_IMM_i64(do_xvnegdp_i64, tcg_gen_xori_i64, SGN_MASK_DP) +#undef TCG_OP_IMM_i64 + +static void xv_msb_op1(unsigned vece, TCGv_vec t, TCGv_vec b, + void (*tcg_gen_op_vec)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec)) +{ + uint64_t msb = (vece == MO_32) ? SGN_MASK_SP : SGN_MASK_DP; + tcg_gen_op_vec(vece, t, b, tcg_constant_vec_matching(t, vece, msb)); +} + +static void do_xvabs_vec(unsigned vece, TCGv_vec t, TCGv_vec b) +{ + xv_msb_op1(vece, t, b, tcg_gen_andc_vec); +} + +static void do_xvnabs_vec(unsigned vece, TCGv_vec t, TCGv_vec b) +{ + xv_msb_op1(vece, t, b, tcg_gen_or_vec); +} + +static void do_xvneg_vec(unsigned vece, TCGv_vec t, TCGv_vec b) +{ + xv_msb_op1(vece, t, b, tcg_gen_xor_vec); +} + +static bool do_vsx_msb_op(DisasContext *ctx, arg_XX2 *a, unsigned vece, + void (*vec)(unsigned, TCGv_vec, TCGv_vec), + void (*i64)(TCGv_i64, TCGv_i64)) +{ + static const TCGOpcode vecop_list[] = { + 0 + }; + + const GVecGen2 op = { + .fni8 = i64, + .fniv = vec, + .opt_opc = vecop_list, + .vece = vece + }; + + REQUIRE_INSNS_FLAGS2(ctx, VSX); + REQUIRE_VSX(ctx); + + tcg_gen_gvec_2(vsr_full_offset(a->xt), vsr_full_offset(a->xb), + 16, 16, &op); + + return true; +} + +TRANS(XVABSDP, do_vsx_msb_op, MO_64, do_xvabs_vec, do_xvabsdp_i64) +TRANS(XVNABSDP, do_vsx_msb_op, MO_64, do_xvnabs_vec, do_xvnabsdp_i64) +TRANS(XVNEGDP, do_vsx_msb_op, MO_64, do_xvneg_vec, do_xvnegdp_i64) +TRANS(XVABSSP, do_vsx_msb_op, MO_32, do_xvabs_vec, do_xvabssp_i64) +TRANS(XVNABSSP, do_vsx_msb_op, MO_32, do_xvnabs_vec, do_xvnabssp_i64) +TRANS(XVNEGSP, do_vsx_msb_op, MO_32, do_xvneg_vec, do_xvnegsp_i64) + +static void do_xvcpsgndp_i64(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b) +{ + tcg_gen_andi_i64(a, a, SGN_MASK_DP); + tcg_gen_andi_i64(b, b, ~SGN_MASK_DP); + tcg_gen_or_i64(t, a, b); +} + +static void do_xvcpsgnsp_i64(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b) +{ + tcg_gen_andi_i64(a, a, SGN_MASK_SP); + tcg_gen_andi_i64(b, b, ~SGN_MASK_SP); + tcg_gen_or_i64(t, a, b); +} + +static void do_xvcpsgn_vec(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b) +{ + uint64_t msb = (vece == MO_32) ? SGN_MASK_SP : SGN_MASK_DP; + tcg_gen_bitsel_vec(vece, t, tcg_constant_vec_matching(t, vece, msb), a, b); +} + +static bool do_xvcpsgn(DisasContext *ctx, arg_XX3 *a, unsigned vece) +{ + static const TCGOpcode vecop_list[] = { + 0 + }; + + static const GVecGen3 op[] = { + { + .fni8 = do_xvcpsgnsp_i64, + .fniv = do_xvcpsgn_vec, + .opt_opc = vecop_list, + .vece = MO_32 + }, + { + .fni8 = do_xvcpsgndp_i64, + .fniv = do_xvcpsgn_vec, + .opt_opc = vecop_list, + .vece = MO_64 + }, + }; + + REQUIRE_INSNS_FLAGS2(ctx, VSX); + REQUIRE_VSX(ctx); + + tcg_gen_gvec_3(vsr_full_offset(a->xt), vsr_full_offset(a->xa), + vsr_full_offset(a->xb), 16, 16, &op[vece - MO_32]); + + return true; +} + +TRANS(XVCPSGNSP, do_xvcpsgn, MO_32) +TRANS(XVCPSGNDP, do_xvcpsgn, MO_64) #define VSX_CMP(name, op1, op2, inval, type) \ static void gen_##name(DisasContext *ctx) \ @@ -1052,6 +1114,192 @@ GEN_VSX_HELPER_X2(xscvhpdp, 0x16, 0x15, 0x10, PPC2_ISA300) GEN_VSX_HELPER_R2(xscvsdqp, 0x04, 0x1A, 0x0A, PPC2_ISA300) GEN_VSX_HELPER_X2(xscvspdp, 0x12, 0x14, 0, PPC2_VSX) +/* test if +Inf */ +static void gen_is_pos_inf(unsigned vece, TCGv_vec t, TCGv_vec b, int64_t v) +{ + uint64_t exp_msk = (vece == MO_32) ? (uint32_t)EXP_MASK_SP : EXP_MASK_DP; + tcg_gen_cmp_vec(TCG_COND_EQ, vece, t, b, + tcg_constant_vec_matching(t, vece, exp_msk)); +} + +/* test if -Inf */ +static void gen_is_neg_inf(unsigned vece, TCGv_vec t, TCGv_vec b, int64_t v) +{ + uint64_t exp_msk = (vece == MO_32) ? (uint32_t)EXP_MASK_SP : EXP_MASK_DP; + uint64_t sgn_msk = (vece == MO_32) ? (uint32_t)SGN_MASK_SP : SGN_MASK_DP; + tcg_gen_cmp_vec(TCG_COND_EQ, vece, t, b, + tcg_constant_vec_matching(t, vece, sgn_msk | exp_msk)); +} + +/* test if +Inf or -Inf */ +static void gen_is_any_inf(unsigned vece, TCGv_vec t, TCGv_vec b, int64_t v) +{ + uint64_t exp_msk = (vece == MO_32) ? (uint32_t)EXP_MASK_SP : EXP_MASK_DP; + uint64_t sgn_msk = (vece == MO_32) ? (uint32_t)SGN_MASK_SP : SGN_MASK_DP; + tcg_gen_andc_vec(vece, b, b, tcg_constant_vec_matching(t, vece, sgn_msk)); + tcg_gen_cmp_vec(TCG_COND_EQ, vece, t, b, + tcg_constant_vec_matching(t, vece, exp_msk)); +} + +/* test if +0 */ +static void gen_is_pos_zero(unsigned vece, TCGv_vec t, TCGv_vec b, int64_t v) +{ + tcg_gen_cmp_vec(TCG_COND_EQ, vece, t, b, + tcg_constant_vec_matching(t, vece, 0)); +} + +/* test if -0 */ +static void gen_is_neg_zero(unsigned vece, TCGv_vec t, TCGv_vec b, int64_t v) +{ + uint64_t sgn_msk = (vece == MO_32) ? (uint32_t)SGN_MASK_SP : SGN_MASK_DP; + tcg_gen_cmp_vec(TCG_COND_EQ, vece, t, b, + tcg_constant_vec_matching(t, vece, sgn_msk)); +} + +/* test if +0 or -0 */ +static void gen_is_any_zero(unsigned vece, TCGv_vec t, TCGv_vec b, int64_t v) +{ + uint64_t sgn_msk = (vece == MO_32) ? (uint32_t)SGN_MASK_SP : SGN_MASK_DP; + tcg_gen_andc_vec(vece, b, b, tcg_constant_vec_matching(t, vece, sgn_msk)); + tcg_gen_cmp_vec(TCG_COND_EQ, vece, t, b, + tcg_constant_vec_matching(t, vece, 0)); +} + +/* test if +Denormal */ +static void gen_is_pos_denormal(unsigned vece, TCGv_vec t, + TCGv_vec b, int64_t v) +{ + uint64_t frc_msk = (vece == MO_32) ? (uint32_t)FRC_MASK_SP : FRC_MASK_DP; + tcg_gen_cmp_vec(TCG_COND_LEU, vece, t, b, + tcg_constant_vec_matching(t, vece, frc_msk)); + tcg_gen_cmp_vec(TCG_COND_NE, vece, b, b, + tcg_constant_vec_matching(t, vece, 0)); + tcg_gen_and_vec(vece, t, t, b); +} + +/* test if -Denormal */ +static void gen_is_neg_denormal(unsigned vece, TCGv_vec t, + TCGv_vec b, int64_t v) +{ + uint64_t sgn_msk = (vece == MO_32) ? (uint32_t)SGN_MASK_SP : SGN_MASK_DP; + uint64_t frc_msk = (vece == MO_32) ? (uint32_t)FRC_MASK_SP : FRC_MASK_DP; + tcg_gen_cmp_vec(TCG_COND_LEU, vece, t, b, + tcg_constant_vec_matching(t, vece, sgn_msk | frc_msk)); + tcg_gen_cmp_vec(TCG_COND_GTU, vece, b, b, + tcg_constant_vec_matching(t, vece, sgn_msk)); + tcg_gen_and_vec(vece, t, t, b); +} + +/* test if +Denormal or -Denormal */ +static void gen_is_any_denormal(unsigned vece, TCGv_vec t, + TCGv_vec b, int64_t v) +{ + uint64_t sgn_msk = (vece == MO_32) ? (uint32_t)SGN_MASK_SP : SGN_MASK_DP; + uint64_t frc_msk = (vece == MO_32) ? (uint32_t)FRC_MASK_SP : FRC_MASK_DP; + tcg_gen_andc_vec(vece, b, b, tcg_constant_vec_matching(t, vece, sgn_msk)); + tcg_gen_cmp_vec(TCG_COND_LE, vece, t, b, + tcg_constant_vec_matching(t, vece, frc_msk)); + tcg_gen_cmp_vec(TCG_COND_NE, vece, b, b, + tcg_constant_vec_matching(t, vece, 0)); + tcg_gen_and_vec(vece, t, t, b); +} + +/* test if NaN */ +static void gen_is_nan(unsigned vece, TCGv_vec t, TCGv_vec b, int64_t v) +{ + uint64_t exp_msk = (vece == MO_32) ? (uint32_t)EXP_MASK_SP : EXP_MASK_DP; + uint64_t sgn_msk = (vece == MO_32) ? (uint32_t)SGN_MASK_SP : SGN_MASK_DP; + tcg_gen_and_vec(vece, b, b, tcg_constant_vec_matching(t, vece, ~sgn_msk)); + tcg_gen_cmp_vec(TCG_COND_GT, vece, t, b, + tcg_constant_vec_matching(t, vece, exp_msk)); +} + +static bool do_xvtstdc(DisasContext *ctx, arg_XX2_uim *a, unsigned vece) +{ + static const TCGOpcode vecop_list[] = { + INDEX_op_cmp_vec, 0 + }; + + GVecGen2i op = { + .fnoi = (vece == MO_32) ? gen_helper_XVTSTDCSP : gen_helper_XVTSTDCDP, + .vece = vece, + .opt_opc = vecop_list + }; + + REQUIRE_VSX(ctx); + + switch (a->uim) { + case 0: + set_cpu_vsr(a->xt, tcg_constant_i64(0), true); + set_cpu_vsr(a->xt, tcg_constant_i64(0), false); + return true; + case ((1 << 0) | (1 << 1)): + /* test if +Denormal or -Denormal */ + op.fniv = gen_is_any_denormal; + break; + case (1 << 0): + /* test if -Denormal */ + op.fniv = gen_is_neg_denormal; + break; + case (1 << 1): + /* test if +Denormal */ + op.fniv = gen_is_pos_denormal; + break; + case ((1 << 2) | (1 << 3)): + /* test if +0 or -0 */ + op.fniv = gen_is_any_zero; + break; + case (1 << 2): + /* test if -0 */ + op.fniv = gen_is_neg_zero; + break; + case (1 << 3): + /* test if +0 */ + op.fniv = gen_is_pos_zero; + break; + case ((1 << 4) | (1 << 5)): + /* test if +Inf or -Inf */ + op.fniv = gen_is_any_inf; + break; + case (1 << 4): + /* test if -Inf */ + op.fniv = gen_is_neg_inf; + break; + case (1 << 5): + /* test if +Inf */ + op.fniv = gen_is_pos_inf; + break; + case (1 << 6): + /* test if NaN */ + op.fniv = gen_is_nan; + break; + } + tcg_gen_gvec_2i(vsr_full_offset(a->xt), vsr_full_offset(a->xb), + 16, 16, a->uim, &op); + + return true; +} + +TRANS_FLAGS2(VSX, XVTSTDCSP, do_xvtstdc, MO_32) +TRANS_FLAGS2(VSX, XVTSTDCDP, do_xvtstdc, MO_64) + +static bool do_XX2_bf_uim(DisasContext *ctx, arg_XX2_bf_uim *a, bool vsr, + void (*gen_helper)(TCGv_env, TCGv_i32, TCGv_i32, TCGv_ptr)) +{ + TCGv_ptr xb; + + REQUIRE_VSX(ctx); + xb = vsr ? gen_vsr_ptr(a->xb) : gen_avr_ptr(a->xb); + gen_helper(cpu_env, tcg_constant_i32(a->bf), tcg_constant_i32(a->uim), xb); + tcg_temp_free_ptr(xb); + + return true; +} + +TRANS_FLAGS2(ISA300, XSTSTDCSP, do_XX2_bf_uim, true, gen_helper_XSTSTDCSP) +TRANS_FLAGS2(ISA300, XSTSTDCDP, do_XX2_bf_uim, true, gen_helper_XSTSTDCDP) +TRANS_FLAGS2(ISA300, XSTSTDCQP, do_XX2_bf_uim, false, gen_helper_XSTSTDCQP) + bool trans_XSCVSPDPN(DisasContext *ctx, arg_XX2 *a) { TCGv_i64 tmp; @@ -1098,9 +1346,6 @@ GEN_VSX_HELPER_X2(xssqrtsp, 0x16, 0x00, 0, PPC2_VSX207) GEN_VSX_HELPER_X2(xsrsqrtesp, 0x14, 0x00, 0, PPC2_VSX207) GEN_VSX_HELPER_X2(xscvsxdsp, 0x10, 0x13, 0, PPC2_VSX207) GEN_VSX_HELPER_X2(xscvuxdsp, 0x10, 0x12, 0, PPC2_VSX207) -GEN_VSX_HELPER_X1(xststdcsp, 0x14, 0x12, 0, PPC2_ISA300) -GEN_VSX_HELPER_2(xststdcdp, 0x14, 0x16, 0, PPC2_ISA300) -GEN_VSX_HELPER_2(xststdcqp, 0x04, 0x16, 0, PPC2_ISA300) GEN_VSX_HELPER_X3(xvadddp, 0x00, 0x0C, 0, PPC2_VSX) GEN_VSX_HELPER_X3(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX) @@ -1155,8 +1400,6 @@ GEN_VSX_HELPER_X2(xvrspic, 0x16, 0x0A, 0, PPC2_VSX) GEN_VSX_HELPER_X2(xvrspim, 0x12, 0x0B, 0, PPC2_VSX) GEN_VSX_HELPER_X2(xvrspip, 0x12, 0x0A, 0, PPC2_VSX) GEN_VSX_HELPER_X2(xvrspiz, 0x12, 0x09, 0, PPC2_VSX) -GEN_VSX_HELPER_2(xvtstdcsp, 0x14, 0x1A, 0, PPC2_VSX) -GEN_VSX_HELPER_2(xvtstdcdp, 0x14, 0x1E, 0, PPC2_VSX) static bool trans_XXPERM(DisasContext *ctx, arg_XX3 *a) { diff --git a/target/ppc/translate/vsx-ops.c.inc b/target/ppc/translate/vsx-ops.c.inc index bff14bbece..a3ba094d62 100644 --- a/target/ppc/translate/vsx-ops.c.inc +++ b/target/ppc/translate/vsx-ops.c.inc @@ -147,33 +147,12 @@ GEN_HANDLER_E(xsiexpdp, 0x3C, 0x16, 0x1C, 0, PPC_NONE, PPC2_ISA300), GEN_VSX_XFORM_300(xsiexpqp, 0x4, 0x1B, 0x00000001), #endif -GEN_XX2FORM(xststdcdp, 0x14, 0x16, PPC2_ISA300), -GEN_XX2FORM(xststdcsp, 0x14, 0x12, PPC2_ISA300), -GEN_VSX_XFORM_300(xststdcqp, 0x04, 0x16, 0x00000001), - GEN_XX3FORM(xviexpsp, 0x00, 0x1B, PPC2_ISA300), GEN_XX3FORM(xviexpdp, 0x00, 0x1F, PPC2_ISA300), GEN_XX2FORM_EO(xvxexpdp, 0x16, 0x1D, 0x00, PPC2_ISA300), GEN_XX2FORM_EO(xvxsigdp, 0x16, 0x1D, 0x01, PPC2_ISA300), GEN_XX2FORM_EO(xvxexpsp, 0x16, 0x1D, 0x08, PPC2_ISA300), -/* DCMX = bit[25] << 6 | bit[29] << 5 | bit[11:15] */ -#define GEN_XX2FORM_DCMX(name, opc2, opc3, fl2) \ -GEN_XX3FORM(name, opc2, opc3 | 0, fl2), \ -GEN_XX3FORM(name, opc2, opc3 | 1, fl2) - -GEN_XX2FORM_DCMX(xvtstdcdp, 0x14, 0x1E, PPC2_ISA300), -GEN_XX2FORM_DCMX(xvtstdcsp, 0x14, 0x1A, PPC2_ISA300), - -GEN_XX2FORM(xvabsdp, 0x12, 0x1D, PPC2_VSX), -GEN_XX2FORM(xvnabsdp, 0x12, 0x1E, PPC2_VSX), -GEN_XX2FORM(xvnegdp, 0x12, 0x1F, PPC2_VSX), -GEN_XX3FORM(xvcpsgndp, 0x00, 0x1E, PPC2_VSX), -GEN_XX2FORM(xvabssp, 0x12, 0x19, PPC2_VSX), -GEN_XX2FORM(xvnabssp, 0x12, 0x1A, PPC2_VSX), -GEN_XX2FORM(xvnegsp, 0x12, 0x1B, PPC2_VSX), -GEN_XX3FORM(xvcpsgnsp, 0x00, 0x1A, PPC2_VSX), - GEN_XX3FORM(xsadddp, 0x00, 0x04, PPC2_VSX), GEN_VSX_XFORM_300(xsaddqp, 0x04, 0x00, 0x0), GEN_XX3FORM(xssubdp, 0x00, 0x05, PPC2_VSX), diff --git a/target/s390x/tcg/translate_vx.c.inc b/target/s390x/tcg/translate_vx.c.inc index 3526ba3e3b..b69c1a111c 100644 --- a/target/s390x/tcg/translate_vx.c.inc +++ b/target/s390x/tcg/translate_vx.c.inc @@ -2723,7 +2723,7 @@ static DisasJumpType op_vfene(DisasContext *s, DisasOps *o) static DisasJumpType op_vistr(DisasContext *s, DisasOps *o) { - const uint8_t es = get_field(s, m4); + const uint8_t es = get_field(s, m3); const uint8_t m5 = get_field(s, m5); static gen_helper_gvec_2 * const g[3] = { gen_helper_gvec_vistr8, diff --git a/tests/docker/dockerfiles/alpine.docker b/tests/docker/dockerfiles/alpine.docker index 9b7541261a..094f66f4eb 100644 --- a/tests/docker/dockerfiles/alpine.docker +++ b/tests/docker/dockerfiles/alpine.docker @@ -94,6 +94,7 @@ RUN apk update && \ sdl2_image-dev \ sed \ snappy-dev \ + sndio-dev \ sparse \ spice-dev \ spice-protocol \ @@ -119,8 +120,8 @@ RUN apk update && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" diff --git a/tests/docker/dockerfiles/centos8.docker b/tests/docker/dockerfiles/centos8.docker index d89113c0df..1f70d41aeb 100644 --- a/tests/docker/dockerfiles/centos8.docker +++ b/tests/docker/dockerfiles/centos8.docker @@ -130,8 +130,8 @@ RUN dnf distro-sync -y && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" diff --git a/tests/docker/dockerfiles/debian-amd64-cross.docker b/tests/docker/dockerfiles/debian-amd64-cross.docker index 9047759e76..5e57309361 100644 --- a/tests/docker/dockerfiles/debian-amd64-cross.docker +++ b/tests/docker/dockerfiles/debian-amd64-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture amd64 && \ @@ -74,76 +75,76 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-x86-64-linux-gnu \ - gcc-x86-64-linux-gnu \ - libaio-dev:amd64 \ - libasan5:amd64 \ - libasound2-dev:amd64 \ - libattr1-dev:amd64 \ - libbpf-dev:amd64 \ - libbrlapi-dev:amd64 \ - libbz2-dev:amd64 \ - libc6-dev:amd64 \ - libcacard-dev:amd64 \ - libcap-ng-dev:amd64 \ - libcapstone-dev:amd64 \ - libcmocka-dev:amd64 \ - libcurl4-gnutls-dev:amd64 \ - libdaxctl-dev:amd64 \ - libdrm-dev:amd64 \ - libepoxy-dev:amd64 \ - libfdt-dev:amd64 \ - libffi-dev:amd64 \ - libfuse3-dev:amd64 \ - libgbm-dev:amd64 \ - libgcrypt20-dev:amd64 \ - libglib2.0-dev:amd64 \ - libglusterfs-dev:amd64 \ - libgnutls28-dev:amd64 \ - libgtk-3-dev:amd64 \ - libibumad-dev:amd64 \ - libibverbs-dev:amd64 \ - libiscsi-dev:amd64 \ - libjemalloc-dev:amd64 \ - libjpeg62-turbo-dev:amd64 \ - libjson-c-dev:amd64 \ - liblttng-ust-dev:amd64 \ - liblzo2-dev:amd64 \ - libncursesw5-dev:amd64 \ - libnfs-dev:amd64 \ - libnuma-dev:amd64 \ - libpam0g-dev:amd64 \ - libpixman-1-dev:amd64 \ - libpmem-dev:amd64 \ - libpng-dev:amd64 \ - libpulse-dev:amd64 \ - librbd-dev:amd64 \ - librdmacm-dev:amd64 \ - libsasl2-dev:amd64 \ - libsdl2-dev:amd64 \ - libsdl2-image-dev:amd64 \ - libseccomp-dev:amd64 \ - libselinux1-dev:amd64 \ - libslirp-dev:amd64 \ - libsnappy-dev:amd64 \ - libspice-server-dev:amd64 \ - libssh-gcrypt-dev:amd64 \ - libsystemd-dev:amd64 \ - libtasn1-6-dev:amd64 \ - libubsan1:amd64 \ - libudev-dev:amd64 \ - liburing-dev:amd64 \ - libusb-1.0-0-dev:amd64 \ - libusbredirhost-dev:amd64 \ - libvdeplug-dev:amd64 \ - libvirglrenderer-dev:amd64 \ - libvte-2.91-dev:amd64 \ - libxen-dev:amd64 \ - libzstd-dev:amd64 \ - nettle-dev:amd64 \ - systemtap-sdt-dev:amd64 \ - xfslibs-dev:amd64 \ - zlib1g-dev:amd64 && \ + g++-x86-64-linux-gnu \ + gcc-x86-64-linux-gnu \ + libaio-dev:amd64 \ + libasan5:amd64 \ + libasound2-dev:amd64 \ + libattr1-dev:amd64 \ + libbpf-dev:amd64 \ + libbrlapi-dev:amd64 \ + libbz2-dev:amd64 \ + libc6-dev:amd64 \ + libcacard-dev:amd64 \ + libcap-ng-dev:amd64 \ + libcapstone-dev:amd64 \ + libcmocka-dev:amd64 \ + libcurl4-gnutls-dev:amd64 \ + libdaxctl-dev:amd64 \ + libdrm-dev:amd64 \ + libepoxy-dev:amd64 \ + libfdt-dev:amd64 \ + libffi-dev:amd64 \ + libfuse3-dev:amd64 \ + libgbm-dev:amd64 \ + libgcrypt20-dev:amd64 \ + libglib2.0-dev:amd64 \ + libglusterfs-dev:amd64 \ + libgnutls28-dev:amd64 \ + libgtk-3-dev:amd64 \ + libibumad-dev:amd64 \ + libibverbs-dev:amd64 \ + libiscsi-dev:amd64 \ + libjemalloc-dev:amd64 \ + libjpeg62-turbo-dev:amd64 \ + libjson-c-dev:amd64 \ + liblttng-ust-dev:amd64 \ + liblzo2-dev:amd64 \ + libncursesw5-dev:amd64 \ + libnfs-dev:amd64 \ + libnuma-dev:amd64 \ + libpam0g-dev:amd64 \ + libpixman-1-dev:amd64 \ + libpmem-dev:amd64 \ + libpng-dev:amd64 \ + libpulse-dev:amd64 \ + librbd-dev:amd64 \ + librdmacm-dev:amd64 \ + libsasl2-dev:amd64 \ + libsdl2-dev:amd64 \ + libsdl2-image-dev:amd64 \ + libseccomp-dev:amd64 \ + libselinux1-dev:amd64 \ + libslirp-dev:amd64 \ + libsnappy-dev:amd64 \ + libspice-server-dev:amd64 \ + libssh-gcrypt-dev:amd64 \ + libsystemd-dev:amd64 \ + libtasn1-6-dev:amd64 \ + libubsan1:amd64 \ + libudev-dev:amd64 \ + liburing-dev:amd64 \ + libusb-1.0-0-dev:amd64 \ + libusbredirhost-dev:amd64 \ + libvdeplug-dev:amd64 \ + libvirglrenderer-dev:amd64 \ + libvte-2.91-dev:amd64 \ + libxen-dev:amd64 \ + libzstd-dev:amd64 \ + nettle-dev:amd64 \ + systemtap-sdt-dev:amd64 \ + xfslibs-dev:amd64 \ + zlib1g-dev:amd64 && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/debian-amd64.docker b/tests/docker/dockerfiles/debian-amd64.docker index a8b728ca64..bfeab01ee3 100644 --- a/tests/docker/dockerfiles/debian-amd64.docker +++ b/tests/docker/dockerfiles/debian-amd64.docker @@ -11,123 +11,124 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - clang \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - g++ \ - gcc \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libaio-dev \ - libasan5 \ - libasound2-dev \ - libattr1-dev \ - libbpf-dev \ - libbrlapi-dev \ - libbz2-dev \ - libc6-dev \ - libcacard-dev \ - libcap-ng-dev \ - libcapstone-dev \ - libcmocka-dev \ - libcurl4-gnutls-dev \ - libdaxctl-dev \ - libdrm-dev \ - libepoxy-dev \ - libfdt-dev \ - libffi-dev \ - libfuse3-dev \ - libgbm-dev \ - libgcrypt20-dev \ - libglib2.0-dev \ - libglusterfs-dev \ - libgnutls28-dev \ - libgtk-3-dev \ - libibumad-dev \ - libibverbs-dev \ - libiscsi-dev \ - libjemalloc-dev \ - libjpeg62-turbo-dev \ - libjson-c-dev \ - liblttng-ust-dev \ - liblzo2-dev \ - libncursesw5-dev \ - libnfs-dev \ - libnuma-dev \ - libpam0g-dev \ - libpcre2-dev \ - libpixman-1-dev \ - libpmem-dev \ - libpng-dev \ - libpulse-dev \ - librbd-dev \ - librdmacm-dev \ - libsasl2-dev \ - libsdl2-dev \ - libsdl2-image-dev \ - libseccomp-dev \ - libselinux1-dev \ - libslirp-dev \ - libsnappy-dev \ - libspice-protocol-dev \ - libspice-server-dev \ - libssh-gcrypt-dev \ - libsystemd-dev \ - libtasn1-6-dev \ - libubsan1 \ - libudev-dev \ - liburing-dev \ - libusb-1.0-0-dev \ - libusbredirhost-dev \ - libvdeplug-dev \ - libvirglrenderer-dev \ - libvte-2.91-dev \ - libxen-dev \ - libzstd-dev \ - llvm \ - locales \ - make \ - meson \ - multipath-tools \ - ncat \ - nettle-dev \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - systemtap-sdt-dev \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo \ - xfslibs-dev \ - zlib1g-dev && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + clang \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + g++ \ + gcc \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libaio-dev \ + libasan5 \ + libasound2-dev \ + libattr1-dev \ + libbpf-dev \ + libbrlapi-dev \ + libbz2-dev \ + libc6-dev \ + libcacard-dev \ + libcap-ng-dev \ + libcapstone-dev \ + libcmocka-dev \ + libcurl4-gnutls-dev \ + libdaxctl-dev \ + libdrm-dev \ + libepoxy-dev \ + libfdt-dev \ + libffi-dev \ + libfuse3-dev \ + libgbm-dev \ + libgcrypt20-dev \ + libglib2.0-dev \ + libglusterfs-dev \ + libgnutls28-dev \ + libgtk-3-dev \ + libibumad-dev \ + libibverbs-dev \ + libiscsi-dev \ + libjemalloc-dev \ + libjpeg62-turbo-dev \ + libjson-c-dev \ + liblttng-ust-dev \ + liblzo2-dev \ + libncursesw5-dev \ + libnfs-dev \ + libnuma-dev \ + libpam0g-dev \ + libpcre2-dev \ + libpixman-1-dev \ + libpmem-dev \ + libpng-dev \ + libpulse-dev \ + librbd-dev \ + librdmacm-dev \ + libsasl2-dev \ + libsdl2-dev \ + libsdl2-image-dev \ + libseccomp-dev \ + libselinux1-dev \ + libslirp-dev \ + libsnappy-dev \ + libsndio-dev \ + libspice-protocol-dev \ + libspice-server-dev \ + libssh-gcrypt-dev \ + libsystemd-dev \ + libtasn1-6-dev \ + libubsan1 \ + libudev-dev \ + liburing-dev \ + libusb-1.0-0-dev \ + libusbredirhost-dev \ + libvdeplug-dev \ + libvirglrenderer-dev \ + libvte-2.91-dev \ + libxen-dev \ + libzstd-dev \ + llvm \ + locales \ + make \ + meson \ + multipath-tools \ + ncat \ + nettle-dev \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + systemtap-sdt-dev \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo \ + xfslibs-dev \ + zlib1g-dev && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ @@ -140,11 +141,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" # netmap/cscope/global RUN DEBIAN_FRONTEND=noninteractive eatmydata \ apt install -y --no-install-recommends \ diff --git a/tests/docker/dockerfiles/debian-arm64-cross.docker b/tests/docker/dockerfiles/debian-arm64-cross.docker index 17a5709245..98885bd0ee 100644 --- a/tests/docker/dockerfiles/debian-arm64-cross.docker +++ b/tests/docker/dockerfiles/debian-arm64-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture arm64 && \ @@ -74,75 +75,75 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-aarch64-linux-gnu \ - gcc-aarch64-linux-gnu \ - libaio-dev:arm64 \ - libasan5:arm64 \ - libasound2-dev:arm64 \ - libattr1-dev:arm64 \ - libbpf-dev:arm64 \ - libbrlapi-dev:arm64 \ - libbz2-dev:arm64 \ - libc6-dev:arm64 \ - libcacard-dev:arm64 \ - libcap-ng-dev:arm64 \ - libcapstone-dev:arm64 \ - libcmocka-dev:arm64 \ - libcurl4-gnutls-dev:arm64 \ - libdaxctl-dev:arm64 \ - libdrm-dev:arm64 \ - libepoxy-dev:arm64 \ - libfdt-dev:arm64 \ - libffi-dev:arm64 \ - libfuse3-dev:arm64 \ - libgbm-dev:arm64 \ - libgcrypt20-dev:arm64 \ - libglib2.0-dev:arm64 \ - libglusterfs-dev:arm64 \ - libgnutls28-dev:arm64 \ - libgtk-3-dev:arm64 \ - libibumad-dev:arm64 \ - libibverbs-dev:arm64 \ - libiscsi-dev:arm64 \ - libjemalloc-dev:arm64 \ - libjpeg62-turbo-dev:arm64 \ - libjson-c-dev:arm64 \ - liblttng-ust-dev:arm64 \ - liblzo2-dev:arm64 \ - libncursesw5-dev:arm64 \ - libnfs-dev:arm64 \ - libnuma-dev:arm64 \ - libpam0g-dev:arm64 \ - libpixman-1-dev:arm64 \ - libpng-dev:arm64 \ - libpulse-dev:arm64 \ - librbd-dev:arm64 \ - librdmacm-dev:arm64 \ - libsasl2-dev:arm64 \ - libsdl2-dev:arm64 \ - libsdl2-image-dev:arm64 \ - libseccomp-dev:arm64 \ - libselinux1-dev:arm64 \ - libslirp-dev:arm64 \ - libsnappy-dev:arm64 \ - libspice-server-dev:arm64 \ - libssh-gcrypt-dev:arm64 \ - libsystemd-dev:arm64 \ - libtasn1-6-dev:arm64 \ - libubsan1:arm64 \ - libudev-dev:arm64 \ - liburing-dev:arm64 \ - libusb-1.0-0-dev:arm64 \ - libusbredirhost-dev:arm64 \ - libvdeplug-dev:arm64 \ - libvirglrenderer-dev:arm64 \ - libvte-2.91-dev:arm64 \ - libxen-dev:arm64 \ - libzstd-dev:arm64 \ - nettle-dev:arm64 \ - systemtap-sdt-dev:arm64 \ - xfslibs-dev:arm64 \ - zlib1g-dev:arm64 && \ + g++-aarch64-linux-gnu \ + gcc-aarch64-linux-gnu \ + libaio-dev:arm64 \ + libasan5:arm64 \ + libasound2-dev:arm64 \ + libattr1-dev:arm64 \ + libbpf-dev:arm64 \ + libbrlapi-dev:arm64 \ + libbz2-dev:arm64 \ + libc6-dev:arm64 \ + libcacard-dev:arm64 \ + libcap-ng-dev:arm64 \ + libcapstone-dev:arm64 \ + libcmocka-dev:arm64 \ + libcurl4-gnutls-dev:arm64 \ + libdaxctl-dev:arm64 \ + libdrm-dev:arm64 \ + libepoxy-dev:arm64 \ + libfdt-dev:arm64 \ + libffi-dev:arm64 \ + libfuse3-dev:arm64 \ + libgbm-dev:arm64 \ + libgcrypt20-dev:arm64 \ + libglib2.0-dev:arm64 \ + libglusterfs-dev:arm64 \ + libgnutls28-dev:arm64 \ + libgtk-3-dev:arm64 \ + libibumad-dev:arm64 \ + libibverbs-dev:arm64 \ + libiscsi-dev:arm64 \ + libjemalloc-dev:arm64 \ + libjpeg62-turbo-dev:arm64 \ + libjson-c-dev:arm64 \ + liblttng-ust-dev:arm64 \ + liblzo2-dev:arm64 \ + libncursesw5-dev:arm64 \ + libnfs-dev:arm64 \ + libnuma-dev:arm64 \ + libpam0g-dev:arm64 \ + libpixman-1-dev:arm64 \ + libpng-dev:arm64 \ + libpulse-dev:arm64 \ + librbd-dev:arm64 \ + librdmacm-dev:arm64 \ + libsasl2-dev:arm64 \ + libsdl2-dev:arm64 \ + libsdl2-image-dev:arm64 \ + libseccomp-dev:arm64 \ + libselinux1-dev:arm64 \ + libslirp-dev:arm64 \ + libsnappy-dev:arm64 \ + libspice-server-dev:arm64 \ + libssh-gcrypt-dev:arm64 \ + libsystemd-dev:arm64 \ + libtasn1-6-dev:arm64 \ + libubsan1:arm64 \ + libudev-dev:arm64 \ + liburing-dev:arm64 \ + libusb-1.0-0-dev:arm64 \ + libusbredirhost-dev:arm64 \ + libvdeplug-dev:arm64 \ + libvirglrenderer-dev:arm64 \ + libvte-2.91-dev:arm64 \ + libxen-dev:arm64 \ + libzstd-dev:arm64 \ + nettle-dev:arm64 \ + systemtap-sdt-dev:arm64 \ + xfslibs-dev:arm64 \ + zlib1g-dev:arm64 && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/debian-armel-cross.docker b/tests/docker/dockerfiles/debian-armel-cross.docker index 701fc70db0..d5c08714e4 100644 --- a/tests/docker/dockerfiles/debian-armel-cross.docker +++ b/tests/docker/dockerfiles/debian-armel-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture armel && \ @@ -74,74 +75,74 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-arm-linux-gnueabi \ - gcc-arm-linux-gnueabi \ - libaio-dev:armel \ - libasan5:armel \ - libasound2-dev:armel \ - libattr1-dev:armel \ - libbpf-dev:armel \ - libbrlapi-dev:armel \ - libbz2-dev:armel \ - libc6-dev:armel \ - libcacard-dev:armel \ - libcap-ng-dev:armel \ - libcapstone-dev:armel \ - libcmocka-dev:armel \ - libcurl4-gnutls-dev:armel \ - libdaxctl-dev:armel \ - libdrm-dev:armel \ - libepoxy-dev:armel \ - libfdt-dev:armel \ - libffi-dev:armel \ - libfuse3-dev:armel \ - libgbm-dev:armel \ - libgcrypt20-dev:armel \ - libglib2.0-dev:armel \ - libglusterfs-dev:armel \ - libgnutls28-dev:armel \ - libgtk-3-dev:armel \ - libibumad-dev:armel \ - libibverbs-dev:armel \ - libiscsi-dev:armel \ - libjemalloc-dev:armel \ - libjpeg62-turbo-dev:armel \ - libjson-c-dev:armel \ - liblttng-ust-dev:armel \ - liblzo2-dev:armel \ - libncursesw5-dev:armel \ - libnfs-dev:armel \ - libnuma-dev:armel \ - libpam0g-dev:armel \ - libpixman-1-dev:armel \ - libpng-dev:armel \ - libpulse-dev:armel \ - librbd-dev:armel \ - librdmacm-dev:armel \ - libsasl2-dev:armel \ - libsdl2-dev:armel \ - libsdl2-image-dev:armel \ - libseccomp-dev:armel \ - libselinux1-dev:armel \ - libslirp-dev:armel \ - libsnappy-dev:armel \ - libspice-server-dev:armel \ - libssh-gcrypt-dev:armel \ - libsystemd-dev:armel \ - libtasn1-6-dev:armel \ - libubsan1:armel \ - libudev-dev:armel \ - liburing-dev:armel \ - libusb-1.0-0-dev:armel \ - libusbredirhost-dev:armel \ - libvdeplug-dev:armel \ - libvirglrenderer-dev:armel \ - libvte-2.91-dev:armel \ - libzstd-dev:armel \ - nettle-dev:armel \ - systemtap-sdt-dev:armel \ - xfslibs-dev:armel \ - zlib1g-dev:armel && \ + g++-arm-linux-gnueabi \ + gcc-arm-linux-gnueabi \ + libaio-dev:armel \ + libasan5:armel \ + libasound2-dev:armel \ + libattr1-dev:armel \ + libbpf-dev:armel \ + libbrlapi-dev:armel \ + libbz2-dev:armel \ + libc6-dev:armel \ + libcacard-dev:armel \ + libcap-ng-dev:armel \ + libcapstone-dev:armel \ + libcmocka-dev:armel \ + libcurl4-gnutls-dev:armel \ + libdaxctl-dev:armel \ + libdrm-dev:armel \ + libepoxy-dev:armel \ + libfdt-dev:armel \ + libffi-dev:armel \ + libfuse3-dev:armel \ + libgbm-dev:armel \ + libgcrypt20-dev:armel \ + libglib2.0-dev:armel \ + libglusterfs-dev:armel \ + libgnutls28-dev:armel \ + libgtk-3-dev:armel \ + libibumad-dev:armel \ + libibverbs-dev:armel \ + libiscsi-dev:armel \ + libjemalloc-dev:armel \ + libjpeg62-turbo-dev:armel \ + libjson-c-dev:armel \ + liblttng-ust-dev:armel \ + liblzo2-dev:armel \ + libncursesw5-dev:armel \ + libnfs-dev:armel \ + libnuma-dev:armel \ + libpam0g-dev:armel \ + libpixman-1-dev:armel \ + libpng-dev:armel \ + libpulse-dev:armel \ + librbd-dev:armel \ + librdmacm-dev:armel \ + libsasl2-dev:armel \ + libsdl2-dev:armel \ + libsdl2-image-dev:armel \ + libseccomp-dev:armel \ + libselinux1-dev:armel \ + libslirp-dev:armel \ + libsnappy-dev:armel \ + libspice-server-dev:armel \ + libssh-gcrypt-dev:armel \ + libsystemd-dev:armel \ + libtasn1-6-dev:armel \ + libubsan1:armel \ + libudev-dev:armel \ + liburing-dev:armel \ + libusb-1.0-0-dev:armel \ + libusbredirhost-dev:armel \ + libvdeplug-dev:armel \ + libvirglrenderer-dev:armel \ + libvte-2.91-dev:armel \ + libzstd-dev:armel \ + nettle-dev:armel \ + systemtap-sdt-dev:armel \ + xfslibs-dev:armel \ + zlib1g-dev:armel && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/debian-armhf-cross.docker b/tests/docker/dockerfiles/debian-armhf-cross.docker index 5a11fe3900..471444fcf4 100644 --- a/tests/docker/dockerfiles/debian-armhf-cross.docker +++ b/tests/docker/dockerfiles/debian-armhf-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture armhf && \ @@ -74,75 +75,75 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-arm-linux-gnueabihf \ - gcc-arm-linux-gnueabihf \ - libaio-dev:armhf \ - libasan5:armhf \ - libasound2-dev:armhf \ - libattr1-dev:armhf \ - libbpf-dev:armhf \ - libbrlapi-dev:armhf \ - libbz2-dev:armhf \ - libc6-dev:armhf \ - libcacard-dev:armhf \ - libcap-ng-dev:armhf \ - libcapstone-dev:armhf \ - libcmocka-dev:armhf \ - libcurl4-gnutls-dev:armhf \ - libdaxctl-dev:armhf \ - libdrm-dev:armhf \ - libepoxy-dev:armhf \ - libfdt-dev:armhf \ - libffi-dev:armhf \ - libfuse3-dev:armhf \ - libgbm-dev:armhf \ - libgcrypt20-dev:armhf \ - libglib2.0-dev:armhf \ - libglusterfs-dev:armhf \ - libgnutls28-dev:armhf \ - libgtk-3-dev:armhf \ - libibumad-dev:armhf \ - libibverbs-dev:armhf \ - libiscsi-dev:armhf \ - libjemalloc-dev:armhf \ - libjpeg62-turbo-dev:armhf \ - libjson-c-dev:armhf \ - liblttng-ust-dev:armhf \ - liblzo2-dev:armhf \ - libncursesw5-dev:armhf \ - libnfs-dev:armhf \ - libnuma-dev:armhf \ - libpam0g-dev:armhf \ - libpixman-1-dev:armhf \ - libpng-dev:armhf \ - libpulse-dev:armhf \ - librbd-dev:armhf \ - librdmacm-dev:armhf \ - libsasl2-dev:armhf \ - libsdl2-dev:armhf \ - libsdl2-image-dev:armhf \ - libseccomp-dev:armhf \ - libselinux1-dev:armhf \ - libslirp-dev:armhf \ - libsnappy-dev:armhf \ - libspice-server-dev:armhf \ - libssh-gcrypt-dev:armhf \ - libsystemd-dev:armhf \ - libtasn1-6-dev:armhf \ - libubsan1:armhf \ - libudev-dev:armhf \ - liburing-dev:armhf \ - libusb-1.0-0-dev:armhf \ - libusbredirhost-dev:armhf \ - libvdeplug-dev:armhf \ - libvirglrenderer-dev:armhf \ - libvte-2.91-dev:armhf \ - libxen-dev:armhf \ - libzstd-dev:armhf \ - nettle-dev:armhf \ - systemtap-sdt-dev:armhf \ - xfslibs-dev:armhf \ - zlib1g-dev:armhf && \ + g++-arm-linux-gnueabihf \ + gcc-arm-linux-gnueabihf \ + libaio-dev:armhf \ + libasan5:armhf \ + libasound2-dev:armhf \ + libattr1-dev:armhf \ + libbpf-dev:armhf \ + libbrlapi-dev:armhf \ + libbz2-dev:armhf \ + libc6-dev:armhf \ + libcacard-dev:armhf \ + libcap-ng-dev:armhf \ + libcapstone-dev:armhf \ + libcmocka-dev:armhf \ + libcurl4-gnutls-dev:armhf \ + libdaxctl-dev:armhf \ + libdrm-dev:armhf \ + libepoxy-dev:armhf \ + libfdt-dev:armhf \ + libffi-dev:armhf \ + libfuse3-dev:armhf \ + libgbm-dev:armhf \ + libgcrypt20-dev:armhf \ + libglib2.0-dev:armhf \ + libglusterfs-dev:armhf \ + libgnutls28-dev:armhf \ + libgtk-3-dev:armhf \ + libibumad-dev:armhf \ + libibverbs-dev:armhf \ + libiscsi-dev:armhf \ + libjemalloc-dev:armhf \ + libjpeg62-turbo-dev:armhf \ + libjson-c-dev:armhf \ + liblttng-ust-dev:armhf \ + liblzo2-dev:armhf \ + libncursesw5-dev:armhf \ + libnfs-dev:armhf \ + libnuma-dev:armhf \ + libpam0g-dev:armhf \ + libpixman-1-dev:armhf \ + libpng-dev:armhf \ + libpulse-dev:armhf \ + librbd-dev:armhf \ + librdmacm-dev:armhf \ + libsasl2-dev:armhf \ + libsdl2-dev:armhf \ + libsdl2-image-dev:armhf \ + libseccomp-dev:armhf \ + libselinux1-dev:armhf \ + libslirp-dev:armhf \ + libsnappy-dev:armhf \ + libspice-server-dev:armhf \ + libssh-gcrypt-dev:armhf \ + libsystemd-dev:armhf \ + libtasn1-6-dev:armhf \ + libubsan1:armhf \ + libudev-dev:armhf \ + liburing-dev:armhf \ + libusb-1.0-0-dev:armhf \ + libusbredirhost-dev:armhf \ + libvdeplug-dev:armhf \ + libvirglrenderer-dev:armhf \ + libvte-2.91-dev:armhf \ + libxen-dev:armhf \ + libzstd-dev:armhf \ + nettle-dev:armhf \ + systemtap-sdt-dev:armhf \ + xfslibs-dev:armhf \ + zlib1g-dev:armhf && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/debian-mips64el-cross.docker b/tests/docker/dockerfiles/debian-mips64el-cross.docker index 9b90a4d6ff..15b0224b76 100644 --- a/tests/docker/dockerfiles/debian-mips64el-cross.docker +++ b/tests/docker/dockerfiles/debian-mips64el-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture mips64el && \ @@ -74,72 +75,72 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-mips64el-linux-gnuabi64 \ - gcc-mips64el-linux-gnuabi64 \ - libaio-dev:mips64el \ - libasound2-dev:mips64el \ - libattr1-dev:mips64el \ - libbpf-dev:mips64el \ - libbrlapi-dev:mips64el \ - libbz2-dev:mips64el \ - libc6-dev:mips64el \ - libcacard-dev:mips64el \ - libcap-ng-dev:mips64el \ - libcapstone-dev:mips64el \ - libcmocka-dev:mips64el \ - libcurl4-gnutls-dev:mips64el \ - libdaxctl-dev:mips64el \ - libdrm-dev:mips64el \ - libepoxy-dev:mips64el \ - libfdt-dev:mips64el \ - libffi-dev:mips64el \ - libfuse3-dev:mips64el \ - libgbm-dev:mips64el \ - libgcrypt20-dev:mips64el \ - libglib2.0-dev:mips64el \ - libglusterfs-dev:mips64el \ - libgnutls28-dev:mips64el \ - libgtk-3-dev:mips64el \ - libibumad-dev:mips64el \ - libibverbs-dev:mips64el \ - libiscsi-dev:mips64el \ - libjemalloc-dev:mips64el \ - libjpeg62-turbo-dev:mips64el \ - libjson-c-dev:mips64el \ - liblttng-ust-dev:mips64el \ - liblzo2-dev:mips64el \ - libncursesw5-dev:mips64el \ - libnfs-dev:mips64el \ - libnuma-dev:mips64el \ - libpam0g-dev:mips64el \ - libpixman-1-dev:mips64el \ - libpng-dev:mips64el \ - libpulse-dev:mips64el \ - librbd-dev:mips64el \ - librdmacm-dev:mips64el \ - libsasl2-dev:mips64el \ - libsdl2-dev:mips64el \ - libsdl2-image-dev:mips64el \ - libseccomp-dev:mips64el \ - libselinux1-dev:mips64el \ - libslirp-dev:mips64el \ - libsnappy-dev:mips64el \ - libspice-server-dev:mips64el \ - libssh-gcrypt-dev:mips64el \ - libsystemd-dev:mips64el \ - libtasn1-6-dev:mips64el \ - libudev-dev:mips64el \ - liburing-dev:mips64el \ - libusb-1.0-0-dev:mips64el \ - libusbredirhost-dev:mips64el \ - libvdeplug-dev:mips64el \ - libvirglrenderer-dev:mips64el \ - libvte-2.91-dev:mips64el \ - libzstd-dev:mips64el \ - nettle-dev:mips64el \ - systemtap-sdt-dev:mips64el \ - xfslibs-dev:mips64el \ - zlib1g-dev:mips64el && \ + g++-mips64el-linux-gnuabi64 \ + gcc-mips64el-linux-gnuabi64 \ + libaio-dev:mips64el \ + libasound2-dev:mips64el \ + libattr1-dev:mips64el \ + libbpf-dev:mips64el \ + libbrlapi-dev:mips64el \ + libbz2-dev:mips64el \ + libc6-dev:mips64el \ + libcacard-dev:mips64el \ + libcap-ng-dev:mips64el \ + libcapstone-dev:mips64el \ + libcmocka-dev:mips64el \ + libcurl4-gnutls-dev:mips64el \ + libdaxctl-dev:mips64el \ + libdrm-dev:mips64el \ + libepoxy-dev:mips64el \ + libfdt-dev:mips64el \ + libffi-dev:mips64el \ + libfuse3-dev:mips64el \ + libgbm-dev:mips64el \ + libgcrypt20-dev:mips64el \ + libglib2.0-dev:mips64el \ + libglusterfs-dev:mips64el \ + libgnutls28-dev:mips64el \ + libgtk-3-dev:mips64el \ + libibumad-dev:mips64el \ + libibverbs-dev:mips64el \ + libiscsi-dev:mips64el \ + libjemalloc-dev:mips64el \ + libjpeg62-turbo-dev:mips64el \ + libjson-c-dev:mips64el \ + liblttng-ust-dev:mips64el \ + liblzo2-dev:mips64el \ + libncursesw5-dev:mips64el \ + libnfs-dev:mips64el \ + libnuma-dev:mips64el \ + libpam0g-dev:mips64el \ + libpixman-1-dev:mips64el \ + libpng-dev:mips64el \ + libpulse-dev:mips64el \ + librbd-dev:mips64el \ + librdmacm-dev:mips64el \ + libsasl2-dev:mips64el \ + libsdl2-dev:mips64el \ + libsdl2-image-dev:mips64el \ + libseccomp-dev:mips64el \ + libselinux1-dev:mips64el \ + libslirp-dev:mips64el \ + libsnappy-dev:mips64el \ + libspice-server-dev:mips64el \ + libssh-gcrypt-dev:mips64el \ + libsystemd-dev:mips64el \ + libtasn1-6-dev:mips64el \ + libudev-dev:mips64el \ + liburing-dev:mips64el \ + libusb-1.0-0-dev:mips64el \ + libusbredirhost-dev:mips64el \ + libvdeplug-dev:mips64el \ + libvirglrenderer-dev:mips64el \ + libvte-2.91-dev:mips64el \ + libzstd-dev:mips64el \ + nettle-dev:mips64el \ + systemtap-sdt-dev:mips64el \ + xfslibs-dev:mips64el \ + zlib1g-dev:mips64el && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/debian-mipsel-cross.docker b/tests/docker/dockerfiles/debian-mipsel-cross.docker index 02feaf26cb..a5d3ca6e2f 100644 --- a/tests/docker/dockerfiles/debian-mipsel-cross.docker +++ b/tests/docker/dockerfiles/debian-mipsel-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture mipsel && \ @@ -74,72 +75,72 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-mipsel-linux-gnu \ - gcc-mipsel-linux-gnu \ - libaio-dev:mipsel \ - libasound2-dev:mipsel \ - libattr1-dev:mipsel \ - libbpf-dev:mipsel \ - libbrlapi-dev:mipsel \ - libbz2-dev:mipsel \ - libc6-dev:mipsel \ - libcacard-dev:mipsel \ - libcap-ng-dev:mipsel \ - libcapstone-dev:mipsel \ - libcmocka-dev:mipsel \ - libcurl4-gnutls-dev:mipsel \ - libdaxctl-dev:mipsel \ - libdrm-dev:mipsel \ - libepoxy-dev:mipsel \ - libfdt-dev:mipsel \ - libffi-dev:mipsel \ - libfuse3-dev:mipsel \ - libgbm-dev:mipsel \ - libgcrypt20-dev:mipsel \ - libglib2.0-dev:mipsel \ - libglusterfs-dev:mipsel \ - libgnutls28-dev:mipsel \ - libgtk-3-dev:mipsel \ - libibumad-dev:mipsel \ - libibverbs-dev:mipsel \ - libiscsi-dev:mipsel \ - libjemalloc-dev:mipsel \ - libjpeg62-turbo-dev:mipsel \ - libjson-c-dev:mipsel \ - liblttng-ust-dev:mipsel \ - liblzo2-dev:mipsel \ - libncursesw5-dev:mipsel \ - libnfs-dev:mipsel \ - libnuma-dev:mipsel \ - libpam0g-dev:mipsel \ - libpixman-1-dev:mipsel \ - libpng-dev:mipsel \ - libpulse-dev:mipsel \ - librbd-dev:mipsel \ - librdmacm-dev:mipsel \ - libsasl2-dev:mipsel \ - libsdl2-dev:mipsel \ - libsdl2-image-dev:mipsel \ - libseccomp-dev:mipsel \ - libselinux1-dev:mipsel \ - libslirp-dev:mipsel \ - libsnappy-dev:mipsel \ - libspice-server-dev:mipsel \ - libssh-gcrypt-dev:mipsel \ - libsystemd-dev:mipsel \ - libtasn1-6-dev:mipsel \ - libudev-dev:mipsel \ - liburing-dev:mipsel \ - libusb-1.0-0-dev:mipsel \ - libusbredirhost-dev:mipsel \ - libvdeplug-dev:mipsel \ - libvirglrenderer-dev:mipsel \ - libvte-2.91-dev:mipsel \ - libzstd-dev:mipsel \ - nettle-dev:mipsel \ - systemtap-sdt-dev:mipsel \ - xfslibs-dev:mipsel \ - zlib1g-dev:mipsel && \ + g++-mipsel-linux-gnu \ + gcc-mipsel-linux-gnu \ + libaio-dev:mipsel \ + libasound2-dev:mipsel \ + libattr1-dev:mipsel \ + libbpf-dev:mipsel \ + libbrlapi-dev:mipsel \ + libbz2-dev:mipsel \ + libc6-dev:mipsel \ + libcacard-dev:mipsel \ + libcap-ng-dev:mipsel \ + libcapstone-dev:mipsel \ + libcmocka-dev:mipsel \ + libcurl4-gnutls-dev:mipsel \ + libdaxctl-dev:mipsel \ + libdrm-dev:mipsel \ + libepoxy-dev:mipsel \ + libfdt-dev:mipsel \ + libffi-dev:mipsel \ + libfuse3-dev:mipsel \ + libgbm-dev:mipsel \ + libgcrypt20-dev:mipsel \ + libglib2.0-dev:mipsel \ + libglusterfs-dev:mipsel \ + libgnutls28-dev:mipsel \ + libgtk-3-dev:mipsel \ + libibumad-dev:mipsel \ + libibverbs-dev:mipsel \ + libiscsi-dev:mipsel \ + libjemalloc-dev:mipsel \ + libjpeg62-turbo-dev:mipsel \ + libjson-c-dev:mipsel \ + liblttng-ust-dev:mipsel \ + liblzo2-dev:mipsel \ + libncursesw5-dev:mipsel \ + libnfs-dev:mipsel \ + libnuma-dev:mipsel \ + libpam0g-dev:mipsel \ + libpixman-1-dev:mipsel \ + libpng-dev:mipsel \ + libpulse-dev:mipsel \ + librbd-dev:mipsel \ + librdmacm-dev:mipsel \ + libsasl2-dev:mipsel \ + libsdl2-dev:mipsel \ + libsdl2-image-dev:mipsel \ + libseccomp-dev:mipsel \ + libselinux1-dev:mipsel \ + libslirp-dev:mipsel \ + libsnappy-dev:mipsel \ + libspice-server-dev:mipsel \ + libssh-gcrypt-dev:mipsel \ + libsystemd-dev:mipsel \ + libtasn1-6-dev:mipsel \ + libudev-dev:mipsel \ + liburing-dev:mipsel \ + libusb-1.0-0-dev:mipsel \ + libusbredirhost-dev:mipsel \ + libvdeplug-dev:mipsel \ + libvirglrenderer-dev:mipsel \ + libvte-2.91-dev:mipsel \ + libzstd-dev:mipsel \ + nettle-dev:mipsel \ + systemtap-sdt-dev:mipsel \ + xfslibs-dev:mipsel \ + zlib1g-dev:mipsel && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/debian-ppc64el-cross.docker b/tests/docker/dockerfiles/debian-ppc64el-cross.docker index 97d3872ee2..d2954e61f6 100644 --- a/tests/docker/dockerfiles/debian-ppc64el-cross.docker +++ b/tests/docker/dockerfiles/debian-ppc64el-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture ppc64el && \ @@ -74,74 +75,74 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-powerpc64le-linux-gnu \ - gcc-powerpc64le-linux-gnu \ - libaio-dev:ppc64el \ - libasan5:ppc64el \ - libasound2-dev:ppc64el \ - libattr1-dev:ppc64el \ - libbpf-dev:ppc64el \ - libbrlapi-dev:ppc64el \ - libbz2-dev:ppc64el \ - libc6-dev:ppc64el \ - libcacard-dev:ppc64el \ - libcap-ng-dev:ppc64el \ - libcapstone-dev:ppc64el \ - libcmocka-dev:ppc64el \ - libcurl4-gnutls-dev:ppc64el \ - libdaxctl-dev:ppc64el \ - libdrm-dev:ppc64el \ - libepoxy-dev:ppc64el \ - libfdt-dev:ppc64el \ - libffi-dev:ppc64el \ - libfuse3-dev:ppc64el \ - libgbm-dev:ppc64el \ - libgcrypt20-dev:ppc64el \ - libglib2.0-dev:ppc64el \ - libglusterfs-dev:ppc64el \ - libgnutls28-dev:ppc64el \ - libgtk-3-dev:ppc64el \ - libibumad-dev:ppc64el \ - libibverbs-dev:ppc64el \ - libiscsi-dev:ppc64el \ - libjemalloc-dev:ppc64el \ - libjpeg62-turbo-dev:ppc64el \ - libjson-c-dev:ppc64el \ - liblttng-ust-dev:ppc64el \ - liblzo2-dev:ppc64el \ - libncursesw5-dev:ppc64el \ - libnfs-dev:ppc64el \ - libnuma-dev:ppc64el \ - libpam0g-dev:ppc64el \ - libpixman-1-dev:ppc64el \ - libpng-dev:ppc64el \ - libpulse-dev:ppc64el \ - librbd-dev:ppc64el \ - librdmacm-dev:ppc64el \ - libsasl2-dev:ppc64el \ - libsdl2-dev:ppc64el \ - libsdl2-image-dev:ppc64el \ - libseccomp-dev:ppc64el \ - libselinux1-dev:ppc64el \ - libslirp-dev:ppc64el \ - libsnappy-dev:ppc64el \ - libspice-server-dev:ppc64el \ - libssh-gcrypt-dev:ppc64el \ - libsystemd-dev:ppc64el \ - libtasn1-6-dev:ppc64el \ - libubsan1:ppc64el \ - libudev-dev:ppc64el \ - liburing-dev:ppc64el \ - libusb-1.0-0-dev:ppc64el \ - libusbredirhost-dev:ppc64el \ - libvdeplug-dev:ppc64el \ - libvirglrenderer-dev:ppc64el \ - libvte-2.91-dev:ppc64el \ - libzstd-dev:ppc64el \ - nettle-dev:ppc64el \ - systemtap-sdt-dev:ppc64el \ - xfslibs-dev:ppc64el \ - zlib1g-dev:ppc64el && \ + g++-powerpc64le-linux-gnu \ + gcc-powerpc64le-linux-gnu \ + libaio-dev:ppc64el \ + libasan5:ppc64el \ + libasound2-dev:ppc64el \ + libattr1-dev:ppc64el \ + libbpf-dev:ppc64el \ + libbrlapi-dev:ppc64el \ + libbz2-dev:ppc64el \ + libc6-dev:ppc64el \ + libcacard-dev:ppc64el \ + libcap-ng-dev:ppc64el \ + libcapstone-dev:ppc64el \ + libcmocka-dev:ppc64el \ + libcurl4-gnutls-dev:ppc64el \ + libdaxctl-dev:ppc64el \ + libdrm-dev:ppc64el \ + libepoxy-dev:ppc64el \ + libfdt-dev:ppc64el \ + libffi-dev:ppc64el \ + libfuse3-dev:ppc64el \ + libgbm-dev:ppc64el \ + libgcrypt20-dev:ppc64el \ + libglib2.0-dev:ppc64el \ + libglusterfs-dev:ppc64el \ + libgnutls28-dev:ppc64el \ + libgtk-3-dev:ppc64el \ + libibumad-dev:ppc64el \ + libibverbs-dev:ppc64el \ + libiscsi-dev:ppc64el \ + libjemalloc-dev:ppc64el \ + libjpeg62-turbo-dev:ppc64el \ + libjson-c-dev:ppc64el \ + liblttng-ust-dev:ppc64el \ + liblzo2-dev:ppc64el \ + libncursesw5-dev:ppc64el \ + libnfs-dev:ppc64el \ + libnuma-dev:ppc64el \ + libpam0g-dev:ppc64el \ + libpixman-1-dev:ppc64el \ + libpng-dev:ppc64el \ + libpulse-dev:ppc64el \ + librbd-dev:ppc64el \ + librdmacm-dev:ppc64el \ + libsasl2-dev:ppc64el \ + libsdl2-dev:ppc64el \ + libsdl2-image-dev:ppc64el \ + libseccomp-dev:ppc64el \ + libselinux1-dev:ppc64el \ + libslirp-dev:ppc64el \ + libsnappy-dev:ppc64el \ + libspice-server-dev:ppc64el \ + libssh-gcrypt-dev:ppc64el \ + libsystemd-dev:ppc64el \ + libtasn1-6-dev:ppc64el \ + libubsan1:ppc64el \ + libudev-dev:ppc64el \ + liburing-dev:ppc64el \ + libusb-1.0-0-dev:ppc64el \ + libusbredirhost-dev:ppc64el \ + libvdeplug-dev:ppc64el \ + libvirglrenderer-dev:ppc64el \ + libvte-2.91-dev:ppc64el \ + libzstd-dev:ppc64el \ + nettle-dev:ppc64el \ + systemtap-sdt-dev:ppc64el \ + xfslibs-dev:ppc64el \ + zlib1g-dev:ppc64el && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/debian-s390x-cross.docker b/tests/docker/dockerfiles/debian-s390x-cross.docker index 95585e9e56..d43ce16317 100644 --- a/tests/docker/dockerfiles/debian-s390x-cross.docker +++ b/tests/docker/dockerfiles/debian-s390x-cross.docker @@ -11,62 +11,63 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdextrautils \ - bzip2 \ - ca-certificates \ - ccache \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libglib2.0-dev \ - libpcre2-dev \ - libspice-protocol-dev \ - llvm \ - locales \ - make \ - meson \ - ncat \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo && \ + bash \ + bc \ + bison \ + bsdextrautils \ + bzip2 \ + ca-certificates \ + ccache \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libglib2.0-dev \ + libpcre2-dev \ + libsndio-dev \ + libspice-protocol-dev \ + llvm \ + locales \ + make \ + meson \ + ncat \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ dpkg-reconfigure locales +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" RUN export DEBIAN_FRONTEND=noninteractive && \ dpkg --add-architecture s390x && \ @@ -74,73 +75,73 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y dpkg-dev && \ eatmydata apt-get install --no-install-recommends -y \ - g++-s390x-linux-gnu \ - gcc-s390x-linux-gnu \ - libaio-dev:s390x \ - libasan5:s390x \ - libasound2-dev:s390x \ - libattr1-dev:s390x \ - libbpf-dev:s390x \ - libbrlapi-dev:s390x \ - libbz2-dev:s390x \ - libc6-dev:s390x \ - libcacard-dev:s390x \ - libcap-ng-dev:s390x \ - libcapstone-dev:s390x \ - libcmocka-dev:s390x \ - libcurl4-gnutls-dev:s390x \ - libdaxctl-dev:s390x \ - libdrm-dev:s390x \ - libepoxy-dev:s390x \ - libfdt-dev:s390x \ - libffi-dev:s390x \ - libfuse3-dev:s390x \ - libgbm-dev:s390x \ - libgcrypt20-dev:s390x \ - libglib2.0-dev:s390x \ - libglusterfs-dev:s390x \ - libgnutls28-dev:s390x \ - libgtk-3-dev:s390x \ - libibumad-dev:s390x \ - libibverbs-dev:s390x \ - libiscsi-dev:s390x \ - libjemalloc-dev:s390x \ - libjpeg62-turbo-dev:s390x \ - libjson-c-dev:s390x \ - liblttng-ust-dev:s390x \ - liblzo2-dev:s390x \ - libncursesw5-dev:s390x \ - libnfs-dev:s390x \ - libnuma-dev:s390x \ - libpam0g-dev:s390x \ - libpixman-1-dev:s390x \ - libpng-dev:s390x \ - libpulse-dev:s390x \ - librbd-dev:s390x \ - librdmacm-dev:s390x \ - libsasl2-dev:s390x \ - libsdl2-dev:s390x \ - libsdl2-image-dev:s390x \ - libseccomp-dev:s390x \ - libselinux1-dev:s390x \ - libslirp-dev:s390x \ - libsnappy-dev:s390x \ - libssh-gcrypt-dev:s390x \ - libsystemd-dev:s390x \ - libtasn1-6-dev:s390x \ - libubsan1:s390x \ - libudev-dev:s390x \ - liburing-dev:s390x \ - libusb-1.0-0-dev:s390x \ - libusbredirhost-dev:s390x \ - libvdeplug-dev:s390x \ - libvirglrenderer-dev:s390x \ - libvte-2.91-dev:s390x \ - libzstd-dev:s390x \ - nettle-dev:s390x \ - systemtap-sdt-dev:s390x \ - xfslibs-dev:s390x \ - zlib1g-dev:s390x && \ + g++-s390x-linux-gnu \ + gcc-s390x-linux-gnu \ + libaio-dev:s390x \ + libasan5:s390x \ + libasound2-dev:s390x \ + libattr1-dev:s390x \ + libbpf-dev:s390x \ + libbrlapi-dev:s390x \ + libbz2-dev:s390x \ + libc6-dev:s390x \ + libcacard-dev:s390x \ + libcap-ng-dev:s390x \ + libcapstone-dev:s390x \ + libcmocka-dev:s390x \ + libcurl4-gnutls-dev:s390x \ + libdaxctl-dev:s390x \ + libdrm-dev:s390x \ + libepoxy-dev:s390x \ + libfdt-dev:s390x \ + libffi-dev:s390x \ + libfuse3-dev:s390x \ + libgbm-dev:s390x \ + libgcrypt20-dev:s390x \ + libglib2.0-dev:s390x \ + libglusterfs-dev:s390x \ + libgnutls28-dev:s390x \ + libgtk-3-dev:s390x \ + libibumad-dev:s390x \ + libibverbs-dev:s390x \ + libiscsi-dev:s390x \ + libjemalloc-dev:s390x \ + libjpeg62-turbo-dev:s390x \ + libjson-c-dev:s390x \ + liblttng-ust-dev:s390x \ + liblzo2-dev:s390x \ + libncursesw5-dev:s390x \ + libnfs-dev:s390x \ + libnuma-dev:s390x \ + libpam0g-dev:s390x \ + libpixman-1-dev:s390x \ + libpng-dev:s390x \ + libpulse-dev:s390x \ + librbd-dev:s390x \ + librdmacm-dev:s390x \ + libsasl2-dev:s390x \ + libsdl2-dev:s390x \ + libsdl2-image-dev:s390x \ + libseccomp-dev:s390x \ + libselinux1-dev:s390x \ + libslirp-dev:s390x \ + libsnappy-dev:s390x \ + libssh-gcrypt-dev:s390x \ + libsystemd-dev:s390x \ + libtasn1-6-dev:s390x \ + libubsan1:s390x \ + libudev-dev:s390x \ + liburing-dev:s390x \ + libusb-1.0-0-dev:s390x \ + libusbredirhost-dev:s390x \ + libvdeplug-dev:s390x \ + libvirglrenderer-dev:s390x \ + libvte-2.91-dev:s390x \ + libzstd-dev:s390x \ + nettle-dev:s390x \ + systemtap-sdt-dev:s390x \ + xfslibs-dev:s390x \ + zlib1g-dev:s390x && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ mkdir -p /usr/local/share/meson/cross && \ diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker index fe84166ca1..d200c7fc10 100644 --- a/tests/docker/dockerfiles/fedora.docker +++ b/tests/docker/dockerfiles/fedora.docker @@ -18,120 +18,120 @@ exec "$@"' > /usr/bin/nosync && \ chmod +x /usr/bin/nosync && \ nosync dnf update -y && \ nosync dnf install -y \ - SDL2-devel \ - SDL2_image-devel \ - alsa-lib-devel \ - bash \ - bc \ - bison \ - brlapi-devel \ - bzip2 \ - bzip2-devel \ - ca-certificates \ - capstone-devel \ - ccache \ - clang \ - ctags \ - cyrus-sasl-devel \ - daxctl-devel \ - dbus-daemon \ - device-mapper-multipath-devel \ - diffutils \ - findutils \ - flex \ - fuse3-devel \ - gcc \ - gcc-c++ \ - gcovr \ - genisoimage \ - gettext \ - git \ - glib2-devel \ - glib2-static \ - glibc-langpack-en \ - glibc-static \ - glusterfs-api-devel \ - gnutls-devel \ - gtk3-devel \ - hostname \ - jemalloc-devel \ - json-c-devel \ - libaio-devel \ - libasan \ - libattr-devel \ - libbpf-devel \ - libcacard-devel \ - libcap-ng-devel \ - libcmocka-devel \ - libcurl-devel \ - libdrm-devel \ - libepoxy-devel \ - libfdt-devel \ - libffi-devel \ - libgcrypt-devel \ - libiscsi-devel \ - libjpeg-devel \ - libnfs-devel \ - libpmem-devel \ - libpng-devel \ - librbd-devel \ - libseccomp-devel \ - libselinux-devel \ - libslirp-devel \ - libssh-devel \ - libtasn1-devel \ - libubsan \ - liburing-devel \ - libusbx-devel \ - libzstd-devel \ - llvm \ - lttng-ust-devel \ - lzo-devel \ - make \ - mesa-libgbm-devel \ - meson \ - ncurses-devel \ - nettle-devel \ - ninja-build \ - nmap-ncat \ - numactl-devel \ - openssh-clients \ - pam-devel \ - pcre-static \ - perl-base \ - pixman-devel \ - pkgconfig \ - pulseaudio-libs-devel \ - python3 \ - python3-PyYAML \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-sphinx \ - python3-sphinx_rtd_theme \ - rdma-core-devel \ - rpm \ - sed \ - snappy-devel \ - sparse \ - spice-protocol \ - spice-server-devel \ - systemd-devel \ - systemtap-sdt-devel \ - tar \ - tesseract \ - tesseract-langpack-eng \ - texinfo \ - usbredir-devel \ - util-linux \ - virglrenderer-devel \ - vte291-devel \ - which \ - xen-devel \ - xfsprogs-devel \ - zlib-devel \ - zlib-static && \ + SDL2-devel \ + SDL2_image-devel \ + alsa-lib-devel \ + bash \ + bc \ + bison \ + brlapi-devel \ + bzip2 \ + bzip2-devel \ + ca-certificates \ + capstone-devel \ + ccache \ + clang \ + ctags \ + cyrus-sasl-devel \ + daxctl-devel \ + dbus-daemon \ + device-mapper-multipath-devel \ + diffutils \ + findutils \ + flex \ + fuse3-devel \ + gcc \ + gcc-c++ \ + gcovr \ + genisoimage \ + gettext \ + git \ + glib2-devel \ + glib2-static \ + glibc-langpack-en \ + glibc-static \ + glusterfs-api-devel \ + gnutls-devel \ + gtk3-devel \ + hostname \ + jemalloc-devel \ + json-c-devel \ + libaio-devel \ + libasan \ + libattr-devel \ + libbpf-devel \ + libcacard-devel \ + libcap-ng-devel \ + libcmocka-devel \ + libcurl-devel \ + libdrm-devel \ + libepoxy-devel \ + libfdt-devel \ + libffi-devel \ + libgcrypt-devel \ + libiscsi-devel \ + libjpeg-devel \ + libnfs-devel \ + libpmem-devel \ + libpng-devel \ + librbd-devel \ + libseccomp-devel \ + libselinux-devel \ + libslirp-devel \ + libssh-devel \ + libtasn1-devel \ + libubsan \ + liburing-devel \ + libusbx-devel \ + libzstd-devel \ + llvm \ + lttng-ust-devel \ + lzo-devel \ + make \ + mesa-libgbm-devel \ + meson \ + ncurses-devel \ + nettle-devel \ + ninja-build \ + nmap-ncat \ + numactl-devel \ + openssh-clients \ + pam-devel \ + pcre-static \ + perl-base \ + pixman-devel \ + pkgconfig \ + pulseaudio-libs-devel \ + python3 \ + python3-PyYAML \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-sphinx \ + python3-sphinx_rtd_theme \ + rdma-core-devel \ + rpm \ + sed \ + snappy-devel \ + sparse \ + spice-protocol \ + spice-server-devel \ + systemd-devel \ + systemtap-sdt-devel \ + tar \ + tesseract \ + tesseract-langpack-eng \ + texinfo \ + usbredir-devel \ + util-linux \ + virglrenderer-devel \ + vte291-devel \ + which \ + xen-devel \ + xfsprogs-devel \ + zlib-devel \ + zlib-static && \ nosync dnf autoremove -y && \ nosync dnf clean all -y && \ rpm -qa | sort > /packages.txt && \ @@ -142,8 +142,8 @@ exec "$@"' > /usr/bin/nosync && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \ ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" diff --git a/tests/docker/dockerfiles/opensuse-leap.docker b/tests/docker/dockerfiles/opensuse-leap.docker index d80064756f..4361b01464 100644 --- a/tests/docker/dockerfiles/opensuse-leap.docker +++ b/tests/docker/dockerfiles/opensuse-leap.docker @@ -104,6 +104,7 @@ RUN zypper update -y && \ rpm \ sed \ snappy-devel \ + sndio-devel \ sparse \ spice-protocol-devel \ systemd-devel \ @@ -132,8 +133,8 @@ RUN zypper update -y && \ RUN /usr/bin/pip3 install meson==0.56.0 +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" diff --git a/tests/docker/dockerfiles/ubuntu2004.docker b/tests/docker/dockerfiles/ubuntu2004.docker index 24594afc15..9417bca2fa 100644 --- a/tests/docker/dockerfiles/ubuntu2004.docker +++ b/tests/docker/dockerfiles/ubuntu2004.docker @@ -11,122 +11,123 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y eatmydata && \ eatmydata apt-get dist-upgrade -y && \ eatmydata apt-get install --no-install-recommends -y \ - bash \ - bc \ - bison \ - bsdmainutils \ - bzip2 \ - ca-certificates \ - ccache \ - clang \ - dbus \ - debianutils \ - diffutils \ - exuberant-ctags \ - findutils \ - flex \ - g++ \ - gcc \ - gcovr \ - genisoimage \ - gettext \ - git \ - hostname \ - libaio-dev \ - libasan5 \ - libasound2-dev \ - libattr1-dev \ - libbrlapi-dev \ - libbz2-dev \ - libc6-dev \ - libcacard-dev \ - libcap-ng-dev \ - libcapstone-dev \ - libcmocka-dev \ - libcurl4-gnutls-dev \ - libdaxctl-dev \ - libdrm-dev \ - libepoxy-dev \ - libfdt-dev \ - libffi-dev \ - libfuse3-dev \ - libgbm-dev \ - libgcrypt20-dev \ - libglib2.0-dev \ - libglusterfs-dev \ - libgnutls28-dev \ - libgtk-3-dev \ - libibumad-dev \ - libibverbs-dev \ - libiscsi-dev \ - libjemalloc-dev \ - libjpeg-turbo8-dev \ - libjson-c-dev \ - liblttng-ust-dev \ - liblzo2-dev \ - libncursesw5-dev \ - libnfs-dev \ - libnuma-dev \ - libpam0g-dev \ - libpcre2-dev \ - libpixman-1-dev \ - libpmem-dev \ - libpng-dev \ - libpulse-dev \ - librbd-dev \ - librdmacm-dev \ - libsasl2-dev \ - libsdl2-dev \ - libsdl2-image-dev \ - libseccomp-dev \ - libselinux1-dev \ - libslirp-dev \ - libsnappy-dev \ - libspice-protocol-dev \ - libspice-server-dev \ - libssh-dev \ - libsystemd-dev \ - libtasn1-6-dev \ - libubsan1 \ - libudev-dev \ - libusb-1.0-0-dev \ - libusbredirhost-dev \ - libvdeplug-dev \ - libvirglrenderer-dev \ - libvte-2.91-dev \ - libxen-dev \ - libzstd-dev \ - llvm \ - locales \ - make \ - multipath-tools \ - ncat \ - nettle-dev \ - ninja-build \ - openssh-client \ - perl-base \ - pkgconf \ - python3 \ - python3-numpy \ - python3-opencv \ - python3-pillow \ - python3-pip \ - python3-setuptools \ - python3-sphinx \ - python3-sphinx-rtd-theme \ - python3-venv \ - python3-wheel \ - python3-yaml \ - rpm2cpio \ - sed \ - sparse \ - systemtap-sdt-dev \ - tar \ - tesseract-ocr \ - tesseract-ocr-eng \ - texinfo \ - xfslibs-dev \ - zlib1g-dev && \ + bash \ + bc \ + bison \ + bsdmainutils \ + bzip2 \ + ca-certificates \ + ccache \ + clang \ + dbus \ + debianutils \ + diffutils \ + exuberant-ctags \ + findutils \ + flex \ + g++ \ + gcc \ + gcovr \ + genisoimage \ + gettext \ + git \ + hostname \ + libaio-dev \ + libasan5 \ + libasound2-dev \ + libattr1-dev \ + libbrlapi-dev \ + libbz2-dev \ + libc6-dev \ + libcacard-dev \ + libcap-ng-dev \ + libcapstone-dev \ + libcmocka-dev \ + libcurl4-gnutls-dev \ + libdaxctl-dev \ + libdrm-dev \ + libepoxy-dev \ + libfdt-dev \ + libffi-dev \ + libfuse3-dev \ + libgbm-dev \ + libgcrypt20-dev \ + libglib2.0-dev \ + libglusterfs-dev \ + libgnutls28-dev \ + libgtk-3-dev \ + libibumad-dev \ + libibverbs-dev \ + libiscsi-dev \ + libjemalloc-dev \ + libjpeg-turbo8-dev \ + libjson-c-dev \ + liblttng-ust-dev \ + liblzo2-dev \ + libncursesw5-dev \ + libnfs-dev \ + libnuma-dev \ + libpam0g-dev \ + libpcre2-dev \ + libpixman-1-dev \ + libpmem-dev \ + libpng-dev \ + libpulse-dev \ + librbd-dev \ + librdmacm-dev \ + libsasl2-dev \ + libsdl2-dev \ + libsdl2-image-dev \ + libseccomp-dev \ + libselinux1-dev \ + libslirp-dev \ + libsnappy-dev \ + libsndio-dev \ + libspice-protocol-dev \ + libspice-server-dev \ + libssh-dev \ + libsystemd-dev \ + libtasn1-6-dev \ + libubsan1 \ + libudev-dev \ + libusb-1.0-0-dev \ + libusbredirhost-dev \ + libvdeplug-dev \ + libvirglrenderer-dev \ + libvte-2.91-dev \ + libxen-dev \ + libzstd-dev \ + llvm \ + locales \ + make \ + multipath-tools \ + ncat \ + nettle-dev \ + ninja-build \ + openssh-client \ + perl-base \ + pkgconf \ + python3 \ + python3-numpy \ + python3-opencv \ + python3-pillow \ + python3-pip \ + python3-setuptools \ + python3-sphinx \ + python3-sphinx-rtd-theme \ + python3-venv \ + python3-wheel \ + python3-yaml \ + rpm2cpio \ + sed \ + sparse \ + systemtap-sdt-dev \ + tar \ + tesseract-ocr \ + tesseract-ocr-eng \ + texinfo \ + xfslibs-dev \ + zlib1g-dev && \ eatmydata apt-get autoremove -y && \ eatmydata apt-get autoclean -y && \ sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \ @@ -141,11 +142,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ RUN /usr/bin/pip3 install meson==0.56.0 +ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" ENV LANG "en_US.UTF-8" ENV MAKE "/usr/bin/make" ENV NINJA "/usr/bin/ninja" ENV PYTHON "/usr/bin/python3" -ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers" # Apply patch https://reviews.llvm.org/D75820 # This is required for TSan in clang-10 to compile with QEMU. RUN sed -i 's/^const/static const/g' /usr/lib/llvm-10/lib/clang/10.0.0/include/sanitizer/tsan_interface.h diff --git a/tests/lcitool/libvirt-ci b/tests/lcitool/libvirt-ci -Subproject e3712b79122180fdb3b7a7ea8cbee47ece253f9 +Subproject 79691a50a5f99bd7adda236f66c3c09371b01af diff --git a/tests/lcitool/projects/qemu.yml b/tests/lcitool/projects/qemu.yml index 0d92819249..c62dbc00f9 100644 --- a/tests/lcitool/projects/qemu.yml +++ b/tests/lcitool/projects/qemu.yml @@ -101,6 +101,7 @@ packages: - sdl2-image - sed - snappy + - sndio - sparse - spice-protocol - spice-server diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051 index f1a506518b..4c079b11e3 100755 --- a/tests/qemu-iotests/051 +++ b/tests/qemu-iotests/051 @@ -375,7 +375,8 @@ if [ "${VALGRIND_QEMU_VM}" == "y" ]; then _casenotrun "Valgrind needs a valid TMPDIR for itself" fi VALGRIND_QEMU_VM= \ -TMPDIR=/nonexistent run_qemu -drive driver=null-co,snapshot=on +TMPDIR=/nonexistent run_qemu -drive driver=null-co,snapshot=on | + sed -e "s#'[^']*/vl\.[A-Za-z0-9]\{6\}'#SNAPSHOT_PATH#g" # Using snapshot=on together with read-only=on echo "info block" | diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out index 441f83e41a..e5ddb03bda 100644 --- a/tests/qemu-iotests/051.out +++ b/tests/qemu-iotests/051.out @@ -459,7 +459,7 @@ wrote 4096/4096 bytes at offset 0 read 4096/4096 bytes at offset 0 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) Testing: -drive driver=null-co,snapshot=on -QEMU_PROG: -drive driver=null-co,snapshot=on: Could not get temporary filename: No such file or directory +QEMU_PROG: -drive driver=null-co,snapshot=on: Could not open temporary file SNAPSHOT_PATH: No such file or directory Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,read-only=on,if=none,id=drive0 QEMU X.Y.Z monitor - type 'help' for more information diff --git a/tests/qemu-iotests/051.pc.out b/tests/qemu-iotests/051.pc.out index 063e4fc584..bade1ff3b9 100644 --- a/tests/qemu-iotests/051.pc.out +++ b/tests/qemu-iotests/051.pc.out @@ -539,7 +539,7 @@ wrote 4096/4096 bytes at offset 0 read 4096/4096 bytes at offset 0 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) Testing: -drive driver=null-co,snapshot=on -QEMU_PROG: -drive driver=null-co,snapshot=on: Could not get temporary filename: No such file or directory +QEMU_PROG: -drive driver=null-co,snapshot=on: Could not open temporary file SNAPSHOT_PATH: No such file or directory Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,read-only=on,if=none,id=drive0 QEMU X.Y.Z monitor - type 'help' for more information diff --git a/tests/qtest/cxl-test.c b/tests/qtest/cxl-test.c index cbe0fb549b..61f25a72b6 100644 --- a/tests/qtest/cxl-test.c +++ b/tests/qtest/cxl-test.c @@ -101,6 +101,7 @@ static void cxl_t3d(void) qtest_start(cmdline->str); qtest_end(); + rmdir(tmpfs); } static void cxl_1pxb_2rp_2t3d(void) @@ -115,6 +116,7 @@ static void cxl_1pxb_2rp_2t3d(void) qtest_start(cmdline->str); qtest_end(); + rmdir(tmpfs); } static void cxl_2pxb_4rp_4t3d(void) @@ -130,6 +132,7 @@ static void cxl_2pxb_4rp_4t3d(void) qtest_start(cmdline->str); qtest_end(); + rmdir(tmpfs); } #endif /* CONFIG_POSIX */ diff --git a/tests/qtest/dbus-vmstate-test.c b/tests/qtest/dbus-vmstate-test.c index 74ede651f6..6c990864e3 100644 --- a/tests/qtest/dbus-vmstate-test.c +++ b/tests/qtest/dbus-vmstate-test.c @@ -233,7 +233,7 @@ test_dbus_vmstate(Test *test) test->src_qemu = src_qemu; if (test->migrate_fail) { wait_for_migration_fail(src_qemu, true); - qtest_set_expected_status(dst_qemu, 1); + qtest_set_expected_status(dst_qemu, EXIT_FAILURE); } else { wait_for_migration_complete(src_qemu); } diff --git a/tests/qtest/device-plug-test.c b/tests/qtest/device-plug-test.c index 3f44f731d1..5a6afa2b57 100644 --- a/tests/qtest/device-plug-test.c +++ b/tests/qtest/device-plug-test.c @@ -112,16 +112,16 @@ static void test_pci_unplug_json_request(void) static void test_q35_pci_unplug_json_request(void) { - const char *port = "-device '{\"driver\": \"pcie-root-port\", " - "\"id\": \"p1\"}'"; + const char *port = "-device \"{'driver': 'pcie-root-port', " + "'id': 'p1'}\""; - const char *bridge = "-device '{\"driver\": \"pcie-pci-bridge\", " - "\"id\": \"b1\", " - "\"bus\": \"p1\"}'"; + const char *bridge = "-device \"{'driver': 'pcie-pci-bridge', " + "'id': 'b1', " + "'bus': 'p1'}\""; - const char *device = "-device '{\"driver\": \"virtio-mouse-pci\", " - "\"bus\": \"b1\", " - "\"id\": \"dev0\"}'"; + const char *device = "-device \"{'driver': 'virtio-mouse-pci', " + "'bus': 'b1', " + "'id': 'dev0'}\""; QTestState *qtest = qtest_initf("-machine q35 %s %s %s", port, bridge, device); diff --git a/tests/qtest/libqmp.c b/tests/qtest/libqmp.c index ade26c15f0..2b08382e5d 100644 --- a/tests/qtest/libqmp.c +++ b/tests/qtest/libqmp.c @@ -23,6 +23,7 @@ #endif #include "qemu/cutils.h" +#include "qemu/sockets.h" #include "qapi/error.h" #include "qapi/qmp/json-parser.h" #include "qapi/qmp/qjson.h" @@ -36,7 +37,7 @@ typedef struct { static void socket_send(int fd, const char *buf, size_t size) { - size_t res = qemu_write_full(fd, buf, size); + ssize_t res = qemu_send_full(fd, buf, size); assert(res == size); } @@ -69,7 +70,7 @@ QDict *qmp_fd_receive(int fd) ssize_t len; char c; - len = read(fd, &c, 1); + len = recv(fd, &c, 1, 0); if (len == -1 && errno == EINTR) { continue; } diff --git a/tests/qtest/libqos/e1000e.c b/tests/qtest/libqos/e1000e.c index fc14b07884..ed47e34044 100644 --- a/tests/qtest/libqos/e1000e.c +++ b/tests/qtest/libqos/e1000e.c @@ -17,6 +17,7 @@ */ #include "qemu/osdep.h" +#include "hw/net/e1000_regs.h" #include "../libqtest.h" #include "pci-pc.h" #include "qemu/sockets.h" @@ -27,49 +28,13 @@ #include "qgraph.h" #include "e1000e.h" -#define E1000E_IMS (0x00d0) +#define E1000E_IVAR_TEST_CFG \ + (E1000E_RX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID | \ + ((E1000E_TX0_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << 8) | \ + ((E1000E_OTHER_MSG_ID | E1000_IVAR_INT_ALLOC_VALID) << 16) | \ + E1000_IVAR_TX_INT_EVERY_WB) -#define E1000E_STATUS (0x0008) -#define E1000E_STATUS_LU BIT(1) -#define E1000E_STATUS_ASDV1000 BIT(9) - -#define E1000E_CTRL (0x0000) -#define E1000E_CTRL_RESET BIT(26) - -#define E1000E_RCTL (0x0100) -#define E1000E_RCTL_EN BIT(1) -#define E1000E_RCTL_UPE BIT(3) -#define E1000E_RCTL_MPE BIT(4) - -#define E1000E_RFCTL (0x5008) -#define E1000E_RFCTL_EXTEN BIT(15) - -#define E1000E_TCTL (0x0400) -#define E1000E_TCTL_EN BIT(1) - -#define E1000E_CTRL_EXT (0x0018) -#define E1000E_CTRL_EXT_DRV_LOAD BIT(28) -#define E1000E_CTRL_EXT_TXLSFLOW BIT(22) - -#define E1000E_IVAR (0x00E4) -#define E1000E_IVAR_TEST_CFG ((E1000E_RX0_MSG_ID << 0) | BIT(3) | \ - (E1000E_TX0_MSG_ID << 8) | BIT(11) | \ - (E1000E_OTHER_MSG_ID << 16) | BIT(19) | \ - BIT(31)) - -#define E1000E_RING_LEN (0x1000) - -#define E1000E_TDBAL (0x3800) - -#define E1000E_TDBAH (0x3804) -#define E1000E_TDH (0x3810) - -#define E1000E_RDBAL (0x2800) -#define E1000E_RDBAH (0x2804) -#define E1000E_RDH (0x2810) - -#define E1000E_TXD_LEN (16) -#define E1000E_RXD_LEN (16) +#define E1000E_RING_LEN (0x1000) static void e1000e_macreg_write(QE1000E *d, uint32_t reg, uint32_t val) { @@ -87,30 +52,34 @@ void e1000e_tx_ring_push(QE1000E *d, void *descr) { QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e); uint32_t tail = e1000e_macreg_read(d, E1000E_TDT); - uint32_t len = e1000e_macreg_read(d, E1000E_TDLEN) / E1000E_TXD_LEN; + uint32_t len = e1000e_macreg_read(d, E1000E_TDLEN) / E1000_RING_DESC_LEN; - qtest_memwrite(d_pci->pci_dev.bus->qts, d->tx_ring + tail * E1000E_TXD_LEN, - descr, E1000E_TXD_LEN); + qtest_memwrite(d_pci->pci_dev.bus->qts, + d->tx_ring + tail * E1000_RING_DESC_LEN, + descr, E1000_RING_DESC_LEN); e1000e_macreg_write(d, E1000E_TDT, (tail + 1) % len); /* Read WB data for the packet transmitted */ - qtest_memread(d_pci->pci_dev.bus->qts, d->tx_ring + tail * E1000E_TXD_LEN, - descr, E1000E_TXD_LEN); + qtest_memread(d_pci->pci_dev.bus->qts, + d->tx_ring + tail * E1000_RING_DESC_LEN, + descr, E1000_RING_DESC_LEN); } void e1000e_rx_ring_push(QE1000E *d, void *descr) { QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e); uint32_t tail = e1000e_macreg_read(d, E1000E_RDT); - uint32_t len = e1000e_macreg_read(d, E1000E_RDLEN) / E1000E_RXD_LEN; + uint32_t len = e1000e_macreg_read(d, E1000E_RDLEN) / E1000_RING_DESC_LEN; - qtest_memwrite(d_pci->pci_dev.bus->qts, d->rx_ring + tail * E1000E_RXD_LEN, - descr, E1000E_RXD_LEN); + qtest_memwrite(d_pci->pci_dev.bus->qts, + d->rx_ring + tail * E1000_RING_DESC_LEN, + descr, E1000_RING_DESC_LEN); e1000e_macreg_write(d, E1000E_RDT, (tail + 1) % len); /* Read WB data for the packet received */ - qtest_memread(d_pci->pci_dev.bus->qts, d->rx_ring + tail * E1000E_RXD_LEN, - descr, E1000E_RXD_LEN); + qtest_memread(d_pci->pci_dev.bus->qts, + d->rx_ring + tail * E1000_RING_DESC_LEN, + descr, E1000_RING_DESC_LEN); } static void e1000e_foreach_callback(QPCIDevice *dev, int devfn, void *data) @@ -151,53 +120,53 @@ static void e1000e_pci_start_hw(QOSGraphObject *obj) qpci_device_enable(&d->pci_dev); /* Reset the device */ - val = e1000e_macreg_read(&d->e1000e, E1000E_CTRL); - e1000e_macreg_write(&d->e1000e, E1000E_CTRL, val | E1000E_CTRL_RESET); + val = e1000e_macreg_read(&d->e1000e, E1000_CTRL); + e1000e_macreg_write(&d->e1000e, E1000_CTRL, val | E1000_CTRL_RST); /* Enable and configure MSI-X */ qpci_msix_enable(&d->pci_dev); - e1000e_macreg_write(&d->e1000e, E1000E_IVAR, E1000E_IVAR_TEST_CFG); + e1000e_macreg_write(&d->e1000e, E1000_IVAR, E1000E_IVAR_TEST_CFG); /* Check the device status - link and speed */ - val = e1000e_macreg_read(&d->e1000e, E1000E_STATUS); - g_assert_cmphex(val & (E1000E_STATUS_LU | E1000E_STATUS_ASDV1000), - ==, E1000E_STATUS_LU | E1000E_STATUS_ASDV1000); + val = e1000e_macreg_read(&d->e1000e, E1000_STATUS); + g_assert_cmphex(val & (E1000_STATUS_LU | E1000_STATUS_LAN_INIT_DONE), + ==, E1000_STATUS_LU | E1000_STATUS_LAN_INIT_DONE); /* Initialize TX/RX logic */ - e1000e_macreg_write(&d->e1000e, E1000E_RCTL, 0); - e1000e_macreg_write(&d->e1000e, E1000E_TCTL, 0); + e1000e_macreg_write(&d->e1000e, E1000_RCTL, 0); + e1000e_macreg_write(&d->e1000e, E1000_TCTL, 0); /* Notify the device that the driver is ready */ - val = e1000e_macreg_read(&d->e1000e, E1000E_CTRL_EXT); - e1000e_macreg_write(&d->e1000e, E1000E_CTRL_EXT, - val | E1000E_CTRL_EXT_DRV_LOAD | E1000E_CTRL_EXT_TXLSFLOW); + val = e1000e_macreg_read(&d->e1000e, E1000_CTRL_EXT); + e1000e_macreg_write(&d->e1000e, E1000_CTRL_EXT, + val | E1000_CTRL_EXT_DRV_LOAD); - e1000e_macreg_write(&d->e1000e, E1000E_TDBAL, + e1000e_macreg_write(&d->e1000e, E1000_TDBAL, (uint32_t) d->e1000e.tx_ring); - e1000e_macreg_write(&d->e1000e, E1000E_TDBAH, + e1000e_macreg_write(&d->e1000e, E1000_TDBAH, (uint32_t) (d->e1000e.tx_ring >> 32)); e1000e_macreg_write(&d->e1000e, E1000E_TDLEN, E1000E_RING_LEN); e1000e_macreg_write(&d->e1000e, E1000E_TDT, 0); - e1000e_macreg_write(&d->e1000e, E1000E_TDH, 0); + e1000e_macreg_write(&d->e1000e, E1000_TDH, 0); /* Enable transmit */ - e1000e_macreg_write(&d->e1000e, E1000E_TCTL, E1000E_TCTL_EN); - e1000e_macreg_write(&d->e1000e, E1000E_RDBAL, + e1000e_macreg_write(&d->e1000e, E1000_TCTL, E1000_TCTL_EN); + e1000e_macreg_write(&d->e1000e, E1000_RDBAL, (uint32_t)d->e1000e.rx_ring); - e1000e_macreg_write(&d->e1000e, E1000E_RDBAH, + e1000e_macreg_write(&d->e1000e, E1000_RDBAH, (uint32_t)(d->e1000e.rx_ring >> 32)); e1000e_macreg_write(&d->e1000e, E1000E_RDLEN, E1000E_RING_LEN); e1000e_macreg_write(&d->e1000e, E1000E_RDT, 0); - e1000e_macreg_write(&d->e1000e, E1000E_RDH, 0); + e1000e_macreg_write(&d->e1000e, E1000_RDH, 0); /* Enable receive */ - e1000e_macreg_write(&d->e1000e, E1000E_RFCTL, E1000E_RFCTL_EXTEN); - e1000e_macreg_write(&d->e1000e, E1000E_RCTL, E1000E_RCTL_EN | - E1000E_RCTL_UPE | - E1000E_RCTL_MPE); + e1000e_macreg_write(&d->e1000e, E1000_RFCTL, E1000_RFCTL_EXTEN); + e1000e_macreg_write(&d->e1000e, E1000_RCTL, E1000_RCTL_EN | + E1000_RCTL_UPE | + E1000_RCTL_MPE); /* Enable all interrupts */ - e1000e_macreg_write(&d->e1000e, E1000E_IMS, 0xFFFFFFFF); + e1000e_macreg_write(&d->e1000e, E1000_IMS, 0xFFFFFFFF); } diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build index 113c80b4e4..32f028872c 100644 --- a/tests/qtest/libqos/meson.build +++ b/tests/qtest/libqos/meson.build @@ -33,8 +33,6 @@ libqos_srcs = files( 'sdhci.c', 'tpci200.c', 'virtio.c', - 'virtio-9p.c', - 'virtio-9p-client.c', 'virtio-balloon.c', 'virtio-blk.c', 'vhost-user-blk.c', @@ -62,6 +60,10 @@ libqos_srcs = files( 'x86_64_pc-machine.c', ) +if have_virtfs + libqos_srcs += files('virtio-9p.c', 'virtio-9p-client.c') +endif + libqos = static_library('qos', libqos_srcs + genh, name_suffix: 'fa', build_by_default: false) diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index b23eb3edc3..2fbc3b88f3 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -16,9 +16,11 @@ #include "qemu/osdep.h" +#ifndef _WIN32 #include <sys/socket.h> #include <sys/wait.h> #include <sys/un.h> +#endif /* _WIN32 */ #ifdef __linux__ #include <sys/prctl.h> #endif /* __linux__ */ @@ -27,13 +29,25 @@ #include "libqmp.h" #include "qemu/ctype.h" #include "qemu/cutils.h" +#include "qemu/sockets.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qjson.h" #include "qapi/qmp/qlist.h" #include "qapi/qmp/qstring.h" #define MAX_IRQ 256 -#define SOCKET_TIMEOUT 50 + +#ifndef _WIN32 +# define SOCKET_TIMEOUT 50 +# define CMD_EXEC "exec " +# define DEV_STDERR "/dev/fd/2" +# define DEV_NULL "/dev/null" +#else +# define SOCKET_TIMEOUT 50000 +# define CMD_EXEC "" +# define DEV_STDERR "2" +# define DEV_NULL "nul" +#endif typedef void (*QTestSendFn)(QTestState *s, const char *buf); typedef void (*ExternalSendFn)(void *s, const char *buf); @@ -57,6 +71,9 @@ struct QTestState int qmp_fd; pid_t qemu_pid; /* our child QEMU process */ int wstatus; +#ifdef _WIN32 + DWORD exit_code; +#endif int expected_status; bool big_endian; bool irq_level[MAX_IRQ]; @@ -90,8 +107,16 @@ static int socket_accept(int sock) struct sockaddr_un addr; socklen_t addrlen; int ret; + /* + * timeout unit of blocking receive calls is different among platfoms. + * It's in seconds on non-Windows platforms but milliseconds on Windows. + */ +#ifndef _WIN32 struct timeval timeout = { .tv_sec = SOCKET_TIMEOUT, .tv_usec = 0 }; +#else + DWORD timeout = SOCKET_TIMEOUT; +#endif if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, sizeof(timeout))) { @@ -118,10 +143,18 @@ bool qtest_probe_child(QTestState *s) pid_t pid = s->qemu_pid; if (pid != -1) { +#ifndef _WIN32 pid = waitpid(pid, &s->wstatus, WNOHANG); if (pid == 0) { return true; } +#else + GetExitCodeProcess((HANDLE)pid, &s->exit_code); + if (s->exit_code == STILL_ACTIVE) { + return true; + } + CloseHandle((HANDLE)pid); +#endif s->qemu_pid = -1; } return false; @@ -132,24 +165,14 @@ void qtest_set_expected_status(QTestState *s, int status) s->expected_status = status; } -void qtest_kill_qemu(QTestState *s) +static void qtest_check_status(QTestState *s) { - pid_t pid = s->qemu_pid; - int wstatus; - - /* Skip wait if qtest_probe_child already reaped. */ - if (pid != -1) { - kill(pid, SIGTERM); - TFR(pid = waitpid(s->qemu_pid, &s->wstatus, 0)); - assert(pid == s->qemu_pid); - s->qemu_pid = -1; - } - /* * Check whether qemu exited with expected exit status; anything else is * fishy and should be logged with as much detail as possible. */ - wstatus = s->wstatus; +#ifndef _WIN32 + int wstatus = s->wstatus; if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != s->expected_status) { fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU " "process but encountered exit status %d (expected %d)\n", @@ -165,6 +188,50 @@ void qtest_kill_qemu(QTestState *s) __FILE__, __LINE__, sig, signame, dump); abort(); } +#else + if (s->exit_code != s->expected_status) { + fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU " + "process but encountered exit status %ld (expected %d)\n", + __FILE__, __LINE__, s->exit_code, s->expected_status); + abort(); + } +#endif +} + +void qtest_wait_qemu(QTestState *s) +{ +#ifndef _WIN32 + pid_t pid; + + TFR(pid = waitpid(s->qemu_pid, &s->wstatus, 0)); + assert(pid == s->qemu_pid); +#else + DWORD ret; + + ret = WaitForSingleObject((HANDLE)s->qemu_pid, INFINITE); + assert(ret == WAIT_OBJECT_0); + GetExitCodeProcess((HANDLE)s->qemu_pid, &s->exit_code); + CloseHandle((HANDLE)s->qemu_pid); +#endif + + qtest_check_status(s); +} + +void qtest_kill_qemu(QTestState *s) +{ + /* Skip wait if qtest_probe_child() already reaped */ + if (s->qemu_pid != -1) { +#ifndef _WIN32 + kill(s->qemu_pid, SIGTERM); +#else + TerminateProcess((HANDLE)s->qemu_pid, s->expected_status); +#endif + qtest_wait_qemu(s); + s->qemu_pid = -1; + return; + } + + qtest_check_status(s); } static void kill_qemu_hook_func(void *s) @@ -243,6 +310,38 @@ static const char *qtest_qemu_binary(void) return qemu_bin; } +#ifdef _WIN32 +static pid_t qtest_create_process(char *cmd) +{ + STARTUPINFO si; + PROCESS_INFORMATION pi; + BOOL ret; + + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + ZeroMemory(&pi, sizeof(pi)); + + ret = CreateProcess(NULL, /* module name */ + cmd, /* command line */ + NULL, /* process handle not inheritable */ + NULL, /* thread handle not inheritable */ + FALSE, /* set handle inheritance to FALSE */ + 0, /* No creation flags */ + NULL, /* use parent's environment block */ + NULL, /* use parent's starting directory */ + &si, /* pointer to STARTUPINFO structure */ + &pi /* pointer to PROCESS_INFORMATION structure */ + ); + if (ret == 0) { + fprintf(stderr, "%s:%d: unable to create a new process (%s)\n", + __FILE__, __LINE__, strerror(GetLastError())); + abort(); + } + + return (pid_t)pi.hProcess; +} +#endif /* _WIN32 */ + QTestState *qtest_init_without_qmp_handshake(const char *extra_args) { QTestState *s; @@ -270,6 +369,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) unlink(socket_path); unlink(qmp_socket_path); + socket_init(); sock = init_socket(socket_path); qmpsock = init_socket(qmp_socket_path); @@ -278,7 +378,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) qtest_add_abrt_handler(kill_qemu_hook_func, s); - command = g_strdup_printf("exec %s %s" + command = g_strdup_printf(CMD_EXEC "%s %s" "-qtest unix:%s " "-qtest-log %s " "-chardev socket,path=%s,id=char0 " @@ -287,7 +387,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) "%s" " -accel qtest", qemu_binary, tracearg, socket_path, - getenv("QTEST_LOG") ? "/dev/fd/2" : "/dev/null", + getenv("QTEST_LOG") ? DEV_STDERR : DEV_NULL, qmp_socket_path, extra_args ?: ""); @@ -296,6 +396,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) s->pending_events = NULL; s->wstatus = 0; s->expected_status = 0; +#ifndef _WIN32 s->qemu_pid = fork(); if (s->qemu_pid == 0) { #ifdef __linux__ @@ -318,6 +419,9 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) execlp("/bin/sh", "sh", "-c", command, NULL); exit(1); } +#else + s->qemu_pid = qtest_create_process(command); +#endif /* _WIN32 */ g_free(command); s->fd = socket_accept(sock); @@ -336,9 +440,19 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) s->irq_level[i] = false; } + /* + * Stopping QEMU for debugging is not supported on Windows. + * + * Using DebugActiveProcess() API can suspend the QEMU process, + * but gdb cannot attach to the process. Using the undocumented + * NtSuspendProcess() can suspend the QEMU process and gdb can + * attach to the process, but gdb cannot resume it. + */ +#ifndef _WIN32 if (getenv("QTEST_STOP")) { kill(s->qemu_pid, SIGSTOP); } +#endif /* ask endianness of the target */ @@ -392,6 +506,7 @@ QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd) g_assert_true(sock_dir != NULL); sock_path = g_strdup_printf("%s/sock", sock_dir); + socket_init(); sock_fd_init = init_socket(sock_path); qts = qtest_initf("-chardev socket,id=s0,path=%s -serial chardev:s0 %s", @@ -428,7 +543,7 @@ void qtest_quit(QTestState *s) static void socket_send(int fd, const char *buf, size_t size) { - size_t res = qemu_write_full(fd, buf, size); + ssize_t res = qemu_send_full(fd, buf, size); assert(res == size); } @@ -460,7 +575,7 @@ static GString *qtest_client_socket_recv_line(QTestState *s) ssize_t len; char buffer[1024]; - len = read(s->fd, buffer, sizeof(buffer)); + len = recv(s->fd, buffer, sizeof(buffer), 0); if (len == -1 && errno == EINTR) { continue; } diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h index 65c040e504..91a5f7edd9 100644 --- a/tests/qtest/libqtest.h +++ b/tests/qtest/libqtest.h @@ -76,6 +76,15 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args); QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd); /** + * qtest_wait_qemu: + * @s: #QTestState instance to operate on. + * + * Wait for the QEMU process to terminate. It is safe to call this function + * multiple times. + */ +void qtest_wait_qemu(QTestState *s); + +/** * qtest_kill_qemu: * @s: #QTestState instance to operate on. * diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c index aa1ba179fa..d2eb107f0c 100644 --- a/tests/qtest/migration-test.c +++ b/tests/qtest/migration-test.c @@ -1342,7 +1342,7 @@ static void test_precopy_common(MigrateCommon *args) wait_for_migration_fail(from, allow_active); if (args->result == MIG_TEST_FAIL_DEST_QUIT_ERR) { - qtest_set_expected_status(to, 1); + qtest_set_expected_status(to, EXIT_FAILURE); } } else { if (args->iterations) { @@ -1738,7 +1738,7 @@ static void do_test_validate_uuid(MigrateStart *args, bool should_fail) migrate_qmp(from, uri, "{}"); if (should_fail) { - qtest_set_expected_status(to, 1); + qtest_set_expected_status(to, EXIT_FAILURE); wait_for_migration_fail(from, true); } else { wait_for_migration_complete(from); @@ -2141,6 +2141,10 @@ static void test_multifd_tcp_cancel(void) migrate_cancel(from); + /* Make sure QEMU process "to" exited */ + qtest_set_expected_status(to, EXIT_FAILURE); + qtest_wait_qemu(to); + args = (MigrateStart){ .only_target = true, }; diff --git a/tests/qtest/tpm-crb-swtpm-test.c b/tests/qtest/tpm-crb-swtpm-test.c index 55fdb5657d..40254f762f 100644 --- a/tests/qtest/tpm-crb-swtpm-test.c +++ b/tests/qtest/tpm-crb-swtpm-test.c @@ -13,7 +13,6 @@ */ #include "qemu/osdep.h" -#include <glib/gstdio.h> #include "libqtest.h" #include "qemu/module.h" @@ -62,9 +61,9 @@ int main(int argc, char **argv) tpm_crb_swtpm_migration_test); ret = g_test_run(); - g_rmdir(ts.dst_tpm_path); + tpm_util_rmdir(ts.dst_tpm_path); g_free(ts.dst_tpm_path); - g_rmdir(ts.src_tpm_path); + tpm_util_rmdir(ts.src_tpm_path); g_free(ts.src_tpm_path); g_free(ts.uri); diff --git a/tests/qtest/tpm-tis-device-swtpm-test.c b/tests/qtest/tpm-tis-device-swtpm-test.c index 7b20035142..8c067fddd4 100644 --- a/tests/qtest/tpm-tis-device-swtpm-test.c +++ b/tests/qtest/tpm-tis-device-swtpm-test.c @@ -14,7 +14,6 @@ */ #include "qemu/osdep.h" -#include <glib/gstdio.h> #include "libqtest.h" #include "qemu/module.h" @@ -66,9 +65,9 @@ int main(int argc, char **argv) tpm_tis_swtpm_migration_test); ret = g_test_run(); - g_rmdir(ts.dst_tpm_path); + tpm_util_rmdir(ts.dst_tpm_path); g_free(ts.dst_tpm_path); - g_rmdir(ts.src_tpm_path); + tpm_util_rmdir(ts.src_tpm_path); g_free(ts.src_tpm_path); g_free(ts.uri); diff --git a/tests/qtest/tpm-tis-swtpm-test.c b/tests/qtest/tpm-tis-swtpm-test.c index 90131cb3c4..11539c0a52 100644 --- a/tests/qtest/tpm-tis-swtpm-test.c +++ b/tests/qtest/tpm-tis-swtpm-test.c @@ -13,7 +13,6 @@ */ #include "qemu/osdep.h" -#include <glib/gstdio.h> #include "libqtest.h" #include "qemu/module.h" @@ -61,9 +60,9 @@ int main(int argc, char **argv) tpm_tis_swtpm_migration_test); ret = g_test_run(); - g_rmdir(ts.dst_tpm_path); + tpm_util_rmdir(ts.dst_tpm_path); g_free(ts.dst_tpm_path); - g_rmdir(ts.src_tpm_path); + tpm_util_rmdir(ts.src_tpm_path); g_free(ts.src_tpm_path); g_free(ts.uri); diff --git a/tests/qtest/tpm-util.c b/tests/qtest/tpm-util.c index e0dc5da0af..a7efe2d0d2 100644 --- a/tests/qtest/tpm-util.c +++ b/tests/qtest/tpm-util.c @@ -13,6 +13,7 @@ */ #include "qemu/osdep.h" +#include <glib/gstdio.h> #include "hw/acpi/tpm.h" #include "libqtest.h" @@ -292,3 +293,21 @@ void tpm_util_migration_start_qemu(QTestState **src_qemu, g_free(src_qemu_args); g_free(dst_qemu_args); } + +/* Remove directory with remainders of swtpm */ +void tpm_util_rmdir(const char *path) +{ + char *filename; + int ret; + + filename = g_strdup_printf("%s/tpm2-00.permall", path); + g_unlink(filename); + g_free(filename); + + filename = g_strdup_printf("%s/.lock", path); + g_unlink(filename); + g_free(filename); + + ret = g_rmdir(path); + g_assert(!ret); +} diff --git a/tests/qtest/tpm-util.h b/tests/qtest/tpm-util.h index 3b97d69017..80720afac0 100644 --- a/tests/qtest/tpm-util.h +++ b/tests/qtest/tpm-util.h @@ -53,5 +53,6 @@ void tpm_util_migration_start_qemu(QTestState **src_qemu, const char *machine_options); void tpm_util_wait_for_migration_complete(QTestState *who); +void tpm_util_rmdir(const char *path); #endif /* TESTS_TPM_UTIL_H */ diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target index c830313e67..07fcc6d0ce 100644 --- a/tests/tcg/s390x/Makefile.target +++ b/tests/tcg/s390x/Makefile.target @@ -1,6 +1,13 @@ S390X_SRC=$(SRC_PATH)/tests/tcg/s390x VPATH+=$(S390X_SRC) CFLAGS+=-march=zEC12 -m64 + +config-cc.mak: Makefile + $(quiet-@)( \ + $(call cc-option,-march=z14, CROSS_CC_HAS_Z14); \ + $(call cc-option,-march=z15, CROSS_CC_HAS_Z15)) 3> config-cc.mak +-include config-cc.mak + TESTS+=hello-s390x TESTS+=csst TESTS+=ipm @@ -18,20 +25,24 @@ TESTS+=signals-s390x TESTS+=branch-relative-long TESTS+=noexec +Z13_TESTS=vistr +$(Z13_TESTS): CFLAGS+=-march=z13 -O2 +TESTS+=$(Z13_TESTS) + +ifneq ($(CROSS_CC_HAS_Z14),) Z14_TESTS=vfminmax vfminmax: LDFLAGS+=-lm $(Z14_TESTS): CFLAGS+=-march=z14 -O2 +TESTS+=$(Z14_TESTS) +endif -TESTS+=$(if $(shell $(CC) -march=z14 -S -o /dev/null -xc /dev/null \ - >/dev/null 2>&1 && echo OK),$(Z14_TESTS)) - -VECTOR_TESTS=vxeh2_vs -VECTOR_TESTS+=vxeh2_vcvt -VECTOR_TESTS+=vxeh2_vlstr -$(VECTOR_TESTS): CFLAGS+=-march=z15 -O2 - -TESTS+=$(if $(shell $(CC) -march=z15 -S -o /dev/null -xc /dev/null \ - >/dev/null 2>&1 && echo OK),$(VECTOR_TESTS)) +ifneq ($(CROSS_CC_HAS_Z15),) +Z15_TESTS=vxeh2_vs +Z15_TESTS+=vxeh2_vcvt +Z15_TESTS+=vxeh2_vlstr +$(Z15_TESTS): CFLAGS+=-march=z15 -O2 +TESTS+=$(Z15_TESTS) +endif ifneq ($(HAVE_GDB_BIN),) GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py diff --git a/tests/tcg/s390x/vistr.c b/tests/tcg/s390x/vistr.c new file mode 100644 index 0000000000..8e3e987d71 --- /dev/null +++ b/tests/tcg/s390x/vistr.c @@ -0,0 +1,45 @@ +/* + * Test the VECTOR ISOLATE STRING (vistr) instruction + */ +#include <stdint.h> +#include <stdio.h> +#include "vx.h" + +static inline void vistr(S390Vector *v1, S390Vector *v2, + const uint8_t m3, const uint8_t m5) +{ + asm volatile("vistr %[v1], %[v2], %[m3], %[m5]\n" + : [v1] "=v" (v1->v) + : [v2] "v" (v2->v) + , [m3] "i" (m3) + , [m5] "i" (m5) + : "cc"); +} + +int main(int argc, char *argv[]) +{ + S390Vector vd = {}; + S390Vector vs16 = { + .h[0] = 0x1234, .h[1] = 0x0056, .h[2] = 0x7800, .h[3] = 0x0000, + .h[4] = 0x0078, .h[5] = 0x0000, .h[6] = 0x6543, .h[7] = 0x2100 + }; + S390Vector vs32 = { + .w[0] = 0x12340000, .w[1] = 0x78654300, + .w[2] = 0x0, .w[3] = 0x12, + }; + + vistr(&vd, &vs16, 1, 0); + if (vd.h[0] != 0x1234 || vd.h[1] != 0x0056 || vd.h[2] != 0x7800 || + vd.h[3] || vd.h[4] || vd.h[5] || vd.h[6] || vd.h[7]) { + puts("ERROR: vitrh failed!"); + return 1; + } + + vistr(&vd, &vs32, 2, 0); + if (vd.w[0] != 0x12340000 || vd.w[1] != 0x78654300 || vd.w[2] || vd.w[3]) { + puts("ERROR: vitrf failed!"); + return 1; + } + + return 0; +} diff --git a/tests/unit/crypto-tls-psk-helpers.c b/tests/unit/crypto-tls-psk-helpers.c index 511e08cc9c..c6cc740772 100644 --- a/tests/unit/crypto-tls-psk-helpers.c +++ b/tests/unit/crypto-tls-psk-helpers.c @@ -27,15 +27,14 @@ static void test_tls_psk_init_common(const char *pskfile, const char *user, const char *key) { - FILE *fp; + g_autoptr(GError) gerr = NULL; + g_autofree char *line = g_strdup_printf("%s:%s\n", user, key); - fp = fopen(pskfile, "w"); - if (fp == NULL) { - g_critical("Failed to create pskfile %s: %s", pskfile, strerror(errno)); + g_file_set_contents(pskfile, line, strlen(line), &gerr); + if (gerr != NULL) { + g_critical("Failed to create pskfile %s: %s", pskfile, gerr->message); abort(); } - fprintf(fp, "%s:%s\n", user, key); - fclose(fp); } void test_tls_psk_init(const char *pskfile) diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c index 4924ceb562..09dc4a4891 100644 --- a/tests/unit/test-bdrv-drain.c +++ b/tests/unit/test-bdrv-drain.c @@ -1538,16 +1538,16 @@ static void test_set_aio_context(void) &error_abort); bdrv_drained_begin(bs); - bdrv_try_set_aio_context(bs, ctx_a, &error_abort); + bdrv_try_change_aio_context(bs, ctx_a, NULL, &error_abort); aio_context_acquire(ctx_a); bdrv_drained_end(bs); bdrv_drained_begin(bs); - bdrv_try_set_aio_context(bs, ctx_b, &error_abort); + bdrv_try_change_aio_context(bs, ctx_b, NULL, &error_abort); aio_context_release(ctx_a); aio_context_acquire(ctx_b); - bdrv_try_set_aio_context(bs, qemu_get_aio_context(), &error_abort); + bdrv_try_change_aio_context(bs, qemu_get_aio_context(), NULL, &error_abort); aio_context_release(ctx_b); bdrv_drained_end(bs); @@ -1830,9 +1830,8 @@ static void test_drop_intermediate_poll(void) for (i = 0; i < 3; i++) { if (i) { /* Takes the reference to chain[i - 1] */ - chain[i]->backing = bdrv_attach_child(chain[i], chain[i - 1], - "chain", &chain_child_class, - BDRV_CHILD_COW, &error_abort); + bdrv_attach_child(chain[i], chain[i - 1], "chain", + &chain_child_class, BDRV_CHILD_COW, &error_abort); } } @@ -1970,6 +1969,7 @@ static void coroutine_fn bdrv_replace_test_co_drain_end(BlockDriverState *bs) static BlockDriver bdrv_replace_test = { .format_name = "replace_test", .instance_size = sizeof(BDRVReplaceTestState), + .supports_backing = true, .bdrv_close = bdrv_replace_test_close, .bdrv_co_preadv = bdrv_replace_test_co_preadv, @@ -2049,9 +2049,8 @@ static void do_test_replace_child_mid_drain(int old_drain_count, new_child_bs->total_sectors = 1; bdrv_ref(old_child_bs); - parent_bs->backing = bdrv_attach_child(parent_bs, old_child_bs, "child", - &child_of_bds, BDRV_CHILD_COW, - &error_abort); + bdrv_attach_child(parent_bs, old_child_bs, "child", &child_of_bds, + BDRV_CHILD_COW, &error_abort); for (i = 0; i < old_drain_count; i++) { bdrv_drained_begin(old_child_bs); diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c index a6e3bb79be..c522591531 100644 --- a/tests/unit/test-bdrv-graph-mod.c +++ b/tests/unit/test-bdrv-graph-mod.c @@ -26,6 +26,8 @@ static BlockDriver bdrv_pass_through = { .format_name = "pass-through", + .is_filter = true, + .filtered_child_is_backing = true, .bdrv_child_perm = bdrv_default_perms, }; @@ -57,6 +59,8 @@ static void exclusive_write_perms(BlockDriverState *bs, BdrvChild *c, static BlockDriver bdrv_exclusive_writer = { .format_name = "exclusive-writer", + .is_filter = true, + .filtered_child_is_backing = true, .bdrv_child_perm = exclusive_write_perms, }; @@ -134,7 +138,7 @@ static void test_update_perm_tree(void) blk_insert_bs(root, bs, &error_abort); bdrv_attach_child(filter, bs, "child", &child_of_bds, - BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); + BDRV_CHILD_DATA, &error_abort); ret = bdrv_append(filter, bs, NULL); g_assert_cmpint(ret, <, 0); @@ -228,11 +232,14 @@ static void test_parallel_exclusive_write(void) */ bdrv_ref(base); - bdrv_attach_child(top, fl1, "backing", &child_of_bds, BDRV_CHILD_DATA, + bdrv_attach_child(top, fl1, "backing", &child_of_bds, + BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); - bdrv_attach_child(fl1, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED, + bdrv_attach_child(fl1, base, "backing", &child_of_bds, + BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); - bdrv_attach_child(fl2, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED, + bdrv_attach_child(fl2, base, "backing", &child_of_bds, + BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); bdrv_replace_node(fl1, fl2, &error_abort); @@ -241,13 +248,26 @@ static void test_parallel_exclusive_write(void) bdrv_unref(top); } -static void write_to_file_perms(BlockDriverState *bs, BdrvChild *c, - BdrvChildRole role, - BlockReopenQueue *reopen_queue, - uint64_t perm, uint64_t shared, - uint64_t *nperm, uint64_t *nshared) +/* + * write-to-selected node may have several DATA children, one of them may be + * "selected". Exclusive write permission is taken on selected child. + * + * We don't realize write handler itself, as we need only to test how permission + * update works. + */ +typedef struct BDRVWriteToSelectedState { + BdrvChild *selected; +} BDRVWriteToSelectedState; + +static void write_to_selected_perms(BlockDriverState *bs, BdrvChild *c, + BdrvChildRole role, + BlockReopenQueue *reopen_queue, + uint64_t perm, uint64_t shared, + uint64_t *nperm, uint64_t *nshared) { - if (bs->file && c == bs->file) { + BDRVWriteToSelectedState *s = bs->opaque; + + if (s->selected && c == s->selected) { *nperm = BLK_PERM_WRITE; *nshared = BLK_PERM_ALL & ~BLK_PERM_WRITE; } else { @@ -256,9 +276,10 @@ static void write_to_file_perms(BlockDriverState *bs, BdrvChild *c, } } -static BlockDriver bdrv_write_to_file = { - .format_name = "tricky-perm", - .bdrv_child_perm = write_to_file_perms, +static BlockDriver bdrv_write_to_selected = { + .format_name = "write-to-selected", + .instance_size = sizeof(BDRVWriteToSelectedState), + .bdrv_child_perm = write_to_selected_perms, }; @@ -266,15 +287,18 @@ static BlockDriver bdrv_write_to_file = { * The following test shows that topological-sort order is required for * permission update, simple DFS is not enough. * - * Consider the block driver which has two filter children: one active - * with exclusive write access and one inactive with no specific - * permissions. + * Consider the block driver (write-to-selected) which has two children: one is + * selected so we have exclusive write access to it and for the other one we + * don't need any specific permissions. * * And, these two children has a common base child, like this: + * (additional "top" on top is used in test just because the only public + * function to update permission should get a specific child to update. + * Making bdrv_refresh_perms() public just for this test isn't worth it) * - * ┌─────┐ ┌──────┐ - * │ fl2 │ ◀── │ top │ - * └─────┘ └──────┘ + * ┌─────┐ ┌───────────────────┐ ┌─────┐ + * │ fl2 │ ◀── │ write-to-selected │ ◀── │ top │ + * └─────┘ └───────────────────┘ └─────┘ * │ │ * │ │ w * │ ▼ @@ -290,14 +314,14 @@ static BlockDriver bdrv_write_to_file = { * * So, exclusive write is propagated. * - * Assume, we want to make fl2 active instead of fl1. - * So, we set some option for top driver and do permission update. + * Assume, we want to select fl2 instead of fl1. + * So, we set some option for write-to-selected driver and do permission update. * * With simple DFS, if permission update goes first through - * top->fl1->base branch it will succeed: it firstly drop exclusive write - * permissions and than apply them for another BdrvChildren. - * But if permission update goes first through top->fl2->base branch it - * will fail, as when we try to update fl2->base child, old not yet + * write-to-selected -> fl1 -> base branch it will succeed: it firstly drop + * exclusive write permissions and than apply them for another BdrvChildren. + * But if permission update goes first through write-to-selected -> fl2 -> base + * branch it will fail, as when we try to update fl2->base child, old not yet * updated fl1->base child will be in conflict. * * With topological-sort order we always update parents before children, so fl1 @@ -306,9 +330,10 @@ static BlockDriver bdrv_write_to_file = { static void test_parallel_perm_update(void) { BlockDriverState *top = no_perm_node("top"); - BlockDriverState *tricky = - bdrv_new_open_driver(&bdrv_write_to_file, "tricky", BDRV_O_RDWR, + BlockDriverState *ws = + bdrv_new_open_driver(&bdrv_write_to_selected, "ws", BDRV_O_RDWR, &error_abort); + BDRVWriteToSelectedState *s = ws->opaque; BlockDriverState *base = no_perm_node("base"); BlockDriverState *fl1 = pass_through_node("fl1"); BlockDriverState *fl2 = pass_through_node("fl2"); @@ -320,33 +345,35 @@ static void test_parallel_perm_update(void) */ bdrv_ref(base); - bdrv_attach_child(top, tricky, "file", &child_of_bds, BDRV_CHILD_DATA, + bdrv_attach_child(top, ws, "file", &child_of_bds, BDRV_CHILD_DATA, &error_abort); - c_fl1 = bdrv_attach_child(tricky, fl1, "first", &child_of_bds, - BDRV_CHILD_FILTERED, &error_abort); - c_fl2 = bdrv_attach_child(tricky, fl2, "second", &child_of_bds, - BDRV_CHILD_FILTERED, &error_abort); - bdrv_attach_child(fl1, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED, + c_fl1 = bdrv_attach_child(ws, fl1, "first", &child_of_bds, + BDRV_CHILD_DATA, &error_abort); + c_fl2 = bdrv_attach_child(ws, fl2, "second", &child_of_bds, + BDRV_CHILD_DATA, &error_abort); + bdrv_attach_child(fl1, base, "backing", &child_of_bds, + BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); - bdrv_attach_child(fl2, base, "backing", &child_of_bds, BDRV_CHILD_FILTERED, + bdrv_attach_child(fl2, base, "backing", &child_of_bds, + BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); /* Select fl1 as first child to be active */ - tricky->file = c_fl1; + s->selected = c_fl1; bdrv_child_refresh_perms(top, top->children.lh_first, &error_abort); assert(c_fl1->perm & BLK_PERM_WRITE); assert(!(c_fl2->perm & BLK_PERM_WRITE)); /* Now, try to switch active child and update permissions */ - tricky->file = c_fl2; + s->selected = c_fl2; bdrv_child_refresh_perms(top, top->children.lh_first, &error_abort); assert(c_fl2->perm & BLK_PERM_WRITE); assert(!(c_fl1->perm & BLK_PERM_WRITE)); /* Switch once more, to not care about real child order in the list */ - tricky->file = c_fl1; + s->selected = c_fl1; bdrv_child_refresh_perms(top, top->children.lh_first, &error_abort); assert(c_fl1->perm & BLK_PERM_WRITE); @@ -379,7 +406,8 @@ static void test_append_greedy_filter(void) BlockDriverState *base = no_perm_node("base"); BlockDriverState *fl = exclusive_writer_node("fl1"); - bdrv_attach_child(top, base, "backing", &child_of_bds, BDRV_CHILD_COW, + bdrv_attach_child(top, base, "backing", &child_of_bds, + BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, &error_abort); bdrv_append(fl, base, &error_abort); diff --git a/tests/unit/test-block-iothread.c b/tests/unit/test-block-iothread.c index def0709b2b..8ca5adec5e 100644 --- a/tests/unit/test-block-iothread.c +++ b/tests/unit/test-block-iothread.c @@ -765,7 +765,7 @@ static void test_propagate_mirror(void) filter = bdrv_find_node("filter_node"); /* Change the AioContext of src */ - bdrv_try_set_aio_context(src, ctx, &error_abort); + bdrv_try_change_aio_context(src, ctx, NULL, &error_abort); g_assert(bdrv_get_aio_context(src) == ctx); g_assert(bdrv_get_aio_context(target) == ctx); g_assert(bdrv_get_aio_context(filter) == ctx); @@ -773,7 +773,7 @@ static void test_propagate_mirror(void) /* Change the AioContext of target */ aio_context_acquire(ctx); - bdrv_try_set_aio_context(target, main_ctx, &error_abort); + bdrv_try_change_aio_context(target, main_ctx, NULL, &error_abort); aio_context_release(ctx); g_assert(bdrv_get_aio_context(src) == main_ctx); g_assert(bdrv_get_aio_context(target) == main_ctx); @@ -783,7 +783,7 @@ static void test_propagate_mirror(void) blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL); blk_insert_bs(blk, src, &error_abort); - bdrv_try_set_aio_context(target, ctx, &local_err); + bdrv_try_change_aio_context(target, ctx, NULL, &local_err); error_free_or_abort(&local_err); g_assert(blk_get_aio_context(blk) == main_ctx); @@ -794,7 +794,7 @@ static void test_propagate_mirror(void) /* ...unless we explicitly allow it */ aio_context_acquire(ctx); blk_set_allow_aio_context_change(blk, true); - bdrv_try_set_aio_context(target, ctx, &error_abort); + bdrv_try_change_aio_context(target, ctx, NULL, &error_abort); aio_context_release(ctx); g_assert(blk_get_aio_context(blk) == ctx); @@ -806,7 +806,7 @@ static void test_propagate_mirror(void) aio_context_acquire(ctx); blk_set_aio_context(blk, main_ctx, &error_abort); - bdrv_try_set_aio_context(target, main_ctx, &error_abort); + bdrv_try_change_aio_context(target, main_ctx, NULL, &error_abort); aio_context_release(ctx); blk_unref(blk); diff --git a/tests/unit/test-crypto-block.c b/tests/unit/test-crypto-block.c index 3417b67be5..b629e240a9 100644 --- a/tests/unit/test-crypto-block.c +++ b/tests/unit/test-crypto-block.c @@ -22,6 +22,7 @@ #include "qapi/error.h" #include "crypto/init.h" #include "crypto/block.h" +#include "crypto/block-luks-priv.h" #include "qemu/buffer.h" #include "qemu/module.h" #include "crypto/secret.h" @@ -30,7 +31,8 @@ #endif #if (defined(_WIN32) || defined RUSAGE_THREAD) && \ - (defined(CONFIG_NETTLE) || defined(CONFIG_GCRYPT)) + (defined(CONFIG_NETTLE) || defined(CONFIG_GCRYPT) || \ + defined(CONFIG_GNUTLS_CRYPTO)) #define TEST_LUKS #else #undef TEST_LUKS @@ -344,6 +346,230 @@ static void test_block(gconstpointer opaque) } +#ifdef TEST_LUKS +typedef const char *(*LuksHeaderDoBadStuff)(QCryptoBlockLUKSHeader *hdr); + +static void +test_luks_bad_header(gconstpointer data) +{ + LuksHeaderDoBadStuff badstuff = data; + QCryptoBlock *blk; + Buffer buf; + Object *sec = test_block_secret(); + QCryptoBlockLUKSHeader hdr; + Error *err = NULL; + const char *msg; + + memset(&buf, 0, sizeof(buf)); + buffer_init(&buf, "header"); + + /* Correctly create the volume initially */ + blk = qcrypto_block_create(&luks_create_opts_default, NULL, + test_block_init_func, + test_block_write_func, + &buf, + &error_abort); + g_assert(blk); + + qcrypto_block_free(blk); + + /* Mangle it in some unpleasant way */ + g_assert(buf.offset >= sizeof(hdr)); + memcpy(&hdr, buf.buffer, sizeof(hdr)); + qcrypto_block_luks_to_disk_endian(&hdr); + + msg = badstuff(&hdr); + + qcrypto_block_luks_from_disk_endian(&hdr); + memcpy(buf.buffer, &hdr, sizeof(hdr)); + + /* Check that we fail to open it again */ + blk = qcrypto_block_open(&luks_open_opts, NULL, + test_block_read_func, + &buf, + 0, + 1, + &err); + g_assert(!blk); + g_assert(err); + + g_assert_cmpstr(error_get_pretty(err), ==, msg); + error_free(err); + + object_unparent(sec); + + buffer_free(&buf); +} + +static const char *luks_bad_null_term_cipher_name(QCryptoBlockLUKSHeader *hdr) +{ + /* Replace NUL termination with spaces */ + char *offset = hdr->cipher_name + strlen(hdr->cipher_name); + memset(offset, ' ', sizeof(hdr->cipher_name) - (offset - hdr->cipher_name)); + + return "LUKS header cipher name is not NUL terminated"; +} + +static const char *luks_bad_null_term_cipher_mode(QCryptoBlockLUKSHeader *hdr) +{ + /* Replace NUL termination with spaces */ + char *offset = hdr->cipher_mode + strlen(hdr->cipher_mode); + memset(offset, ' ', sizeof(hdr->cipher_mode) - (offset - hdr->cipher_mode)); + + return "LUKS header cipher mode is not NUL terminated"; +} + +static const char *luks_bad_null_term_hash_spec(QCryptoBlockLUKSHeader *hdr) +{ + /* Replace NUL termination with spaces */ + char *offset = hdr->hash_spec + strlen(hdr->hash_spec); + memset(offset, ' ', sizeof(hdr->hash_spec) - (offset - hdr->hash_spec)); + + return "LUKS header hash spec is not NUL terminated"; +} + +static const char *luks_bad_cipher_name_empty(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_name, "", 1); + + return "Algorithm '' with key size 32 bytes not supported"; +} + +static const char *luks_bad_cipher_name_unknown(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_name, "aess", 5); + + return "Algorithm 'aess' with key size 32 bytes not supported"; +} + +static const char *luks_bad_cipher_xts_size(QCryptoBlockLUKSHeader *hdr) +{ + hdr->master_key_len = 33; + + return "XTS cipher key length should be a multiple of 2"; +} + +static const char *luks_bad_cipher_cbc_size(QCryptoBlockLUKSHeader *hdr) +{ + hdr->master_key_len = 33; + memcpy(hdr->cipher_mode, "cbc-essiv", 10); + + return "Algorithm 'aes' with key size 33 bytes not supported"; +} + +static const char *luks_bad_cipher_mode_empty(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_mode, "", 1); + + return "Unexpected cipher mode string format ''"; +} + +static const char *luks_bad_cipher_mode_unknown(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_mode, "xfs", 4); + + return "Unexpected cipher mode string format 'xfs'"; +} + +static const char *luks_bad_ivgen_separator(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_mode, "xts:plain64", 12); + + return "Unexpected cipher mode string format 'xts:plain64'"; +} + +static const char *luks_bad_ivgen_name_empty(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_mode, "xts-", 5); + + return "IV generator '' not supported"; +} + +static const char *luks_bad_ivgen_name_unknown(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_mode, "xts-plain65", 12); + + return "IV generator 'plain65' not supported"; +} + +static const char *luks_bad_ivgen_hash_empty(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_mode, "xts-plain65:", 13); + + return "Hash algorithm '' not supported"; +} + +static const char *luks_bad_ivgen_hash_unknown(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->cipher_mode, "xts-plain65:sha257", 19); + + return "Hash algorithm 'sha257' not supported"; +} + +static const char *luks_bad_hash_spec_empty(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->hash_spec, "", 1); + + return "Hash algorithm '' not supported"; +} + +static const char *luks_bad_hash_spec_unknown(QCryptoBlockLUKSHeader *hdr) +{ + memcpy(hdr->hash_spec, "sha2566", 8); + + return "Hash algorithm 'sha2566' not supported"; +} + +static const char *luks_bad_stripes(QCryptoBlockLUKSHeader *hdr) +{ + hdr->key_slots[0].stripes = 3999; + + return "Keyslot 0 is corrupted (stripes 3999 != 4000)"; +} + +static const char *luks_bad_key_overlap_header(QCryptoBlockLUKSHeader *hdr) +{ + hdr->key_slots[0].key_offset_sector = 2; + + return "Keyslot 0 is overlapping with the LUKS header"; +} + +static const char *luks_bad_key_overlap_key(QCryptoBlockLUKSHeader *hdr) +{ + hdr->key_slots[0].key_offset_sector = hdr->key_slots[1].key_offset_sector; + + return "Keyslots 0 and 1 are overlapping in the header"; +} + +static const char *luks_bad_key_overlap_payload(QCryptoBlockLUKSHeader *hdr) +{ + hdr->key_slots[0].key_offset_sector = hdr->payload_offset_sector + 42; + + return "Keyslot 0 is overlapping with the encrypted payload"; +} + +static const char *luks_bad_payload_overlap_header(QCryptoBlockLUKSHeader *hdr) +{ + hdr->payload_offset_sector = 2; + + return "LUKS payload is overlapping with the header"; +} + +static const char *luks_bad_key_iterations(QCryptoBlockLUKSHeader *hdr) +{ + hdr->key_slots[0].iterations = 0; + + return "Keyslot 0 iteration count is zero"; +} + +static const char *luks_bad_iterations(QCryptoBlockLUKSHeader *hdr) +{ + hdr->master_key_iterations = 0; + + return "LUKS key iteration count is zero"; +} +#endif + int main(int argc, char **argv) { gsize i; @@ -364,5 +590,79 @@ int main(int argc, char **argv) } } +#ifdef TEST_LUKS + if (g_test_slow()) { + g_test_add_data_func("/crypto/block/luks/bad/cipher-name-nul-term", + luks_bad_null_term_cipher_name, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-nul-term", + luks_bad_null_term_cipher_mode, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/hash-spec-nul-term", + luks_bad_null_term_hash_spec, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/cipher-name-empty", + luks_bad_cipher_name_empty, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/cipher-name-unknown", + luks_bad_cipher_name_unknown, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/cipher-xts-size", + luks_bad_cipher_xts_size, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/cipher-cbc-size", + luks_bad_cipher_cbc_size, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-empty", + luks_bad_cipher_mode_empty, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/cipher-mode-unknown", + luks_bad_cipher_mode_unknown, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/ivgen-separator", + luks_bad_ivgen_separator, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/ivgen-name-empty", + luks_bad_ivgen_name_empty, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/ivgen-name-unknown", + luks_bad_ivgen_name_unknown, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/ivgen-hash-empty", + luks_bad_ivgen_hash_empty, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/ivgen-hash-unknown", + luks_bad_ivgen_hash_unknown, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/hash-spec-empty", + luks_bad_hash_spec_empty, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/hash-spec-unknown", + luks_bad_hash_spec_unknown, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/stripes", + luks_bad_stripes, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/key-overlap-header", + luks_bad_key_overlap_header, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/key-overlap-key", + luks_bad_key_overlap_key, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/key-overlap-payload", + luks_bad_key_overlap_payload, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/payload-overlap-header", + luks_bad_payload_overlap_header, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/iterations", + luks_bad_iterations, + test_luks_bad_header); + g_test_add_data_func("/crypto/block/luks/bad/key-iterations", + luks_bad_key_iterations, + test_luks_bad_header); + } +#endif + return g_test_run(); } diff --git a/tests/vm/freebsd b/tests/vm/freebsd index 3643fe325d..d6ff4461ba 100755 --- a/tests/vm/freebsd +++ b/tests/vm/freebsd @@ -66,6 +66,9 @@ class FreeBSDVM(basevm.BaseVM): # libs: networking "libslirp", + + # libs: sndio + "sndio", ] BUILD_SCRIPT = """ diff --git a/tests/vm/openbsd b/tests/vm/openbsd index 6f1b6f5b98..eaeb201e91 100755 --- a/tests/vm/openbsd +++ b/tests/vm/openbsd @@ -22,8 +22,8 @@ class OpenBSDVM(basevm.BaseVM): name = "openbsd" arch = "x86_64" - link = "https://cdn.openbsd.org/pub/OpenBSD/7.1/amd64/install71.iso" - csum = "d3a7c5b9bf890bc404304a1c96f9ee72e1d9bbcf9cc849c1133bdb0d67843396" + link = "https://cdn.openbsd.org/pub/OpenBSD/7.2/amd64/install72.iso" + csum = "0369ef40a3329efcb978c578c7fdc7bda71e502aecec930a74b44160928c91d3" size = "20G" pkgs = [ # tools @@ -56,6 +56,9 @@ class OpenBSDVM(basevm.BaseVM): # libs: migration "zstd", + + # libs: networking + "libslirp", ] BUILD_SCRIPT = """ diff --git a/util/meson.build b/util/meson.build index 5e282130df..c0a7bc54d4 100644 --- a/util/meson.build +++ b/util/meson.build @@ -1,4 +1,5 @@ util_ss.add(files('osdep.c', 'cutils.c', 'unicode.c', 'qemu-timer-common.c')) +util_ss.add(files('thread-context.c'), numa) if not config_host_data.get('CONFIG_ATOMIC64') util_ss.add(files('atomic64.c')) endif diff --git a/util/osdep.c b/util/osdep.c index 746d5f7d71..77c1a6c562 100644 --- a/util/osdep.c +++ b/util/osdep.c @@ -502,6 +502,28 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen) return ret; } +ssize_t qemu_send_full(int s, const void *buf, size_t count) +{ + ssize_t ret = 0; + ssize_t total = 0; + + while (count) { + ret = send(s, buf, count, 0); + if (ret < 0) { + if (errno == EINTR) { + continue; + } + break; + } + + count -= ret; + buf += ret; + total += ret; + } + + return total; +} + void qemu_set_hw_version(const char *version) { hw_version = version; diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 827a7aadba..59a891b6a8 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -42,6 +42,7 @@ #include "qemu/cutils.h" #include "qemu/compiler.h" #include "qemu/units.h" +#include "qemu/thread-context.h" #ifdef CONFIG_LINUX #include <sys/syscall.h> @@ -329,7 +330,7 @@ static void sigbus_handler(int signal) return; } #endif /* CONFIG_LINUX */ - warn_report("os_mem_prealloc: unrelated SIGBUS detected and ignored"); + warn_report("qemu_prealloc_mem: unrelated SIGBUS detected and ignored"); } static void *do_touch_pages(void *arg) @@ -399,13 +400,13 @@ static void *do_madv_populate_write_pages(void *arg) } static inline int get_memset_num_threads(size_t hpagesize, size_t numpages, - int smp_cpus) + int max_threads) { long host_procs = sysconf(_SC_NPROCESSORS_ONLN); int ret = 1; if (host_procs > 0) { - ret = MIN(MIN(host_procs, MAX_MEM_PREALLOC_THREAD_COUNT), smp_cpus); + ret = MIN(MIN(host_procs, MAX_MEM_PREALLOC_THREAD_COUNT), max_threads); } /* Especially with gigantic pages, don't create more threads than pages. */ @@ -418,11 +419,12 @@ static inline int get_memset_num_threads(size_t hpagesize, size_t numpages, } static int touch_all_pages(char *area, size_t hpagesize, size_t numpages, - int smp_cpus, bool use_madv_populate_write) + int max_threads, ThreadContext *tc, + bool use_madv_populate_write) { static gsize initialized = 0; MemsetContext context = { - .num_threads = get_memset_num_threads(hpagesize, numpages, smp_cpus), + .num_threads = get_memset_num_threads(hpagesize, numpages, max_threads), }; size_t numpages_per_thread, leftover; void *(*touch_fn)(void *); @@ -457,9 +459,16 @@ static int touch_all_pages(char *area, size_t hpagesize, size_t numpages, context.threads[i].numpages = numpages_per_thread + (i < leftover); context.threads[i].hpagesize = hpagesize; context.threads[i].context = &context; - qemu_thread_create(&context.threads[i].pgthread, "touch_pages", - touch_fn, &context.threads[i], - QEMU_THREAD_JOINABLE); + if (tc) { + thread_context_create_thread(tc, &context.threads[i].pgthread, + "touch_pages", + touch_fn, &context.threads[i], + QEMU_THREAD_JOINABLE); + } else { + qemu_thread_create(&context.threads[i].pgthread, "touch_pages", + touch_fn, &context.threads[i], + QEMU_THREAD_JOINABLE); + } addr += context.threads[i].numpages * hpagesize; } @@ -494,13 +503,13 @@ static bool madv_populate_write_possible(char *area, size_t pagesize) errno != EINVAL; } -void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus, - Error **errp) +void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, + ThreadContext *tc, Error **errp) { static gsize initialized; int ret; size_t hpagesize = qemu_fd_getpagesize(fd); - size_t numpages = DIV_ROUND_UP(memory, hpagesize); + size_t numpages = DIV_ROUND_UP(sz, hpagesize); bool use_madv_populate_write; struct sigaction act; @@ -530,24 +539,24 @@ void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus, if (ret) { qemu_mutex_unlock(&sigbus_mutex); error_setg_errno(errp, errno, - "os_mem_prealloc: failed to install signal handler"); + "qemu_prealloc_mem: failed to install signal handler"); return; } } /* touch pages simultaneously */ - ret = touch_all_pages(area, hpagesize, numpages, smp_cpus, + ret = touch_all_pages(area, hpagesize, numpages, max_threads, tc, use_madv_populate_write); if (ret) { error_setg_errno(errp, -ret, - "os_mem_prealloc: preallocating memory failed"); + "qemu_prealloc_mem: preallocating memory failed"); } if (!use_madv_populate_write) { ret = sigaction(SIGBUS, &sigbus_oldact, NULL); if (ret) { /* Terminate QEMU since it can't recover from error */ - perror("os_mem_prealloc: failed to reinstall signal handler"); + perror("qemu_prealloc_mem: failed to reinstall signal handler"); exit(1); } qemu_mutex_unlock(&sigbus_mutex); diff --git a/util/oslib-win32.c b/util/oslib-win32.c index 5723d3eb4c..a67cb3822e 100644 --- a/util/oslib-win32.c +++ b/util/oslib-win32.c @@ -268,14 +268,14 @@ int getpagesize(void) return system_info.dwPageSize; } -void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus, - Error **errp) +void qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, + ThreadContext *tc, Error **errp) { int i; size_t pagesize = qemu_real_host_page_size(); - memory = (memory + pagesize - 1) & -pagesize; - for (i = 0; i < memory / pagesize; i++) { + sz = (sz + pagesize - 1) & -pagesize; + for (i = 0; i < sz / pagesize; i++) { memset(area + pagesize * i, 0, 1); } } diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 83f4bd6fd2..d185245023 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -919,9 +919,8 @@ static int unix_listen_saddr(UnixSocketAddress *saddr, if (saddr->path[0] || abstract) { path = saddr->path; } else { - const char *tmpdir = getenv("TMPDIR"); - tmpdir = tmpdir ? tmpdir : "/tmp"; - path = pathbuf = g_strdup_printf("%s/qemu-socket-XXXXXX", tmpdir); + path = pathbuf = g_strdup_printf("%s/qemu-socket-XXXXXX", + g_get_tmp_dir()); } pathlen = strlen(path); @@ -1077,6 +1076,26 @@ int unix_connect(const char *path, Error **errp) return sock; } +char *socket_uri(SocketAddress *addr) +{ + switch (addr->type) { + case SOCKET_ADDRESS_TYPE_INET: + return g_strdup_printf("tcp:%s:%s", + addr->u.inet.host, + addr->u.inet.port); + case SOCKET_ADDRESS_TYPE_UNIX: + return g_strdup_printf("unix:%s", + addr->u.q_unix.path); + case SOCKET_ADDRESS_TYPE_FD: + return g_strdup_printf("fd:%s", addr->u.fd.str); + case SOCKET_ADDRESS_TYPE_VSOCK: + return g_strdup_printf("vsock:%s:%s", + addr->u.vsock.cid, + addr->u.vsock.port); + default: + return g_strdup("unknown address type"); + } +} SocketAddress *socket_parse(const char *str, Error **errp) { @@ -1104,6 +1123,11 @@ SocketAddress *socket_parse(const char *str, Error **errp) if (vsock_parse(&addr->u.vsock, str + strlen("vsock:"), errp)) { goto fail; } + } else if (strstart(str, "tcp:", NULL)) { + addr->type = SOCKET_ADDRESS_TYPE_INET; + if (inet_parse(&addr->u.inet, str + strlen("tcp:"), errp)) { + goto fail; + } } else { addr->type = SOCKET_ADDRESS_TYPE_INET; if (inet_parse(&addr->u.inet, str, errp)) { diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index ac1d56e673..bae938c670 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -16,6 +16,7 @@ #include "qemu/notify.h" #include "qemu-thread-common.h" #include "qemu/tsan.h" +#include "qemu/bitmap.h" static bool name_threads; @@ -552,6 +553,75 @@ void qemu_thread_create(QemuThread *thread, const char *name, pthread_attr_destroy(&attr); } +int qemu_thread_set_affinity(QemuThread *thread, unsigned long *host_cpus, + unsigned long nbits) +{ +#if defined(CONFIG_PTHREAD_AFFINITY_NP) + const size_t setsize = CPU_ALLOC_SIZE(nbits); + unsigned long value; + cpu_set_t *cpuset; + int err; + + cpuset = CPU_ALLOC(nbits); + g_assert(cpuset); + + CPU_ZERO_S(setsize, cpuset); + value = find_first_bit(host_cpus, nbits); + while (value < nbits) { + CPU_SET_S(value, setsize, cpuset); + value = find_next_bit(host_cpus, nbits, value + 1); + } + + err = pthread_setaffinity_np(thread->thread, setsize, cpuset); + CPU_FREE(cpuset); + return err; +#else + return -ENOSYS; +#endif +} + +int qemu_thread_get_affinity(QemuThread *thread, unsigned long **host_cpus, + unsigned long *nbits) +{ +#if defined(CONFIG_PTHREAD_AFFINITY_NP) + unsigned long tmpbits; + cpu_set_t *cpuset; + size_t setsize; + int i, err; + + tmpbits = CPU_SETSIZE; + while (true) { + setsize = CPU_ALLOC_SIZE(tmpbits); + cpuset = CPU_ALLOC(tmpbits); + g_assert(cpuset); + + err = pthread_getaffinity_np(thread->thread, setsize, cpuset); + if (err) { + CPU_FREE(cpuset); + if (err != -EINVAL) { + return err; + } + tmpbits *= 2; + } else { + break; + } + } + + /* Convert the result into a proper bitmap. */ + *nbits = tmpbits; + *host_cpus = bitmap_new(tmpbits); + for (i = 0; i < tmpbits; i++) { + if (CPU_ISSET(i, cpuset)) { + set_bit(i, *host_cpus); + } + } + CPU_FREE(cpuset); + return 0; +#else + return -ENOSYS; +#endif +} + void qemu_thread_get_self(QemuThread *thread) { thread->thread = pthread_self(); diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c index b9a467d7db..69db254ac7 100644 --- a/util/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c @@ -477,6 +477,18 @@ void qemu_thread_create(QemuThread *thread, const char *name, thread->data = data; } +int qemu_thread_set_affinity(QemuThread *thread, unsigned long *host_cpus, + unsigned long nbits) +{ + return -ENOSYS; +} + +int qemu_thread_get_affinity(QemuThread *thread, unsigned long **host_cpus, + unsigned long *nbits) +{ + return -ENOSYS; +} + void qemu_thread_get_self(QemuThread *thread) { thread->data = qemu_thread_data; diff --git a/util/thread-context.c b/util/thread-context.c new file mode 100644 index 0000000000..4138245332 --- /dev/null +++ b/util/thread-context.c @@ -0,0 +1,362 @@ +/* + * QEMU Thread Context + * + * Copyright Red Hat Inc., 2022 + * + * Authors: + * David Hildenbrand <david@redhat.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/thread-context.h" +#include "qapi/error.h" +#include "qapi/qapi-builtin-visit.h" +#include "qapi/visitor.h" +#include "qemu/config-file.h" +#include "qapi/qapi-builtin-visit.h" +#include "qom/object_interfaces.h" +#include "qemu/module.h" +#include "qemu/bitmap.h" + +#ifdef CONFIG_NUMA +#include <numa.h> +#endif + +enum { + TC_CMD_NONE = 0, + TC_CMD_STOP, + TC_CMD_NEW, +}; + +typedef struct ThreadContextCmdNew { + QemuThread *thread; + const char *name; + void *(*start_routine)(void *); + void *arg; + int mode; +} ThreadContextCmdNew; + +static void *thread_context_run(void *opaque) +{ + ThreadContext *tc = opaque; + + tc->thread_id = qemu_get_thread_id(); + qemu_sem_post(&tc->sem); + + while (true) { + /* + * Threads inherit the CPU affinity of the creating thread. For this + * reason, we create new (especially short-lived) threads from our + * persistent context thread. + * + * Especially when QEMU is not allowed to set the affinity itself, + * management tools can simply set the affinity of the context thread + * after creating the context, to have new threads created via + * the context inherit the CPU affinity automatically. + */ + switch (tc->thread_cmd) { + case TC_CMD_NONE: + break; + case TC_CMD_STOP: + tc->thread_cmd = TC_CMD_NONE; + qemu_sem_post(&tc->sem); + return NULL; + case TC_CMD_NEW: { + ThreadContextCmdNew *cmd_new = tc->thread_cmd_data; + + qemu_thread_create(cmd_new->thread, cmd_new->name, + cmd_new->start_routine, cmd_new->arg, + cmd_new->mode); + tc->thread_cmd = TC_CMD_NONE; + tc->thread_cmd_data = NULL; + qemu_sem_post(&tc->sem); + break; + } + default: + g_assert_not_reached(); + } + qemu_sem_wait(&tc->sem_thread); + } +} + +static void thread_context_set_cpu_affinity(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + ThreadContext *tc = THREAD_CONTEXT(obj); + uint16List *l, *host_cpus = NULL; + unsigned long *bitmap = NULL; + int nbits = 0, ret; + Error *err = NULL; + + if (tc->init_cpu_bitmap) { + error_setg(errp, "Mixing CPU and node affinity not supported"); + return; + } + + visit_type_uint16List(v, name, &host_cpus, &err); + if (err) { + error_propagate(errp, err); + return; + } + + if (!host_cpus) { + error_setg(errp, "CPU list is empty"); + goto out; + } + + for (l = host_cpus; l; l = l->next) { + nbits = MAX(nbits, l->value + 1); + } + bitmap = bitmap_new(nbits); + for (l = host_cpus; l; l = l->next) { + set_bit(l->value, bitmap); + } + + if (tc->thread_id != -1) { + /* + * Note: we won't be adjusting the affinity of any thread that is still + * around, but only the affinity of the context thread. + */ + ret = qemu_thread_set_affinity(&tc->thread, bitmap, nbits); + if (ret) { + error_setg(errp, "Setting CPU affinity failed: %s", strerror(ret)); + } + } else { + tc->init_cpu_bitmap = bitmap; + bitmap = NULL; + tc->init_cpu_nbits = nbits; + } +out: + g_free(bitmap); + qapi_free_uint16List(host_cpus); +} + +static void thread_context_get_cpu_affinity(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + unsigned long *bitmap, nbits, value; + ThreadContext *tc = THREAD_CONTEXT(obj); + uint16List *host_cpus = NULL; + uint16List **tail = &host_cpus; + int ret; + + if (tc->thread_id == -1) { + error_setg(errp, "Object not initialized yet"); + return; + } + + ret = qemu_thread_get_affinity(&tc->thread, &bitmap, &nbits); + if (ret) { + error_setg(errp, "Getting CPU affinity failed: %s", strerror(ret)); + return; + } + + value = find_first_bit(bitmap, nbits); + while (value < nbits) { + QAPI_LIST_APPEND(tail, value); + + value = find_next_bit(bitmap, nbits, value + 1); + } + g_free(bitmap); + + visit_type_uint16List(v, name, &host_cpus, errp); + qapi_free_uint16List(host_cpus); +} + +static void thread_context_set_node_affinity(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ +#ifdef CONFIG_NUMA + const int nbits = numa_num_possible_cpus(); + ThreadContext *tc = THREAD_CONTEXT(obj); + uint16List *l, *host_nodes = NULL; + unsigned long *bitmap = NULL; + struct bitmask *tmp_cpus; + Error *err = NULL; + int ret, i; + + if (tc->init_cpu_bitmap) { + error_setg(errp, "Mixing CPU and node affinity not supported"); + return; + } + + visit_type_uint16List(v, name, &host_nodes, &err); + if (err) { + error_propagate(errp, err); + return; + } + + if (!host_nodes) { + error_setg(errp, "Node list is empty"); + goto out; + } + + bitmap = bitmap_new(nbits); + tmp_cpus = numa_allocate_cpumask(); + for (l = host_nodes; l; l = l->next) { + numa_bitmask_clearall(tmp_cpus); + ret = numa_node_to_cpus(l->value, tmp_cpus); + if (ret) { + /* We ignore any errors, such as impossible nodes. */ + continue; + } + for (i = 0; i < nbits; i++) { + if (numa_bitmask_isbitset(tmp_cpus, i)) { + set_bit(i, bitmap); + } + } + } + numa_free_cpumask(tmp_cpus); + + if (bitmap_empty(bitmap, nbits)) { + error_setg(errp, "The nodes select no CPUs"); + goto out; + } + + if (tc->thread_id != -1) { + /* + * Note: we won't be adjusting the affinity of any thread that is still + * around for now, but only the affinity of the context thread. + */ + ret = qemu_thread_set_affinity(&tc->thread, bitmap, nbits); + if (ret) { + error_setg(errp, "Setting CPU affinity failed: %s", strerror(ret)); + } + } else { + tc->init_cpu_bitmap = bitmap; + bitmap = NULL; + tc->init_cpu_nbits = nbits; + } +out: + g_free(bitmap); + qapi_free_uint16List(host_nodes); +#else + error_setg(errp, "NUMA node affinity is not supported by this QEMU"); +#endif +} + +static void thread_context_get_thread_id(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + ThreadContext *tc = THREAD_CONTEXT(obj); + uint64_t value = tc->thread_id; + + visit_type_uint64(v, name, &value, errp); +} + +static void thread_context_instance_complete(UserCreatable *uc, Error **errp) +{ + ThreadContext *tc = THREAD_CONTEXT(uc); + char *thread_name; + int ret; + + thread_name = g_strdup_printf("TC %s", + object_get_canonical_path_component(OBJECT(uc))); + qemu_thread_create(&tc->thread, thread_name, thread_context_run, tc, + QEMU_THREAD_JOINABLE); + g_free(thread_name); + + /* Wait until initialization of the thread is done. */ + while (tc->thread_id == -1) { + qemu_sem_wait(&tc->sem); + } + + if (tc->init_cpu_bitmap) { + ret = qemu_thread_set_affinity(&tc->thread, tc->init_cpu_bitmap, + tc->init_cpu_nbits); + if (ret) { + error_setg(errp, "Setting CPU affinity failed: %s", strerror(ret)); + } + g_free(tc->init_cpu_bitmap); + tc->init_cpu_bitmap = NULL; + } +} + +static void thread_context_class_init(ObjectClass *oc, void *data) +{ + UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); + + ucc->complete = thread_context_instance_complete; + object_class_property_add(oc, "thread-id", "int", + thread_context_get_thread_id, NULL, NULL, + NULL); + object_class_property_add(oc, "cpu-affinity", "int", + thread_context_get_cpu_affinity, + thread_context_set_cpu_affinity, NULL, NULL); + object_class_property_add(oc, "node-affinity", "int", NULL, + thread_context_set_node_affinity, NULL, NULL); +} + +static void thread_context_instance_init(Object *obj) +{ + ThreadContext *tc = THREAD_CONTEXT(obj); + + tc->thread_id = -1; + qemu_sem_init(&tc->sem, 0); + qemu_sem_init(&tc->sem_thread, 0); + qemu_mutex_init(&tc->mutex); +} + +static void thread_context_instance_finalize(Object *obj) +{ + ThreadContext *tc = THREAD_CONTEXT(obj); + + if (tc->thread_id != -1) { + tc->thread_cmd = TC_CMD_STOP; + qemu_sem_post(&tc->sem_thread); + qemu_thread_join(&tc->thread); + } + qemu_sem_destroy(&tc->sem); + qemu_sem_destroy(&tc->sem_thread); + qemu_mutex_destroy(&tc->mutex); +} + +static const TypeInfo thread_context_info = { + .name = TYPE_THREAD_CONTEXT, + .parent = TYPE_OBJECT, + .class_init = thread_context_class_init, + .instance_size = sizeof(ThreadContext), + .instance_init = thread_context_instance_init, + .instance_finalize = thread_context_instance_finalize, + .interfaces = (InterfaceInfo[]) { + { TYPE_USER_CREATABLE }, + { } + } +}; + +static void thread_context_register_types(void) +{ + type_register_static(&thread_context_info); +} +type_init(thread_context_register_types) + +void thread_context_create_thread(ThreadContext *tc, QemuThread *thread, + const char *name, + void *(*start_routine)(void *), void *arg, + int mode) +{ + ThreadContextCmdNew data = { + .thread = thread, + .name = name, + .start_routine = start_routine, + .arg = arg, + .mode = mode, + }; + + qemu_mutex_lock(&tc->mutex); + tc->thread_cmd = TC_CMD_NEW; + tc->thread_cmd_data = &data; + qemu_sem_post(&tc->sem_thread); + + while (tc->thread_cmd != TC_CMD_NONE) { + qemu_sem_wait(&tc->sem); + } + qemu_mutex_unlock(&tc->mutex); +} |