- libseccomp-dev
- libspice-protocol-dev
- libspice-server-dev
- - libssh2-1-dev
+ - libssh-dev
- liburcu-dev
- libusb-1.0-0-dev
- libvte-2.91-dev
- libseccomp-dev
- libspice-protocol-dev
- libspice-server-dev
- - libssh2-1-dev
+ - libssh-dev
- liburcu-dev
- libusb-1.0-0-dev
- libvte-2.91-dev
F: target/s390x/ioinst.[ch]
F: target/s390x/machine.c
F: target/s390x/sigp.c
+F: target/s390x/cpu_features*.[ch]
+F: target/s390x/cpu_models.[ch]
F: hw/intc/s390_flic.c
F: hw/intc/s390_flic_kvm.c
F: include/hw/s390x/s390_flic.h
L: xen-devel@lists.xenproject.org
S: Supported
F: */xen*
-F: hw/9pfs/xen-9p-backend.c
+F: hw/9pfs/xen-9p*
F: hw/char/xen_console.c
F: hw/display/xenfb.c
F: hw/net/xen_nic.c
F: include/hw/misc/imx6_*.h
F: include/hw/ssi/imx_spi.h
+SBSA-REF
+M: Radoslaw Biernacki <radoslaw.biernacki@linaro.org>
+M: Peter Maydell <peter.maydell@linaro.org>
+R: Leif Lindholm <leif.lindholm@linaro.org>
+L: qemu-arm@nongnu.org
+S: Maintained
+F: hw/arm/sbsa-ref.c
+
Sharp SL-5500 (Collie) PDA
M: Peter Maydell <peter.maydell@linaro.org>
L: qemu-arm@nongnu.org
M: Eduardo Habkost <ehabkost@redhat.com>
M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
S: Supported
+F: hw/core/machine-qmp-cmds.c
F: hw/core/machine.c
F: hw/core/null-machine.c
+F: hw/core/numa.c
F: hw/cpu/cluster.c
+F: qapi/machine.json
+F: qapi/machine-target.json
+F: qom/cpu.c
F: include/hw/boards.h
F: include/hw/cpu/cluster.h
+F: include/qom/cpu.h
+F: include/sysemu/numa.h
T: git https://github.com/ehabkost/qemu.git machine-next
Xtensa Machines
M: Greg Kurz <groug@kaod.org>
S: Supported
F: hw/9pfs/
+X: hw/9pfs/xen-9p*
F: fsdev/
F: tests/virtio-9p-test.c
T: git https://github.com/gkurz/qemu.git 9p-next
S: Supported
F: scripts/coverity-model.c
-CPU
-S: Supported
-F: qom/cpu.c
-F: include/qom/cpu.h
-
Device Tree
M: Alistair Francis <alistair.francis@wdc.com>
R: David Gibson <david@gibson.dropbear.id.au>
Dump
S: Supported
M: Marc-André Lureau <marcandre.lureau@redhat.com>
-F: dump.c
+F: dump/
F: hw/misc/vmcoreinfo.c
F: include/hw/misc/vmcoreinfo.h
+F: include/qemu/win_dump_defs
F: include/sysemu/dump-arch.h
F: include/sysemu/dump.h
+F: qapi/dump.json
F: scripts/dump-guest-memory.py
F: stubs/dump.c
S: Maintained
F: net/
F: include/net/
+F: qemu-bridge-helper.c
T: git https://github.com/jasowang/qemu.git net
F: qapi/net.json
S: Maintained
F: net/netmap.c
-NUMA
-M: Eduardo Habkost <ehabkost@redhat.com>
-S: Maintained
-F: numa.c
-F: include/sysemu/numa.h
-T: git https://github.com/ehabkost/qemu.git machine-next
-
Host Memory Backends
M: Eduardo Habkost <ehabkost@redhat.com>
M: Igor Mammedov <imammedo@redhat.com>
T: git https://github.com/mdroth/qemu.git qga
QOM
-M: Andreas Färber <afaerber@suse.de>
+M: Paolo Bonzini <pbonzini@redhat.com>
+R: Daniel P. Berrange <berrange@redhat.com>
+R: Eduardo Habkost <ehabkost@redhat.com>
S: Supported
-T: git https://github.com/afaerber/qemu-cpu.git qom-next
+F: docs/qdev-device-use.txt
+F: hw/core/qdev*
+F: include/hw/qdev*
+F: include/monitor/qdev.h
F: include/qom/
X: include/qom/cpu.h
+F: qapi/qom.json
+F: qapi/qdev.json
+F: qdev-monitor.c
F: qom/
X: qom/cpu.c
F: tests/check-qom-interface.c
F: tests/check-qom-proplist.c
+F: tests/test-qdev-global-props.c
QMP
M: Markus Armbruster <armbru@redhat.com>
# Makefile for QEMU.
+ifneq ($(words $(subst :, ,$(CURDIR))), 1)
+ $(error main directory cannot contain spaces nor colons)
+endif
+
# Always point to the root of the build tree (needs GNU make).
BUILD_DIR=$(CURDIR)
ifdef INSTALL_BLOBS
BLOBS=bios.bin bios-256k.bin sgabios.bin vgabios.bin vgabios-cirrus.bin \
vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin vgabios-virtio.bin \
-vgabios-ramfb.bin vgabios-bochs-display.bin \
+vgabios-ramfb.bin vgabios-bochs-display.bin vgabios-ati.bin \
ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc QEMU,tcx.bin QEMU,cgthree.bin \
pxe-e1000.rom pxe-eepro100.rom pxe-ne2k_pci.rom \
pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
done
endif
for s in $(ICON_SIZES); do \
- mkdir -p "$(DESTDIR)/$(qemu_icondir)/hicolor/$${s}/apps"; \
+ mkdir -p "$(DESTDIR)$(qemu_icondir)/hicolor/$${s}/apps"; \
$(INSTALL_DATA) $(SRC_PATH)/ui/icons/qemu_$${s}.png \
- "$(DESTDIR)/$(qemu_icondir)/hicolor/$${s}/apps/qemu.png"; \
+ "$(DESTDIR)$(qemu_icondir)/hicolor/$${s}/apps/qemu.png"; \
done; \
- mkdir -p "$(DESTDIR)/$(qemu_icondir)/hicolor/32x32/apps"; \
+ mkdir -p "$(DESTDIR)$(qemu_icondir)/hicolor/32x32/apps"; \
$(INSTALL_DATA) $(SRC_PATH)/ui/icons/qemu_32x32.bmp \
- "$(DESTDIR)/$(qemu_icondir)/hicolor/32x32/apps/qemu.bmp"; \
- mkdir -p "$(DESTDIR)/$(qemu_icondir)/hicolor/scalable/apps"; \
+ "$(DESTDIR)$(qemu_icondir)/hicolor/32x32/apps/qemu.bmp"; \
+ mkdir -p "$(DESTDIR)$(qemu_icondir)/hicolor/scalable/apps"; \
$(INSTALL_DATA) $(SRC_PATH)/ui/icons/qemu.svg \
- "$(DESTDIR)/$(qemu_icondir)/hicolor/scalable/apps/qemu.svg"
- mkdir -p "$(DESTDIR)/$(qemu_desktopdir)"
+ "$(DESTDIR)$(qemu_icondir)/hicolor/scalable/apps/qemu.svg"
+ mkdir -p "$(DESTDIR)$(qemu_desktopdir)"
$(INSTALL_DATA) $(SRC_PATH)/ui/qemu.desktop \
- "$(DESTDIR)/$(qemu_desktopdir)/qemu.desktop"
+ "$(DESTDIR)$(qemu_desktopdir)/qemu.desktop"
ifdef CONFIG_GTK
$(MAKE) -C po $@
endif
ifeq ($(CONFIG_SOFTMMU),y)
common-obj-y = blockdev.o blockdev-nbd.o block/
common-obj-y += bootdevice.o iothread.o
+common-obj-y += dump/
common-obj-y += job-qmp.o
common-obj-y += monitor/
common-obj-y += net/
# qapi
common-obj-y += qapi/
-common-obj-y += monitor/
endif
#######################################################################
trace-events-subdirs += hw/intc
trace-events-subdirs += hw/isa
trace-events-subdirs += hw/mem
+trace-events-subdirs += hw/mips
trace-events-subdirs += hw/misc
trace-events-subdirs += hw/misc/macio
trace-events-subdirs += hw/net
#########################################################
# System emulator target
ifdef CONFIG_SOFTMMU
-obj-y += arch_init.o cpus.o gdbstub.o balloon.o ioport.o numa.o
+obj-y += arch_init.o cpus.o gdbstub.o balloon.o ioport.o
obj-y += qtest.o
+obj-y += dump/
obj-y += hw/
obj-y += monitor/
obj-y += qapi/
obj-y += memory.o
obj-y += memory_mapping.o
-obj-y += dump.o
-obj-$(TARGET_X86_64) += win_dump.o
obj-y += migration/ram.o
LIBS := $(libs_softmmu) $(LIBS)
block-obj-$(CONFIG_RBD) += rbd.o
block-obj-$(CONFIG_GLUSTERFS) += gluster.o
block-obj-$(CONFIG_VXHS) += vxhs.o
-block-obj-$(CONFIG_LIBSSH2) += ssh.o
+block-obj-$(CONFIG_LIBSSH) += ssh.o
block-obj-y += accounting.o dirty-bitmap.o
block-obj-y += write-threshold.o
block-obj-y += backup.o
gluster.o-cflags := $(GLUSTERFS_CFLAGS)
gluster.o-libs := $(GLUSTERFS_LIBS)
vxhs.o-libs := $(VXHS_LIBS)
-ssh.o-cflags := $(LIBSSH2_CFLAGS)
-ssh.o-libs := $(LIBSSH2_LIBS)
+ssh.o-cflags := $(LIBSSH_CFLAGS)
+ssh.o-libs := $(LIBSSH_LIBS)
block-obj-dmg-bz2-$(CONFIG_BZIP2) += dmg-bz2.o
block-obj-$(if $(CONFIG_DMG),m,n) += $(block-obj-dmg-bz2-y)
dmg-bz2.o-libs := $(BZIP2_LIBS)
break;
}
/* Copy if allocated above the base */
- ret = bdrv_is_allocated_above(blk_bs(s->top), blk_bs(s->base),
+ ret = bdrv_is_allocated_above(blk_bs(s->top), blk_bs(s->base), false,
offset, COMMIT_BUFFER_SIZE, &n);
copy = (ret == 1);
trace_commit_one_iteration(s, offset, n, ret);
/*
* Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP]
*
- * Return true if (a prefix of) the given range is allocated in any image
- * between BASE and TOP (inclusive). BASE can be NULL to check if the given
- * offset is allocated in any image of the chain. Return false otherwise,
- * or negative errno on failure.
+ * Return 1 if (a prefix of) the given range is allocated in any image
+ * between BASE and TOP (BASE is only included if include_base is set).
+ * BASE can be NULL to check if the given offset is allocated in any
+ * image of the chain. Return 0 otherwise, or negative errno on
+ * failure.
*
* 'pnum' is set to the number of bytes (including and immediately
* following the specified offset) that are known to be in the same
*/
int bdrv_is_allocated_above(BlockDriverState *top,
BlockDriverState *base,
- int64_t offset, int64_t bytes, int64_t *pnum)
+ bool include_base, int64_t offset,
+ int64_t bytes, int64_t *pnum)
{
BlockDriverState *intermediate;
int ret;
int64_t n = bytes;
+ assert(base || !include_base);
+
intermediate = top;
- while (intermediate && intermediate != base) {
+ while (include_base || intermediate != base) {
int64_t pnum_inter;
int64_t size_inter;
+ assert(intermediate);
ret = bdrv_is_allocated(intermediate, offset, bytes, &pnum_inter);
if (ret < 0) {
return ret;
n = pnum_inter;
}
+ if (intermediate == base) {
+ break;
+ }
+
intermediate = backing_bs(intermediate);
}
return 0;
}
- ret = bdrv_is_allocated_above(bs, base, offset, bytes, &count);
+ ret = bdrv_is_allocated_above(bs, base, false, offset, bytes, &count);
if (ret < 0) {
return ret;
}
{
int64_t nr;
return !bytes ||
- (!bdrv_is_allocated_above(bs, NULL, offset, bytes, &nr) && nr == bytes);
+ (!bdrv_is_allocated_above(bs, NULL, false, offset, bytes, &nr) &&
+ nr == bytes);
}
static bool is_zero_cow(BlockDriverState *bs, QCowL2Meta *m)
rbd_image_t image;
char *image_name;
char *snap;
+ uint64_t image_size;
} BDRVRBDState;
static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
goto failed_open;
}
+ r = rbd_get_size(s->image, &s->image_size);
+ if (r < 0) {
+ error_setg_errno(errp, -r, "error getting image size from %s",
+ s->image_name);
+ rbd_close(s->image);
+ goto failed_open;
+ }
+
/* If we are using an rbd snapshot, we must be r/o, otherwise
* leave as-is */
if (s->snap != NULL) {
rados_shutdown(s->cluster);
}
+/* Resize the RBD image and update the 'image_size' with the current size */
+static int qemu_rbd_resize(BlockDriverState *bs, uint64_t size)
+{
+ BDRVRBDState *s = bs->opaque;
+ int r;
+
+ r = rbd_resize(s->image, size);
+ if (r < 0) {
+ return r;
+ }
+
+ s->image_size = size;
+
+ return 0;
+}
+
static const AIOCBInfo rbd_aiocb_info = {
.aiocb_size = sizeof(RBDAIOCB),
};
}
switch (cmd) {
- case RBD_AIO_WRITE:
+ case RBD_AIO_WRITE: {
+ /*
+ * RBD APIs don't allow us to write more than actual size, so in order
+ * to support growing images, we resize the image before write
+ * operations that exceed the current size.
+ */
+ if (off + size > s->image_size) {
+ r = qemu_rbd_resize(bs, off + size);
+ if (r < 0) {
+ goto failed_completion;
+ }
+ }
#ifdef LIBRBD_SUPPORTS_IOVEC
r = rbd_aio_writev(s->image, qiov->iov, qiov->niov, off, c);
#else
r = rbd_aio_write(s->image, off, size, rcb->buf, c);
#endif
break;
+ }
case RBD_AIO_READ:
#ifdef LIBRBD_SUPPORTS_IOVEC
r = rbd_aio_readv(s->image, qiov->iov, qiov->niov, off, c);
PreallocMode prealloc,
Error **errp)
{
- BDRVRBDState *s = bs->opaque;
int r;
if (prealloc != PREALLOC_MODE_OFF) {
return -ENOTSUP;
}
- r = rbd_resize(s->image, offset);
+ r = qemu_rbd_resize(bs, offset);
if (r < 0) {
error_setg_errno(errp, -r, "Failed to resize file");
return r;
while (remaining_sectors > 0) {
int64_t count;
- ret = bdrv_is_allocated_above(top->bs, base->bs,
+ ret = bdrv_is_allocated_above(top->bs, base->bs, false,
sector_num * BDRV_SECTOR_SIZE,
remaining_sectors * BDRV_SECTOR_SIZE,
&count);
#include "qemu/osdep.h"
-#include <libssh2.h>
-#include <libssh2_sftp.h>
+#include <libssh/libssh.h>
+#include <libssh/sftp.h>
#include "block/block_int.h"
#include "block/qdict.h"
#include "trace.h"
/*
- * TRACE_LIBSSH2=<bitmask> enables tracing in libssh2 itself. Note
- * that this requires that libssh2 was specially compiled with the
- * `./configure --enable-debug' option, so most likely you will have
- * to compile it yourself. The meaning of <bitmask> is described
- * here: http://www.libssh2.org/libssh2_trace.html
+ * TRACE_LIBSSH=<level> enables tracing in libssh itself.
+ * The meaning of <level> is described here:
+ * http://api.libssh.org/master/group__libssh__log.html
*/
-#define TRACE_LIBSSH2 0 /* or try: LIBSSH2_TRACE_SFTP */
+#define TRACE_LIBSSH 0 /* see: SSH_LOG_* */
typedef struct BDRVSSHState {
/* Coroutine. */
/* SSH connection. */
int sock; /* socket */
- LIBSSH2_SESSION *session; /* ssh session */
- LIBSSH2_SFTP *sftp; /* sftp session */
- LIBSSH2_SFTP_HANDLE *sftp_handle; /* sftp remote file handle */
+ ssh_session session; /* ssh session */
+ sftp_session sftp; /* sftp session */
+ sftp_file sftp_handle; /* sftp remote file handle */
- /* See ssh_seek() function below. */
- int64_t offset;
- bool offset_op_read;
-
- /* File attributes at open. We try to keep the .filesize field
+ /*
+ * File attributes at open. We try to keep the .size field
* updated if it changes (eg by writing at the end of the file).
*/
- LIBSSH2_SFTP_ATTRIBUTES attrs;
+ sftp_attributes attrs;
InetSocketAddress *inet;
{
memset(s, 0, sizeof *s);
s->sock = -1;
- s->offset = -1;
qemu_co_mutex_init(&s->lock);
}
{
g_free(s->user);
+ if (s->attrs) {
+ sftp_attributes_free(s->attrs);
+ }
if (s->sftp_handle) {
- libssh2_sftp_close(s->sftp_handle);
+ sftp_close(s->sftp_handle);
}
if (s->sftp) {
- libssh2_sftp_shutdown(s->sftp);
+ sftp_free(s->sftp);
}
if (s->session) {
- libssh2_session_disconnect(s->session,
- "from qemu ssh client: "
- "user closed the connection");
- libssh2_session_free(s->session);
- }
- if (s->sock >= 0) {
- close(s->sock);
+ ssh_disconnect(s->session);
+ ssh_free(s->session); /* This frees s->sock */
}
}
va_end(args);
if (s->session) {
- char *ssh_err;
+ const char *ssh_err;
int ssh_err_code;
- /* This is not an errno. See <libssh2.h>. */
- ssh_err_code = libssh2_session_last_error(s->session,
- &ssh_err, NULL, 0);
- error_setg(errp, "%s: %s (libssh2 error code: %d)",
+ /* This is not an errno. See <libssh/libssh.h>. */
+ ssh_err = ssh_get_error(s->session);
+ ssh_err_code = ssh_get_error_code(s->session);
+ error_setg(errp, "%s: %s (libssh error code: %d)",
msg, ssh_err, ssh_err_code);
} else {
error_setg(errp, "%s", msg);
va_end(args);
if (s->sftp) {
- char *ssh_err;
+ const char *ssh_err;
int ssh_err_code;
- unsigned long sftp_err_code;
+ int sftp_err_code;
- /* This is not an errno. See <libssh2.h>. */
- ssh_err_code = libssh2_session_last_error(s->session,
- &ssh_err, NULL, 0);
- /* See <libssh2_sftp.h>. */
- sftp_err_code = libssh2_sftp_last_error((s)->sftp);
+ /* This is not an errno. See <libssh/libssh.h>. */
+ ssh_err = ssh_get_error(s->session);
+ ssh_err_code = ssh_get_error_code(s->session);
+ /* See <libssh/sftp.h>. */
+ sftp_err_code = sftp_get_error(s->sftp);
error_setg(errp,
- "%s: %s (libssh2 error code: %d, sftp error code: %lu)",
+ "%s: %s (libssh error code: %d, sftp error code: %d)",
msg, ssh_err, ssh_err_code, sftp_err_code);
} else {
error_setg(errp, "%s", msg);
static void sftp_error_trace(BDRVSSHState *s, const char *op)
{
- char *ssh_err;
+ const char *ssh_err;
int ssh_err_code;
- unsigned long sftp_err_code;
+ int sftp_err_code;
- /* This is not an errno. See <libssh2.h>. */
- ssh_err_code = libssh2_session_last_error(s->session,
- &ssh_err, NULL, 0);
- /* See <libssh2_sftp.h>. */
- sftp_err_code = libssh2_sftp_last_error((s)->sftp);
+ /* This is not an errno. See <libssh/libssh.h>. */
+ ssh_err = ssh_get_error(s->session);
+ ssh_err_code = ssh_get_error_code(s->session);
+ /* See <libssh/sftp.h>. */
+ sftp_err_code = sftp_get_error(s->sftp);
trace_sftp_error(op, ssh_err, ssh_err_code, sftp_err_code);
}
parse_uri(filename, options, errp);
}
-static int check_host_key_knownhosts(BDRVSSHState *s,
- const char *host, int port, Error **errp)
+static int check_host_key_knownhosts(BDRVSSHState *s, Error **errp)
{
- const char *home;
- char *knh_file = NULL;
- LIBSSH2_KNOWNHOSTS *knh = NULL;
- struct libssh2_knownhost *found;
- int ret, r;
- const char *hostkey;
- size_t len;
- int type;
-
- hostkey = libssh2_session_hostkey(s->session, &len, &type);
- if (!hostkey) {
+ int ret;
+#ifdef HAVE_LIBSSH_0_8
+ enum ssh_known_hosts_e state;
+ int r;
+ ssh_key pubkey;
+ enum ssh_keytypes_e pubkey_type;
+ unsigned char *server_hash = NULL;
+ size_t server_hash_len;
+ char *fingerprint = NULL;
+
+ state = ssh_session_is_known_server(s->session);
+ trace_ssh_server_status(state);
+
+ switch (state) {
+ case SSH_KNOWN_HOSTS_OK:
+ /* OK */
+ trace_ssh_check_host_key_knownhosts();
+ break;
+ case SSH_KNOWN_HOSTS_CHANGED:
ret = -EINVAL;
- session_error_setg(errp, s, "failed to read remote host key");
+ r = ssh_get_server_publickey(s->session, &pubkey);
+ if (r == 0) {
+ r = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_SHA256,
+ &server_hash, &server_hash_len);
+ pubkey_type = ssh_key_type(pubkey);
+ ssh_key_free(pubkey);
+ }
+ if (r == 0) {
+ fingerprint = ssh_get_fingerprint_hash(SSH_PUBLICKEY_HASH_SHA256,
+ server_hash,
+ server_hash_len);
+ ssh_clean_pubkey_hash(&server_hash);
+ }
+ if (fingerprint) {
+ error_setg(errp,
+ "host key (%s key with fingerprint %s) does not match "
+ "the one in known_hosts; this may be a possible attack",
+ ssh_key_type_to_char(pubkey_type), fingerprint);
+ ssh_string_free_char(fingerprint);
+ } else {
+ error_setg(errp,
+ "host key does not match the one in known_hosts; this "
+ "may be a possible attack");
+ }
goto out;
- }
-
- knh = libssh2_knownhost_init(s->session);
- if (!knh) {
+ case SSH_KNOWN_HOSTS_OTHER:
ret = -EINVAL;
- session_error_setg(errp, s,
- "failed to initialize known hosts support");
+ error_setg(errp,
+ "host key for this server not found, another type exists");
+ goto out;
+ case SSH_KNOWN_HOSTS_UNKNOWN:
+ ret = -EINVAL;
+ error_setg(errp, "no host key was found in known_hosts");
+ goto out;
+ case SSH_KNOWN_HOSTS_NOT_FOUND:
+ ret = -ENOENT;
+ error_setg(errp, "known_hosts file not found");
+ goto out;
+ case SSH_KNOWN_HOSTS_ERROR:
+ ret = -EINVAL;
+ error_setg(errp, "error while checking the host");
+ goto out;
+ default:
+ ret = -EINVAL;
+ error_setg(errp, "error while checking for known server (%d)", state);
goto out;
}
+#else /* !HAVE_LIBSSH_0_8 */
+ int state;
- home = getenv("HOME");
- if (home) {
- knh_file = g_strdup_printf("%s/.ssh/known_hosts", home);
- } else {
- knh_file = g_strdup_printf("/root/.ssh/known_hosts");
- }
-
- /* Read all known hosts from OpenSSH-style known_hosts file. */
- libssh2_knownhost_readfile(knh, knh_file, LIBSSH2_KNOWNHOST_FILE_OPENSSH);
+ state = ssh_is_server_known(s->session);
+ trace_ssh_server_status(state);
- r = libssh2_knownhost_checkp(knh, host, port, hostkey, len,
- LIBSSH2_KNOWNHOST_TYPE_PLAIN|
- LIBSSH2_KNOWNHOST_KEYENC_RAW,
- &found);
- switch (r) {
- case LIBSSH2_KNOWNHOST_CHECK_MATCH:
+ switch (state) {
+ case SSH_SERVER_KNOWN_OK:
/* OK */
- trace_ssh_check_host_key_knownhosts(found->key);
+ trace_ssh_check_host_key_knownhosts();
break;
- case LIBSSH2_KNOWNHOST_CHECK_MISMATCH:
+ case SSH_SERVER_KNOWN_CHANGED:
ret = -EINVAL;
- session_error_setg(errp, s,
- "host key does not match the one in known_hosts"
- " (found key %s)", found->key);
+ error_setg(errp,
+ "host key does not match the one in known_hosts; this "
+ "may be a possible attack");
goto out;
- case LIBSSH2_KNOWNHOST_CHECK_NOTFOUND:
+ case SSH_SERVER_FOUND_OTHER:
ret = -EINVAL;
- session_error_setg(errp, s, "no host key was found in known_hosts");
+ error_setg(errp,
+ "host key for this server not found, another type exists");
+ goto out;
+ case SSH_SERVER_FILE_NOT_FOUND:
+ ret = -ENOENT;
+ error_setg(errp, "known_hosts file not found");
goto out;
- case LIBSSH2_KNOWNHOST_CHECK_FAILURE:
+ case SSH_SERVER_NOT_KNOWN:
ret = -EINVAL;
- session_error_setg(errp, s,
- "failure matching the host key with known_hosts");
+ error_setg(errp, "no host key was found in known_hosts");
+ goto out;
+ case SSH_SERVER_ERROR:
+ ret = -EINVAL;
+ error_setg(errp, "server error");
goto out;
default:
ret = -EINVAL;
- session_error_setg(errp, s, "unknown error matching the host key"
- " with known_hosts (%d)", r);
+ error_setg(errp, "error while checking for known server (%d)", state);
goto out;
}
+#endif /* !HAVE_LIBSSH_0_8 */
/* known_hosts checking successful. */
ret = 0;
out:
- if (knh != NULL) {
- libssh2_knownhost_free(knh);
- }
- g_free(knh_file);
return ret;
}
static int
check_host_key_hash(BDRVSSHState *s, const char *hash,
- int hash_type, size_t fingerprint_len, Error **errp)
+ enum ssh_publickey_hash_type type, Error **errp)
{
- const char *fingerprint;
-
- fingerprint = libssh2_hostkey_hash(s->session, hash_type);
- if (!fingerprint) {
+ int r;
+ ssh_key pubkey;
+ unsigned char *server_hash;
+ size_t server_hash_len;
+
+#ifdef HAVE_LIBSSH_0_8
+ r = ssh_get_server_publickey(s->session, &pubkey);
+#else
+ r = ssh_get_publickey(s->session, &pubkey);
+#endif
+ if (r != SSH_OK) {
session_error_setg(errp, s, "failed to read remote host key");
return -EINVAL;
}
- if(compare_fingerprint((unsigned char *) fingerprint, fingerprint_len,
- hash) != 0) {
+ r = ssh_get_publickey_hash(pubkey, type, &server_hash, &server_hash_len);
+ ssh_key_free(pubkey);
+ if (r != 0) {
+ session_error_setg(errp, s,
+ "failed reading the hash of the server SSH key");
+ return -EINVAL;
+ }
+
+ r = compare_fingerprint(server_hash, server_hash_len, hash);
+ ssh_clean_pubkey_hash(&server_hash);
+ if (r != 0) {
error_setg(errp, "remote host key does not match host_key_check '%s'",
hash);
return -EPERM;
return 0;
}
-static int check_host_key(BDRVSSHState *s, const char *host, int port,
- SshHostKeyCheck *hkc, Error **errp)
+static int check_host_key(BDRVSSHState *s, SshHostKeyCheck *hkc, Error **errp)
{
SshHostKeyCheckMode mode;
case SSH_HOST_KEY_CHECK_MODE_HASH:
if (hkc->u.hash.type == SSH_HOST_KEY_CHECK_HASH_TYPE_MD5) {
return check_host_key_hash(s, hkc->u.hash.hash,
- LIBSSH2_HOSTKEY_HASH_MD5, 16, errp);
+ SSH_PUBLICKEY_HASH_MD5, errp);
} else if (hkc->u.hash.type == SSH_HOST_KEY_CHECK_HASH_TYPE_SHA1) {
return check_host_key_hash(s, hkc->u.hash.hash,
- LIBSSH2_HOSTKEY_HASH_SHA1, 20, errp);
+ SSH_PUBLICKEY_HASH_SHA1, errp);
}
g_assert_not_reached();
break;
case SSH_HOST_KEY_CHECK_MODE_KNOWN_HOSTS:
- return check_host_key_knownhosts(s, host, port, errp);
+ return check_host_key_knownhosts(s, errp);
default:
g_assert_not_reached();
}
return -EINVAL;
}
-static int authenticate(BDRVSSHState *s, const char *user, Error **errp)
+static int authenticate(BDRVSSHState *s, Error **errp)
{
int r, ret;
- const char *userauthlist;
- LIBSSH2_AGENT *agent = NULL;
- struct libssh2_agent_publickey *identity;
- struct libssh2_agent_publickey *prev_identity = NULL;
+ int method;
- userauthlist = libssh2_userauth_list(s->session, user, strlen(user));
- if (strstr(userauthlist, "publickey") == NULL) {
+ /* Try to authenticate with the "none" method. */
+ r = ssh_userauth_none(s->session, NULL);
+ if (r == SSH_AUTH_ERROR) {
ret = -EPERM;
- error_setg(errp,
- "remote server does not support \"publickey\" authentication");
+ session_error_setg(errp, s, "failed to authenticate using none "
+ "authentication");
goto out;
- }
-
- /* Connect to ssh-agent and try each identity in turn. */
- agent = libssh2_agent_init(s->session);
- if (!agent) {
- ret = -EINVAL;
- session_error_setg(errp, s, "failed to initialize ssh-agent support");
- goto out;
- }
- if (libssh2_agent_connect(agent)) {
- ret = -ECONNREFUSED;
- session_error_setg(errp, s, "failed to connect to ssh-agent");
- goto out;
- }
- if (libssh2_agent_list_identities(agent)) {
- ret = -EINVAL;
- session_error_setg(errp, s,
- "failed requesting identities from ssh-agent");
+ } else if (r == SSH_AUTH_SUCCESS) {
+ /* Authenticated! */
+ ret = 0;
goto out;
}
- for(;;) {
- r = libssh2_agent_get_identity(agent, &identity, prev_identity);
- if (r == 1) { /* end of list */
- break;
- }
- if (r < 0) {
+ method = ssh_userauth_list(s->session, NULL);
+ trace_ssh_auth_methods(method);
+
+ /*
+ * Try to authenticate with publickey, using the ssh-agent
+ * if available.
+ */
+ if (method & SSH_AUTH_METHOD_PUBLICKEY) {
+ r = ssh_userauth_publickey_auto(s->session, NULL, NULL);
+ if (r == SSH_AUTH_ERROR) {
ret = -EINVAL;
- session_error_setg(errp, s,
- "failed to obtain identity from ssh-agent");
+ session_error_setg(errp, s, "failed to authenticate using "
+ "publickey authentication");
goto out;
- }
- r = libssh2_agent_userauth(agent, user, identity);
- if (r == 0) {
+ } else if (r == SSH_AUTH_SUCCESS) {
/* Authenticated! */
ret = 0;
goto out;
}
- /* Failed to authenticate with this identity, try the next one. */
- prev_identity = identity;
}
ret = -EPERM;
"and the identities held by your ssh-agent");
out:
- if (agent != NULL) {
- /* Note: libssh2 implementation implicitly calls
- * libssh2_agent_disconnect if necessary.
- */
- libssh2_agent_free(agent);
- }
-
return ret;
}
int ssh_flags, int creat_mode, Error **errp)
{
int r, ret;
- long port = 0;
+ unsigned int port = 0;
+ int new_sock = -1;
if (opts->has_user) {
s->user = g_strdup(opts->user);
s->inet = opts->server;
opts->server = NULL;
- if (qemu_strtol(s->inet->port, NULL, 10, &port) < 0) {
+ if (qemu_strtoui(s->inet->port, NULL, 10, &port) < 0) {
error_setg(errp, "Use only numeric port value");
ret = -EINVAL;
goto err;
}
/* Open the socket and connect. */
- s->sock = inet_connect_saddr(s->inet, errp);
- if (s->sock < 0) {
+ new_sock = inet_connect_saddr(s->inet, errp);
+ if (new_sock < 0) {
ret = -EIO;
goto err;
}
+ /*
+ * Try to disable the Nagle algorithm on TCP sockets to reduce latency,
+ * but do not fail if it cannot be disabled.
+ */
+ r = socket_set_nodelay(new_sock);
+ if (r < 0) {
+ warn_report("can't set TCP_NODELAY for the ssh server %s: %s",
+ s->inet->host, strerror(errno));
+ }
+
/* Create SSH session. */
- s->session = libssh2_session_init();
+ s->session = ssh_new();
if (!s->session) {
ret = -EINVAL;
- session_error_setg(errp, s, "failed to initialize libssh2 session");
+ session_error_setg(errp, s, "failed to initialize libssh session");
goto err;
}
-#if TRACE_LIBSSH2 != 0
- libssh2_trace(s->session, TRACE_LIBSSH2);
-#endif
+ /*
+ * Make sure we are in blocking mode during the connection and
+ * authentication phases.
+ */
+ ssh_set_blocking(s->session, 1);
- r = libssh2_session_handshake(s->session, s->sock);
- if (r != 0) {
+ r = ssh_options_set(s->session, SSH_OPTIONS_USER, s->user);
+ if (r < 0) {
+ ret = -EINVAL;
+ session_error_setg(errp, s,
+ "failed to set the user in the libssh session");
+ goto err;
+ }
+
+ r = ssh_options_set(s->session, SSH_OPTIONS_HOST, s->inet->host);
+ if (r < 0) {
+ ret = -EINVAL;
+ session_error_setg(errp, s,
+ "failed to set the host in the libssh session");
+ goto err;
+ }
+
+ if (port > 0) {
+ r = ssh_options_set(s->session, SSH_OPTIONS_PORT, &port);
+ if (r < 0) {
+ ret = -EINVAL;
+ session_error_setg(errp, s,
+ "failed to set the port in the libssh session");
+ goto err;
+ }
+ }
+
+ r = ssh_options_set(s->session, SSH_OPTIONS_COMPRESSION, "none");
+ if (r < 0) {
+ ret = -EINVAL;
+ session_error_setg(errp, s,
+ "failed to disable the compression in the libssh "
+ "session");
+ goto err;
+ }
+
+ /* Read ~/.ssh/config. */
+ r = ssh_options_parse_config(s->session, NULL);
+ if (r < 0) {
+ ret = -EINVAL;
+ session_error_setg(errp, s, "failed to parse ~/.ssh/config");
+ goto err;
+ }
+
+ r = ssh_options_set(s->session, SSH_OPTIONS_FD, &new_sock);
+ if (r < 0) {
+ ret = -EINVAL;
+ session_error_setg(errp, s,
+ "failed to set the socket in the libssh session");
+ goto err;
+ }
+ /* libssh took ownership of the socket. */
+ s->sock = new_sock;
+ new_sock = -1;
+
+ /* Connect. */
+ r = ssh_connect(s->session);
+ if (r != SSH_OK) {
ret = -EINVAL;
session_error_setg(errp, s, "failed to establish SSH session");
goto err;
}
/* Check the remote host's key against known_hosts. */
- ret = check_host_key(s, s->inet->host, port, opts->host_key_check, errp);
+ ret = check_host_key(s, opts->host_key_check, errp);
if (ret < 0) {
goto err;
}
/* Authenticate. */
- ret = authenticate(s, s->user, errp);
+ ret = authenticate(s, errp);
if (ret < 0) {
goto err;
}
/* Start SFTP. */
- s->sftp = libssh2_sftp_init(s->session);
+ s->sftp = sftp_new(s->session);
if (!s->sftp) {
- session_error_setg(errp, s, "failed to initialize sftp handle");
+ session_error_setg(errp, s, "failed to create sftp handle");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ r = sftp_init(s->sftp);
+ if (r < 0) {
+ sftp_error_setg(errp, s, "failed to initialize sftp handle");
ret = -EINVAL;
goto err;
}
/* Open the remote file. */
trace_ssh_connect_to_ssh(opts->path, ssh_flags, creat_mode);
- s->sftp_handle = libssh2_sftp_open(s->sftp, opts->path, ssh_flags,
- creat_mode);
+ s->sftp_handle = sftp_open(s->sftp, opts->path, ssh_flags, creat_mode);
if (!s->sftp_handle) {
- session_error_setg(errp, s, "failed to open remote file '%s'",
- opts->path);
+ sftp_error_setg(errp, s, "failed to open remote file '%s'",
+ opts->path);
ret = -EINVAL;
goto err;
}
- r = libssh2_sftp_fstat(s->sftp_handle, &s->attrs);
- if (r < 0) {
+ /* Make sure the SFTP file is handled in blocking mode. */
+ sftp_file_set_blocking(s->sftp_handle);
+
+ s->attrs = sftp_fstat(s->sftp_handle);
+ if (!s->attrs) {
sftp_error_setg(errp, s, "failed to read file attributes");
return -EINVAL;
}
return 0;
err:
+ if (s->attrs) {
+ sftp_attributes_free(s->attrs);
+ }
+ s->attrs = NULL;
if (s->sftp_handle) {
- libssh2_sftp_close(s->sftp_handle);
+ sftp_close(s->sftp_handle);
}
s->sftp_handle = NULL;
if (s->sftp) {
- libssh2_sftp_shutdown(s->sftp);
+ sftp_free(s->sftp);
}
s->sftp = NULL;
if (s->session) {
- libssh2_session_disconnect(s->session,
- "from qemu ssh client: "
- "error opening connection");
- libssh2_session_free(s->session);
+ ssh_disconnect(s->session);
+ ssh_free(s->session);
}
s->session = NULL;
+ s->sock = -1;
+ if (new_sock >= 0) {
+ close(new_sock);
+ }
return ret;
}
ssh_state_init(s);
- ssh_flags = LIBSSH2_FXF_READ;
+ ssh_flags = 0;
if (bdrv_flags & BDRV_O_RDWR) {
- ssh_flags |= LIBSSH2_FXF_WRITE;
+ ssh_flags |= O_RDWR;
+ } else {
+ ssh_flags |= O_RDONLY;
}
opts = ssh_parse_options(options, errp);
}
/* Go non-blocking. */
- libssh2_session_set_blocking(s->session, 0);
+ ssh_set_blocking(s->session, 0);
qapi_free_BlockdevOptionsSsh(opts);
return 0;
err:
- if (s->sock >= 0) {
- close(s->sock);
- }
- s->sock = -1;
-
qapi_free_BlockdevOptionsSsh(opts);
return ret;
{
ssize_t ret;
char c[1] = { '\0' };
- int was_blocking = libssh2_session_get_blocking(s->session);
+ int was_blocking = ssh_is_blocking(s->session);
/* offset must be strictly greater than the current size so we do
* not overwrite anything */
- assert(offset > 0 && offset > s->attrs.filesize);
+ assert(offset > 0 && offset > s->attrs->size);
- libssh2_session_set_blocking(s->session, 1);
+ ssh_set_blocking(s->session, 1);
- libssh2_sftp_seek64(s->sftp_handle, offset - 1);
- ret = libssh2_sftp_write(s->sftp_handle, c, 1);
+ sftp_seek64(s->sftp_handle, offset - 1);
+ ret = sftp_write(s->sftp_handle, c, 1);
- libssh2_session_set_blocking(s->session, was_blocking);
+ ssh_set_blocking(s->session, was_blocking);
if (ret < 0) {
sftp_error_setg(errp, s, "Failed to grow file");
return -EIO;
}
- s->attrs.filesize = offset;
+ s->attrs->size = offset;
return 0;
}
ssh_state_init(&s);
ret = connect_to_ssh(&s, opts->location,
- LIBSSH2_FXF_READ|LIBSSH2_FXF_WRITE|
- LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
+ O_RDWR | O_CREAT | O_TRUNC,
0644, errp);
if (ret < 0) {
goto fail;
/* Assume false, unless we can positively prove it's true. */
int has_zero_init = 0;
- if (s->attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
- if (s->attrs.permissions & LIBSSH2_SFTP_S_IFREG) {
- has_zero_init = 1;
- }
+ if (s->attrs->type == SSH_FILEXFER_TYPE_REGULAR) {
+ has_zero_init = 1;
}
return has_zero_init;
.co = qemu_coroutine_self()
};
- r = libssh2_session_block_directions(s->session);
+ r = ssh_get_poll_flags(s->session);
- if (r & LIBSSH2_SESSION_BLOCK_INBOUND) {
+ if (r & SSH_READ_PENDING) {
rd_handler = restart_coroutine;
}
- if (r & LIBSSH2_SESSION_BLOCK_OUTBOUND) {
+ if (r & SSH_WRITE_PENDING) {
wr_handler = restart_coroutine;
}
trace_ssh_co_yield_back(s->sock);
}
-/* SFTP has a function `libssh2_sftp_seek64' which seeks to a position
- * in the remote file. Notice that it just updates a field in the
- * sftp_handle structure, so there is no network traffic and it cannot
- * fail.
- *
- * However, `libssh2_sftp_seek64' does have a catastrophic effect on
- * performance since it causes the handle to throw away all in-flight
- * reads and buffered readahead data. Therefore this function tries
- * to be intelligent about when to call the underlying libssh2 function.
- */
-#define SSH_SEEK_WRITE 0
-#define SSH_SEEK_READ 1
-#define SSH_SEEK_FORCE 2
-
-static void ssh_seek(BDRVSSHState *s, int64_t offset, int flags)
-{
- bool op_read = (flags & SSH_SEEK_READ) != 0;
- bool force = (flags & SSH_SEEK_FORCE) != 0;
-
- if (force || op_read != s->offset_op_read || offset != s->offset) {
- trace_ssh_seek(offset);
- libssh2_sftp_seek64(s->sftp_handle, offset);
- s->offset = offset;
- s->offset_op_read = op_read;
- }
-}
-
static coroutine_fn int ssh_read(BDRVSSHState *s, BlockDriverState *bs,
int64_t offset, size_t size,
QEMUIOVector *qiov)
trace_ssh_read(offset, size);
- ssh_seek(s, offset, SSH_SEEK_READ);
+ trace_ssh_seek(offset);
+ sftp_seek64(s->sftp_handle, offset);
/* This keeps track of the current iovec element ('i'), where we
* will write to next ('buf'), and the end of the current iovec
buf = i->iov_base;
end_of_vec = i->iov_base + i->iov_len;
- /* libssh2 has a hard-coded limit of 2000 bytes per request,
- * although it will also do readahead behind our backs. Therefore
- * we may have to do repeated reads here until we have read 'size'
- * bytes.
- */
for (got = 0; got < size; ) {
+ size_t request_read_size;
again:
- trace_ssh_read_buf(buf, end_of_vec - buf);
- r = libssh2_sftp_read(s->sftp_handle, buf, end_of_vec - buf);
- trace_ssh_read_return(r);
+ /*
+ * The size of SFTP packets is limited to 32K bytes, so limit
+ * the amount of data requested to 16K, as libssh currently
+ * does not handle multiple requests on its own.
+ */
+ request_read_size = MIN(end_of_vec - buf, 16384);
+ trace_ssh_read_buf(buf, end_of_vec - buf, request_read_size);
+ r = sftp_read(s->sftp_handle, buf, request_read_size);
+ trace_ssh_read_return(r, sftp_get_error(s->sftp));
- if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
+ if (r == SSH_AGAIN) {
co_yield(s, bs);
goto again;
}
- if (r < 0) {
- sftp_error_trace(s, "read");
- s->offset = -1;
- return -EIO;
- }
- if (r == 0) {
+ if (r == SSH_EOF || (r == 0 && sftp_get_error(s->sftp) == SSH_FX_EOF)) {
/* EOF: Short read so pad the buffer with zeroes and return it. */
qemu_iovec_memset(qiov, got, 0, size - got);
return 0;
}
+ if (r <= 0) {
+ sftp_error_trace(s, "read");
+ return -EIO;
+ }
got += r;
buf += r;
- s->offset += r;
if (buf >= end_of_vec && got < size) {
i++;
buf = i->iov_base;
trace_ssh_write(offset, size);
- ssh_seek(s, offset, SSH_SEEK_WRITE);
+ trace_ssh_seek(offset);
+ sftp_seek64(s->sftp_handle, offset);
/* This keeps track of the current iovec element ('i'), where we
* will read from next ('buf'), and the end of the current iovec
end_of_vec = i->iov_base + i->iov_len;
for (written = 0; written < size; ) {
+ size_t request_write_size;
again:
- trace_ssh_write_buf(buf, end_of_vec - buf);
- r = libssh2_sftp_write(s->sftp_handle, buf, end_of_vec - buf);
- trace_ssh_write_return(r);
+ /*
+ * Avoid too large data packets, as libssh currently does not
+ * handle multiple requests on its own.
+ */
+ request_write_size = MIN(end_of_vec - buf, 131072);
+ trace_ssh_write_buf(buf, end_of_vec - buf, request_write_size);
+ r = sftp_write(s->sftp_handle, buf, request_write_size);
+ trace_ssh_write_return(r, sftp_get_error(s->sftp));
- if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
+ if (r == SSH_AGAIN) {
co_yield(s, bs);
goto again;
}
if (r < 0) {
sftp_error_trace(s, "write");
- s->offset = -1;
return -EIO;
}
- /* The libssh2 API is very unclear about this. A comment in
- * the code says "nothing was acked, and no EAGAIN was
- * received!" which apparently means that no data got sent
- * out, and the underlying channel didn't return any EAGAIN
- * indication. I think this is a bug in either libssh2 or
- * OpenSSH (server-side). In any case, forcing a seek (to
- * discard libssh2 internal buffers), and then trying again
- * works for me.
- */
- if (r == 0) {
- ssh_seek(s, offset + written, SSH_SEEK_WRITE|SSH_SEEK_FORCE);
- co_yield(s, bs);
- goto again;
- }
written += r;
buf += r;
- s->offset += r;
if (buf >= end_of_vec && written < size) {
i++;
buf = i->iov_base;
end_of_vec = i->iov_base + i->iov_len;
}
- if (offset + written > s->attrs.filesize)
- s->attrs.filesize = offset + written;
+ if (offset + written > s->attrs->size) {
+ s->attrs->size = offset + written;
+ }
}
return 0;
}
}
-#ifdef HAS_LIBSSH2_SFTP_FSYNC
+#ifdef HAVE_LIBSSH_0_8
static coroutine_fn int ssh_flush(BDRVSSHState *s, BlockDriverState *bs)
{
int r;
trace_ssh_flush();
+
+ if (!sftp_extension_supported(s->sftp, "fsync@openssh.com", "1")) {
+ unsafe_flush_warning(s, "OpenSSH >= 6.3");
+ return 0;
+ }
again:
- r = libssh2_sftp_fsync(s->sftp_handle);
- if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
+ r = sftp_fsync(s->sftp_handle);
+ if (r == SSH_AGAIN) {
co_yield(s, bs);
goto again;
}
- if (r == LIBSSH2_ERROR_SFTP_PROTOCOL &&
- libssh2_sftp_last_error(s->sftp) == LIBSSH2_FX_OP_UNSUPPORTED) {
- unsafe_flush_warning(s, "OpenSSH >= 6.3");
- return 0;
- }
if (r < 0) {
sftp_error_trace(s, "fsync");
return -EIO;
return ret;
}
-#else /* !HAS_LIBSSH2_SFTP_FSYNC */
+#else /* !HAVE_LIBSSH_0_8 */
static coroutine_fn int ssh_co_flush(BlockDriverState *bs)
{
BDRVSSHState *s = bs->opaque;
- unsafe_flush_warning(s, "libssh2 >= 1.4.4");
+ unsafe_flush_warning(s, "libssh >= 0.8.0");
return 0;
}
-#endif /* !HAS_LIBSSH2_SFTP_FSYNC */
+#endif /* !HAVE_LIBSSH_0_8 */
static int64_t ssh_getlength(BlockDriverState *bs)
{
BDRVSSHState *s = bs->opaque;
int64_t length;
- /* Note we cannot make a libssh2 call here. */
- length = (int64_t) s->attrs.filesize;
+ /* Note we cannot make a libssh call here. */
+ length = (int64_t) s->attrs->size;
trace_ssh_getlength(length);
return length;
return -ENOTSUP;
}
- if (offset < s->attrs.filesize) {
+ if (offset < s->attrs->size) {
error_setg(errp, "ssh driver does not support shrinking files");
return -ENOTSUP;
}
- if (offset == s->attrs.filesize) {
+ if (offset == s->attrs->size) {
return 0;
}
{
int r;
- r = libssh2_init(0);
+ r = ssh_init();
if (r != 0) {
- fprintf(stderr, "libssh2 initialization failed, %d\n", r);
+ fprintf(stderr, "libssh initialization failed, %d\n", r);
exit(EXIT_FAILURE);
}
+#if TRACE_LIBSSH != 0
+ ssh_set_log_level(TRACE_LIBSSH);
+#endif
+
bdrv_register(&bdrv_ssh);
}
typedef struct StreamBlockJob {
BlockJob common;
- BlockDriverState *base;
+ BlockDriverState *bottom;
BlockdevOnError on_error;
char *backing_file_str;
bool bs_read_only;
if (s->chain_frozen) {
BlockJob *bjob = &s->common;
- bdrv_unfreeze_backing_chain(blk_bs(bjob->blk), s->base);
+ bdrv_unfreeze_backing_chain(blk_bs(bjob->blk), s->bottom);
}
}
StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
BlockJob *bjob = &s->common;
BlockDriverState *bs = blk_bs(bjob->blk);
- BlockDriverState *base = s->base;
+ BlockDriverState *base = backing_bs(s->bottom);
Error *local_err = NULL;
int ret = 0;
- bdrv_unfreeze_backing_chain(bs, base);
+ bdrv_unfreeze_backing_chain(bs, s->bottom);
s->chain_frozen = false;
if (bs->backing) {
StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
BlockBackend *blk = s->common.blk;
BlockDriverState *bs = blk_bs(blk);
- BlockDriverState *base = s->base;
+ bool enable_cor = !backing_bs(s->bottom);
int64_t len;
int64_t offset = 0;
uint64_t delay_ns = 0;
int64_t n = 0; /* bytes */
void *buf;
- if (!bs->backing) {
- goto out;
+ if (bs == s->bottom) {
+ /* Nothing to stream */
+ return 0;
}
len = bdrv_getlength(bs);
if (len < 0) {
- ret = len;
- goto out;
+ return len;
}
job_progress_set_remaining(&s->common.job, len);
* backing chain since the copy-on-read operation does not take base into
* account.
*/
- if (!base) {
+ if (enable_cor) {
bdrv_enable_copy_on_read(bs);
}
} else if (ret >= 0) {
/* Copy if allocated in the intermediate images. Limit to the
* known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE). */
- ret = bdrv_is_allocated_above(backing_bs(bs), base,
+ ret = bdrv_is_allocated_above(backing_bs(bs), s->bottom, true,
offset, n, &n);
-
/* Finish early if end of backing file has been reached */
if (ret == 0 && n == 0) {
n = len - offset;
}
}
- if (!base) {
+ if (enable_cor) {
bdrv_disable_copy_on_read(bs);
}
- /* Do not remove the backing file if an error was there but ignored. */
- ret = error;
-
qemu_vfree(buf);
-out:
- /* Modify backing chain and close BDSes in main loop */
- return ret;
+ /* Do not remove the backing file if an error was there but ignored. */
+ return error;
}
static const BlockJobDriver stream_job_driver = {
StreamBlockJob *s;
BlockDriverState *iter;
bool bs_read_only;
+ int basic_flags = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED;
+ BlockDriverState *bottom = bdrv_find_overlay(bs, base);
- if (bdrv_freeze_backing_chain(bs, base, errp) < 0) {
+ if (bdrv_freeze_backing_chain(bs, bottom, errp) < 0) {
return;
}
* already have our own plans. Also don't allow resize as the image size is
* queried only at the job start and then cached. */
s = block_job_create(job_id, &stream_job_driver, NULL, bs,
- BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
- BLK_PERM_GRAPH_MOD,
- BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED |
- BLK_PERM_WRITE,
+ basic_flags | BLK_PERM_GRAPH_MOD,
+ basic_flags | BLK_PERM_WRITE,
speed, creation_flags, NULL, NULL, errp);
if (!s) {
goto fail;
/* Block all intermediate nodes between bs and base, because they will
* disappear from the chain after this operation. The streaming job reads
- * every block only once, assuming that it doesn't change, so block writes
- * and resizes. */
+ * every block only once, assuming that it doesn't change, so forbid writes
+ * and resizes. Reassign the base node pointer because the backing BS of the
+ * bottom node might change after the call to bdrv_reopen_set_read_only()
+ * due to parallel block jobs running.
+ */
+ base = backing_bs(bottom);
for (iter = backing_bs(bs); iter && iter != base; iter = backing_bs(iter)) {
block_job_add_bdrv(&s->common, "intermediate node", iter, 0,
- BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED,
- &error_abort);
+ basic_flags, &error_abort);
}
- s->base = base;
+ s->bottom = bottom;
s->backing_file_str = g_strdup(backing_file_str);
s->bs_read_only = bs_read_only;
s->chain_frozen = true;
# ssh.c
ssh_restart_coroutine(void *co) "co=%p"
ssh_flush(void) "fsync"
-ssh_check_host_key_knownhosts(const char *key) "host key OK: %s"
+ssh_check_host_key_knownhosts(void) "host key OK"
ssh_connect_to_ssh(char *path, int flags, int mode) "opening file %s flags=0x%x creat_mode=0%o"
ssh_co_yield(int sock, void *rd_handler, void *wr_handler) "s->sock=%d rd_handler=%p wr_handler=%p"
ssh_co_yield_back(int sock) "s->sock=%d - back"
ssh_getlength(int64_t length) "length=%" PRIi64
ssh_co_create_opts(uint64_t size) "total_size=%" PRIu64
ssh_read(int64_t offset, size_t size) "offset=%" PRIi64 " size=%zu"
-ssh_read_buf(void *buf, size_t size) "sftp_read buf=%p size=%zu"
-ssh_read_return(ssize_t ret) "sftp_read returned %zd"
+ssh_read_buf(void *buf, size_t size, size_t actual_size) "sftp_read buf=%p size=%zu (actual size=%zu)"
+ssh_read_return(ssize_t ret, int sftp_err) "sftp_read returned %zd (sftp error=%d)"
ssh_write(int64_t offset, size_t size) "offset=%" PRIi64 " size=%zu"
-ssh_write_buf(void *buf, size_t size) "sftp_write buf=%p size=%zu"
-ssh_write_return(ssize_t ret) "sftp_write returned %zd"
+ssh_write_buf(void *buf, size_t size, size_t actual_size) "sftp_write buf=%p size=%zu (actual size=%zu)"
+ssh_write_return(ssize_t ret, int sftp_err) "sftp_write returned %zd (sftp error=%d)"
ssh_seek(int64_t offset) "seeking to offset=%" PRIi64
+ssh_auth_methods(int methods) "auth methods=0x%x"
+ssh_server_status(int status) "server status=%d"
# curl.c
curl_timer_cb(long timeout_ms) "timer callback timeout_ms %ld"
sheepdog_snapshot_create_inode(const char *name, uint32_t snap, uint32_t vdi) "s->inode: name %s snap_id 0x%" PRIx32 " vdi 0x%" PRIx32
# ssh.c
-sftp_error(const char *op, const char *ssh_err, int ssh_err_code, unsigned long sftp_err_code) "%s failed: %s (libssh2 error code: %d, sftp error code: %lu)"
+sftp_error(const char *op, const char *ssh_err, int ssh_err_code, int sftp_err_code) "%s failed: %s (libssh error code: %d, sftp error code: %d)"
uint16_t compressAlgorithm;
} QEMU_PACKED VMDK4Header;
+typedef struct VMDKSESparseConstHeader {
+ uint64_t magic;
+ uint64_t version;
+ uint64_t capacity;
+ uint64_t grain_size;
+ uint64_t grain_table_size;
+ uint64_t flags;
+ uint64_t reserved1;
+ uint64_t reserved2;
+ uint64_t reserved3;
+ uint64_t reserved4;
+ uint64_t volatile_header_offset;
+ uint64_t volatile_header_size;
+ uint64_t journal_header_offset;
+ uint64_t journal_header_size;
+ uint64_t journal_offset;
+ uint64_t journal_size;
+ uint64_t grain_dir_offset;
+ uint64_t grain_dir_size;
+ uint64_t grain_tables_offset;
+ uint64_t grain_tables_size;
+ uint64_t free_bitmap_offset;
+ uint64_t free_bitmap_size;
+ uint64_t backmap_offset;
+ uint64_t backmap_size;
+ uint64_t grains_offset;
+ uint64_t grains_size;
+ uint8_t pad[304];
+} QEMU_PACKED VMDKSESparseConstHeader;
+
+typedef struct VMDKSESparseVolatileHeader {
+ uint64_t magic;
+ uint64_t free_gt_number;
+ uint64_t next_txn_seq_number;
+ uint64_t replay_journal;
+ uint8_t pad[480];
+} QEMU_PACKED VMDKSESparseVolatileHeader;
+
#define L2_CACHE_SIZE 16
typedef struct VmdkExtent {
bool compressed;
bool has_marker;
bool has_zero_grain;
+ bool sesparse;
+ uint64_t sesparse_l2_tables_offset;
+ uint64_t sesparse_clusters_offset;
+ int32_t entry_size;
int version;
int64_t sectors;
int64_t end_sector;
int64_t flat_start_offset;
int64_t l1_table_offset;
int64_t l1_backup_table_offset;
- uint32_t *l1_table;
+ void *l1_table;
uint32_t *l1_backup_table;
unsigned int l1_size;
uint32_t l1_entry_sectors;
unsigned int l2_size;
- uint32_t *l2_cache;
+ void *l2_cache;
uint32_t l2_cache_offsets[L2_CACHE_SIZE];
uint32_t l2_cache_counts[L2_CACHE_SIZE];
error_setg(errp, "Invalid granularity, image may be corrupt");
return -EFBIG;
}
- if (l1_size > 512 * 1024 * 1024) {
- /* Although with big capacity and small l1_entry_sectors, we can get a
+ if (l1_size > 32 * 1024 * 1024) {
+ /*
+ * Although with big capacity and small l1_entry_sectors, we can get a
* big l1_size, we don't want unbounded value to allocate the table.
- * Limit it to 512M, which is 16PB for default cluster and L2 table
- * size */
+ * Limit it to 32M, which is enough to store:
+ * 8TB - for both VMDK3 & VMDK4 with
+ * minimal cluster size: 512B
+ * minimal L2 table size: 512 entries
+ * 8 TB is still more than the maximal value supported for
+ * VMDK3 & VMDK4 which is 2TB.
+ * 64TB - for "ESXi seSparse Extent"
+ * minimal cluster size: 512B (default is 4KB)
+ * L2 table size: 4096 entries (const).
+ * 64TB is more than the maximal value supported for
+ * seSparse VMDKs (which is slightly less than 64TB)
+ */
error_setg(errp, "L1 size too big");
return -EFBIG;
}
extent->l2_size = l2_size;
extent->cluster_sectors = flat ? sectors : cluster_sectors;
extent->next_cluster_sector = ROUND_UP(nb_sectors, cluster_sectors);
+ extent->entry_size = sizeof(uint32_t);
if (s->num_extents > 1) {
extent->end_sector = (*(extent - 1)).end_sector + extent->sectors;
int i;
/* read the L1 table */
- l1_size = extent->l1_size * sizeof(uint32_t);
+ l1_size = extent->l1_size * extent->entry_size;
extent->l1_table = g_try_malloc(l1_size);
if (l1_size && extent->l1_table == NULL) {
return -ENOMEM;
goto fail_l1;
}
for (i = 0; i < extent->l1_size; i++) {
- le32_to_cpus(&extent->l1_table[i]);
+ if (extent->entry_size == sizeof(uint64_t)) {
+ le64_to_cpus((uint64_t *)extent->l1_table + i);
+ } else {
+ assert(extent->entry_size == sizeof(uint32_t));
+ le32_to_cpus((uint32_t *)extent->l1_table + i);
+ }
}
if (extent->l1_backup_table_offset) {
+ assert(!extent->sesparse);
extent->l1_backup_table = g_try_malloc(l1_size);
if (l1_size && extent->l1_backup_table == NULL) {
ret = -ENOMEM;
}
extent->l2_cache =
- g_new(uint32_t, extent->l2_size * L2_CACHE_SIZE);
+ g_malloc(extent->entry_size * extent->l2_size * L2_CACHE_SIZE);
return 0;
fail_l1b:
g_free(extent->l1_backup_table);
return ret;
}
+#define SESPARSE_CONST_HEADER_MAGIC UINT64_C(0x00000000cafebabe)
+#define SESPARSE_VOLATILE_HEADER_MAGIC UINT64_C(0x00000000cafecafe)
+
+/* Strict checks - format not officially documented */
+static int check_se_sparse_const_header(VMDKSESparseConstHeader *header,
+ Error **errp)
+{
+ header->magic = le64_to_cpu(header->magic);
+ header->version = le64_to_cpu(header->version);
+ header->grain_size = le64_to_cpu(header->grain_size);
+ header->grain_table_size = le64_to_cpu(header->grain_table_size);
+ header->flags = le64_to_cpu(header->flags);
+ header->reserved1 = le64_to_cpu(header->reserved1);
+ header->reserved2 = le64_to_cpu(header->reserved2);
+ header->reserved3 = le64_to_cpu(header->reserved3);
+ header->reserved4 = le64_to_cpu(header->reserved4);
+
+ header->volatile_header_offset =
+ le64_to_cpu(header->volatile_header_offset);
+ header->volatile_header_size = le64_to_cpu(header->volatile_header_size);
+
+ header->journal_header_offset = le64_to_cpu(header->journal_header_offset);
+ header->journal_header_size = le64_to_cpu(header->journal_header_size);
+
+ header->journal_offset = le64_to_cpu(header->journal_offset);
+ header->journal_size = le64_to_cpu(header->journal_size);
+
+ header->grain_dir_offset = le64_to_cpu(header->grain_dir_offset);
+ header->grain_dir_size = le64_to_cpu(header->grain_dir_size);
+
+ header->grain_tables_offset = le64_to_cpu(header->grain_tables_offset);
+ header->grain_tables_size = le64_to_cpu(header->grain_tables_size);
+
+ header->free_bitmap_offset = le64_to_cpu(header->free_bitmap_offset);
+ header->free_bitmap_size = le64_to_cpu(header->free_bitmap_size);
+
+ header->backmap_offset = le64_to_cpu(header->backmap_offset);
+ header->backmap_size = le64_to_cpu(header->backmap_size);
+
+ header->grains_offset = le64_to_cpu(header->grains_offset);
+ header->grains_size = le64_to_cpu(header->grains_size);
+
+ if (header->magic != SESPARSE_CONST_HEADER_MAGIC) {
+ error_setg(errp, "Bad const header magic: 0x%016" PRIx64,
+ header->magic);
+ return -EINVAL;
+ }
+
+ if (header->version != 0x0000000200000001) {
+ error_setg(errp, "Unsupported version: 0x%016" PRIx64,
+ header->version);
+ return -ENOTSUP;
+ }
+
+ if (header->grain_size != 8) {
+ error_setg(errp, "Unsupported grain size: %" PRIu64,
+ header->grain_size);
+ return -ENOTSUP;
+ }
+
+ if (header->grain_table_size != 64) {
+ error_setg(errp, "Unsupported grain table size: %" PRIu64,
+ header->grain_table_size);
+ return -ENOTSUP;
+ }
+
+ if (header->flags != 0) {
+ error_setg(errp, "Unsupported flags: 0x%016" PRIx64,
+ header->flags);
+ return -ENOTSUP;
+ }
+
+ if (header->reserved1 != 0 || header->reserved2 != 0 ||
+ header->reserved3 != 0 || header->reserved4 != 0) {
+ error_setg(errp, "Unsupported reserved bits:"
+ " 0x%016" PRIx64 " 0x%016" PRIx64
+ " 0x%016" PRIx64 " 0x%016" PRIx64,
+ header->reserved1, header->reserved2,
+ header->reserved3, header->reserved4);
+ return -ENOTSUP;
+ }
+
+ /* check that padding is 0 */
+ if (!buffer_is_zero(header->pad, sizeof(header->pad))) {
+ error_setg(errp, "Unsupported non-zero const header padding");
+ return -ENOTSUP;
+ }
+
+ return 0;
+}
+
+static int check_se_sparse_volatile_header(VMDKSESparseVolatileHeader *header,
+ Error **errp)
+{
+ header->magic = le64_to_cpu(header->magic);
+ header->free_gt_number = le64_to_cpu(header->free_gt_number);
+ header->next_txn_seq_number = le64_to_cpu(header->next_txn_seq_number);
+ header->replay_journal = le64_to_cpu(header->replay_journal);
+
+ if (header->magic != SESPARSE_VOLATILE_HEADER_MAGIC) {
+ error_setg(errp, "Bad volatile header magic: 0x%016" PRIx64,
+ header->magic);
+ return -EINVAL;
+ }
+
+ if (header->replay_journal) {
+ error_setg(errp, "Image is dirty, Replaying journal not supported");
+ return -ENOTSUP;
+ }
+
+ /* check that padding is 0 */
+ if (!buffer_is_zero(header->pad, sizeof(header->pad))) {
+ error_setg(errp, "Unsupported non-zero volatile header padding");
+ return -ENOTSUP;
+ }
+
+ return 0;
+}
+
+static int vmdk_open_se_sparse(BlockDriverState *bs,
+ BdrvChild *file,
+ int flags, Error **errp)
+{
+ int ret;
+ VMDKSESparseConstHeader const_header;
+ VMDKSESparseVolatileHeader volatile_header;
+ VmdkExtent *extent;
+
+ ret = bdrv_apply_auto_read_only(bs,
+ "No write support for seSparse images available", errp);
+ if (ret < 0) {
+ return ret;
+ }
+
+ assert(sizeof(const_header) == SECTOR_SIZE);
+
+ ret = bdrv_pread(file, 0, &const_header, sizeof(const_header));
+ if (ret < 0) {
+ bdrv_refresh_filename(file->bs);
+ error_setg_errno(errp, -ret,
+ "Could not read const header from file '%s'",
+ file->bs->filename);
+ return ret;
+ }
+
+ /* check const header */
+ ret = check_se_sparse_const_header(&const_header, errp);
+ if (ret < 0) {
+ return ret;
+ }
+
+ assert(sizeof(volatile_header) == SECTOR_SIZE);
+
+ ret = bdrv_pread(file,
+ const_header.volatile_header_offset * SECTOR_SIZE,
+ &volatile_header, sizeof(volatile_header));
+ if (ret < 0) {
+ bdrv_refresh_filename(file->bs);
+ error_setg_errno(errp, -ret,
+ "Could not read volatile header from file '%s'",
+ file->bs->filename);
+ return ret;
+ }
+
+ /* check volatile header */
+ ret = check_se_sparse_volatile_header(&volatile_header, errp);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = vmdk_add_extent(bs, file, false,
+ const_header.capacity,
+ const_header.grain_dir_offset * SECTOR_SIZE,
+ 0,
+ const_header.grain_dir_size *
+ SECTOR_SIZE / sizeof(uint64_t),
+ const_header.grain_table_size *
+ SECTOR_SIZE / sizeof(uint64_t),
+ const_header.grain_size,
+ &extent,
+ errp);
+ if (ret < 0) {
+ return ret;
+ }
+
+ extent->sesparse = true;
+ extent->sesparse_l2_tables_offset = const_header.grain_tables_offset;
+ extent->sesparse_clusters_offset = const_header.grains_offset;
+ extent->entry_size = sizeof(uint64_t);
+
+ ret = vmdk_init_tables(bs, extent, errp);
+ if (ret) {
+ /* free extent allocated by vmdk_add_extent */
+ vmdk_free_last_extent(bs);
+ }
+
+ return ret;
+}
+
static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
QDict *options, Error **errp);
* RW [size in sectors] SPARSE "file-name.vmdk"
* RW [size in sectors] VMFS "file-name.vmdk"
* RW [size in sectors] VMFSSPARSE "file-name.vmdk"
+ * RW [size in sectors] SESPARSE "file-name.vmdk"
*/
flat_offset = -1;
matches = sscanf(p, "%10s %" SCNd64 " %10s \"%511[^\n\r\"]\" %" SCNd64,
if (sectors <= 0 ||
(strcmp(type, "FLAT") && strcmp(type, "SPARSE") &&
- strcmp(type, "VMFS") && strcmp(type, "VMFSSPARSE")) ||
+ strcmp(type, "VMFS") && strcmp(type, "VMFSSPARSE") &&
+ strcmp(type, "SESPARSE")) ||
(strcmp(access, "RW"))) {
continue;
}
return ret;
}
extent = &s->extents[s->num_extents - 1];
+ } else if (!strcmp(type, "SESPARSE")) {
+ ret = vmdk_open_se_sparse(bs, extent_file, bs->open_flags, errp);
+ if (ret) {
+ bdrv_unref_child(bs, extent_file);
+ return ret;
+ }
+ extent = &s->extents[s->num_extents - 1];
} else {
error_setg(errp, "Unsupported extent type '%s'", type);
bdrv_unref_child(bs, extent_file);
if (strcmp(ct, "monolithicFlat") &&
strcmp(ct, "vmfs") &&
strcmp(ct, "vmfsSparse") &&
+ strcmp(ct, "seSparse") &&
strcmp(ct, "twoGbMaxExtentSparse") &&
strcmp(ct, "twoGbMaxExtentFlat")) {
error_setg(errp, "Unsupported image type '%s'", ct);
{
unsigned int l1_index, l2_offset, l2_index;
int min_index, i, j;
- uint32_t min_count, *l2_table;
+ uint32_t min_count;
+ void *l2_table;
bool zeroed = false;
int64_t ret;
int64_t cluster_sector;
+ unsigned int l2_size_bytes = extent->l2_size * extent->entry_size;
if (m_data) {
m_data->valid = 0;
if (l1_index >= extent->l1_size) {
return VMDK_ERROR;
}
- l2_offset = extent->l1_table[l1_index];
+ if (extent->sesparse) {
+ uint64_t l2_offset_u64;
+
+ assert(extent->entry_size == sizeof(uint64_t));
+
+ l2_offset_u64 = ((uint64_t *)extent->l1_table)[l1_index];
+ if (l2_offset_u64 == 0) {
+ l2_offset = 0;
+ } else if ((l2_offset_u64 & 0xffffffff00000000) != 0x1000000000000000) {
+ /*
+ * Top most nibble is 0x1 if grain table is allocated.
+ * strict check - top most 4 bytes must be 0x10000000 since max
+ * supported size is 64TB for disk - so no more than 64TB / 16MB
+ * grain directories which is smaller than uint32,
+ * where 16MB is the only supported default grain table coverage.
+ */
+ return VMDK_ERROR;
+ } else {
+ l2_offset_u64 = l2_offset_u64 & 0x00000000ffffffff;
+ l2_offset_u64 = extent->sesparse_l2_tables_offset +
+ l2_offset_u64 * l2_size_bytes / SECTOR_SIZE;
+ if (l2_offset_u64 > 0x00000000ffffffff) {
+ return VMDK_ERROR;
+ }
+ l2_offset = (unsigned int)(l2_offset_u64);
+ }
+ } else {
+ assert(extent->entry_size == sizeof(uint32_t));
+ l2_offset = ((uint32_t *)extent->l1_table)[l1_index];
+ }
if (!l2_offset) {
return VMDK_UNALLOC;
}
extent->l2_cache_counts[j] >>= 1;
}
}
- l2_table = extent->l2_cache + (i * extent->l2_size);
+ l2_table = (char *)extent->l2_cache + (i * l2_size_bytes);
goto found;
}
}
min_index = i;
}
}
- l2_table = extent->l2_cache + (min_index * extent->l2_size);
+ l2_table = (char *)extent->l2_cache + (min_index * l2_size_bytes);
BLKDBG_EVENT(extent->file, BLKDBG_L2_LOAD);
if (bdrv_pread(extent->file,
(int64_t)l2_offset * 512,
l2_table,
- extent->l2_size * sizeof(uint32_t)
- ) != extent->l2_size * sizeof(uint32_t)) {
+ l2_size_bytes
+ ) != l2_size_bytes) {
return VMDK_ERROR;
}
extent->l2_cache_counts[min_index] = 1;
found:
l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
- cluster_sector = le32_to_cpu(l2_table[l2_index]);
- if (extent->has_zero_grain && cluster_sector == VMDK_GTE_ZEROED) {
- zeroed = true;
+ if (extent->sesparse) {
+ cluster_sector = le64_to_cpu(((uint64_t *)l2_table)[l2_index]);
+ switch (cluster_sector & 0xf000000000000000) {
+ case 0x0000000000000000:
+ /* unallocated grain */
+ if (cluster_sector != 0) {
+ return VMDK_ERROR;
+ }
+ break;
+ case 0x1000000000000000:
+ /* scsi-unmapped grain - fallthrough */
+ case 0x2000000000000000:
+ /* zero grain */
+ zeroed = true;
+ break;
+ case 0x3000000000000000:
+ /* allocated grain */
+ cluster_sector = (((cluster_sector & 0x0fff000000000000) >> 48) |
+ ((cluster_sector & 0x0000ffffffffffff) << 12));
+ cluster_sector = extent->sesparse_clusters_offset +
+ cluster_sector * extent->cluster_sectors;
+ break;
+ default:
+ return VMDK_ERROR;
+ }
+ } else {
+ cluster_sector = le32_to_cpu(((uint32_t *)l2_table)[l2_index]);
+
+ if (extent->has_zero_grain && cluster_sector == VMDK_GTE_ZEROED) {
+ zeroed = true;
+ }
}
if (!cluster_sector || zeroed) {
if (!allocate) {
return zeroed ? VMDK_ZEROED : VMDK_UNALLOC;
}
+ assert(!extent->sesparse);
if (extent->next_cluster_sector >= VMDK_EXTENT_MAX_SECTORS) {
return VMDK_ERROR;
m_data->l1_index = l1_index;
m_data->l2_index = l2_index;
m_data->l2_offset = l2_offset;
- m_data->l2_cache_entry = &l2_table[l2_index];
+ m_data->l2_cache_entry = ((uint32_t *)l2_table) + l2_index;
}
}
*cluster_offset = cluster_sector << BDRV_SECTOR_BITS;
if (!extent) {
return -EIO;
}
+ if (extent->sesparse) {
+ return -ENOTSUP;
+ }
offset_in_cluster = vmdk_find_offset_in_cluster(extent, offset);
n_bytes = MIN(bytes, extent->cluster_sectors * BDRV_SECTOR_SIZE
- offset_in_cluster);
assert(common->action->type == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);
backup = common->action->u.drive_backup.data;
- bs = qmp_get_root_bs(backup->device, errp);
+ bs = bdrv_lookup_bs(backup->device, backup->device, errp);
if (!bs) {
return;
}
$ld --help 2>/dev/null | grep ".$1" >/dev/null 2>&1
}
-# default parameters
-source_path=$(dirname "$0")
# make source path absolute
-source_path=$(cd "$source_path"; pwd)
+source_path=$(cd "$(dirname -- "$0")"; pwd)
+
+if printf %s\\n "$source_path" "$PWD" | grep -q "[[:space:]:]";
+then
+ error_exit "main directory cannot contain spaces nor colons"
+fi
+
+# default parameters
cpu=""
iasl="iasl"
interp_prefix="/usr/gnemul/qemu-%M"
vte=""
virglrenderer=""
tpm=""
-libssh2=""
+libssh=""
live_block_migration="yes"
numa=""
tcmalloc="no"
;;
--enable-tpm) tpm="yes"
;;
- --disable-libssh2) libssh2="no"
+ --disable-libssh) libssh="no"
;;
- --enable-libssh2) libssh2="yes"
+ --enable-libssh) libssh="yes"
;;
--disable-live-block-migration) live_block_migration="no"
;;
coroutine-pool coroutine freelist (better performance)
glusterfs GlusterFS backend
tpm TPM support
- libssh2 ssh block device support
+ libssh ssh block device support
numa libnuma support
libxml2 for Parallels image format
tcmalloc tcmalloc support
fi
##########################################
-# libssh2 probe
-min_libssh2_version=1.2.8
-if test "$libssh2" != "no" ; then
- if $pkg_config --atleast-version=$min_libssh2_version libssh2; then
- libssh2_cflags=$($pkg_config libssh2 --cflags)
- libssh2_libs=$($pkg_config libssh2 --libs)
- libssh2=yes
+# libssh probe
+if test "$libssh" != "no" ; then
+ if $pkg_config --exists libssh; then
+ libssh_cflags=$($pkg_config libssh --cflags)
+ libssh_libs=$($pkg_config libssh --libs)
+ libssh=yes
else
- if test "$libssh2" = "yes" ; then
- error_exit "libssh2 >= $min_libssh2_version required for --enable-libssh2"
+ if test "$libssh" = "yes" ; then
+ error_exit "libssh required for --enable-libssh"
fi
- libssh2=no
+ libssh=no
fi
fi
##########################################
-# libssh2_sftp_fsync probe
+# Check for libssh 0.8
+# This is done like this instead of using the LIBSSH_VERSION_* and
+# SSH_VERSION_* macros because some distributions in the past shipped
+# snapshots of the future 0.8 from Git, and those snapshots did not
+# have updated version numbers (still referring to 0.7.0).
-if test "$libssh2" = "yes"; then
+if test "$libssh" = "yes"; then
cat > $TMPC <<EOF
-#include <stdio.h>
-#include <libssh2.h>
-#include <libssh2_sftp.h>
-int main(void) {
- LIBSSH2_SESSION *session;
- LIBSSH2_SFTP *sftp;
- LIBSSH2_SFTP_HANDLE *sftp_handle;
- session = libssh2_session_init ();
- sftp = libssh2_sftp_init (session);
- sftp_handle = libssh2_sftp_open (sftp, "/", 0, 0);
- libssh2_sftp_fsync (sftp_handle);
- return 0;
-}
+#include <libssh/libssh.h>
+int main(void) { return ssh_get_server_publickey(NULL, NULL); }
EOF
- # libssh2_cflags/libssh2_libs defined in previous test.
- if compile_prog "$libssh2_cflags" "$libssh2_libs" ; then
- QEMU_CFLAGS="-DHAS_LIBSSH2_SFTP_FSYNC $QEMU_CFLAGS"
+ if compile_prog "$libssh_cflags" "$libssh_libs"; then
+ libssh_cflags="-DHAVE_LIBSSH_0_8 $libssh_cflags"
fi
fi
sem_timedwait=no
cat > $TMPC << EOF
#include <semaphore.h>
-int main(void) { return sem_timedwait(0, 0); }
+int main(void) { sem_t s; struct timespec t = {0}; return sem_timedwait(&s, &t); }
EOF
if compile_prog "" "" ; then
sem_timedwait=yes
echo "gcov $gcov_tool"
echo "gcov enabled $gcov"
echo "TPM support $tpm"
-echo "libssh2 support $libssh2"
+echo "libssh support $libssh"
echo "QOM debugging $qom_cast_debug"
echo "Live block migration $live_block_migration"
echo "lzo support $lzo"
echo "us upstream at qemu-devel@nongnu.org."
fi
+# Note that if the Python conditional here evaluates True we will exit
+# with status 1 which is a shell 'false' value.
+if ! $python -c 'import sys; sys.exit(sys.version_info < (3,0))'; then
+ echo
+ echo "warning: Python 2 support is deprecated" >&2
+ echo "warning: Python 3 will be required for building future versions of QEMU" >&2
+fi
+
config_host_mak="config-host.mak"
echo "# Automatically generated by configure - do not modify" >config-all-disas.mak
echo "CONFIG_GLUSTERFS_IOCB_HAS_STAT=y" >> $config_host_mak
fi
-if test "$libssh2" = "yes" ; then
- echo "CONFIG_LIBSSH2=m" >> $config_host_mak
- echo "LIBSSH2_CFLAGS=$libssh2_cflags" >> $config_host_mak
- echo "LIBSSH2_LIBS=$libssh2_libs" >> $config_host_mak
+if test "$libssh" = "yes" ; then
+ echo "CONFIG_LIBSSH=m" >> $config_host_mak
+ echo "LIBSSH_CFLAGS=$libssh_cflags" >> $config_host_mak
+ echo "LIBSSH_LIBS=$libssh_libs" >> $config_host_mak
fi
if test "$live_block_migration" = "yes" ; then
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/config-file.h"
-#include "cpu.h"
#include "monitor/monitor.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h"
#include "qemu/qemu-print.h"
-#include "sysemu/sysemu.h"
#include "sysemu/tcg.h"
#include "sysemu/block-backend.h"
#include "exec/gdbstub.h"
#include "tcg.h"
#include "hw/nmi.h"
#include "sysemu/replay.h"
-#include "hw/boards.h"
#ifdef CONFIG_LINUX
#endif
}
-CpuInfoList *qmp_query_cpus(Error **errp)
-{
- MachineState *ms = MACHINE(qdev_get_machine());
- MachineClass *mc = MACHINE_GET_CLASS(ms);
- CpuInfoList *head = NULL, *cur_item = NULL;
- CPUState *cpu;
-
- CPU_FOREACH(cpu) {
- CpuInfoList *info;
-#if defined(TARGET_I386)
- X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
-#elif defined(TARGET_PPC)
- PowerPCCPU *ppc_cpu = POWERPC_CPU(cpu);
- CPUPPCState *env = &ppc_cpu->env;
-#elif defined(TARGET_SPARC)
- SPARCCPU *sparc_cpu = SPARC_CPU(cpu);
- CPUSPARCState *env = &sparc_cpu->env;
-#elif defined(TARGET_RISCV)
- RISCVCPU *riscv_cpu = RISCV_CPU(cpu);
- CPURISCVState *env = &riscv_cpu->env;
-#elif defined(TARGET_MIPS)
- MIPSCPU *mips_cpu = MIPS_CPU(cpu);
- CPUMIPSState *env = &mips_cpu->env;
-#elif defined(TARGET_TRICORE)
- TriCoreCPU *tricore_cpu = TRICORE_CPU(cpu);
- CPUTriCoreState *env = &tricore_cpu->env;
-#elif defined(TARGET_S390X)
- S390CPU *s390_cpu = S390_CPU(cpu);
- CPUS390XState *env = &s390_cpu->env;
-#endif
-
- cpu_synchronize_state(cpu);
-
- info = g_malloc0(sizeof(*info));
- info->value = g_malloc0(sizeof(*info->value));
- info->value->CPU = cpu->cpu_index;
- info->value->current = (cpu == first_cpu);
- info->value->halted = cpu->halted;
- info->value->qom_path = object_get_canonical_path(OBJECT(cpu));
- info->value->thread_id = cpu->thread_id;
-#if defined(TARGET_I386)
- info->value->arch = CPU_INFO_ARCH_X86;
- info->value->u.x86.pc = env->eip + env->segs[R_CS].base;
-#elif defined(TARGET_PPC)
- info->value->arch = CPU_INFO_ARCH_PPC;
- info->value->u.ppc.nip = env->nip;
-#elif defined(TARGET_SPARC)
- info->value->arch = CPU_INFO_ARCH_SPARC;
- info->value->u.q_sparc.pc = env->pc;
- info->value->u.q_sparc.npc = env->npc;
-#elif defined(TARGET_MIPS)
- info->value->arch = CPU_INFO_ARCH_MIPS;
- info->value->u.q_mips.PC = env->active_tc.PC;
-#elif defined(TARGET_TRICORE)
- info->value->arch = CPU_INFO_ARCH_TRICORE;
- info->value->u.tricore.PC = env->PC;
-#elif defined(TARGET_S390X)
- info->value->arch = CPU_INFO_ARCH_S390;
- info->value->u.s390.cpu_state = env->cpu_state;
-#elif defined(TARGET_RISCV)
- info->value->arch = CPU_INFO_ARCH_RISCV;
- info->value->u.riscv.pc = env->pc;
-#else
- info->value->arch = CPU_INFO_ARCH_OTHER;
-#endif
- info->value->has_props = !!mc->cpu_index_to_instance_props;
- if (info->value->has_props) {
- CpuInstanceProperties *props;
- props = g_malloc0(sizeof(*props));
- *props = mc->cpu_index_to_instance_props(ms, cpu->cpu_index);
- info->value->props = props;
- }
-
- /* XXX: waiting for the qapi to support GSList */
- if (!cur_item) {
- head = cur_item = info;
- } else {
- cur_item->next = info;
- cur_item = info;
- }
- }
-
- return head;
-}
-
-static CpuInfoArch sysemu_target_to_cpuinfo_arch(SysEmuTarget target)
-{
- /*
- * The @SysEmuTarget -> @CpuInfoArch mapping below is based on the
- * TARGET_ARCH -> TARGET_BASE_ARCH mapping in the "configure" script.
- */
- switch (target) {
- case SYS_EMU_TARGET_I386:
- case SYS_EMU_TARGET_X86_64:
- return CPU_INFO_ARCH_X86;
-
- case SYS_EMU_TARGET_PPC:
- case SYS_EMU_TARGET_PPC64:
- return CPU_INFO_ARCH_PPC;
-
- case SYS_EMU_TARGET_SPARC:
- case SYS_EMU_TARGET_SPARC64:
- return CPU_INFO_ARCH_SPARC;
-
- case SYS_EMU_TARGET_MIPS:
- case SYS_EMU_TARGET_MIPSEL:
- case SYS_EMU_TARGET_MIPS64:
- case SYS_EMU_TARGET_MIPS64EL:
- return CPU_INFO_ARCH_MIPS;
-
- case SYS_EMU_TARGET_TRICORE:
- return CPU_INFO_ARCH_TRICORE;
-
- case SYS_EMU_TARGET_S390X:
- return CPU_INFO_ARCH_S390;
-
- case SYS_EMU_TARGET_RISCV32:
- case SYS_EMU_TARGET_RISCV64:
- return CPU_INFO_ARCH_RISCV;
-
- default:
- return CPU_INFO_ARCH_OTHER;
- }
-}
-
-static void cpustate_to_cpuinfo_s390(CpuInfoS390 *info, const CPUState *cpu)
-{
-#ifdef TARGET_S390X
- S390CPU *s390_cpu = S390_CPU(cpu);
- CPUS390XState *env = &s390_cpu->env;
-
- info->cpu_state = env->cpu_state;
-#else
- abort();
-#endif
-}
-
-/*
- * fast means: we NEVER interrupt vCPU threads to retrieve
- * information from KVM.
- */
-CpuInfoFastList *qmp_query_cpus_fast(Error **errp)
-{
- MachineState *ms = MACHINE(qdev_get_machine());
- MachineClass *mc = MACHINE_GET_CLASS(ms);
- CpuInfoFastList *head = NULL, *cur_item = NULL;
- SysEmuTarget target = qapi_enum_parse(&SysEmuTarget_lookup, TARGET_NAME,
- -1, &error_abort);
- CPUState *cpu;
-
- CPU_FOREACH(cpu) {
- CpuInfoFastList *info = g_malloc0(sizeof(*info));
- info->value = g_malloc0(sizeof(*info->value));
-
- info->value->cpu_index = cpu->cpu_index;
- info->value->qom_path = object_get_canonical_path(OBJECT(cpu));
- info->value->thread_id = cpu->thread_id;
-
- info->value->has_props = !!mc->cpu_index_to_instance_props;
- if (info->value->has_props) {
- CpuInstanceProperties *props;
- props = g_malloc0(sizeof(*props));
- *props = mc->cpu_index_to_instance_props(ms, cpu->cpu_index);
- info->value->props = props;
- }
-
- info->value->arch = sysemu_target_to_cpuinfo_arch(target);
- info->value->target = target;
- if (target == SYS_EMU_TARGET_S390X) {
- cpustate_to_cpuinfo_s390(&info->value->u.s390x, cpu);
- }
-
- if (!cur_item) {
- head = cur_item = info;
- } else {
- cur_item->next = info;
- cur_item = info;
- }
- }
-
- return head;
-}
-
void qmp_memsave(int64_t addr, int64_t size, const char *filename,
bool has_cpu, int64_t cpu_index, Error **errp)
{
CONFIG_XLNX_ZYNQMP_ARM=y
CONFIG_XLNX_VERSAL=y
+CONFIG_SBSA_REF=y
# Common mips*-softmmu CONFIG defines
+# CONFIG_SEMIHOSTING is always required on this architecture
+CONFIG_SEMIHOSTING=y
+
CONFIG_ISA_BUS=y
CONFIG_PCI=y
CONFIG_PCI_DEVICES=y
-CONFIG_ESP=y
CONFIG_VGA_ISA=y
CONFIG_VGA_ISA_MM=y
CONFIG_VGA_CIRRUS=y
CONFIG_PIIX4=y
CONFIG_IDE_ISA=y
CONFIG_IDE_PIIX=y
-CONFIG_NE2000_ISA=y
-CONFIG_MIPSNET=y
CONFIG_PFLASH_CFI01=y
CONFIG_I8259=y
CONFIG_MC146818RTC=y
CONFIG_MIPS_ITU=y
CONFIG_R4K=y
CONFIG_MALTA=y
-CONFIG_SEMIHOSTING=y
CONFIG_PCNET_PCI=y
CONFIG_MIPSSIM=y
CONFIG_ACPI_SMBUS=y
# Default configuration for mips64-softmmu
include mips-softmmu-common.mak
-CONFIG_RC4030=y
-CONFIG_DP8393X=y
-CONFIG_DS1225Y=y
CONFIG_JAZZ=y
-CONFIG_G364FB=y
-CONFIG_JAZZ_LED=y
include mips-softmmu-common.mak
CONFIG_IDE_VIA=y
-CONFIG_RC4030=y
-CONFIG_DP8393X=y
-CONFIG_DS1225Y=y
CONFIG_FULONG=y
CONFIG_ATI_VGA=y
CONFIG_RTL8139_PCI=y
CONFIG_JAZZ=y
-CONFIG_G364FB=y
-CONFIG_JAZZ_LED=y
CONFIG_VT82C686=y
CONFIG_AHCI=y
CONFIG_MIPS_BOSTON=y
const rvc_constraint *constraints;
} rv_comp_data;
+enum {
+ rvcd_imm_nz = 0x1
+};
+
typedef struct {
const char * const name;
const rv_codec codec;
const char * const format;
const rv_comp_data *pseudo;
- const int decomp_rv32;
- const int decomp_rv64;
- const int decomp_rv128;
+ const short decomp_rv32;
+ const short decomp_rv64;
+ const short decomp_rv128;
+ const short decomp_data;
} rv_opcode_data;
/* register names */
static const rvc_constraint rvcc_rdinstret[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc02, rvc_end };
static const rvc_constraint rvcc_rdcycleh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc80, rvc_end };
static const rvc_constraint rvcc_rdtimeh[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc81, rvc_end };
-static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0, rvc_csr_eq_0xc80, rvc_end };
+static const rvc_constraint rvcc_rdinstreth[] = { rvc_rs1_eq_x0,
+ rvc_csr_eq_0xc82, rvc_end };
static const rvc_constraint rvcc_frcsr[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x003, rvc_end };
static const rvc_constraint rvcc_frrm[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x002, rvc_end };
static const rvc_constraint rvcc_frflags[] = { rvc_rs1_eq_x0, rvc_csr_eq_0x001, rvc_end };
{ "fcvt.q.lu", rv_codec_r_m, rv_fmt_rm_frd_rs1, NULL, 0, 0, 0 },
{ "fmv.x.q", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
{ "fmv.q.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
- { "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
+ { "c.addi4spn", rv_codec_ciw_4spn, rv_fmt_rd_rs1_imm, NULL, rv_op_addi,
+ rv_op_addi, rv_op_addi, rvcd_imm_nz },
{ "c.fld", rv_codec_cl_ld, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, 0 },
{ "c.lw", rv_codec_cl_lw, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
{ "c.flw", rv_codec_cl_lw, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
{ "c.sw", rv_codec_cs_sw, rv_fmt_rs2_offset_rs1, NULL, rv_op_sw, rv_op_sw, rv_op_sw },
{ "c.fsw", rv_codec_cs_sw, rv_fmt_frs2_offset_rs1, NULL, rv_op_fsw, 0, 0 },
{ "c.nop", rv_codec_ci_none, rv_fmt_none, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
- { "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
+ { "c.addi", rv_codec_ci, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi,
+ rv_op_addi, rvcd_imm_nz },
{ "c.jal", rv_codec_cj_jal, rv_fmt_rd_offset, NULL, rv_op_jal, 0, 0 },
{ "c.li", rv_codec_ci_li, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
- { "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi, rv_op_addi, rv_op_addi },
- { "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui, rv_op_lui },
- { "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli, rv_op_srli, rv_op_srli },
- { "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srai, rv_op_srai, rv_op_srai },
- { "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi, rv_op_andi, rv_op_andi },
+ { "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi,
+ rv_op_addi, rv_op_addi, rvcd_imm_nz },
+ { "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui,
+ rv_op_lui, rvcd_imm_nz },
+ { "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli,
+ rv_op_srli, rv_op_srli, rvcd_imm_nz },
+ { "c.srai", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srai,
+ rv_op_srai, rv_op_srai, rvcd_imm_nz },
+ { "c.andi", rv_codec_cb_imm, rv_fmt_rd_rs1_imm, NULL, rv_op_andi,
+ rv_op_andi, rv_op_andi },
{ "c.sub", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_sub, rv_op_sub, rv_op_sub },
{ "c.xor", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_xor, rv_op_xor, rv_op_xor },
{ "c.or", rv_codec_cs, rv_fmt_rd_rs1_rs2, NULL, rv_op_or, rv_op_or, rv_op_or },
{ "c.j", rv_codec_cj, rv_fmt_rd_offset, NULL, rv_op_jal, rv_op_jal, rv_op_jal },
{ "c.beqz", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_beq, rv_op_beq, rv_op_beq },
{ "c.bnez", rv_codec_cb, rv_fmt_rs1_rs2_offset, NULL, rv_op_bne, rv_op_bne, rv_op_bne },
- { "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli, rv_op_slli, rv_op_slli },
+ { "c.slli", rv_codec_ci_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_slli,
+ rv_op_slli, rv_op_slli, rvcd_imm_nz },
{ "c.fldsp", rv_codec_ci_ldsp, rv_fmt_frd_offset_rs1, NULL, rv_op_fld, rv_op_fld, rv_op_fld },
{ "c.lwsp", rv_codec_ci_lwsp, rv_fmt_rd_offset_rs1, NULL, rv_op_lw, rv_op_lw, rv_op_lw },
{ "c.flwsp", rv_codec_ci_lwsp, rv_fmt_frd_offset_rs1, NULL, rv_op_flw, 0, 0 },
{
int decomp_op = opcode_data[dec->op].decomp_rv32;
if (decomp_op != rv_op_illegal) {
- dec->op = decomp_op;
- dec->codec = opcode_data[decomp_op].codec;
+ if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
+ && dec->imm == 0) {
+ dec->op = rv_op_illegal;
+ } else {
+ dec->op = decomp_op;
+ dec->codec = opcode_data[decomp_op].codec;
+ }
}
}
{
int decomp_op = opcode_data[dec->op].decomp_rv64;
if (decomp_op != rv_op_illegal) {
- dec->op = decomp_op;
- dec->codec = opcode_data[decomp_op].codec;
+ if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
+ && dec->imm == 0) {
+ dec->op = rv_op_illegal;
+ } else {
+ dec->op = decomp_op;
+ dec->codec = opcode_data[decomp_op].codec;
+ }
}
}
{
int decomp_op = opcode_data[dec->op].decomp_rv128;
if (decomp_op != rv_op_illegal) {
- dec->op = decomp_op;
- dec->codec = opcode_data[decomp_op].codec;
+ if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
+ && dec->imm == 0) {
+ dec->op = rv_op_illegal;
+ } else {
+ dec->op = decomp_op;
+ dec->codec = opcode_data[decomp_op].codec;
+ }
}
}
warning: ssh server @code{ssh.example.com:22} does not support fsync
-With sufficiently new versions of libssh2 and OpenSSH, @code{fsync} is
+With sufficiently new versions of libssh and OpenSSH, @code{fsync} is
supported.
@node disk_images_nvme
---------------
QEMU advertises the supported interrupt modes in the device tree
-property "ibm,arch-vec-5-platform-support" in byte 23 and the OS
-Selection for XIVE is indicated in the "ibm,architecture-vec-5"
+property ``ibm,arch-vec-5-platform-support`` in byte 23 and the OS
+Selection for XIVE is indicated in the ``ibm,architecture-vec-5``
property byte 23.
The interrupt modes supported by the machine depend on the CPU type
(POWER9 is required for XIVE) but also on the machine property
``ic-mode`` which can be set on the command line. It can take the
-following values: ``xics``, ``xive``, ``dual`` and currently ``xics``
-is the default but it may change in the future.
+following values: ``xics``, ``xive``, and ``dual`` which is the
+default mode. ``dual`` means that both modes XICS **and** XIVE are
+supported and if the guest OS supports XIVE, this mode will be
+selected.
The choosen interrupt mode is activated after a reconfiguration done
in a machine reset.
+KVM negotiation
+---------------
+
+When the guest starts under KVM, the capabilities of the host kernel
+and QEMU are also negotiated. Depending on the version of the host
+kernel, KVM will advertise the XIVE capability to QEMU or not.
+
+Nevertheless, the available interrupt modes in the machine should not
+depend on the XIVE KVM capability of the host. On older kernels
+without XIVE KVM support, QEMU will use the emulated XIVE device as a
+fallback and on newer kernels (>=5.2), the KVM XIVE device.
+
+As a final refinement, the user can also switch the use of the KVM
+device with the machine option ``kernel_irqchip``.
+
+
+XIVE support in KVM
+~~~~~~~~~~~~~~~~~~~
+
+For guest OSes supporting XIVE, the resulting interrupt modes on host
+kernels with XIVE KVM support are the following:
+
+============== ============= ============= ================
+ic-mode kernel_irqchip
+-------------- ----------------------------------------------
+/ allowed off on
+ (default)
+============== ============= ============= ================
+dual (default) XIVE KVM XIVE emul. XIVE KVM
+xive XIVE KVM XIVE emul. XIVE KVM
+xics XICS KVM XICS emul. XICS KVM
+============== ============= ============= ================
+
+For legacy guest OSes without XIVE support, the resulting interrupt
+modes are the following:
+
+============== ============= ============= ================
+ic-mode kernel_irqchip
+-------------- ----------------------------------------------
+/ allowed off on
+ (default)
+============== ============= ============= ================
+dual (default) XICS KVM XICS emul. XICS KVM
+xive QEMU error(3) QEMU error(3) QEMU error(3)
+xics XICS KVM XICS emul. XICS KVM
+============== ============= ============= ================
+
+(3) QEMU fails at CAS with ``Guest requested unavailable interrupt
+ mode (XICS), either don't set the ic-mode machine property or try
+ ic-mode=xics or ic-mode=dual``
+
+
+No XIVE support in KVM
+~~~~~~~~~~~~~~~~~~~~~~
+
+For guest OSes supporting XIVE, the resulting interrupt modes on host
+kernels without XIVE KVM support are the following:
+
+============== ============= ============= ================
+ic-mode kernel_irqchip
+-------------- ----------------------------------------------
+/ allowed off on
+ (default)
+============== ============= ============= ================
+dual (default) XIVE emul.(1) XIVE emul. QEMU error (2)
+xive XIVE emul.(1) XIVE emul. QEMU error (2)
+xics XICS KVM XICS emul. XICS KVM
+============== ============= ============= ================
+
+
+(1) QEMU warns with ``warning: kernel_irqchip requested but unavailable:
+ IRQ_XIVE capability must be present for KVM``
+(2) QEMU fails with ``kernel_irqchip requested but unavailable:
+ IRQ_XIVE capability must be present for KVM``
+
+
+For legacy guest OSes without XIVE support, the resulting interrupt
+modes are the following:
+
+============== ============= ============= ================
+ic-mode kernel_irqchip
+-------------- ----------------------------------------------
+/ allowed off on
+ (default)
+============== ============= ============= ================
+dual (default) QEMU error(4) XICS emul. QEMU error(4)
+xive QEMU error(3) QEMU error(3) QEMU error(3)
+xics XICS KVM XICS emul. XICS KVM
+============== ============= ============= ================
+
+(3) QEMU fails at CAS with ``Guest requested unavailable interrupt
+ mode (XICS), either don't set the ic-mode machine property or try
+ ic-mode=xics or ic-mode=dual``
+(4) QEMU/KVM incompatibility due to device destruction in reset. QEMU fails
+ with ``KVM is too old to support ic-mode=dual,kernel-irqchip=on``
+
+
XIVE Device tree properties
---------------------------
- ``0x0000 .. 0x0FFF`` 4K CPU IPIs (only used under XIVE)
- ``0x1000 .. 0x1000`` 1 EPOW
- ``0x1001 .. 0x1001`` 1 HOTPLUG
+- ``0x1002 .. 0x10FF`` unused
- ``0x1100 .. 0x11FF`` 256 VIO devices
-- ``0x1200 .. 0x127F`` 32 PHBs devices
+- ``0x1200 .. 0x127F`` 32x4 LSIs for PHB devices
- ``0x1280 .. 0x12FF`` unused
-- ``0x1300 .. 0x1FFF`` PHB MSIs
+- ``0x1300 .. 0x1FFF`` PHB MSIs (dynamically allocated)
Monitoring XIVE
---------------
processing layer of external interrupts:
- Interrupt Virtualization Source Engine (IVSE), or Source Controller
- (SC). These are found in PCI PHBs, in the PSI host bridge
- controller, but also inside the main controller for the core IPIs
- and other sub-chips (NX, CAP, NPU) of the chip/processor. They are
- configured to feed the IVRE with events.
+ (SC). These are found in PCI PHBs, in the Processor Service
+ Interface (PSI) host bridge Controller, but also inside the main
+ controller for the core IPIs and other sub-chips (NX, CAP, NPU) of
+ the chip/processor. They are configured to feed the IVRE with
+ events.
- Interrupt Virtualization Routing Engine (IVRE) or Virtualization
Controller (VC). It handles event coalescing and perform interrupt
routing by matching an event source number with an Event
+++ /dev/null
-/*
- * QEMU dump
- *
- * Copyright Fujitsu, Corp. 2011, 2012
- *
- * Authors:
- * Wen Congyang <wency@cn.fujitsu.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-common.h"
-#include "qemu/cutils.h"
-#include "elf.h"
-#include "cpu.h"
-#include "exec/hwaddr.h"
-#include "monitor/monitor.h"
-#include "sysemu/kvm.h"
-#include "sysemu/dump.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/memory_mapping.h"
-#include "sysemu/cpus.h"
-#include "qapi/error.h"
-#include "qapi/qapi-commands-misc.h"
-#include "qapi/qapi-events-misc.h"
-#include "qapi/qmp/qerror.h"
-#include "qemu/error-report.h"
-#include "hw/misc/vmcoreinfo.h"
-
-#ifdef TARGET_X86_64
-#include "win_dump.h"
-#endif
-
-#include <zlib.h>
-#ifdef CONFIG_LZO
-#include <lzo/lzo1x.h>
-#endif
-#ifdef CONFIG_SNAPPY
-#include <snappy-c.h>
-#endif
-#ifndef ELF_MACHINE_UNAME
-#define ELF_MACHINE_UNAME "Unknown"
-#endif
-
-#define MAX_GUEST_NOTE_SIZE (1 << 20) /* 1MB should be enough */
-
-#define ELF_NOTE_SIZE(hdr_size, name_size, desc_size) \
- ((DIV_ROUND_UP((hdr_size), 4) + \
- DIV_ROUND_UP((name_size), 4) + \
- DIV_ROUND_UP((desc_size), 4)) * 4)
-
-uint16_t cpu_to_dump16(DumpState *s, uint16_t val)
-{
- if (s->dump_info.d_endian == ELFDATA2LSB) {
- val = cpu_to_le16(val);
- } else {
- val = cpu_to_be16(val);
- }
-
- return val;
-}
-
-uint32_t cpu_to_dump32(DumpState *s, uint32_t val)
-{
- if (s->dump_info.d_endian == ELFDATA2LSB) {
- val = cpu_to_le32(val);
- } else {
- val = cpu_to_be32(val);
- }
-
- return val;
-}
-
-uint64_t cpu_to_dump64(DumpState *s, uint64_t val)
-{
- if (s->dump_info.d_endian == ELFDATA2LSB) {
- val = cpu_to_le64(val);
- } else {
- val = cpu_to_be64(val);
- }
-
- return val;
-}
-
-static int dump_cleanup(DumpState *s)
-{
- guest_phys_blocks_free(&s->guest_phys_blocks);
- memory_mapping_list_free(&s->list);
- close(s->fd);
- g_free(s->guest_note);
- s->guest_note = NULL;
- if (s->resume) {
- if (s->detached) {
- qemu_mutex_lock_iothread();
- }
- vm_start();
- if (s->detached) {
- qemu_mutex_unlock_iothread();
- }
- }
-
- return 0;
-}
-
-static int fd_write_vmcore(const void *buf, size_t size, void *opaque)
-{
- DumpState *s = opaque;
- size_t written_size;
-
- written_size = qemu_write_full(s->fd, buf, size);
- if (written_size != size) {
- return -errno;
- }
-
- return 0;
-}
-
-static void write_elf64_header(DumpState *s, Error **errp)
-{
- Elf64_Ehdr elf_header;
- int ret;
-
- memset(&elf_header, 0, sizeof(Elf64_Ehdr));
- memcpy(&elf_header, ELFMAG, SELFMAG);
- elf_header.e_ident[EI_CLASS] = ELFCLASS64;
- elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
- elf_header.e_ident[EI_VERSION] = EV_CURRENT;
- elf_header.e_type = cpu_to_dump16(s, ET_CORE);
- elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
- elf_header.e_version = cpu_to_dump32(s, EV_CURRENT);
- elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
- elf_header.e_phoff = cpu_to_dump64(s, sizeof(Elf64_Ehdr));
- elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf64_Phdr));
- elf_header.e_phnum = cpu_to_dump16(s, s->phdr_num);
- if (s->have_section) {
- uint64_t shoff = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) * s->sh_info;
-
- elf_header.e_shoff = cpu_to_dump64(s, shoff);
- elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf64_Shdr));
- elf_header.e_shnum = cpu_to_dump16(s, 1);
- }
-
- ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
- if (ret < 0) {
- error_setg_errno(errp, -ret, "dump: failed to write elf header");
- }
-}
-
-static void write_elf32_header(DumpState *s, Error **errp)
-{
- Elf32_Ehdr elf_header;
- int ret;
-
- memset(&elf_header, 0, sizeof(Elf32_Ehdr));
- memcpy(&elf_header, ELFMAG, SELFMAG);
- elf_header.e_ident[EI_CLASS] = ELFCLASS32;
- elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
- elf_header.e_ident[EI_VERSION] = EV_CURRENT;
- elf_header.e_type = cpu_to_dump16(s, ET_CORE);
- elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
- elf_header.e_version = cpu_to_dump32(s, EV_CURRENT);
- elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
- elf_header.e_phoff = cpu_to_dump32(s, sizeof(Elf32_Ehdr));
- elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf32_Phdr));
- elf_header.e_phnum = cpu_to_dump16(s, s->phdr_num);
- if (s->have_section) {
- uint32_t shoff = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) * s->sh_info;
-
- elf_header.e_shoff = cpu_to_dump32(s, shoff);
- elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf32_Shdr));
- elf_header.e_shnum = cpu_to_dump16(s, 1);
- }
-
- ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
- if (ret < 0) {
- error_setg_errno(errp, -ret, "dump: failed to write elf header");
- }
-}
-
-static void write_elf64_load(DumpState *s, MemoryMapping *memory_mapping,
- int phdr_index, hwaddr offset,
- hwaddr filesz, Error **errp)
-{
- Elf64_Phdr phdr;
- int ret;
-
- memset(&phdr, 0, sizeof(Elf64_Phdr));
- phdr.p_type = cpu_to_dump32(s, PT_LOAD);
- phdr.p_offset = cpu_to_dump64(s, offset);
- phdr.p_paddr = cpu_to_dump64(s, memory_mapping->phys_addr);
- phdr.p_filesz = cpu_to_dump64(s, filesz);
- phdr.p_memsz = cpu_to_dump64(s, memory_mapping->length);
- phdr.p_vaddr = cpu_to_dump64(s, memory_mapping->virt_addr) ?: phdr.p_paddr;
-
- assert(memory_mapping->length >= filesz);
-
- ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s);
- if (ret < 0) {
- error_setg_errno(errp, -ret,
- "dump: failed to write program header table");
- }
-}
-
-static void write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
- int phdr_index, hwaddr offset,
- hwaddr filesz, Error **errp)
-{
- Elf32_Phdr phdr;
- int ret;
-
- memset(&phdr, 0, sizeof(Elf32_Phdr));
- phdr.p_type = cpu_to_dump32(s, PT_LOAD);
- phdr.p_offset = cpu_to_dump32(s, offset);
- phdr.p_paddr = cpu_to_dump32(s, memory_mapping->phys_addr);
- phdr.p_filesz = cpu_to_dump32(s, filesz);
- phdr.p_memsz = cpu_to_dump32(s, memory_mapping->length);
- phdr.p_vaddr =
- cpu_to_dump32(s, memory_mapping->virt_addr) ?: phdr.p_paddr;
-
- assert(memory_mapping->length >= filesz);
-
- ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s);
- if (ret < 0) {
- error_setg_errno(errp, -ret,
- "dump: failed to write program header table");
- }
-}
-
-static void write_elf64_note(DumpState *s, Error **errp)
-{
- Elf64_Phdr phdr;
- hwaddr begin = s->memory_offset - s->note_size;
- int ret;
-
- memset(&phdr, 0, sizeof(Elf64_Phdr));
- phdr.p_type = cpu_to_dump32(s, PT_NOTE);
- phdr.p_offset = cpu_to_dump64(s, begin);
- phdr.p_paddr = 0;
- phdr.p_filesz = cpu_to_dump64(s, s->note_size);
- phdr.p_memsz = cpu_to_dump64(s, s->note_size);
- phdr.p_vaddr = 0;
-
- ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s);
- if (ret < 0) {
- error_setg_errno(errp, -ret,
- "dump: failed to write program header table");
- }
-}
-
-static inline int cpu_index(CPUState *cpu)
-{
- return cpu->cpu_index + 1;
-}
-
-static void write_guest_note(WriteCoreDumpFunction f, DumpState *s,
- Error **errp)
-{
- int ret;
-
- if (s->guest_note) {
- ret = f(s->guest_note, s->guest_note_size, s);
- if (ret < 0) {
- error_setg(errp, "dump: failed to write guest note");
- }
- }
-}
-
-static void write_elf64_notes(WriteCoreDumpFunction f, DumpState *s,
- Error **errp)
-{
- CPUState *cpu;
- int ret;
- int id;
-
- CPU_FOREACH(cpu) {
- id = cpu_index(cpu);
- ret = cpu_write_elf64_note(f, cpu, id, s);
- if (ret < 0) {
- error_setg(errp, "dump: failed to write elf notes");
- return;
- }
- }
-
- CPU_FOREACH(cpu) {
- ret = cpu_write_elf64_qemunote(f, cpu, s);
- if (ret < 0) {
- error_setg(errp, "dump: failed to write CPU status");
- return;
- }
- }
-
- write_guest_note(f, s, errp);
-}
-
-static void write_elf32_note(DumpState *s, Error **errp)
-{
- hwaddr begin = s->memory_offset - s->note_size;
- Elf32_Phdr phdr;
- int ret;
-
- memset(&phdr, 0, sizeof(Elf32_Phdr));
- phdr.p_type = cpu_to_dump32(s, PT_NOTE);
- phdr.p_offset = cpu_to_dump32(s, begin);
- phdr.p_paddr = 0;
- phdr.p_filesz = cpu_to_dump32(s, s->note_size);
- phdr.p_memsz = cpu_to_dump32(s, s->note_size);
- phdr.p_vaddr = 0;
-
- ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s);
- if (ret < 0) {
- error_setg_errno(errp, -ret,
- "dump: failed to write program header table");
- }
-}
-
-static void write_elf32_notes(WriteCoreDumpFunction f, DumpState *s,
- Error **errp)
-{
- CPUState *cpu;
- int ret;
- int id;
-
- CPU_FOREACH(cpu) {
- id = cpu_index(cpu);
- ret = cpu_write_elf32_note(f, cpu, id, s);
- if (ret < 0) {
- error_setg(errp, "dump: failed to write elf notes");
- return;
- }
- }
-
- CPU_FOREACH(cpu) {
- ret = cpu_write_elf32_qemunote(f, cpu, s);
- if (ret < 0) {
- error_setg(errp, "dump: failed to write CPU status");
- return;
- }
- }
-
- write_guest_note(f, s, errp);
-}
-
-static void write_elf_section(DumpState *s, int type, Error **errp)
-{
- Elf32_Shdr shdr32;
- Elf64_Shdr shdr64;
- int shdr_size;
- void *shdr;
- int ret;
-
- if (type == 0) {
- shdr_size = sizeof(Elf32_Shdr);
- memset(&shdr32, 0, shdr_size);
- shdr32.sh_info = cpu_to_dump32(s, s->sh_info);
- shdr = &shdr32;
- } else {
- shdr_size = sizeof(Elf64_Shdr);
- memset(&shdr64, 0, shdr_size);
- shdr64.sh_info = cpu_to_dump32(s, s->sh_info);
- shdr = &shdr64;
- }
-
- ret = fd_write_vmcore(&shdr, shdr_size, s);
- if (ret < 0) {
- error_setg_errno(errp, -ret,
- "dump: failed to write section header table");
- }
-}
-
-static void write_data(DumpState *s, void *buf, int length, Error **errp)
-{
- int ret;
-
- ret = fd_write_vmcore(buf, length, s);
- if (ret < 0) {
- error_setg_errno(errp, -ret, "dump: failed to save memory");
- } else {
- s->written_size += length;
- }
-}
-
-/* write the memory to vmcore. 1 page per I/O. */
-static void write_memory(DumpState *s, GuestPhysBlock *block, ram_addr_t start,
- int64_t size, Error **errp)
-{
- int64_t i;
- Error *local_err = NULL;
-
- for (i = 0; i < size / s->dump_info.page_size; i++) {
- write_data(s, block->host_addr + start + i * s->dump_info.page_size,
- s->dump_info.page_size, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
- }
-
- if ((size % s->dump_info.page_size) != 0) {
- write_data(s, block->host_addr + start + i * s->dump_info.page_size,
- size % s->dump_info.page_size, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
- }
-}
-
-/* get the memory's offset and size in the vmcore */
-static void get_offset_range(hwaddr phys_addr,
- ram_addr_t mapping_length,
- DumpState *s,
- hwaddr *p_offset,
- hwaddr *p_filesz)
-{
- GuestPhysBlock *block;
- hwaddr offset = s->memory_offset;
- int64_t size_in_block, start;
-
- /* When the memory is not stored into vmcore, offset will be -1 */
- *p_offset = -1;
- *p_filesz = 0;
-
- if (s->has_filter) {
- if (phys_addr < s->begin || phys_addr >= s->begin + s->length) {
- return;
- }
- }
-
- QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
- if (s->has_filter) {
- if (block->target_start >= s->begin + s->length ||
- block->target_end <= s->begin) {
- /* This block is out of the range */
- continue;
- }
-
- if (s->begin <= block->target_start) {
- start = block->target_start;
- } else {
- start = s->begin;
- }
-
- size_in_block = block->target_end - start;
- if (s->begin + s->length < block->target_end) {
- size_in_block -= block->target_end - (s->begin + s->length);
- }
- } else {
- start = block->target_start;
- size_in_block = block->target_end - block->target_start;
- }
-
- if (phys_addr >= start && phys_addr < start + size_in_block) {
- *p_offset = phys_addr - start + offset;
-
- /* The offset range mapped from the vmcore file must not spill over
- * the GuestPhysBlock, clamp it. The rest of the mapping will be
- * zero-filled in memory at load time; see
- * <http://refspecs.linuxbase.org/elf/gabi4+/ch5.pheader.html>.
- */
- *p_filesz = phys_addr + mapping_length <= start + size_in_block ?
- mapping_length :
- size_in_block - (phys_addr - start);
- return;
- }
-
- offset += size_in_block;
- }
-}
-
-static void write_elf_loads(DumpState *s, Error **errp)
-{
- hwaddr offset, filesz;
- MemoryMapping *memory_mapping;
- uint32_t phdr_index = 1;
- uint32_t max_index;
- Error *local_err = NULL;
-
- if (s->have_section) {
- max_index = s->sh_info;
- } else {
- max_index = s->phdr_num;
- }
-
- QTAILQ_FOREACH(memory_mapping, &s->list.head, next) {
- get_offset_range(memory_mapping->phys_addr,
- memory_mapping->length,
- s, &offset, &filesz);
- if (s->dump_info.d_class == ELFCLASS64) {
- write_elf64_load(s, memory_mapping, phdr_index++, offset,
- filesz, &local_err);
- } else {
- write_elf32_load(s, memory_mapping, phdr_index++, offset,
- filesz, &local_err);
- }
-
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- if (phdr_index >= max_index) {
- break;
- }
- }
-}
-
-/* write elf header, PT_NOTE and elf note to vmcore. */
-static void dump_begin(DumpState *s, Error **errp)
-{
- Error *local_err = NULL;
-
- /*
- * the vmcore's format is:
- * --------------
- * | elf header |
- * --------------
- * | PT_NOTE |
- * --------------
- * | PT_LOAD |
- * --------------
- * | ...... |
- * --------------
- * | PT_LOAD |
- * --------------
- * | sec_hdr |
- * --------------
- * | elf note |
- * --------------
- * | memory |
- * --------------
- *
- * we only know where the memory is saved after we write elf note into
- * vmcore.
- */
-
- /* write elf header to vmcore */
- if (s->dump_info.d_class == ELFCLASS64) {
- write_elf64_header(s, &local_err);
- } else {
- write_elf32_header(s, &local_err);
- }
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- if (s->dump_info.d_class == ELFCLASS64) {
- /* write PT_NOTE to vmcore */
- write_elf64_note(s, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- /* write all PT_LOAD to vmcore */
- write_elf_loads(s, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- /* write section to vmcore */
- if (s->have_section) {
- write_elf_section(s, 1, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
- }
-
- /* write notes to vmcore */
- write_elf64_notes(fd_write_vmcore, s, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
- } else {
- /* write PT_NOTE to vmcore */
- write_elf32_note(s, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- /* write all PT_LOAD to vmcore */
- write_elf_loads(s, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- /* write section to vmcore */
- if (s->have_section) {
- write_elf_section(s, 0, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
- }
-
- /* write notes to vmcore */
- write_elf32_notes(fd_write_vmcore, s, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
- }
-}
-
-static int get_next_block(DumpState *s, GuestPhysBlock *block)
-{
- while (1) {
- block = QTAILQ_NEXT(block, next);
- if (!block) {
- /* no more block */
- return 1;
- }
-
- s->start = 0;
- s->next_block = block;
- if (s->has_filter) {
- if (block->target_start >= s->begin + s->length ||
- block->target_end <= s->begin) {
- /* This block is out of the range */
- continue;
- }
-
- if (s->begin > block->target_start) {
- s->start = s->begin - block->target_start;
- }
- }
-
- return 0;
- }
-}
-
-/* write all memory to vmcore */
-static void dump_iterate(DumpState *s, Error **errp)
-{
- GuestPhysBlock *block;
- int64_t size;
- Error *local_err = NULL;
-
- do {
- block = s->next_block;
-
- size = block->target_end - block->target_start;
- if (s->has_filter) {
- size -= s->start;
- if (s->begin + s->length < block->target_end) {
- size -= block->target_end - (s->begin + s->length);
- }
- }
- write_memory(s, block, s->start, size, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- } while (!get_next_block(s, block));
-}
-
-static void create_vmcore(DumpState *s, Error **errp)
-{
- Error *local_err = NULL;
-
- dump_begin(s, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- dump_iterate(s, errp);
-}
-
-static int write_start_flat_header(int fd)
-{
- MakedumpfileHeader *mh;
- int ret = 0;
-
- QEMU_BUILD_BUG_ON(sizeof *mh > MAX_SIZE_MDF_HEADER);
- mh = g_malloc0(MAX_SIZE_MDF_HEADER);
-
- memcpy(mh->signature, MAKEDUMPFILE_SIGNATURE,
- MIN(sizeof mh->signature, sizeof MAKEDUMPFILE_SIGNATURE));
-
- mh->type = cpu_to_be64(TYPE_FLAT_HEADER);
- mh->version = cpu_to_be64(VERSION_FLAT_HEADER);
-
- size_t written_size;
- written_size = qemu_write_full(fd, mh, MAX_SIZE_MDF_HEADER);
- if (written_size != MAX_SIZE_MDF_HEADER) {
- ret = -1;
- }
-
- g_free(mh);
- return ret;
-}
-
-static int write_end_flat_header(int fd)
-{
- MakedumpfileDataHeader mdh;
-
- mdh.offset = END_FLAG_FLAT_HEADER;
- mdh.buf_size = END_FLAG_FLAT_HEADER;
-
- size_t written_size;
- written_size = qemu_write_full(fd, &mdh, sizeof(mdh));
- if (written_size != sizeof(mdh)) {
- return -1;
- }
-
- return 0;
-}
-
-static int write_buffer(int fd, off_t offset, const void *buf, size_t size)
-{
- size_t written_size;
- MakedumpfileDataHeader mdh;
-
- mdh.offset = cpu_to_be64(offset);
- mdh.buf_size = cpu_to_be64(size);
-
- written_size = qemu_write_full(fd, &mdh, sizeof(mdh));
- if (written_size != sizeof(mdh)) {
- return -1;
- }
-
- written_size = qemu_write_full(fd, buf, size);
- if (written_size != size) {
- return -1;
- }
-
- return 0;
-}
-
-static int buf_write_note(const void *buf, size_t size, void *opaque)
-{
- DumpState *s = opaque;
-
- /* note_buf is not enough */
- if (s->note_buf_offset + size > s->note_size) {
- return -1;
- }
-
- memcpy(s->note_buf + s->note_buf_offset, buf, size);
-
- s->note_buf_offset += size;
-
- return 0;
-}
-
-/*
- * This function retrieves various sizes from an elf header.
- *
- * @note has to be a valid ELF note. The return sizes are unmodified
- * (not padded or rounded up to be multiple of 4).
- */
-static void get_note_sizes(DumpState *s, const void *note,
- uint64_t *note_head_size,
- uint64_t *name_size,
- uint64_t *desc_size)
-{
- uint64_t note_head_sz;
- uint64_t name_sz;
- uint64_t desc_sz;
-
- if (s->dump_info.d_class == ELFCLASS64) {
- const Elf64_Nhdr *hdr = note;
- note_head_sz = sizeof(Elf64_Nhdr);
- name_sz = tswap64(hdr->n_namesz);
- desc_sz = tswap64(hdr->n_descsz);
- } else {
- const Elf32_Nhdr *hdr = note;
- note_head_sz = sizeof(Elf32_Nhdr);
- name_sz = tswap32(hdr->n_namesz);
- desc_sz = tswap32(hdr->n_descsz);
- }
-
- if (note_head_size) {
- *note_head_size = note_head_sz;
- }
- if (name_size) {
- *name_size = name_sz;
- }
- if (desc_size) {
- *desc_size = desc_sz;
- }
-}
-
-static bool note_name_equal(DumpState *s,
- const uint8_t *note, const char *name)
-{
- int len = strlen(name) + 1;
- uint64_t head_size, name_size;
-
- get_note_sizes(s, note, &head_size, &name_size, NULL);
- head_size = ROUND_UP(head_size, 4);
-
- return name_size == len && memcmp(note + head_size, name, len) == 0;
-}
-
-/* write common header, sub header and elf note to vmcore */
-static void create_header32(DumpState *s, Error **errp)
-{
- DiskDumpHeader32 *dh = NULL;
- KdumpSubHeader32 *kh = NULL;
- size_t size;
- uint32_t block_size;
- uint32_t sub_hdr_size;
- uint32_t bitmap_blocks;
- uint32_t status = 0;
- uint64_t offset_note;
- Error *local_err = NULL;
-
- /* write common header, the version of kdump-compressed format is 6th */
- size = sizeof(DiskDumpHeader32);
- dh = g_malloc0(size);
-
- memcpy(dh->signature, KDUMP_SIGNATURE, SIG_LEN);
- dh->header_version = cpu_to_dump32(s, 6);
- block_size = s->dump_info.page_size;
- dh->block_size = cpu_to_dump32(s, block_size);
- sub_hdr_size = sizeof(struct KdumpSubHeader32) + s->note_size;
- sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
- dh->sub_hdr_size = cpu_to_dump32(s, sub_hdr_size);
- /* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
- dh->max_mapnr = cpu_to_dump32(s, MIN(s->max_mapnr, UINT_MAX));
- dh->nr_cpus = cpu_to_dump32(s, s->nr_cpus);
- bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
- dh->bitmap_blocks = cpu_to_dump32(s, bitmap_blocks);
- strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
-
- if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
- status |= DUMP_DH_COMPRESSED_ZLIB;
- }
-#ifdef CONFIG_LZO
- if (s->flag_compress & DUMP_DH_COMPRESSED_LZO) {
- status |= DUMP_DH_COMPRESSED_LZO;
- }
-#endif
-#ifdef CONFIG_SNAPPY
- if (s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) {
- status |= DUMP_DH_COMPRESSED_SNAPPY;
- }
-#endif
- dh->status = cpu_to_dump32(s, status);
-
- if (write_buffer(s->fd, 0, dh, size) < 0) {
- error_setg(errp, "dump: failed to write disk dump header");
- goto out;
- }
-
- /* write sub header */
- size = sizeof(KdumpSubHeader32);
- kh = g_malloc0(size);
-
- /* 64bit max_mapnr_64 */
- kh->max_mapnr_64 = cpu_to_dump64(s, s->max_mapnr);
- kh->phys_base = cpu_to_dump32(s, s->dump_info.phys_base);
- kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
-
- offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
- if (s->guest_note &&
- note_name_equal(s, s->guest_note, "VMCOREINFO")) {
- uint64_t hsize, name_size, size_vmcoreinfo_desc, offset_vmcoreinfo;
-
- get_note_sizes(s, s->guest_note,
- &hsize, &name_size, &size_vmcoreinfo_desc);
- offset_vmcoreinfo = offset_note + s->note_size - s->guest_note_size +
- (DIV_ROUND_UP(hsize, 4) + DIV_ROUND_UP(name_size, 4)) * 4;
- kh->offset_vmcoreinfo = cpu_to_dump64(s, offset_vmcoreinfo);
- kh->size_vmcoreinfo = cpu_to_dump32(s, size_vmcoreinfo_desc);
- }
-
- kh->offset_note = cpu_to_dump64(s, offset_note);
- kh->note_size = cpu_to_dump32(s, s->note_size);
-
- if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
- block_size, kh, size) < 0) {
- error_setg(errp, "dump: failed to write kdump sub header");
- goto out;
- }
-
- /* write note */
- s->note_buf = g_malloc0(s->note_size);
- s->note_buf_offset = 0;
-
- /* use s->note_buf to store notes temporarily */
- write_elf32_notes(buf_write_note, s, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- goto out;
- }
- if (write_buffer(s->fd, offset_note, s->note_buf,
- s->note_size) < 0) {
- error_setg(errp, "dump: failed to write notes");
- goto out;
- }
-
- /* get offset of dump_bitmap */
- s->offset_dump_bitmap = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size) *
- block_size;
-
- /* get offset of page */
- s->offset_page = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size + bitmap_blocks) *
- block_size;
-
-out:
- g_free(dh);
- g_free(kh);
- g_free(s->note_buf);
-}
-
-/* write common header, sub header and elf note to vmcore */
-static void create_header64(DumpState *s, Error **errp)
-{
- DiskDumpHeader64 *dh = NULL;
- KdumpSubHeader64 *kh = NULL;
- size_t size;
- uint32_t block_size;
- uint32_t sub_hdr_size;
- uint32_t bitmap_blocks;
- uint32_t status = 0;
- uint64_t offset_note;
- Error *local_err = NULL;
-
- /* write common header, the version of kdump-compressed format is 6th */
- size = sizeof(DiskDumpHeader64);
- dh = g_malloc0(size);
-
- memcpy(dh->signature, KDUMP_SIGNATURE, SIG_LEN);
- dh->header_version = cpu_to_dump32(s, 6);
- block_size = s->dump_info.page_size;
- dh->block_size = cpu_to_dump32(s, block_size);
- sub_hdr_size = sizeof(struct KdumpSubHeader64) + s->note_size;
- sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
- dh->sub_hdr_size = cpu_to_dump32(s, sub_hdr_size);
- /* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
- dh->max_mapnr = cpu_to_dump32(s, MIN(s->max_mapnr, UINT_MAX));
- dh->nr_cpus = cpu_to_dump32(s, s->nr_cpus);
- bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
- dh->bitmap_blocks = cpu_to_dump32(s, bitmap_blocks);
- strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
-
- if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
- status |= DUMP_DH_COMPRESSED_ZLIB;
- }
-#ifdef CONFIG_LZO
- if (s->flag_compress & DUMP_DH_COMPRESSED_LZO) {
- status |= DUMP_DH_COMPRESSED_LZO;
- }
-#endif
-#ifdef CONFIG_SNAPPY
- if (s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) {
- status |= DUMP_DH_COMPRESSED_SNAPPY;
- }
-#endif
- dh->status = cpu_to_dump32(s, status);
-
- if (write_buffer(s->fd, 0, dh, size) < 0) {
- error_setg(errp, "dump: failed to write disk dump header");
- goto out;
- }
-
- /* write sub header */
- size = sizeof(KdumpSubHeader64);
- kh = g_malloc0(size);
-
- /* 64bit max_mapnr_64 */
- kh->max_mapnr_64 = cpu_to_dump64(s, s->max_mapnr);
- kh->phys_base = cpu_to_dump64(s, s->dump_info.phys_base);
- kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
-
- offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
- if (s->guest_note &&
- note_name_equal(s, s->guest_note, "VMCOREINFO")) {
- uint64_t hsize, name_size, size_vmcoreinfo_desc, offset_vmcoreinfo;
-
- get_note_sizes(s, s->guest_note,
- &hsize, &name_size, &size_vmcoreinfo_desc);
- offset_vmcoreinfo = offset_note + s->note_size - s->guest_note_size +
- (DIV_ROUND_UP(hsize, 4) + DIV_ROUND_UP(name_size, 4)) * 4;
- kh->offset_vmcoreinfo = cpu_to_dump64(s, offset_vmcoreinfo);
- kh->size_vmcoreinfo = cpu_to_dump64(s, size_vmcoreinfo_desc);
- }
-
- kh->offset_note = cpu_to_dump64(s, offset_note);
- kh->note_size = cpu_to_dump64(s, s->note_size);
-
- if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
- block_size, kh, size) < 0) {
- error_setg(errp, "dump: failed to write kdump sub header");
- goto out;
- }
-
- /* write note */
- s->note_buf = g_malloc0(s->note_size);
- s->note_buf_offset = 0;
-
- /* use s->note_buf to store notes temporarily */
- write_elf64_notes(buf_write_note, s, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- goto out;
- }
-
- if (write_buffer(s->fd, offset_note, s->note_buf,
- s->note_size) < 0) {
- error_setg(errp, "dump: failed to write notes");
- goto out;
- }
-
- /* get offset of dump_bitmap */
- s->offset_dump_bitmap = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size) *
- block_size;
-
- /* get offset of page */
- s->offset_page = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size + bitmap_blocks) *
- block_size;
-
-out:
- g_free(dh);
- g_free(kh);
- g_free(s->note_buf);
-}
-
-static void write_dump_header(DumpState *s, Error **errp)
-{
- Error *local_err = NULL;
-
- if (s->dump_info.d_class == ELFCLASS32) {
- create_header32(s, &local_err);
- } else {
- create_header64(s, &local_err);
- }
- error_propagate(errp, local_err);
-}
-
-static size_t dump_bitmap_get_bufsize(DumpState *s)
-{
- return s->dump_info.page_size;
-}
-
-/*
- * set dump_bitmap sequencely. the bit before last_pfn is not allowed to be
- * rewritten, so if need to set the first bit, set last_pfn and pfn to 0.
- * set_dump_bitmap will always leave the recently set bit un-sync. And setting
- * (last bit + sizeof(buf) * 8) to 0 will do flushing the content in buf into
- * vmcore, ie. synchronizing un-sync bit into vmcore.
- */
-static int set_dump_bitmap(uint64_t last_pfn, uint64_t pfn, bool value,
- uint8_t *buf, DumpState *s)
-{
- off_t old_offset, new_offset;
- off_t offset_bitmap1, offset_bitmap2;
- uint32_t byte, bit;
- size_t bitmap_bufsize = dump_bitmap_get_bufsize(s);
- size_t bits_per_buf = bitmap_bufsize * CHAR_BIT;
-
- /* should not set the previous place */
- assert(last_pfn <= pfn);
-
- /*
- * if the bit needed to be set is not cached in buf, flush the data in buf
- * to vmcore firstly.
- * making new_offset be bigger than old_offset can also sync remained data
- * into vmcore.
- */
- old_offset = bitmap_bufsize * (last_pfn / bits_per_buf);
- new_offset = bitmap_bufsize * (pfn / bits_per_buf);
-
- while (old_offset < new_offset) {
- /* calculate the offset and write dump_bitmap */
- offset_bitmap1 = s->offset_dump_bitmap + old_offset;
- if (write_buffer(s->fd, offset_bitmap1, buf,
- bitmap_bufsize) < 0) {
- return -1;
- }
-
- /* dump level 1 is chosen, so 1st and 2nd bitmap are same */
- offset_bitmap2 = s->offset_dump_bitmap + s->len_dump_bitmap +
- old_offset;
- if (write_buffer(s->fd, offset_bitmap2, buf,
- bitmap_bufsize) < 0) {
- return -1;
- }
-
- memset(buf, 0, bitmap_bufsize);
- old_offset += bitmap_bufsize;
- }
-
- /* get the exact place of the bit in the buf, and set it */
- byte = (pfn % bits_per_buf) / CHAR_BIT;
- bit = (pfn % bits_per_buf) % CHAR_BIT;
- if (value) {
- buf[byte] |= 1u << bit;
- } else {
- buf[byte] &= ~(1u << bit);
- }
-
- return 0;
-}
-
-static uint64_t dump_paddr_to_pfn(DumpState *s, uint64_t addr)
-{
- int target_page_shift = ctz32(s->dump_info.page_size);
-
- return (addr >> target_page_shift) - ARCH_PFN_OFFSET;
-}
-
-static uint64_t dump_pfn_to_paddr(DumpState *s, uint64_t pfn)
-{
- int target_page_shift = ctz32(s->dump_info.page_size);
-
- return (pfn + ARCH_PFN_OFFSET) << target_page_shift;
-}
-
-/*
- * exam every page and return the page frame number and the address of the page.
- * bufptr can be NULL. note: the blocks here is supposed to reflect guest-phys
- * blocks, so block->target_start and block->target_end should be interal
- * multiples of the target page size.
- */
-static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
- uint8_t **bufptr, DumpState *s)
-{
- GuestPhysBlock *block = *blockptr;
- hwaddr addr, target_page_mask = ~((hwaddr)s->dump_info.page_size - 1);
- uint8_t *buf;
-
- /* block == NULL means the start of the iteration */
- if (!block) {
- block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
- *blockptr = block;
- assert((block->target_start & ~target_page_mask) == 0);
- assert((block->target_end & ~target_page_mask) == 0);
- *pfnptr = dump_paddr_to_pfn(s, block->target_start);
- if (bufptr) {
- *bufptr = block->host_addr;
- }
- return true;
- }
-
- *pfnptr = *pfnptr + 1;
- addr = dump_pfn_to_paddr(s, *pfnptr);
-
- if ((addr >= block->target_start) &&
- (addr + s->dump_info.page_size <= block->target_end)) {
- buf = block->host_addr + (addr - block->target_start);
- } else {
- /* the next page is in the next block */
- block = QTAILQ_NEXT(block, next);
- *blockptr = block;
- if (!block) {
- return false;
- }
- assert((block->target_start & ~target_page_mask) == 0);
- assert((block->target_end & ~target_page_mask) == 0);
- *pfnptr = dump_paddr_to_pfn(s, block->target_start);
- buf = block->host_addr;
- }
-
- if (bufptr) {
- *bufptr = buf;
- }
-
- return true;
-}
-
-static void write_dump_bitmap(DumpState *s, Error **errp)
-{
- int ret = 0;
- uint64_t last_pfn, pfn;
- void *dump_bitmap_buf;
- size_t num_dumpable;
- GuestPhysBlock *block_iter = NULL;
- size_t bitmap_bufsize = dump_bitmap_get_bufsize(s);
- size_t bits_per_buf = bitmap_bufsize * CHAR_BIT;
-
- /* dump_bitmap_buf is used to store dump_bitmap temporarily */
- dump_bitmap_buf = g_malloc0(bitmap_bufsize);
-
- num_dumpable = 0;
- last_pfn = 0;
-
- /*
- * exam memory page by page, and set the bit in dump_bitmap corresponded
- * to the existing page.
- */
- while (get_next_page(&block_iter, &pfn, NULL, s)) {
- ret = set_dump_bitmap(last_pfn, pfn, true, dump_bitmap_buf, s);
- if (ret < 0) {
- error_setg(errp, "dump: failed to set dump_bitmap");
- goto out;
- }
-
- last_pfn = pfn;
- num_dumpable++;
- }
-
- /*
- * set_dump_bitmap will always leave the recently set bit un-sync. Here we
- * set the remaining bits from last_pfn to the end of the bitmap buffer to
- * 0. With those set, the un-sync bit will be synchronized into the vmcore.
- */
- if (num_dumpable > 0) {
- ret = set_dump_bitmap(last_pfn, last_pfn + bits_per_buf, false,
- dump_bitmap_buf, s);
- if (ret < 0) {
- error_setg(errp, "dump: failed to sync dump_bitmap");
- goto out;
- }
- }
-
- /* number of dumpable pages that will be dumped later */
- s->num_dumpable = num_dumpable;
-
-out:
- g_free(dump_bitmap_buf);
-}
-
-static void prepare_data_cache(DataCache *data_cache, DumpState *s,
- off_t offset)
-{
- data_cache->fd = s->fd;
- data_cache->data_size = 0;
- data_cache->buf_size = 4 * dump_bitmap_get_bufsize(s);
- data_cache->buf = g_malloc0(data_cache->buf_size);
- data_cache->offset = offset;
-}
-
-static int write_cache(DataCache *dc, const void *buf, size_t size,
- bool flag_sync)
-{
- /*
- * dc->buf_size should not be less than size, otherwise dc will never be
- * enough
- */
- assert(size <= dc->buf_size);
-
- /*
- * if flag_sync is set, synchronize data in dc->buf into vmcore.
- * otherwise check if the space is enough for caching data in buf, if not,
- * write the data in dc->buf to dc->fd and reset dc->buf
- */
- if ((!flag_sync && dc->data_size + size > dc->buf_size) ||
- (flag_sync && dc->data_size > 0)) {
- if (write_buffer(dc->fd, dc->offset, dc->buf, dc->data_size) < 0) {
- return -1;
- }
-
- dc->offset += dc->data_size;
- dc->data_size = 0;
- }
-
- if (!flag_sync) {
- memcpy(dc->buf + dc->data_size, buf, size);
- dc->data_size += size;
- }
-
- return 0;
-}
-
-static void free_data_cache(DataCache *data_cache)
-{
- g_free(data_cache->buf);
-}
-
-static size_t get_len_buf_out(size_t page_size, uint32_t flag_compress)
-{
- switch (flag_compress) {
- case DUMP_DH_COMPRESSED_ZLIB:
- return compressBound(page_size);
-
- case DUMP_DH_COMPRESSED_LZO:
- /*
- * LZO will expand incompressible data by a little amount. Please check
- * the following URL to see the expansion calculation:
- * http://www.oberhumer.com/opensource/lzo/lzofaq.php
- */
- return page_size + page_size / 16 + 64 + 3;
-
-#ifdef CONFIG_SNAPPY
- case DUMP_DH_COMPRESSED_SNAPPY:
- return snappy_max_compressed_length(page_size);
-#endif
- }
- return 0;
-}
-
-/*
- * check if the page is all 0
- */
-static inline bool is_zero_page(const uint8_t *buf, size_t page_size)
-{
- return buffer_is_zero(buf, page_size);
-}
-
-static void write_dump_pages(DumpState *s, Error **errp)
-{
- int ret = 0;
- DataCache page_desc, page_data;
- size_t len_buf_out, size_out;
-#ifdef CONFIG_LZO
- lzo_bytep wrkmem = NULL;
-#endif
- uint8_t *buf_out = NULL;
- off_t offset_desc, offset_data;
- PageDescriptor pd, pd_zero;
- uint8_t *buf;
- GuestPhysBlock *block_iter = NULL;
- uint64_t pfn_iter;
-
- /* get offset of page_desc and page_data in dump file */
- offset_desc = s->offset_page;
- offset_data = offset_desc + sizeof(PageDescriptor) * s->num_dumpable;
-
- prepare_data_cache(&page_desc, s, offset_desc);
- prepare_data_cache(&page_data, s, offset_data);
-
- /* prepare buffer to store compressed data */
- len_buf_out = get_len_buf_out(s->dump_info.page_size, s->flag_compress);
- assert(len_buf_out != 0);
-
-#ifdef CONFIG_LZO
- wrkmem = g_malloc(LZO1X_1_MEM_COMPRESS);
-#endif
-
- buf_out = g_malloc(len_buf_out);
-
- /*
- * init zero page's page_desc and page_data, because every zero page
- * uses the same page_data
- */
- pd_zero.size = cpu_to_dump32(s, s->dump_info.page_size);
- pd_zero.flags = cpu_to_dump32(s, 0);
- pd_zero.offset = cpu_to_dump64(s, offset_data);
- pd_zero.page_flags = cpu_to_dump64(s, 0);
- buf = g_malloc0(s->dump_info.page_size);
- ret = write_cache(&page_data, buf, s->dump_info.page_size, false);
- g_free(buf);
- if (ret < 0) {
- error_setg(errp, "dump: failed to write page data (zero page)");
- goto out;
- }
-
- offset_data += s->dump_info.page_size;
-
- /*
- * dump memory to vmcore page by page. zero page will all be resided in the
- * first page of page section
- */
- while (get_next_page(&block_iter, &pfn_iter, &buf, s)) {
- /* check zero page */
- if (is_zero_page(buf, s->dump_info.page_size)) {
- ret = write_cache(&page_desc, &pd_zero, sizeof(PageDescriptor),
- false);
- if (ret < 0) {
- error_setg(errp, "dump: failed to write page desc");
- goto out;
- }
- } else {
- /*
- * not zero page, then:
- * 1. compress the page
- * 2. write the compressed page into the cache of page_data
- * 3. get page desc of the compressed page and write it into the
- * cache of page_desc
- *
- * only one compression format will be used here, for
- * s->flag_compress is set. But when compression fails to work,
- * we fall back to save in plaintext.
- */
- size_out = len_buf_out;
- if ((s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) &&
- (compress2(buf_out, (uLongf *)&size_out, buf,
- s->dump_info.page_size, Z_BEST_SPEED) == Z_OK) &&
- (size_out < s->dump_info.page_size)) {
- pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_ZLIB);
- pd.size = cpu_to_dump32(s, size_out);
-
- ret = write_cache(&page_data, buf_out, size_out, false);
- if (ret < 0) {
- error_setg(errp, "dump: failed to write page data");
- goto out;
- }
-#ifdef CONFIG_LZO
- } else if ((s->flag_compress & DUMP_DH_COMPRESSED_LZO) &&
- (lzo1x_1_compress(buf, s->dump_info.page_size, buf_out,
- (lzo_uint *)&size_out, wrkmem) == LZO_E_OK) &&
- (size_out < s->dump_info.page_size)) {
- pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_LZO);
- pd.size = cpu_to_dump32(s, size_out);
-
- ret = write_cache(&page_data, buf_out, size_out, false);
- if (ret < 0) {
- error_setg(errp, "dump: failed to write page data");
- goto out;
- }
-#endif
-#ifdef CONFIG_SNAPPY
- } else if ((s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) &&
- (snappy_compress((char *)buf, s->dump_info.page_size,
- (char *)buf_out, &size_out) == SNAPPY_OK) &&
- (size_out < s->dump_info.page_size)) {
- pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_SNAPPY);
- pd.size = cpu_to_dump32(s, size_out);
-
- ret = write_cache(&page_data, buf_out, size_out, false);
- if (ret < 0) {
- error_setg(errp, "dump: failed to write page data");
- goto out;
- }
-#endif
- } else {
- /*
- * fall back to save in plaintext, size_out should be
- * assigned the target's page size
- */
- pd.flags = cpu_to_dump32(s, 0);
- size_out = s->dump_info.page_size;
- pd.size = cpu_to_dump32(s, size_out);
-
- ret = write_cache(&page_data, buf,
- s->dump_info.page_size, false);
- if (ret < 0) {
- error_setg(errp, "dump: failed to write page data");
- goto out;
- }
- }
-
- /* get and write page desc here */
- pd.page_flags = cpu_to_dump64(s, 0);
- pd.offset = cpu_to_dump64(s, offset_data);
- offset_data += size_out;
-
- ret = write_cache(&page_desc, &pd, sizeof(PageDescriptor), false);
- if (ret < 0) {
- error_setg(errp, "dump: failed to write page desc");
- goto out;
- }
- }
- s->written_size += s->dump_info.page_size;
- }
-
- ret = write_cache(&page_desc, NULL, 0, true);
- if (ret < 0) {
- error_setg(errp, "dump: failed to sync cache for page_desc");
- goto out;
- }
- ret = write_cache(&page_data, NULL, 0, true);
- if (ret < 0) {
- error_setg(errp, "dump: failed to sync cache for page_data");
- goto out;
- }
-
-out:
- free_data_cache(&page_desc);
- free_data_cache(&page_data);
-
-#ifdef CONFIG_LZO
- g_free(wrkmem);
-#endif
-
- g_free(buf_out);
-}
-
-static void create_kdump_vmcore(DumpState *s, Error **errp)
-{
- int ret;
- Error *local_err = NULL;
-
- /*
- * the kdump-compressed format is:
- * File offset
- * +------------------------------------------+ 0x0
- * | main header (struct disk_dump_header) |
- * |------------------------------------------+ block 1
- * | sub header (struct kdump_sub_header) |
- * |------------------------------------------+ block 2
- * | 1st-dump_bitmap |
- * |------------------------------------------+ block 2 + X blocks
- * | 2nd-dump_bitmap | (aligned by block)
- * |------------------------------------------+ block 2 + 2 * X blocks
- * | page desc for pfn 0 (struct page_desc) | (aligned by block)
- * | page desc for pfn 1 (struct page_desc) |
- * | : |
- * |------------------------------------------| (not aligned by block)
- * | page data (pfn 0) |
- * | page data (pfn 1) |
- * | : |
- * +------------------------------------------+
- */
-
- ret = write_start_flat_header(s->fd);
- if (ret < 0) {
- error_setg(errp, "dump: failed to write start flat header");
- return;
- }
-
- write_dump_header(s, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- write_dump_bitmap(s, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- write_dump_pages(s, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- ret = write_end_flat_header(s->fd);
- if (ret < 0) {
- error_setg(errp, "dump: failed to write end flat header");
- return;
- }
-}
-
-static ram_addr_t get_start_block(DumpState *s)
-{
- GuestPhysBlock *block;
-
- if (!s->has_filter) {
- s->next_block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
- return 0;
- }
-
- QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
- if (block->target_start >= s->begin + s->length ||
- block->target_end <= s->begin) {
- /* This block is out of the range */
- continue;
- }
-
- s->next_block = block;
- if (s->begin > block->target_start) {
- s->start = s->begin - block->target_start;
- } else {
- s->start = 0;
- }
- return s->start;
- }
-
- return -1;
-}
-
-static void get_max_mapnr(DumpState *s)
-{
- GuestPhysBlock *last_block;
-
- last_block = QTAILQ_LAST(&s->guest_phys_blocks.head);
- s->max_mapnr = dump_paddr_to_pfn(s, last_block->target_end);
-}
-
-static DumpState dump_state_global = { .status = DUMP_STATUS_NONE };
-
-static void dump_state_prepare(DumpState *s)
-{
- /* zero the struct, setting status to active */
- *s = (DumpState) { .status = DUMP_STATUS_ACTIVE };
-}
-
-bool dump_in_progress(void)
-{
- DumpState *state = &dump_state_global;
- return (atomic_read(&state->status) == DUMP_STATUS_ACTIVE);
-}
-
-/* calculate total size of memory to be dumped (taking filter into
- * acoount.) */
-static int64_t dump_calculate_size(DumpState *s)
-{
- GuestPhysBlock *block;
- int64_t size = 0, total = 0, left = 0, right = 0;
-
- QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
- if (s->has_filter) {
- /* calculate the overlapped region. */
- left = MAX(s->begin, block->target_start);
- right = MIN(s->begin + s->length, block->target_end);
- size = right - left;
- size = size > 0 ? size : 0;
- } else {
- /* count the whole region in */
- size = (block->target_end - block->target_start);
- }
- total += size;
- }
-
- return total;
-}
-
-static void vmcoreinfo_update_phys_base(DumpState *s)
-{
- uint64_t size, note_head_size, name_size, phys_base;
- char **lines;
- uint8_t *vmci;
- size_t i;
-
- if (!note_name_equal(s, s->guest_note, "VMCOREINFO")) {
- return;
- }
-
- get_note_sizes(s, s->guest_note, ¬e_head_size, &name_size, &size);
- note_head_size = ROUND_UP(note_head_size, 4);
-
- vmci = s->guest_note + note_head_size + ROUND_UP(name_size, 4);
- *(vmci + size) = '\0';
-
- lines = g_strsplit((char *)vmci, "\n", -1);
- for (i = 0; lines[i]; i++) {
- const char *prefix = NULL;
-
- if (s->dump_info.d_machine == EM_X86_64) {
- prefix = "NUMBER(phys_base)=";
- } else if (s->dump_info.d_machine == EM_AARCH64) {
- prefix = "NUMBER(PHYS_OFFSET)=";
- }
-
- if (prefix && g_str_has_prefix(lines[i], prefix)) {
- if (qemu_strtou64(lines[i] + strlen(prefix), NULL, 16,
- &phys_base) < 0) {
- warn_report("Failed to read %s", prefix);
- } else {
- s->dump_info.phys_base = phys_base;
- }
- break;
- }
- }
-
- g_strfreev(lines);
-}
-
-static void dump_init(DumpState *s, int fd, bool has_format,
- DumpGuestMemoryFormat format, bool paging, bool has_filter,
- int64_t begin, int64_t length, Error **errp)
-{
- VMCoreInfoState *vmci = vmcoreinfo_find();
- CPUState *cpu;
- int nr_cpus;
- Error *err = NULL;
- int ret;
-
- s->has_format = has_format;
- s->format = format;
- s->written_size = 0;
-
- /* kdump-compressed is conflict with paging and filter */
- if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
- assert(!paging && !has_filter);
- }
-
- if (runstate_is_running()) {
- vm_stop(RUN_STATE_SAVE_VM);
- s->resume = true;
- } else {
- s->resume = false;
- }
-
- /* If we use KVM, we should synchronize the registers before we get dump
- * info or physmap info.
- */
- cpu_synchronize_all_states();
- nr_cpus = 0;
- CPU_FOREACH(cpu) {
- nr_cpus++;
- }
-
- s->fd = fd;
- s->has_filter = has_filter;
- s->begin = begin;
- s->length = length;
-
- memory_mapping_list_init(&s->list);
-
- guest_phys_blocks_init(&s->guest_phys_blocks);
- guest_phys_blocks_append(&s->guest_phys_blocks);
- s->total_size = dump_calculate_size(s);
-#ifdef DEBUG_DUMP_GUEST_MEMORY
- fprintf(stderr, "DUMP: total memory to dump: %lu\n", s->total_size);
-#endif
-
- /* it does not make sense to dump non-existent memory */
- if (!s->total_size) {
- error_setg(errp, "dump: no guest memory to dump");
- goto cleanup;
- }
-
- s->start = get_start_block(s);
- if (s->start == -1) {
- error_setg(errp, QERR_INVALID_PARAMETER, "begin");
- goto cleanup;
- }
-
- /* get dump info: endian, class and architecture.
- * If the target architecture is not supported, cpu_get_dump_info() will
- * return -1.
- */
- ret = cpu_get_dump_info(&s->dump_info, &s->guest_phys_blocks);
- if (ret < 0) {
- error_setg(errp, QERR_UNSUPPORTED);
- goto cleanup;
- }
-
- if (!s->dump_info.page_size) {
- s->dump_info.page_size = TARGET_PAGE_SIZE;
- }
-
- s->note_size = cpu_get_note_size(s->dump_info.d_class,
- s->dump_info.d_machine, nr_cpus);
- if (s->note_size < 0) {
- error_setg(errp, QERR_UNSUPPORTED);
- goto cleanup;
- }
-
- /*
- * The goal of this block is to (a) update the previously guessed
- * phys_base, (b) copy the guest note out of the guest.
- * Failure to do so is not fatal for dumping.
- */
- if (vmci) {
- uint64_t addr, note_head_size, name_size, desc_size;
- uint32_t size;
- uint16_t format;
-
- note_head_size = s->dump_info.d_class == ELFCLASS32 ?
- sizeof(Elf32_Nhdr) : sizeof(Elf64_Nhdr);
-
- format = le16_to_cpu(vmci->vmcoreinfo.guest_format);
- size = le32_to_cpu(vmci->vmcoreinfo.size);
- addr = le64_to_cpu(vmci->vmcoreinfo.paddr);
- if (!vmci->has_vmcoreinfo) {
- warn_report("guest note is not present");
- } else if (size < note_head_size || size > MAX_GUEST_NOTE_SIZE) {
- warn_report("guest note size is invalid: %" PRIu32, size);
- } else if (format != FW_CFG_VMCOREINFO_FORMAT_ELF) {
- warn_report("guest note format is unsupported: %" PRIu16, format);
- } else {
- s->guest_note = g_malloc(size + 1); /* +1 for adding \0 */
- cpu_physical_memory_read(addr, s->guest_note, size);
-
- get_note_sizes(s, s->guest_note, NULL, &name_size, &desc_size);
- s->guest_note_size = ELF_NOTE_SIZE(note_head_size, name_size,
- desc_size);
- if (name_size > MAX_GUEST_NOTE_SIZE ||
- desc_size > MAX_GUEST_NOTE_SIZE ||
- s->guest_note_size > size) {
- warn_report("Invalid guest note header");
- g_free(s->guest_note);
- s->guest_note = NULL;
- } else {
- vmcoreinfo_update_phys_base(s);
- s->note_size += s->guest_note_size;
- }
- }
- }
-
- /* get memory mapping */
- if (paging) {
- qemu_get_guest_memory_mapping(&s->list, &s->guest_phys_blocks, &err);
- if (err != NULL) {
- error_propagate(errp, err);
- goto cleanup;
- }
- } else {
- qemu_get_guest_simple_memory_mapping(&s->list, &s->guest_phys_blocks);
- }
-
- s->nr_cpus = nr_cpus;
-
- get_max_mapnr(s);
-
- uint64_t tmp;
- tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT),
- s->dump_info.page_size);
- s->len_dump_bitmap = tmp * s->dump_info.page_size;
-
- /* init for kdump-compressed format */
- if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
- switch (format) {
- case DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB:
- s->flag_compress = DUMP_DH_COMPRESSED_ZLIB;
- break;
-
- case DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO:
-#ifdef CONFIG_LZO
- if (lzo_init() != LZO_E_OK) {
- error_setg(errp, "failed to initialize the LZO library");
- goto cleanup;
- }
-#endif
- s->flag_compress = DUMP_DH_COMPRESSED_LZO;
- break;
-
- case DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY:
- s->flag_compress = DUMP_DH_COMPRESSED_SNAPPY;
- break;
-
- default:
- s->flag_compress = 0;
- }
-
- return;
- }
-
- if (s->has_filter) {
- memory_mapping_filter(&s->list, s->begin, s->length);
- }
-
- /*
- * calculate phdr_num
- *
- * the type of ehdr->e_phnum is uint16_t, so we should avoid overflow
- */
- s->phdr_num = 1; /* PT_NOTE */
- if (s->list.num < UINT16_MAX - 2) {
- s->phdr_num += s->list.num;
- s->have_section = false;
- } else {
- s->have_section = true;
- s->phdr_num = PN_XNUM;
- s->sh_info = 1; /* PT_NOTE */
-
- /* the type of shdr->sh_info is uint32_t, so we should avoid overflow */
- if (s->list.num <= UINT32_MAX - 1) {
- s->sh_info += s->list.num;
- } else {
- s->sh_info = UINT32_MAX;
- }
- }
-
- if (s->dump_info.d_class == ELFCLASS64) {
- if (s->have_section) {
- s->memory_offset = sizeof(Elf64_Ehdr) +
- sizeof(Elf64_Phdr) * s->sh_info +
- sizeof(Elf64_Shdr) + s->note_size;
- } else {
- s->memory_offset = sizeof(Elf64_Ehdr) +
- sizeof(Elf64_Phdr) * s->phdr_num + s->note_size;
- }
- } else {
- if (s->have_section) {
- s->memory_offset = sizeof(Elf32_Ehdr) +
- sizeof(Elf32_Phdr) * s->sh_info +
- sizeof(Elf32_Shdr) + s->note_size;
- } else {
- s->memory_offset = sizeof(Elf32_Ehdr) +
- sizeof(Elf32_Phdr) * s->phdr_num + s->note_size;
- }
- }
-
- return;
-
-cleanup:
- dump_cleanup(s);
-}
-
-/* this operation might be time consuming. */
-static void dump_process(DumpState *s, Error **errp)
-{
- Error *local_err = NULL;
- DumpQueryResult *result = NULL;
-
- if (s->has_format && s->format == DUMP_GUEST_MEMORY_FORMAT_WIN_DMP) {
-#ifdef TARGET_X86_64
- create_win_dump(s, &local_err);
-#endif
- } else if (s->has_format && s->format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
- create_kdump_vmcore(s, &local_err);
- } else {
- create_vmcore(s, &local_err);
- }
-
- /* make sure status is written after written_size updates */
- smp_wmb();
- atomic_set(&s->status,
- (local_err ? DUMP_STATUS_FAILED : DUMP_STATUS_COMPLETED));
-
- /* send DUMP_COMPLETED message (unconditionally) */
- result = qmp_query_dump(NULL);
- /* should never fail */
- assert(result);
- qapi_event_send_dump_completed(result, !!local_err, (local_err ? \
- error_get_pretty(local_err) : NULL));
- qapi_free_DumpQueryResult(result);
-
- error_propagate(errp, local_err);
- dump_cleanup(s);
-}
-
-static void *dump_thread(void *data)
-{
- DumpState *s = (DumpState *)data;
- dump_process(s, NULL);
- return NULL;
-}
-
-DumpQueryResult *qmp_query_dump(Error **errp)
-{
- DumpQueryResult *result = g_new(DumpQueryResult, 1);
- DumpState *state = &dump_state_global;
- result->status = atomic_read(&state->status);
- /* make sure we are reading status and written_size in order */
- smp_rmb();
- result->completed = state->written_size;
- result->total = state->total_size;
- return result;
-}
-
-void qmp_dump_guest_memory(bool paging, const char *file,
- bool has_detach, bool detach,
- bool has_begin, int64_t begin, bool has_length,
- int64_t length, bool has_format,
- DumpGuestMemoryFormat format, Error **errp)
-{
- const char *p;
- int fd = -1;
- DumpState *s;
- Error *local_err = NULL;
- bool detach_p = false;
-
- if (runstate_check(RUN_STATE_INMIGRATE)) {
- error_setg(errp, "Dump not allowed during incoming migration.");
- return;
- }
-
- /* if there is a dump in background, we should wait until the dump
- * finished */
- if (dump_in_progress()) {
- error_setg(errp, "There is a dump in process, please wait.");
- return;
- }
-
- /*
- * kdump-compressed format need the whole memory dumped, so paging or
- * filter is not supported here.
- */
- if ((has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) &&
- (paging || has_begin || has_length)) {
- error_setg(errp, "kdump-compressed format doesn't support paging or "
- "filter");
- return;
- }
- if (has_begin && !has_length) {
- error_setg(errp, QERR_MISSING_PARAMETER, "length");
- return;
- }
- if (!has_begin && has_length) {
- error_setg(errp, QERR_MISSING_PARAMETER, "begin");
- return;
- }
- if (has_detach) {
- detach_p = detach;
- }
-
- /* check whether lzo/snappy is supported */
-#ifndef CONFIG_LZO
- if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO) {
- error_setg(errp, "kdump-lzo is not available now");
- return;
- }
-#endif
-
-#ifndef CONFIG_SNAPPY
- if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY) {
- error_setg(errp, "kdump-snappy is not available now");
- return;
- }
-#endif
-
-#ifndef TARGET_X86_64
- if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_WIN_DMP) {
- error_setg(errp, "Windows dump is only available for x86-64");
- return;
- }
-#endif
-
-#if !defined(WIN32)
- if (strstart(file, "fd:", &p)) {
- fd = monitor_get_fd(cur_mon, p, errp);
- if (fd == -1) {
- return;
- }
- }
-#endif
-
- if (strstart(file, "file:", &p)) {
- fd = qemu_open(p, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR);
- if (fd < 0) {
- error_setg_file_open(errp, errno, p);
- return;
- }
- }
-
- if (fd == -1) {
- error_setg(errp, QERR_INVALID_PARAMETER, "protocol");
- return;
- }
-
- s = &dump_state_global;
- dump_state_prepare(s);
-
- dump_init(s, fd, has_format, format, paging, has_begin,
- begin, length, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- atomic_set(&s->status, DUMP_STATUS_FAILED);
- return;
- }
-
- if (detach_p) {
- /* detached dump */
- s->detached = true;
- qemu_thread_create(&s->dump_thread, "dump_thread", dump_thread,
- s, QEMU_THREAD_DETACHED);
- } else {
- /* sync dump */
- dump_process(s, errp);
- }
-}
-
-DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp)
-{
- DumpGuestMemoryFormatList *item;
- DumpGuestMemoryCapability *cap =
- g_malloc0(sizeof(DumpGuestMemoryCapability));
-
- /* elf is always available */
- item = g_malloc0(sizeof(DumpGuestMemoryFormatList));
- cap->formats = item;
- item->value = DUMP_GUEST_MEMORY_FORMAT_ELF;
-
- /* kdump-zlib is always available */
- item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
- item = item->next;
- item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB;
-
- /* add new item if kdump-lzo is available */
-#ifdef CONFIG_LZO
- item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
- item = item->next;
- item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO;
-#endif
-
- /* add new item if kdump-snappy is available */
-#ifdef CONFIG_SNAPPY
- item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
- item = item->next;
- item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY;
-#endif
-
- /* Windows dump is available only if target is x86_64 */
-#ifdef TARGET_X86_64
- item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
- item = item->next;
- item->value = DUMP_GUEST_MEMORY_FORMAT_WIN_DMP;
-#endif
-
- return cap;
-}
--- /dev/null
+obj-y += dump.o
+common-obj-y += dump-hmp-cmds.o
+obj-$(TARGET_X86_64) += win_dump.o
--- /dev/null
+/*
+ * Human Monitor Interface commands
+ *
+ * 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 "monitor/hmp.h"
+#include "monitor/monitor.h"
+#include "qapi/error.h"
+#include "qapi/qapi-commands-dump.h"
+#include "qapi/qmp/qdict.h"
+
+void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
+{
+ Error *err = NULL;
+ bool win_dmp = qdict_get_try_bool(qdict, "windmp", false);
+ bool paging = qdict_get_try_bool(qdict, "paging", false);
+ bool zlib = qdict_get_try_bool(qdict, "zlib", false);
+ bool lzo = qdict_get_try_bool(qdict, "lzo", false);
+ bool snappy = qdict_get_try_bool(qdict, "snappy", false);
+ const char *file = qdict_get_str(qdict, "filename");
+ bool has_begin = qdict_haskey(qdict, "begin");
+ bool has_length = qdict_haskey(qdict, "length");
+ bool has_detach = qdict_haskey(qdict, "detach");
+ int64_t begin = 0;
+ int64_t length = 0;
+ bool detach = false;
+ enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF;
+ char *prot;
+
+ if (zlib + lzo + snappy + win_dmp > 1) {
+ error_setg(&err, "only one of '-z|-l|-s|-w' can be set");
+ hmp_handle_error(mon, &err);
+ return;
+ }
+
+ if (win_dmp) {
+ dump_format = DUMP_GUEST_MEMORY_FORMAT_WIN_DMP;
+ }
+
+ if (zlib) {
+ dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB;
+ }
+
+ if (lzo) {
+ dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO;
+ }
+
+ if (snappy) {
+ dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY;
+ }
+
+ if (has_begin) {
+ begin = qdict_get_int(qdict, "begin");
+ }
+ if (has_length) {
+ length = qdict_get_int(qdict, "length");
+ }
+ if (has_detach) {
+ detach = qdict_get_bool(qdict, "detach");
+ }
+
+ prot = g_strconcat("file:", file, NULL);
+
+ qmp_dump_guest_memory(paging, prot, true, detach, has_begin, begin,
+ has_length, length, true, dump_format, &err);
+ hmp_handle_error(mon, &err);
+ g_free(prot);
+}
+
+void hmp_info_dump(Monitor *mon, const QDict *qdict)
+{
+ DumpQueryResult *result = qmp_query_dump(NULL);
+
+ assert(result && result->status < DUMP_STATUS__MAX);
+ monitor_printf(mon, "Status: %s\n", DumpStatus_str(result->status));
+
+ if (result->status == DUMP_STATUS_ACTIVE) {
+ float percent = 0;
+ assert(result->total != 0);
+ percent = 100.0 * result->completed / result->total;
+ monitor_printf(mon, "Finished: %.2f %%\n", percent);
+ }
+
+ qapi_free_DumpQueryResult(result);
+}
--- /dev/null
+/*
+ * QEMU dump
+ *
+ * Copyright Fujitsu, Corp. 2011, 2012
+ *
+ * Authors:
+ * Wen Congyang <wency@cn.fujitsu.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-common.h"
+#include "qemu/cutils.h"
+#include "elf.h"
+#include "cpu.h"
+#include "exec/hwaddr.h"
+#include "monitor/monitor.h"
+#include "sysemu/kvm.h"
+#include "sysemu/dump.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/memory_mapping.h"
+#include "sysemu/cpus.h"
+#include "qapi/error.h"
+#include "qapi/qapi-commands-dump.h"
+#include "qapi/qapi-events-dump.h"
+#include "qapi/qmp/qerror.h"
+#include "qemu/error-report.h"
+#include "hw/misc/vmcoreinfo.h"
+
+#ifdef TARGET_X86_64
+#include "win_dump.h"
+#endif
+
+#include <zlib.h>
+#ifdef CONFIG_LZO
+#include <lzo/lzo1x.h>
+#endif
+#ifdef CONFIG_SNAPPY
+#include <snappy-c.h>
+#endif
+#ifndef ELF_MACHINE_UNAME
+#define ELF_MACHINE_UNAME "Unknown"
+#endif
+
+#define MAX_GUEST_NOTE_SIZE (1 << 20) /* 1MB should be enough */
+
+#define ELF_NOTE_SIZE(hdr_size, name_size, desc_size) \
+ ((DIV_ROUND_UP((hdr_size), 4) + \
+ DIV_ROUND_UP((name_size), 4) + \
+ DIV_ROUND_UP((desc_size), 4)) * 4)
+
+uint16_t cpu_to_dump16(DumpState *s, uint16_t val)
+{
+ if (s->dump_info.d_endian == ELFDATA2LSB) {
+ val = cpu_to_le16(val);
+ } else {
+ val = cpu_to_be16(val);
+ }
+
+ return val;
+}
+
+uint32_t cpu_to_dump32(DumpState *s, uint32_t val)
+{
+ if (s->dump_info.d_endian == ELFDATA2LSB) {
+ val = cpu_to_le32(val);
+ } else {
+ val = cpu_to_be32(val);
+ }
+
+ return val;
+}
+
+uint64_t cpu_to_dump64(DumpState *s, uint64_t val)
+{
+ if (s->dump_info.d_endian == ELFDATA2LSB) {
+ val = cpu_to_le64(val);
+ } else {
+ val = cpu_to_be64(val);
+ }
+
+ return val;
+}
+
+static int dump_cleanup(DumpState *s)
+{
+ guest_phys_blocks_free(&s->guest_phys_blocks);
+ memory_mapping_list_free(&s->list);
+ close(s->fd);
+ g_free(s->guest_note);
+ s->guest_note = NULL;
+ if (s->resume) {
+ if (s->detached) {
+ qemu_mutex_lock_iothread();
+ }
+ vm_start();
+ if (s->detached) {
+ qemu_mutex_unlock_iothread();
+ }
+ }
+
+ return 0;
+}
+
+static int fd_write_vmcore(const void *buf, size_t size, void *opaque)
+{
+ DumpState *s = opaque;
+ size_t written_size;
+
+ written_size = qemu_write_full(s->fd, buf, size);
+ if (written_size != size) {
+ return -errno;
+ }
+
+ return 0;
+}
+
+static void write_elf64_header(DumpState *s, Error **errp)
+{
+ Elf64_Ehdr elf_header;
+ int ret;
+
+ memset(&elf_header, 0, sizeof(Elf64_Ehdr));
+ memcpy(&elf_header, ELFMAG, SELFMAG);
+ elf_header.e_ident[EI_CLASS] = ELFCLASS64;
+ elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
+ elf_header.e_ident[EI_VERSION] = EV_CURRENT;
+ elf_header.e_type = cpu_to_dump16(s, ET_CORE);
+ elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
+ elf_header.e_version = cpu_to_dump32(s, EV_CURRENT);
+ elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
+ elf_header.e_phoff = cpu_to_dump64(s, sizeof(Elf64_Ehdr));
+ elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf64_Phdr));
+ elf_header.e_phnum = cpu_to_dump16(s, s->phdr_num);
+ if (s->have_section) {
+ uint64_t shoff = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) * s->sh_info;
+
+ elf_header.e_shoff = cpu_to_dump64(s, shoff);
+ elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf64_Shdr));
+ elf_header.e_shnum = cpu_to_dump16(s, 1);
+ }
+
+ ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "dump: failed to write elf header");
+ }
+}
+
+static void write_elf32_header(DumpState *s, Error **errp)
+{
+ Elf32_Ehdr elf_header;
+ int ret;
+
+ memset(&elf_header, 0, sizeof(Elf32_Ehdr));
+ memcpy(&elf_header, ELFMAG, SELFMAG);
+ elf_header.e_ident[EI_CLASS] = ELFCLASS32;
+ elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
+ elf_header.e_ident[EI_VERSION] = EV_CURRENT;
+ elf_header.e_type = cpu_to_dump16(s, ET_CORE);
+ elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
+ elf_header.e_version = cpu_to_dump32(s, EV_CURRENT);
+ elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
+ elf_header.e_phoff = cpu_to_dump32(s, sizeof(Elf32_Ehdr));
+ elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf32_Phdr));
+ elf_header.e_phnum = cpu_to_dump16(s, s->phdr_num);
+ if (s->have_section) {
+ uint32_t shoff = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) * s->sh_info;
+
+ elf_header.e_shoff = cpu_to_dump32(s, shoff);
+ elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf32_Shdr));
+ elf_header.e_shnum = cpu_to_dump16(s, 1);
+ }
+
+ ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "dump: failed to write elf header");
+ }
+}
+
+static void write_elf64_load(DumpState *s, MemoryMapping *memory_mapping,
+ int phdr_index, hwaddr offset,
+ hwaddr filesz, Error **errp)
+{
+ Elf64_Phdr phdr;
+ int ret;
+
+ memset(&phdr, 0, sizeof(Elf64_Phdr));
+ phdr.p_type = cpu_to_dump32(s, PT_LOAD);
+ phdr.p_offset = cpu_to_dump64(s, offset);
+ phdr.p_paddr = cpu_to_dump64(s, memory_mapping->phys_addr);
+ phdr.p_filesz = cpu_to_dump64(s, filesz);
+ phdr.p_memsz = cpu_to_dump64(s, memory_mapping->length);
+ phdr.p_vaddr = cpu_to_dump64(s, memory_mapping->virt_addr) ?: phdr.p_paddr;
+
+ assert(memory_mapping->length >= filesz);
+
+ ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret,
+ "dump: failed to write program header table");
+ }
+}
+
+static void write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
+ int phdr_index, hwaddr offset,
+ hwaddr filesz, Error **errp)
+{
+ Elf32_Phdr phdr;
+ int ret;
+
+ memset(&phdr, 0, sizeof(Elf32_Phdr));
+ phdr.p_type = cpu_to_dump32(s, PT_LOAD);
+ phdr.p_offset = cpu_to_dump32(s, offset);
+ phdr.p_paddr = cpu_to_dump32(s, memory_mapping->phys_addr);
+ phdr.p_filesz = cpu_to_dump32(s, filesz);
+ phdr.p_memsz = cpu_to_dump32(s, memory_mapping->length);
+ phdr.p_vaddr =
+ cpu_to_dump32(s, memory_mapping->virt_addr) ?: phdr.p_paddr;
+
+ assert(memory_mapping->length >= filesz);
+
+ ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret,
+ "dump: failed to write program header table");
+ }
+}
+
+static void write_elf64_note(DumpState *s, Error **errp)
+{
+ Elf64_Phdr phdr;
+ hwaddr begin = s->memory_offset - s->note_size;
+ int ret;
+
+ memset(&phdr, 0, sizeof(Elf64_Phdr));
+ phdr.p_type = cpu_to_dump32(s, PT_NOTE);
+ phdr.p_offset = cpu_to_dump64(s, begin);
+ phdr.p_paddr = 0;
+ phdr.p_filesz = cpu_to_dump64(s, s->note_size);
+ phdr.p_memsz = cpu_to_dump64(s, s->note_size);
+ phdr.p_vaddr = 0;
+
+ ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret,
+ "dump: failed to write program header table");
+ }
+}
+
+static inline int cpu_index(CPUState *cpu)
+{
+ return cpu->cpu_index + 1;
+}
+
+static void write_guest_note(WriteCoreDumpFunction f, DumpState *s,
+ Error **errp)
+{
+ int ret;
+
+ if (s->guest_note) {
+ ret = f(s->guest_note, s->guest_note_size, s);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to write guest note");
+ }
+ }
+}
+
+static void write_elf64_notes(WriteCoreDumpFunction f, DumpState *s,
+ Error **errp)
+{
+ CPUState *cpu;
+ int ret;
+ int id;
+
+ CPU_FOREACH(cpu) {
+ id = cpu_index(cpu);
+ ret = cpu_write_elf64_note(f, cpu, id, s);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to write elf notes");
+ return;
+ }
+ }
+
+ CPU_FOREACH(cpu) {
+ ret = cpu_write_elf64_qemunote(f, cpu, s);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to write CPU status");
+ return;
+ }
+ }
+
+ write_guest_note(f, s, errp);
+}
+
+static void write_elf32_note(DumpState *s, Error **errp)
+{
+ hwaddr begin = s->memory_offset - s->note_size;
+ Elf32_Phdr phdr;
+ int ret;
+
+ memset(&phdr, 0, sizeof(Elf32_Phdr));
+ phdr.p_type = cpu_to_dump32(s, PT_NOTE);
+ phdr.p_offset = cpu_to_dump32(s, begin);
+ phdr.p_paddr = 0;
+ phdr.p_filesz = cpu_to_dump32(s, s->note_size);
+ phdr.p_memsz = cpu_to_dump32(s, s->note_size);
+ phdr.p_vaddr = 0;
+
+ ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret,
+ "dump: failed to write program header table");
+ }
+}
+
+static void write_elf32_notes(WriteCoreDumpFunction f, DumpState *s,
+ Error **errp)
+{
+ CPUState *cpu;
+ int ret;
+ int id;
+
+ CPU_FOREACH(cpu) {
+ id = cpu_index(cpu);
+ ret = cpu_write_elf32_note(f, cpu, id, s);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to write elf notes");
+ return;
+ }
+ }
+
+ CPU_FOREACH(cpu) {
+ ret = cpu_write_elf32_qemunote(f, cpu, s);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to write CPU status");
+ return;
+ }
+ }
+
+ write_guest_note(f, s, errp);
+}
+
+static void write_elf_section(DumpState *s, int type, Error **errp)
+{
+ Elf32_Shdr shdr32;
+ Elf64_Shdr shdr64;
+ int shdr_size;
+ void *shdr;
+ int ret;
+
+ if (type == 0) {
+ shdr_size = sizeof(Elf32_Shdr);
+ memset(&shdr32, 0, shdr_size);
+ shdr32.sh_info = cpu_to_dump32(s, s->sh_info);
+ shdr = &shdr32;
+ } else {
+ shdr_size = sizeof(Elf64_Shdr);
+ memset(&shdr64, 0, shdr_size);
+ shdr64.sh_info = cpu_to_dump32(s, s->sh_info);
+ shdr = &shdr64;
+ }
+
+ ret = fd_write_vmcore(&shdr, shdr_size, s);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret,
+ "dump: failed to write section header table");
+ }
+}
+
+static void write_data(DumpState *s, void *buf, int length, Error **errp)
+{
+ int ret;
+
+ ret = fd_write_vmcore(buf, length, s);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "dump: failed to save memory");
+ } else {
+ s->written_size += length;
+ }
+}
+
+/* write the memory to vmcore. 1 page per I/O. */
+static void write_memory(DumpState *s, GuestPhysBlock *block, ram_addr_t start,
+ int64_t size, Error **errp)
+{
+ int64_t i;
+ Error *local_err = NULL;
+
+ for (i = 0; i < size / s->dump_info.page_size; i++) {
+ write_data(s, block->host_addr + start + i * s->dump_info.page_size,
+ s->dump_info.page_size, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
+
+ if ((size % s->dump_info.page_size) != 0) {
+ write_data(s, block->host_addr + start + i * s->dump_info.page_size,
+ size % s->dump_info.page_size, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
+}
+
+/* get the memory's offset and size in the vmcore */
+static void get_offset_range(hwaddr phys_addr,
+ ram_addr_t mapping_length,
+ DumpState *s,
+ hwaddr *p_offset,
+ hwaddr *p_filesz)
+{
+ GuestPhysBlock *block;
+ hwaddr offset = s->memory_offset;
+ int64_t size_in_block, start;
+
+ /* When the memory is not stored into vmcore, offset will be -1 */
+ *p_offset = -1;
+ *p_filesz = 0;
+
+ if (s->has_filter) {
+ if (phys_addr < s->begin || phys_addr >= s->begin + s->length) {
+ return;
+ }
+ }
+
+ QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
+ if (s->has_filter) {
+ if (block->target_start >= s->begin + s->length ||
+ block->target_end <= s->begin) {
+ /* This block is out of the range */
+ continue;
+ }
+
+ if (s->begin <= block->target_start) {
+ start = block->target_start;
+ } else {
+ start = s->begin;
+ }
+
+ size_in_block = block->target_end - start;
+ if (s->begin + s->length < block->target_end) {
+ size_in_block -= block->target_end - (s->begin + s->length);
+ }
+ } else {
+ start = block->target_start;
+ size_in_block = block->target_end - block->target_start;
+ }
+
+ if (phys_addr >= start && phys_addr < start + size_in_block) {
+ *p_offset = phys_addr - start + offset;
+
+ /* The offset range mapped from the vmcore file must not spill over
+ * the GuestPhysBlock, clamp it. The rest of the mapping will be
+ * zero-filled in memory at load time; see
+ * <http://refspecs.linuxbase.org/elf/gabi4+/ch5.pheader.html>.
+ */
+ *p_filesz = phys_addr + mapping_length <= start + size_in_block ?
+ mapping_length :
+ size_in_block - (phys_addr - start);
+ return;
+ }
+
+ offset += size_in_block;
+ }
+}
+
+static void write_elf_loads(DumpState *s, Error **errp)
+{
+ hwaddr offset, filesz;
+ MemoryMapping *memory_mapping;
+ uint32_t phdr_index = 1;
+ uint32_t max_index;
+ Error *local_err = NULL;
+
+ if (s->have_section) {
+ max_index = s->sh_info;
+ } else {
+ max_index = s->phdr_num;
+ }
+
+ QTAILQ_FOREACH(memory_mapping, &s->list.head, next) {
+ get_offset_range(memory_mapping->phys_addr,
+ memory_mapping->length,
+ s, &offset, &filesz);
+ if (s->dump_info.d_class == ELFCLASS64) {
+ write_elf64_load(s, memory_mapping, phdr_index++, offset,
+ filesz, &local_err);
+ } else {
+ write_elf32_load(s, memory_mapping, phdr_index++, offset,
+ filesz, &local_err);
+ }
+
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ if (phdr_index >= max_index) {
+ break;
+ }
+ }
+}
+
+/* write elf header, PT_NOTE and elf note to vmcore. */
+static void dump_begin(DumpState *s, Error **errp)
+{
+ Error *local_err = NULL;
+
+ /*
+ * the vmcore's format is:
+ * --------------
+ * | elf header |
+ * --------------
+ * | PT_NOTE |
+ * --------------
+ * | PT_LOAD |
+ * --------------
+ * | ...... |
+ * --------------
+ * | PT_LOAD |
+ * --------------
+ * | sec_hdr |
+ * --------------
+ * | elf note |
+ * --------------
+ * | memory |
+ * --------------
+ *
+ * we only know where the memory is saved after we write elf note into
+ * vmcore.
+ */
+
+ /* write elf header to vmcore */
+ if (s->dump_info.d_class == ELFCLASS64) {
+ write_elf64_header(s, &local_err);
+ } else {
+ write_elf32_header(s, &local_err);
+ }
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ if (s->dump_info.d_class == ELFCLASS64) {
+ /* write PT_NOTE to vmcore */
+ write_elf64_note(s, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /* write all PT_LOAD to vmcore */
+ write_elf_loads(s, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /* write section to vmcore */
+ if (s->have_section) {
+ write_elf_section(s, 1, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
+
+ /* write notes to vmcore */
+ write_elf64_notes(fd_write_vmcore, s, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ } else {
+ /* write PT_NOTE to vmcore */
+ write_elf32_note(s, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /* write all PT_LOAD to vmcore */
+ write_elf_loads(s, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /* write section to vmcore */
+ if (s->have_section) {
+ write_elf_section(s, 0, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
+
+ /* write notes to vmcore */
+ write_elf32_notes(fd_write_vmcore, s, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
+}
+
+static int get_next_block(DumpState *s, GuestPhysBlock *block)
+{
+ while (1) {
+ block = QTAILQ_NEXT(block, next);
+ if (!block) {
+ /* no more block */
+ return 1;
+ }
+
+ s->start = 0;
+ s->next_block = block;
+ if (s->has_filter) {
+ if (block->target_start >= s->begin + s->length ||
+ block->target_end <= s->begin) {
+ /* This block is out of the range */
+ continue;
+ }
+
+ if (s->begin > block->target_start) {
+ s->start = s->begin - block->target_start;
+ }
+ }
+
+ return 0;
+ }
+}
+
+/* write all memory to vmcore */
+static void dump_iterate(DumpState *s, Error **errp)
+{
+ GuestPhysBlock *block;
+ int64_t size;
+ Error *local_err = NULL;
+
+ do {
+ block = s->next_block;
+
+ size = block->target_end - block->target_start;
+ if (s->has_filter) {
+ size -= s->start;
+ if (s->begin + s->length < block->target_end) {
+ size -= block->target_end - (s->begin + s->length);
+ }
+ }
+ write_memory(s, block, s->start, size, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ } while (!get_next_block(s, block));
+}
+
+static void create_vmcore(DumpState *s, Error **errp)
+{
+ Error *local_err = NULL;
+
+ dump_begin(s, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ dump_iterate(s, errp);
+}
+
+static int write_start_flat_header(int fd)
+{
+ MakedumpfileHeader *mh;
+ int ret = 0;
+
+ QEMU_BUILD_BUG_ON(sizeof *mh > MAX_SIZE_MDF_HEADER);
+ mh = g_malloc0(MAX_SIZE_MDF_HEADER);
+
+ memcpy(mh->signature, MAKEDUMPFILE_SIGNATURE,
+ MIN(sizeof mh->signature, sizeof MAKEDUMPFILE_SIGNATURE));
+
+ mh->type = cpu_to_be64(TYPE_FLAT_HEADER);
+ mh->version = cpu_to_be64(VERSION_FLAT_HEADER);
+
+ size_t written_size;
+ written_size = qemu_write_full(fd, mh, MAX_SIZE_MDF_HEADER);
+ if (written_size != MAX_SIZE_MDF_HEADER) {
+ ret = -1;
+ }
+
+ g_free(mh);
+ return ret;
+}
+
+static int write_end_flat_header(int fd)
+{
+ MakedumpfileDataHeader mdh;
+
+ mdh.offset = END_FLAG_FLAT_HEADER;
+ mdh.buf_size = END_FLAG_FLAT_HEADER;
+
+ size_t written_size;
+ written_size = qemu_write_full(fd, &mdh, sizeof(mdh));
+ if (written_size != sizeof(mdh)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int write_buffer(int fd, off_t offset, const void *buf, size_t size)
+{
+ size_t written_size;
+ MakedumpfileDataHeader mdh;
+
+ mdh.offset = cpu_to_be64(offset);
+ mdh.buf_size = cpu_to_be64(size);
+
+ written_size = qemu_write_full(fd, &mdh, sizeof(mdh));
+ if (written_size != sizeof(mdh)) {
+ return -1;
+ }
+
+ written_size = qemu_write_full(fd, buf, size);
+ if (written_size != size) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int buf_write_note(const void *buf, size_t size, void *opaque)
+{
+ DumpState *s = opaque;
+
+ /* note_buf is not enough */
+ if (s->note_buf_offset + size > s->note_size) {
+ return -1;
+ }
+
+ memcpy(s->note_buf + s->note_buf_offset, buf, size);
+
+ s->note_buf_offset += size;
+
+ return 0;
+}
+
+/*
+ * This function retrieves various sizes from an elf header.
+ *
+ * @note has to be a valid ELF note. The return sizes are unmodified
+ * (not padded or rounded up to be multiple of 4).
+ */
+static void get_note_sizes(DumpState *s, const void *note,
+ uint64_t *note_head_size,
+ uint64_t *name_size,
+ uint64_t *desc_size)
+{
+ uint64_t note_head_sz;
+ uint64_t name_sz;
+ uint64_t desc_sz;
+
+ if (s->dump_info.d_class == ELFCLASS64) {
+ const Elf64_Nhdr *hdr = note;
+ note_head_sz = sizeof(Elf64_Nhdr);
+ name_sz = tswap64(hdr->n_namesz);
+ desc_sz = tswap64(hdr->n_descsz);
+ } else {
+ const Elf32_Nhdr *hdr = note;
+ note_head_sz = sizeof(Elf32_Nhdr);
+ name_sz = tswap32(hdr->n_namesz);
+ desc_sz = tswap32(hdr->n_descsz);
+ }
+
+ if (note_head_size) {
+ *note_head_size = note_head_sz;
+ }
+ if (name_size) {
+ *name_size = name_sz;
+ }
+ if (desc_size) {
+ *desc_size = desc_sz;
+ }
+}
+
+static bool note_name_equal(DumpState *s,
+ const uint8_t *note, const char *name)
+{
+ int len = strlen(name) + 1;
+ uint64_t head_size, name_size;
+
+ get_note_sizes(s, note, &head_size, &name_size, NULL);
+ head_size = ROUND_UP(head_size, 4);
+
+ return name_size == len && memcmp(note + head_size, name, len) == 0;
+}
+
+/* write common header, sub header and elf note to vmcore */
+static void create_header32(DumpState *s, Error **errp)
+{
+ DiskDumpHeader32 *dh = NULL;
+ KdumpSubHeader32 *kh = NULL;
+ size_t size;
+ uint32_t block_size;
+ uint32_t sub_hdr_size;
+ uint32_t bitmap_blocks;
+ uint32_t status = 0;
+ uint64_t offset_note;
+ Error *local_err = NULL;
+
+ /* write common header, the version of kdump-compressed format is 6th */
+ size = sizeof(DiskDumpHeader32);
+ dh = g_malloc0(size);
+
+ memcpy(dh->signature, KDUMP_SIGNATURE, SIG_LEN);
+ dh->header_version = cpu_to_dump32(s, 6);
+ block_size = s->dump_info.page_size;
+ dh->block_size = cpu_to_dump32(s, block_size);
+ sub_hdr_size = sizeof(struct KdumpSubHeader32) + s->note_size;
+ sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
+ dh->sub_hdr_size = cpu_to_dump32(s, sub_hdr_size);
+ /* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
+ dh->max_mapnr = cpu_to_dump32(s, MIN(s->max_mapnr, UINT_MAX));
+ dh->nr_cpus = cpu_to_dump32(s, s->nr_cpus);
+ bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
+ dh->bitmap_blocks = cpu_to_dump32(s, bitmap_blocks);
+ strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
+
+ if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
+ status |= DUMP_DH_COMPRESSED_ZLIB;
+ }
+#ifdef CONFIG_LZO
+ if (s->flag_compress & DUMP_DH_COMPRESSED_LZO) {
+ status |= DUMP_DH_COMPRESSED_LZO;
+ }
+#endif
+#ifdef CONFIG_SNAPPY
+ if (s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) {
+ status |= DUMP_DH_COMPRESSED_SNAPPY;
+ }
+#endif
+ dh->status = cpu_to_dump32(s, status);
+
+ if (write_buffer(s->fd, 0, dh, size) < 0) {
+ error_setg(errp, "dump: failed to write disk dump header");
+ goto out;
+ }
+
+ /* write sub header */
+ size = sizeof(KdumpSubHeader32);
+ kh = g_malloc0(size);
+
+ /* 64bit max_mapnr_64 */
+ kh->max_mapnr_64 = cpu_to_dump64(s, s->max_mapnr);
+ kh->phys_base = cpu_to_dump32(s, s->dump_info.phys_base);
+ kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
+
+ offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
+ if (s->guest_note &&
+ note_name_equal(s, s->guest_note, "VMCOREINFO")) {
+ uint64_t hsize, name_size, size_vmcoreinfo_desc, offset_vmcoreinfo;
+
+ get_note_sizes(s, s->guest_note,
+ &hsize, &name_size, &size_vmcoreinfo_desc);
+ offset_vmcoreinfo = offset_note + s->note_size - s->guest_note_size +
+ (DIV_ROUND_UP(hsize, 4) + DIV_ROUND_UP(name_size, 4)) * 4;
+ kh->offset_vmcoreinfo = cpu_to_dump64(s, offset_vmcoreinfo);
+ kh->size_vmcoreinfo = cpu_to_dump32(s, size_vmcoreinfo_desc);
+ }
+
+ kh->offset_note = cpu_to_dump64(s, offset_note);
+ kh->note_size = cpu_to_dump32(s, s->note_size);
+
+ if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
+ block_size, kh, size) < 0) {
+ error_setg(errp, "dump: failed to write kdump sub header");
+ goto out;
+ }
+
+ /* write note */
+ s->note_buf = g_malloc0(s->note_size);
+ s->note_buf_offset = 0;
+
+ /* use s->note_buf to store notes temporarily */
+ write_elf32_notes(buf_write_note, s, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ goto out;
+ }
+ if (write_buffer(s->fd, offset_note, s->note_buf,
+ s->note_size) < 0) {
+ error_setg(errp, "dump: failed to write notes");
+ goto out;
+ }
+
+ /* get offset of dump_bitmap */
+ s->offset_dump_bitmap = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size) *
+ block_size;
+
+ /* get offset of page */
+ s->offset_page = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size + bitmap_blocks) *
+ block_size;
+
+out:
+ g_free(dh);
+ g_free(kh);
+ g_free(s->note_buf);
+}
+
+/* write common header, sub header and elf note to vmcore */
+static void create_header64(DumpState *s, Error **errp)
+{
+ DiskDumpHeader64 *dh = NULL;
+ KdumpSubHeader64 *kh = NULL;
+ size_t size;
+ uint32_t block_size;
+ uint32_t sub_hdr_size;
+ uint32_t bitmap_blocks;
+ uint32_t status = 0;
+ uint64_t offset_note;
+ Error *local_err = NULL;
+
+ /* write common header, the version of kdump-compressed format is 6th */
+ size = sizeof(DiskDumpHeader64);
+ dh = g_malloc0(size);
+
+ memcpy(dh->signature, KDUMP_SIGNATURE, SIG_LEN);
+ dh->header_version = cpu_to_dump32(s, 6);
+ block_size = s->dump_info.page_size;
+ dh->block_size = cpu_to_dump32(s, block_size);
+ sub_hdr_size = sizeof(struct KdumpSubHeader64) + s->note_size;
+ sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
+ dh->sub_hdr_size = cpu_to_dump32(s, sub_hdr_size);
+ /* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
+ dh->max_mapnr = cpu_to_dump32(s, MIN(s->max_mapnr, UINT_MAX));
+ dh->nr_cpus = cpu_to_dump32(s, s->nr_cpus);
+ bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
+ dh->bitmap_blocks = cpu_to_dump32(s, bitmap_blocks);
+ strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
+
+ if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
+ status |= DUMP_DH_COMPRESSED_ZLIB;
+ }
+#ifdef CONFIG_LZO
+ if (s->flag_compress & DUMP_DH_COMPRESSED_LZO) {
+ status |= DUMP_DH_COMPRESSED_LZO;
+ }
+#endif
+#ifdef CONFIG_SNAPPY
+ if (s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) {
+ status |= DUMP_DH_COMPRESSED_SNAPPY;
+ }
+#endif
+ dh->status = cpu_to_dump32(s, status);
+
+ if (write_buffer(s->fd, 0, dh, size) < 0) {
+ error_setg(errp, "dump: failed to write disk dump header");
+ goto out;
+ }
+
+ /* write sub header */
+ size = sizeof(KdumpSubHeader64);
+ kh = g_malloc0(size);
+
+ /* 64bit max_mapnr_64 */
+ kh->max_mapnr_64 = cpu_to_dump64(s, s->max_mapnr);
+ kh->phys_base = cpu_to_dump64(s, s->dump_info.phys_base);
+ kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
+
+ offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
+ if (s->guest_note &&
+ note_name_equal(s, s->guest_note, "VMCOREINFO")) {
+ uint64_t hsize, name_size, size_vmcoreinfo_desc, offset_vmcoreinfo;
+
+ get_note_sizes(s, s->guest_note,
+ &hsize, &name_size, &size_vmcoreinfo_desc);
+ offset_vmcoreinfo = offset_note + s->note_size - s->guest_note_size +
+ (DIV_ROUND_UP(hsize, 4) + DIV_ROUND_UP(name_size, 4)) * 4;
+ kh->offset_vmcoreinfo = cpu_to_dump64(s, offset_vmcoreinfo);
+ kh->size_vmcoreinfo = cpu_to_dump64(s, size_vmcoreinfo_desc);
+ }
+
+ kh->offset_note = cpu_to_dump64(s, offset_note);
+ kh->note_size = cpu_to_dump64(s, s->note_size);
+
+ if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
+ block_size, kh, size) < 0) {
+ error_setg(errp, "dump: failed to write kdump sub header");
+ goto out;
+ }
+
+ /* write note */
+ s->note_buf = g_malloc0(s->note_size);
+ s->note_buf_offset = 0;
+
+ /* use s->note_buf to store notes temporarily */
+ write_elf64_notes(buf_write_note, s, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ goto out;
+ }
+
+ if (write_buffer(s->fd, offset_note, s->note_buf,
+ s->note_size) < 0) {
+ error_setg(errp, "dump: failed to write notes");
+ goto out;
+ }
+
+ /* get offset of dump_bitmap */
+ s->offset_dump_bitmap = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size) *
+ block_size;
+
+ /* get offset of page */
+ s->offset_page = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size + bitmap_blocks) *
+ block_size;
+
+out:
+ g_free(dh);
+ g_free(kh);
+ g_free(s->note_buf);
+}
+
+static void write_dump_header(DumpState *s, Error **errp)
+{
+ Error *local_err = NULL;
+
+ if (s->dump_info.d_class == ELFCLASS32) {
+ create_header32(s, &local_err);
+ } else {
+ create_header64(s, &local_err);
+ }
+ error_propagate(errp, local_err);
+}
+
+static size_t dump_bitmap_get_bufsize(DumpState *s)
+{
+ return s->dump_info.page_size;
+}
+
+/*
+ * set dump_bitmap sequencely. the bit before last_pfn is not allowed to be
+ * rewritten, so if need to set the first bit, set last_pfn and pfn to 0.
+ * set_dump_bitmap will always leave the recently set bit un-sync. And setting
+ * (last bit + sizeof(buf) * 8) to 0 will do flushing the content in buf into
+ * vmcore, ie. synchronizing un-sync bit into vmcore.
+ */
+static int set_dump_bitmap(uint64_t last_pfn, uint64_t pfn, bool value,
+ uint8_t *buf, DumpState *s)
+{
+ off_t old_offset, new_offset;
+ off_t offset_bitmap1, offset_bitmap2;
+ uint32_t byte, bit;
+ size_t bitmap_bufsize = dump_bitmap_get_bufsize(s);
+ size_t bits_per_buf = bitmap_bufsize * CHAR_BIT;
+
+ /* should not set the previous place */
+ assert(last_pfn <= pfn);
+
+ /*
+ * if the bit needed to be set is not cached in buf, flush the data in buf
+ * to vmcore firstly.
+ * making new_offset be bigger than old_offset can also sync remained data
+ * into vmcore.
+ */
+ old_offset = bitmap_bufsize * (last_pfn / bits_per_buf);
+ new_offset = bitmap_bufsize * (pfn / bits_per_buf);
+
+ while (old_offset < new_offset) {
+ /* calculate the offset and write dump_bitmap */
+ offset_bitmap1 = s->offset_dump_bitmap + old_offset;
+ if (write_buffer(s->fd, offset_bitmap1, buf,
+ bitmap_bufsize) < 0) {
+ return -1;
+ }
+
+ /* dump level 1 is chosen, so 1st and 2nd bitmap are same */
+ offset_bitmap2 = s->offset_dump_bitmap + s->len_dump_bitmap +
+ old_offset;
+ if (write_buffer(s->fd, offset_bitmap2, buf,
+ bitmap_bufsize) < 0) {
+ return -1;
+ }
+
+ memset(buf, 0, bitmap_bufsize);
+ old_offset += bitmap_bufsize;
+ }
+
+ /* get the exact place of the bit in the buf, and set it */
+ byte = (pfn % bits_per_buf) / CHAR_BIT;
+ bit = (pfn % bits_per_buf) % CHAR_BIT;
+ if (value) {
+ buf[byte] |= 1u << bit;
+ } else {
+ buf[byte] &= ~(1u << bit);
+ }
+
+ return 0;
+}
+
+static uint64_t dump_paddr_to_pfn(DumpState *s, uint64_t addr)
+{
+ int target_page_shift = ctz32(s->dump_info.page_size);
+
+ return (addr >> target_page_shift) - ARCH_PFN_OFFSET;
+}
+
+static uint64_t dump_pfn_to_paddr(DumpState *s, uint64_t pfn)
+{
+ int target_page_shift = ctz32(s->dump_info.page_size);
+
+ return (pfn + ARCH_PFN_OFFSET) << target_page_shift;
+}
+
+/*
+ * exam every page and return the page frame number and the address of the page.
+ * bufptr can be NULL. note: the blocks here is supposed to reflect guest-phys
+ * blocks, so block->target_start and block->target_end should be interal
+ * multiples of the target page size.
+ */
+static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
+ uint8_t **bufptr, DumpState *s)
+{
+ GuestPhysBlock *block = *blockptr;
+ hwaddr addr, target_page_mask = ~((hwaddr)s->dump_info.page_size - 1);
+ uint8_t *buf;
+
+ /* block == NULL means the start of the iteration */
+ if (!block) {
+ block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
+ *blockptr = block;
+ assert((block->target_start & ~target_page_mask) == 0);
+ assert((block->target_end & ~target_page_mask) == 0);
+ *pfnptr = dump_paddr_to_pfn(s, block->target_start);
+ if (bufptr) {
+ *bufptr = block->host_addr;
+ }
+ return true;
+ }
+
+ *pfnptr = *pfnptr + 1;
+ addr = dump_pfn_to_paddr(s, *pfnptr);
+
+ if ((addr >= block->target_start) &&
+ (addr + s->dump_info.page_size <= block->target_end)) {
+ buf = block->host_addr + (addr - block->target_start);
+ } else {
+ /* the next page is in the next block */
+ block = QTAILQ_NEXT(block, next);
+ *blockptr = block;
+ if (!block) {
+ return false;
+ }
+ assert((block->target_start & ~target_page_mask) == 0);
+ assert((block->target_end & ~target_page_mask) == 0);
+ *pfnptr = dump_paddr_to_pfn(s, block->target_start);
+ buf = block->host_addr;
+ }
+
+ if (bufptr) {
+ *bufptr = buf;
+ }
+
+ return true;
+}
+
+static void write_dump_bitmap(DumpState *s, Error **errp)
+{
+ int ret = 0;
+ uint64_t last_pfn, pfn;
+ void *dump_bitmap_buf;
+ size_t num_dumpable;
+ GuestPhysBlock *block_iter = NULL;
+ size_t bitmap_bufsize = dump_bitmap_get_bufsize(s);
+ size_t bits_per_buf = bitmap_bufsize * CHAR_BIT;
+
+ /* dump_bitmap_buf is used to store dump_bitmap temporarily */
+ dump_bitmap_buf = g_malloc0(bitmap_bufsize);
+
+ num_dumpable = 0;
+ last_pfn = 0;
+
+ /*
+ * exam memory page by page, and set the bit in dump_bitmap corresponded
+ * to the existing page.
+ */
+ while (get_next_page(&block_iter, &pfn, NULL, s)) {
+ ret = set_dump_bitmap(last_pfn, pfn, true, dump_bitmap_buf, s);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to set dump_bitmap");
+ goto out;
+ }
+
+ last_pfn = pfn;
+ num_dumpable++;
+ }
+
+ /*
+ * set_dump_bitmap will always leave the recently set bit un-sync. Here we
+ * set the remaining bits from last_pfn to the end of the bitmap buffer to
+ * 0. With those set, the un-sync bit will be synchronized into the vmcore.
+ */
+ if (num_dumpable > 0) {
+ ret = set_dump_bitmap(last_pfn, last_pfn + bits_per_buf, false,
+ dump_bitmap_buf, s);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to sync dump_bitmap");
+ goto out;
+ }
+ }
+
+ /* number of dumpable pages that will be dumped later */
+ s->num_dumpable = num_dumpable;
+
+out:
+ g_free(dump_bitmap_buf);
+}
+
+static void prepare_data_cache(DataCache *data_cache, DumpState *s,
+ off_t offset)
+{
+ data_cache->fd = s->fd;
+ data_cache->data_size = 0;
+ data_cache->buf_size = 4 * dump_bitmap_get_bufsize(s);
+ data_cache->buf = g_malloc0(data_cache->buf_size);
+ data_cache->offset = offset;
+}
+
+static int write_cache(DataCache *dc, const void *buf, size_t size,
+ bool flag_sync)
+{
+ /*
+ * dc->buf_size should not be less than size, otherwise dc will never be
+ * enough
+ */
+ assert(size <= dc->buf_size);
+
+ /*
+ * if flag_sync is set, synchronize data in dc->buf into vmcore.
+ * otherwise check if the space is enough for caching data in buf, if not,
+ * write the data in dc->buf to dc->fd and reset dc->buf
+ */
+ if ((!flag_sync && dc->data_size + size > dc->buf_size) ||
+ (flag_sync && dc->data_size > 0)) {
+ if (write_buffer(dc->fd, dc->offset, dc->buf, dc->data_size) < 0) {
+ return -1;
+ }
+
+ dc->offset += dc->data_size;
+ dc->data_size = 0;
+ }
+
+ if (!flag_sync) {
+ memcpy(dc->buf + dc->data_size, buf, size);
+ dc->data_size += size;
+ }
+
+ return 0;
+}
+
+static void free_data_cache(DataCache *data_cache)
+{
+ g_free(data_cache->buf);
+}
+
+static size_t get_len_buf_out(size_t page_size, uint32_t flag_compress)
+{
+ switch (flag_compress) {
+ case DUMP_DH_COMPRESSED_ZLIB:
+ return compressBound(page_size);
+
+ case DUMP_DH_COMPRESSED_LZO:
+ /*
+ * LZO will expand incompressible data by a little amount. Please check
+ * the following URL to see the expansion calculation:
+ * http://www.oberhumer.com/opensource/lzo/lzofaq.php
+ */
+ return page_size + page_size / 16 + 64 + 3;
+
+#ifdef CONFIG_SNAPPY
+ case DUMP_DH_COMPRESSED_SNAPPY:
+ return snappy_max_compressed_length(page_size);
+#endif
+ }
+ return 0;
+}
+
+/*
+ * check if the page is all 0
+ */
+static inline bool is_zero_page(const uint8_t *buf, size_t page_size)
+{
+ return buffer_is_zero(buf, page_size);
+}
+
+static void write_dump_pages(DumpState *s, Error **errp)
+{
+ int ret = 0;
+ DataCache page_desc, page_data;
+ size_t len_buf_out, size_out;
+#ifdef CONFIG_LZO
+ lzo_bytep wrkmem = NULL;
+#endif
+ uint8_t *buf_out = NULL;
+ off_t offset_desc, offset_data;
+ PageDescriptor pd, pd_zero;
+ uint8_t *buf;
+ GuestPhysBlock *block_iter = NULL;
+ uint64_t pfn_iter;
+
+ /* get offset of page_desc and page_data in dump file */
+ offset_desc = s->offset_page;
+ offset_data = offset_desc + sizeof(PageDescriptor) * s->num_dumpable;
+
+ prepare_data_cache(&page_desc, s, offset_desc);
+ prepare_data_cache(&page_data, s, offset_data);
+
+ /* prepare buffer to store compressed data */
+ len_buf_out = get_len_buf_out(s->dump_info.page_size, s->flag_compress);
+ assert(len_buf_out != 0);
+
+#ifdef CONFIG_LZO
+ wrkmem = g_malloc(LZO1X_1_MEM_COMPRESS);
+#endif
+
+ buf_out = g_malloc(len_buf_out);
+
+ /*
+ * init zero page's page_desc and page_data, because every zero page
+ * uses the same page_data
+ */
+ pd_zero.size = cpu_to_dump32(s, s->dump_info.page_size);
+ pd_zero.flags = cpu_to_dump32(s, 0);
+ pd_zero.offset = cpu_to_dump64(s, offset_data);
+ pd_zero.page_flags = cpu_to_dump64(s, 0);
+ buf = g_malloc0(s->dump_info.page_size);
+ ret = write_cache(&page_data, buf, s->dump_info.page_size, false);
+ g_free(buf);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to write page data (zero page)");
+ goto out;
+ }
+
+ offset_data += s->dump_info.page_size;
+
+ /*
+ * dump memory to vmcore page by page. zero page will all be resided in the
+ * first page of page section
+ */
+ while (get_next_page(&block_iter, &pfn_iter, &buf, s)) {
+ /* check zero page */
+ if (is_zero_page(buf, s->dump_info.page_size)) {
+ ret = write_cache(&page_desc, &pd_zero, sizeof(PageDescriptor),
+ false);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to write page desc");
+ goto out;
+ }
+ } else {
+ /*
+ * not zero page, then:
+ * 1. compress the page
+ * 2. write the compressed page into the cache of page_data
+ * 3. get page desc of the compressed page and write it into the
+ * cache of page_desc
+ *
+ * only one compression format will be used here, for
+ * s->flag_compress is set. But when compression fails to work,
+ * we fall back to save in plaintext.
+ */
+ size_out = len_buf_out;
+ if ((s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) &&
+ (compress2(buf_out, (uLongf *)&size_out, buf,
+ s->dump_info.page_size, Z_BEST_SPEED) == Z_OK) &&
+ (size_out < s->dump_info.page_size)) {
+ pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_ZLIB);
+ pd.size = cpu_to_dump32(s, size_out);
+
+ ret = write_cache(&page_data, buf_out, size_out, false);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to write page data");
+ goto out;
+ }
+#ifdef CONFIG_LZO
+ } else if ((s->flag_compress & DUMP_DH_COMPRESSED_LZO) &&
+ (lzo1x_1_compress(buf, s->dump_info.page_size, buf_out,
+ (lzo_uint *)&size_out, wrkmem) == LZO_E_OK) &&
+ (size_out < s->dump_info.page_size)) {
+ pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_LZO);
+ pd.size = cpu_to_dump32(s, size_out);
+
+ ret = write_cache(&page_data, buf_out, size_out, false);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to write page data");
+ goto out;
+ }
+#endif
+#ifdef CONFIG_SNAPPY
+ } else if ((s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) &&
+ (snappy_compress((char *)buf, s->dump_info.page_size,
+ (char *)buf_out, &size_out) == SNAPPY_OK) &&
+ (size_out < s->dump_info.page_size)) {
+ pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_SNAPPY);
+ pd.size = cpu_to_dump32(s, size_out);
+
+ ret = write_cache(&page_data, buf_out, size_out, false);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to write page data");
+ goto out;
+ }
+#endif
+ } else {
+ /*
+ * fall back to save in plaintext, size_out should be
+ * assigned the target's page size
+ */
+ pd.flags = cpu_to_dump32(s, 0);
+ size_out = s->dump_info.page_size;
+ pd.size = cpu_to_dump32(s, size_out);
+
+ ret = write_cache(&page_data, buf,
+ s->dump_info.page_size, false);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to write page data");
+ goto out;
+ }
+ }
+
+ /* get and write page desc here */
+ pd.page_flags = cpu_to_dump64(s, 0);
+ pd.offset = cpu_to_dump64(s, offset_data);
+ offset_data += size_out;
+
+ ret = write_cache(&page_desc, &pd, sizeof(PageDescriptor), false);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to write page desc");
+ goto out;
+ }
+ }
+ s->written_size += s->dump_info.page_size;
+ }
+
+ ret = write_cache(&page_desc, NULL, 0, true);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to sync cache for page_desc");
+ goto out;
+ }
+ ret = write_cache(&page_data, NULL, 0, true);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to sync cache for page_data");
+ goto out;
+ }
+
+out:
+ free_data_cache(&page_desc);
+ free_data_cache(&page_data);
+
+#ifdef CONFIG_LZO
+ g_free(wrkmem);
+#endif
+
+ g_free(buf_out);
+}
+
+static void create_kdump_vmcore(DumpState *s, Error **errp)
+{
+ int ret;
+ Error *local_err = NULL;
+
+ /*
+ * the kdump-compressed format is:
+ * File offset
+ * +------------------------------------------+ 0x0
+ * | main header (struct disk_dump_header) |
+ * |------------------------------------------+ block 1
+ * | sub header (struct kdump_sub_header) |
+ * |------------------------------------------+ block 2
+ * | 1st-dump_bitmap |
+ * |------------------------------------------+ block 2 + X blocks
+ * | 2nd-dump_bitmap | (aligned by block)
+ * |------------------------------------------+ block 2 + 2 * X blocks
+ * | page desc for pfn 0 (struct page_desc) | (aligned by block)
+ * | page desc for pfn 1 (struct page_desc) |
+ * | : |
+ * |------------------------------------------| (not aligned by block)
+ * | page data (pfn 0) |
+ * | page data (pfn 1) |
+ * | : |
+ * +------------------------------------------+
+ */
+
+ ret = write_start_flat_header(s->fd);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to write start flat header");
+ return;
+ }
+
+ write_dump_header(s, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ write_dump_bitmap(s, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ write_dump_pages(s, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ ret = write_end_flat_header(s->fd);
+ if (ret < 0) {
+ error_setg(errp, "dump: failed to write end flat header");
+ return;
+ }
+}
+
+static ram_addr_t get_start_block(DumpState *s)
+{
+ GuestPhysBlock *block;
+
+ if (!s->has_filter) {
+ s->next_block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
+ return 0;
+ }
+
+ QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
+ if (block->target_start >= s->begin + s->length ||
+ block->target_end <= s->begin) {
+ /* This block is out of the range */
+ continue;
+ }
+
+ s->next_block = block;
+ if (s->begin > block->target_start) {
+ s->start = s->begin - block->target_start;
+ } else {
+ s->start = 0;
+ }
+ return s->start;
+ }
+
+ return -1;
+}
+
+static void get_max_mapnr(DumpState *s)
+{
+ GuestPhysBlock *last_block;
+
+ last_block = QTAILQ_LAST(&s->guest_phys_blocks.head);
+ s->max_mapnr = dump_paddr_to_pfn(s, last_block->target_end);
+}
+
+static DumpState dump_state_global = { .status = DUMP_STATUS_NONE };
+
+static void dump_state_prepare(DumpState *s)
+{
+ /* zero the struct, setting status to active */
+ *s = (DumpState) { .status = DUMP_STATUS_ACTIVE };
+}
+
+bool dump_in_progress(void)
+{
+ DumpState *state = &dump_state_global;
+ return (atomic_read(&state->status) == DUMP_STATUS_ACTIVE);
+}
+
+/* calculate total size of memory to be dumped (taking filter into
+ * acoount.) */
+static int64_t dump_calculate_size(DumpState *s)
+{
+ GuestPhysBlock *block;
+ int64_t size = 0, total = 0, left = 0, right = 0;
+
+ QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
+ if (s->has_filter) {
+ /* calculate the overlapped region. */
+ left = MAX(s->begin, block->target_start);
+ right = MIN(s->begin + s->length, block->target_end);
+ size = right - left;
+ size = size > 0 ? size : 0;
+ } else {
+ /* count the whole region in */
+ size = (block->target_end - block->target_start);
+ }
+ total += size;
+ }
+
+ return total;
+}
+
+static void vmcoreinfo_update_phys_base(DumpState *s)
+{
+ uint64_t size, note_head_size, name_size, phys_base;
+ char **lines;
+ uint8_t *vmci;
+ size_t i;
+
+ if (!note_name_equal(s, s->guest_note, "VMCOREINFO")) {
+ return;
+ }
+
+ get_note_sizes(s, s->guest_note, ¬e_head_size, &name_size, &size);
+ note_head_size = ROUND_UP(note_head_size, 4);
+
+ vmci = s->guest_note + note_head_size + ROUND_UP(name_size, 4);
+ *(vmci + size) = '\0';
+
+ lines = g_strsplit((char *)vmci, "\n", -1);
+ for (i = 0; lines[i]; i++) {
+ const char *prefix = NULL;
+
+ if (s->dump_info.d_machine == EM_X86_64) {
+ prefix = "NUMBER(phys_base)=";
+ } else if (s->dump_info.d_machine == EM_AARCH64) {
+ prefix = "NUMBER(PHYS_OFFSET)=";
+ }
+
+ if (prefix && g_str_has_prefix(lines[i], prefix)) {
+ if (qemu_strtou64(lines[i] + strlen(prefix), NULL, 16,
+ &phys_base) < 0) {
+ warn_report("Failed to read %s", prefix);
+ } else {
+ s->dump_info.phys_base = phys_base;
+ }
+ break;
+ }
+ }
+
+ g_strfreev(lines);
+}
+
+static void dump_init(DumpState *s, int fd, bool has_format,
+ DumpGuestMemoryFormat format, bool paging, bool has_filter,
+ int64_t begin, int64_t length, Error **errp)
+{
+ VMCoreInfoState *vmci = vmcoreinfo_find();
+ CPUState *cpu;
+ int nr_cpus;
+ Error *err = NULL;
+ int ret;
+
+ s->has_format = has_format;
+ s->format = format;
+ s->written_size = 0;
+
+ /* kdump-compressed is conflict with paging and filter */
+ if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
+ assert(!paging && !has_filter);
+ }
+
+ if (runstate_is_running()) {
+ vm_stop(RUN_STATE_SAVE_VM);
+ s->resume = true;
+ } else {
+ s->resume = false;
+ }
+
+ /* If we use KVM, we should synchronize the registers before we get dump
+ * info or physmap info.
+ */
+ cpu_synchronize_all_states();
+ nr_cpus = 0;
+ CPU_FOREACH(cpu) {
+ nr_cpus++;
+ }
+
+ s->fd = fd;
+ s->has_filter = has_filter;
+ s->begin = begin;
+ s->length = length;
+
+ memory_mapping_list_init(&s->list);
+
+ guest_phys_blocks_init(&s->guest_phys_blocks);
+ guest_phys_blocks_append(&s->guest_phys_blocks);
+ s->total_size = dump_calculate_size(s);
+#ifdef DEBUG_DUMP_GUEST_MEMORY
+ fprintf(stderr, "DUMP: total memory to dump: %lu\n", s->total_size);
+#endif
+
+ /* it does not make sense to dump non-existent memory */
+ if (!s->total_size) {
+ error_setg(errp, "dump: no guest memory to dump");
+ goto cleanup;
+ }
+
+ s->start = get_start_block(s);
+ if (s->start == -1) {
+ error_setg(errp, QERR_INVALID_PARAMETER, "begin");
+ goto cleanup;
+ }
+
+ /* get dump info: endian, class and architecture.
+ * If the target architecture is not supported, cpu_get_dump_info() will
+ * return -1.
+ */
+ ret = cpu_get_dump_info(&s->dump_info, &s->guest_phys_blocks);
+ if (ret < 0) {
+ error_setg(errp, QERR_UNSUPPORTED);
+ goto cleanup;
+ }
+
+ if (!s->dump_info.page_size) {
+ s->dump_info.page_size = TARGET_PAGE_SIZE;
+ }
+
+ s->note_size = cpu_get_note_size(s->dump_info.d_class,
+ s->dump_info.d_machine, nr_cpus);
+ if (s->note_size < 0) {
+ error_setg(errp, QERR_UNSUPPORTED);
+ goto cleanup;
+ }
+
+ /*
+ * The goal of this block is to (a) update the previously guessed
+ * phys_base, (b) copy the guest note out of the guest.
+ * Failure to do so is not fatal for dumping.
+ */
+ if (vmci) {
+ uint64_t addr, note_head_size, name_size, desc_size;
+ uint32_t size;
+ uint16_t format;
+
+ note_head_size = s->dump_info.d_class == ELFCLASS32 ?
+ sizeof(Elf32_Nhdr) : sizeof(Elf64_Nhdr);
+
+ format = le16_to_cpu(vmci->vmcoreinfo.guest_format);
+ size = le32_to_cpu(vmci->vmcoreinfo.size);
+ addr = le64_to_cpu(vmci->vmcoreinfo.paddr);
+ if (!vmci->has_vmcoreinfo) {
+ warn_report("guest note is not present");
+ } else if (size < note_head_size || size > MAX_GUEST_NOTE_SIZE) {
+ warn_report("guest note size is invalid: %" PRIu32, size);
+ } else if (format != FW_CFG_VMCOREINFO_FORMAT_ELF) {
+ warn_report("guest note format is unsupported: %" PRIu16, format);
+ } else {
+ s->guest_note = g_malloc(size + 1); /* +1 for adding \0 */
+ cpu_physical_memory_read(addr, s->guest_note, size);
+
+ get_note_sizes(s, s->guest_note, NULL, &name_size, &desc_size);
+ s->guest_note_size = ELF_NOTE_SIZE(note_head_size, name_size,
+ desc_size);
+ if (name_size > MAX_GUEST_NOTE_SIZE ||
+ desc_size > MAX_GUEST_NOTE_SIZE ||
+ s->guest_note_size > size) {
+ warn_report("Invalid guest note header");
+ g_free(s->guest_note);
+ s->guest_note = NULL;
+ } else {
+ vmcoreinfo_update_phys_base(s);
+ s->note_size += s->guest_note_size;
+ }
+ }
+ }
+
+ /* get memory mapping */
+ if (paging) {
+ qemu_get_guest_memory_mapping(&s->list, &s->guest_phys_blocks, &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ goto cleanup;
+ }
+ } else {
+ qemu_get_guest_simple_memory_mapping(&s->list, &s->guest_phys_blocks);
+ }
+
+ s->nr_cpus = nr_cpus;
+
+ get_max_mapnr(s);
+
+ uint64_t tmp;
+ tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT),
+ s->dump_info.page_size);
+ s->len_dump_bitmap = tmp * s->dump_info.page_size;
+
+ /* init for kdump-compressed format */
+ if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
+ switch (format) {
+ case DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB:
+ s->flag_compress = DUMP_DH_COMPRESSED_ZLIB;
+ break;
+
+ case DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO:
+#ifdef CONFIG_LZO
+ if (lzo_init() != LZO_E_OK) {
+ error_setg(errp, "failed to initialize the LZO library");
+ goto cleanup;
+ }
+#endif
+ s->flag_compress = DUMP_DH_COMPRESSED_LZO;
+ break;
+
+ case DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY:
+ s->flag_compress = DUMP_DH_COMPRESSED_SNAPPY;
+ break;
+
+ default:
+ s->flag_compress = 0;
+ }
+
+ return;
+ }
+
+ if (s->has_filter) {
+ memory_mapping_filter(&s->list, s->begin, s->length);
+ }
+
+ /*
+ * calculate phdr_num
+ *
+ * the type of ehdr->e_phnum is uint16_t, so we should avoid overflow
+ */
+ s->phdr_num = 1; /* PT_NOTE */
+ if (s->list.num < UINT16_MAX - 2) {
+ s->phdr_num += s->list.num;
+ s->have_section = false;
+ } else {
+ s->have_section = true;
+ s->phdr_num = PN_XNUM;
+ s->sh_info = 1; /* PT_NOTE */
+
+ /* the type of shdr->sh_info is uint32_t, so we should avoid overflow */
+ if (s->list.num <= UINT32_MAX - 1) {
+ s->sh_info += s->list.num;
+ } else {
+ s->sh_info = UINT32_MAX;
+ }
+ }
+
+ if (s->dump_info.d_class == ELFCLASS64) {
+ if (s->have_section) {
+ s->memory_offset = sizeof(Elf64_Ehdr) +
+ sizeof(Elf64_Phdr) * s->sh_info +
+ sizeof(Elf64_Shdr) + s->note_size;
+ } else {
+ s->memory_offset = sizeof(Elf64_Ehdr) +
+ sizeof(Elf64_Phdr) * s->phdr_num + s->note_size;
+ }
+ } else {
+ if (s->have_section) {
+ s->memory_offset = sizeof(Elf32_Ehdr) +
+ sizeof(Elf32_Phdr) * s->sh_info +
+ sizeof(Elf32_Shdr) + s->note_size;
+ } else {
+ s->memory_offset = sizeof(Elf32_Ehdr) +
+ sizeof(Elf32_Phdr) * s->phdr_num + s->note_size;
+ }
+ }
+
+ return;
+
+cleanup:
+ dump_cleanup(s);
+}
+
+/* this operation might be time consuming. */
+static void dump_process(DumpState *s, Error **errp)
+{
+ Error *local_err = NULL;
+ DumpQueryResult *result = NULL;
+
+ if (s->has_format && s->format == DUMP_GUEST_MEMORY_FORMAT_WIN_DMP) {
+#ifdef TARGET_X86_64
+ create_win_dump(s, &local_err);
+#endif
+ } else if (s->has_format && s->format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
+ create_kdump_vmcore(s, &local_err);
+ } else {
+ create_vmcore(s, &local_err);
+ }
+
+ /* make sure status is written after written_size updates */
+ smp_wmb();
+ atomic_set(&s->status,
+ (local_err ? DUMP_STATUS_FAILED : DUMP_STATUS_COMPLETED));
+
+ /* send DUMP_COMPLETED message (unconditionally) */
+ result = qmp_query_dump(NULL);
+ /* should never fail */
+ assert(result);
+ qapi_event_send_dump_completed(result, !!local_err, (local_err ? \
+ error_get_pretty(local_err) : NULL));
+ qapi_free_DumpQueryResult(result);
+
+ error_propagate(errp, local_err);
+ dump_cleanup(s);
+}
+
+static void *dump_thread(void *data)
+{
+ DumpState *s = (DumpState *)data;
+ dump_process(s, NULL);
+ return NULL;
+}
+
+DumpQueryResult *qmp_query_dump(Error **errp)
+{
+ DumpQueryResult *result = g_new(DumpQueryResult, 1);
+ DumpState *state = &dump_state_global;
+ result->status = atomic_read(&state->status);
+ /* make sure we are reading status and written_size in order */
+ smp_rmb();
+ result->completed = state->written_size;
+ result->total = state->total_size;
+ return result;
+}
+
+void qmp_dump_guest_memory(bool paging, const char *file,
+ bool has_detach, bool detach,
+ bool has_begin, int64_t begin, bool has_length,
+ int64_t length, bool has_format,
+ DumpGuestMemoryFormat format, Error **errp)
+{
+ const char *p;
+ int fd = -1;
+ DumpState *s;
+ Error *local_err = NULL;
+ bool detach_p = false;
+
+ if (runstate_check(RUN_STATE_INMIGRATE)) {
+ error_setg(errp, "Dump not allowed during incoming migration.");
+ return;
+ }
+
+ /* if there is a dump in background, we should wait until the dump
+ * finished */
+ if (dump_in_progress()) {
+ error_setg(errp, "There is a dump in process, please wait.");
+ return;
+ }
+
+ /*
+ * kdump-compressed format need the whole memory dumped, so paging or
+ * filter is not supported here.
+ */
+ if ((has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) &&
+ (paging || has_begin || has_length)) {
+ error_setg(errp, "kdump-compressed format doesn't support paging or "
+ "filter");
+ return;
+ }
+ if (has_begin && !has_length) {
+ error_setg(errp, QERR_MISSING_PARAMETER, "length");
+ return;
+ }
+ if (!has_begin && has_length) {
+ error_setg(errp, QERR_MISSING_PARAMETER, "begin");
+ return;
+ }
+ if (has_detach) {
+ detach_p = detach;
+ }
+
+ /* check whether lzo/snappy is supported */
+#ifndef CONFIG_LZO
+ if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO) {
+ error_setg(errp, "kdump-lzo is not available now");
+ return;
+ }
+#endif
+
+#ifndef CONFIG_SNAPPY
+ if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY) {
+ error_setg(errp, "kdump-snappy is not available now");
+ return;
+ }
+#endif
+
+#ifndef TARGET_X86_64
+ if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_WIN_DMP) {
+ error_setg(errp, "Windows dump is only available for x86-64");
+ return;
+ }
+#endif
+
+#if !defined(WIN32)
+ if (strstart(file, "fd:", &p)) {
+ fd = monitor_get_fd(cur_mon, p, errp);
+ if (fd == -1) {
+ return;
+ }
+ }
+#endif
+
+ if (strstart(file, "file:", &p)) {
+ fd = qemu_open(p, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR);
+ if (fd < 0) {
+ error_setg_file_open(errp, errno, p);
+ return;
+ }
+ }
+
+ if (fd == -1) {
+ error_setg(errp, QERR_INVALID_PARAMETER, "protocol");
+ return;
+ }
+
+ s = &dump_state_global;
+ dump_state_prepare(s);
+
+ dump_init(s, fd, has_format, format, paging, has_begin,
+ begin, length, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ atomic_set(&s->status, DUMP_STATUS_FAILED);
+ return;
+ }
+
+ if (detach_p) {
+ /* detached dump */
+ s->detached = true;
+ qemu_thread_create(&s->dump_thread, "dump_thread", dump_thread,
+ s, QEMU_THREAD_DETACHED);
+ } else {
+ /* sync dump */
+ dump_process(s, errp);
+ }
+}
+
+DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp)
+{
+ DumpGuestMemoryFormatList *item;
+ DumpGuestMemoryCapability *cap =
+ g_malloc0(sizeof(DumpGuestMemoryCapability));
+
+ /* elf is always available */
+ item = g_malloc0(sizeof(DumpGuestMemoryFormatList));
+ cap->formats = item;
+ item->value = DUMP_GUEST_MEMORY_FORMAT_ELF;
+
+ /* kdump-zlib is always available */
+ item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
+ item = item->next;
+ item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB;
+
+ /* add new item if kdump-lzo is available */
+#ifdef CONFIG_LZO
+ item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
+ item = item->next;
+ item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO;
+#endif
+
+ /* add new item if kdump-snappy is available */
+#ifdef CONFIG_SNAPPY
+ item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
+ item = item->next;
+ item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY;
+#endif
+
+ /* Windows dump is available only if target is x86_64 */
+#ifdef TARGET_X86_64
+ item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
+ item = item->next;
+ item->value = DUMP_GUEST_MEMORY_FORMAT_WIN_DMP;
+#endif
+
+ return cap;
+}
--- /dev/null
+/*
+ * Windows crashdump
+ *
+ * Copyright (c) 2018 Virtuozzo International GmbH
+ *
+ * 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-common.h"
+#include "qemu/cutils.h"
+#include "elf.h"
+#include "cpu.h"
+#include "exec/hwaddr.h"
+#include "monitor/monitor.h"
+#include "sysemu/kvm.h"
+#include "sysemu/dump.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/memory_mapping.h"
+#include "sysemu/cpus.h"
+#include "qapi/error.h"
+#include "qapi/qmp/qerror.h"
+#include "qemu/error-report.h"
+#include "hw/misc/vmcoreinfo.h"
+#include "win_dump.h"
+
+static size_t write_run(WinDumpPhyMemRun64 *run, int fd, Error **errp)
+{
+ void *buf;
+ uint64_t addr = run->BasePage << TARGET_PAGE_BITS;
+ uint64_t size = run->PageCount << TARGET_PAGE_BITS;
+ uint64_t len, l;
+ size_t total = 0;
+
+ while (size) {
+ len = size;
+
+ buf = cpu_physical_memory_map(addr, &len, false);
+ if (!buf) {
+ error_setg(errp, "win-dump: failed to map physical range"
+ " 0x%016" PRIx64 "-0x%016" PRIx64, addr, addr + size - 1);
+ return 0;
+ }
+
+ l = qemu_write_full(fd, buf, len);
+ cpu_physical_memory_unmap(buf, addr, false, len);
+ if (l != len) {
+ error_setg(errp, QERR_IO_ERROR);
+ return 0;
+ }
+
+ addr += l;
+ size -= l;
+ total += l;
+ }
+
+ return total;
+}
+
+static void write_runs(DumpState *s, WinDumpHeader64 *h, Error **errp)
+{
+ WinDumpPhyMemDesc64 *desc = &h->PhysicalMemoryBlock;
+ WinDumpPhyMemRun64 *run = desc->Run;
+ Error *local_err = NULL;
+ int i;
+
+ for (i = 0; i < desc->NumberOfRuns; i++) {
+ s->written_size += write_run(run + i, s->fd, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
+}
+
+static void patch_mm_pfn_database(WinDumpHeader64 *h, Error **errp)
+{
+ if (cpu_memory_rw_debug(first_cpu,
+ h->KdDebuggerDataBlock + KDBG_MM_PFN_DATABASE_OFFSET64,
+ (uint8_t *)&h->PfnDatabase, sizeof(h->PfnDatabase), 0)) {
+ error_setg(errp, "win-dump: failed to read MmPfnDatabase");
+ return;
+ }
+}
+
+static void patch_bugcheck_data(WinDumpHeader64 *h, Error **errp)
+{
+ uint64_t KiBugcheckData;
+
+ if (cpu_memory_rw_debug(first_cpu,
+ h->KdDebuggerDataBlock + KDBG_KI_BUGCHECK_DATA_OFFSET64,
+ (uint8_t *)&KiBugcheckData, sizeof(KiBugcheckData), 0)) {
+ error_setg(errp, "win-dump: failed to read KiBugcheckData");
+ return;
+ }
+
+ if (cpu_memory_rw_debug(first_cpu,
+ KiBugcheckData,
+ h->BugcheckData, sizeof(h->BugcheckData), 0)) {
+ error_setg(errp, "win-dump: failed to read bugcheck data");
+ return;
+ }
+
+ /*
+ * If BugcheckCode wasn't saved, we consider guest OS as alive.
+ */
+
+ if (!h->BugcheckCode) {
+ h->BugcheckCode = LIVE_SYSTEM_DUMP;
+ }
+}
+
+/*
+ * This routine tries to correct mistakes in crashdump header.
+ */
+static void patch_header(WinDumpHeader64 *h)
+{
+ Error *local_err = NULL;
+
+ h->RequiredDumpSpace = sizeof(WinDumpHeader64) +
+ (h->PhysicalMemoryBlock.NumberOfPages << TARGET_PAGE_BITS);
+ h->PhysicalMemoryBlock.unused = 0;
+ h->unused1 = 0;
+
+ patch_mm_pfn_database(h, &local_err);
+ if (local_err) {
+ warn_report_err(local_err);
+ local_err = NULL;
+ }
+ patch_bugcheck_data(h, &local_err);
+ if (local_err) {
+ warn_report_err(local_err);
+ }
+}
+
+static void check_header(WinDumpHeader64 *h, Error **errp)
+{
+ const char Signature[] = "PAGE";
+ const char ValidDump[] = "DU64";
+
+ if (memcmp(h->Signature, Signature, sizeof(h->Signature))) {
+ error_setg(errp, "win-dump: invalid header, expected '%.4s',"
+ " got '%.4s'", Signature, h->Signature);
+ return;
+ }
+
+ if (memcmp(h->ValidDump, ValidDump, sizeof(h->ValidDump))) {
+ error_setg(errp, "win-dump: invalid header, expected '%.4s',"
+ " got '%.4s'", ValidDump, h->ValidDump);
+ return;
+ }
+}
+
+static void check_kdbg(WinDumpHeader64 *h, Error **errp)
+{
+ const char OwnerTag[] = "KDBG";
+ char read_OwnerTag[4];
+ uint64_t KdDebuggerDataBlock = h->KdDebuggerDataBlock;
+ bool try_fallback = true;
+
+try_again:
+ if (cpu_memory_rw_debug(first_cpu,
+ KdDebuggerDataBlock + KDBG_OWNER_TAG_OFFSET64,
+ (uint8_t *)&read_OwnerTag, sizeof(read_OwnerTag), 0)) {
+ error_setg(errp, "win-dump: failed to read OwnerTag");
+ return;
+ }
+
+ if (memcmp(read_OwnerTag, OwnerTag, sizeof(read_OwnerTag))) {
+ if (try_fallback) {
+ /*
+ * If attempt to use original KDBG failed
+ * (most likely because of its encryption),
+ * we try to use KDBG obtained by guest driver.
+ */
+
+ KdDebuggerDataBlock = h->BugcheckParameter1;
+ try_fallback = false;
+ goto try_again;
+ } else {
+ error_setg(errp, "win-dump: invalid KDBG OwnerTag,"
+ " expected '%.4s', got '%.4s'",
+ OwnerTag, read_OwnerTag);
+ return;
+ }
+ }
+
+ h->KdDebuggerDataBlock = KdDebuggerDataBlock;
+}
+
+struct saved_context {
+ WinContext ctx;
+ uint64_t addr;
+};
+
+static void patch_and_save_context(WinDumpHeader64 *h,
+ struct saved_context *saved_ctx,
+ Error **errp)
+{
+ uint64_t KiProcessorBlock;
+ uint16_t OffsetPrcbContext;
+ CPUState *cpu;
+ int i = 0;
+
+ if (cpu_memory_rw_debug(first_cpu,
+ h->KdDebuggerDataBlock + KDBG_KI_PROCESSOR_BLOCK_OFFSET64,
+ (uint8_t *)&KiProcessorBlock, sizeof(KiProcessorBlock), 0)) {
+ error_setg(errp, "win-dump: failed to read KiProcessorBlock");
+ return;
+ }
+
+ if (cpu_memory_rw_debug(first_cpu,
+ h->KdDebuggerDataBlock + KDBG_OFFSET_PRCB_CONTEXT_OFFSET64,
+ (uint8_t *)&OffsetPrcbContext, sizeof(OffsetPrcbContext), 0)) {
+ error_setg(errp, "win-dump: failed to read OffsetPrcbContext");
+ return;
+ }
+
+ CPU_FOREACH(cpu) {
+ X86CPU *x86_cpu = X86_CPU(cpu);
+ CPUX86State *env = &x86_cpu->env;
+ uint64_t Prcb;
+ uint64_t Context;
+ WinContext ctx;
+
+ if (cpu_memory_rw_debug(first_cpu,
+ KiProcessorBlock + i * sizeof(uint64_t),
+ (uint8_t *)&Prcb, sizeof(Prcb), 0)) {
+ error_setg(errp, "win-dump: failed to read"
+ " CPU #%d PRCB location", i);
+ return;
+ }
+
+ if (cpu_memory_rw_debug(first_cpu,
+ Prcb + OffsetPrcbContext,
+ (uint8_t *)&Context, sizeof(Context), 0)) {
+ error_setg(errp, "win-dump: failed to read"
+ " CPU #%d ContextFrame location", i);
+ return;
+ }
+
+ saved_ctx[i].addr = Context;
+
+ ctx = (WinContext){
+ .ContextFlags = WIN_CTX_ALL,
+ .MxCsr = env->mxcsr,
+
+ .SegEs = env->segs[0].selector,
+ .SegCs = env->segs[1].selector,
+ .SegSs = env->segs[2].selector,
+ .SegDs = env->segs[3].selector,
+ .SegFs = env->segs[4].selector,
+ .SegGs = env->segs[5].selector,
+ .EFlags = cpu_compute_eflags(env),
+
+ .Dr0 = env->dr[0],
+ .Dr1 = env->dr[1],
+ .Dr2 = env->dr[2],
+ .Dr3 = env->dr[3],
+ .Dr6 = env->dr[6],
+ .Dr7 = env->dr[7],
+
+ .Rax = env->regs[R_EAX],
+ .Rbx = env->regs[R_EBX],
+ .Rcx = env->regs[R_ECX],
+ .Rdx = env->regs[R_EDX],
+ .Rsp = env->regs[R_ESP],
+ .Rbp = env->regs[R_EBP],
+ .Rsi = env->regs[R_ESI],
+ .Rdi = env->regs[R_EDI],
+ .R8 = env->regs[8],
+ .R9 = env->regs[9],
+ .R10 = env->regs[10],
+ .R11 = env->regs[11],
+ .R12 = env->regs[12],
+ .R13 = env->regs[13],
+ .R14 = env->regs[14],
+ .R15 = env->regs[15],
+
+ .Rip = env->eip,
+ .FltSave = {
+ .MxCsr = env->mxcsr,
+ },
+ };
+
+ if (cpu_memory_rw_debug(first_cpu, Context,
+ (uint8_t *)&saved_ctx[i].ctx, sizeof(WinContext), 0)) {
+ error_setg(errp, "win-dump: failed to save CPU #%d context", i);
+ return;
+ }
+
+ if (cpu_memory_rw_debug(first_cpu, Context,
+ (uint8_t *)&ctx, sizeof(WinContext), 1)) {
+ error_setg(errp, "win-dump: failed to write CPU #%d context", i);
+ return;
+ }
+
+ i++;
+ }
+}
+
+static void restore_context(WinDumpHeader64 *h,
+ struct saved_context *saved_ctx)
+{
+ int i;
+ Error *err = NULL;
+
+ for (i = 0; i < h->NumberProcessors; i++) {
+ if (cpu_memory_rw_debug(first_cpu, saved_ctx[i].addr,
+ (uint8_t *)&saved_ctx[i].ctx, sizeof(WinContext), 1)) {
+ error_setg(&err, "win-dump: failed to restore CPU #%d context", i);
+ warn_report_err(err);
+ }
+ }
+}
+
+void create_win_dump(DumpState *s, Error **errp)
+{
+ WinDumpHeader64 *h = (WinDumpHeader64 *)(s->guest_note +
+ VMCOREINFO_ELF_NOTE_HDR_SIZE);
+ X86CPU *first_x86_cpu = X86_CPU(first_cpu);
+ uint64_t saved_cr3 = first_x86_cpu->env.cr[3];
+ struct saved_context *saved_ctx = NULL;
+ Error *local_err = NULL;
+
+ if (s->guest_note_size != sizeof(WinDumpHeader64) +
+ VMCOREINFO_ELF_NOTE_HDR_SIZE) {
+ error_setg(errp, "win-dump: invalid vmcoreinfo note size");
+ return;
+ }
+
+ check_header(h, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /*
+ * Further access to kernel structures by virtual addresses
+ * should be made from system context.
+ */
+
+ first_x86_cpu->env.cr[3] = h->DirectoryTableBase;
+
+ check_kdbg(h, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ goto out_cr3;
+ }
+
+ patch_header(h);
+
+ saved_ctx = g_new(struct saved_context, h->NumberProcessors);
+
+ /*
+ * Always patch context because there is no way
+ * to determine if the system-saved context is valid
+ */
+
+ patch_and_save_context(h, saved_ctx, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ goto out_free;
+ }
+
+ s->total_size = h->RequiredDumpSpace;
+
+ s->written_size = qemu_write_full(s->fd, h, sizeof(*h));
+ if (s->written_size != sizeof(*h)) {
+ error_setg(errp, QERR_IO_ERROR);
+ goto out_restore;
+ }
+
+ write_runs(s, h, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ goto out_restore;
+ }
+
+out_restore:
+ restore_context(h, saved_ctx);
+out_free:
+ g_free(saved_ctx);
+out_cr3:
+ first_x86_cpu->env.cr[3] = saved_cr3;
+
+ return;
+}
--- /dev/null
+/*
+ * Windows crashdump
+ *
+ * Copyright (c) 2018 Virtuozzo International GmbH
+ *
+ * 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 WIN_DUMP_H
+#define WIN_DUMP_H
+
+#include "qemu/win_dump_defs.h"
+
+void create_win_dump(DumpState *s, Error **errp);
+
+#endif /* WIN_DUMP_H */
{
.name = "announce_self",
- .args_type = "",
- .params = "",
+ .args_type = "interfaces:s?,id:s?",
+ .params = "[interfaces] [id]",
.help = "Trigger GARP/RARP announcements",
.cmd = hmp_announce_self,
},
Trigger a round of GARP/RARP broadcasts; this is useful for explicitly updating the
network infrastructure after a reconfiguration or some forms of migration.
The timings of the round are set by the migration announce parameters.
+An optional comma separated @var{interfaces} list restricts the announce to the
+named set of interfaces. An optional @var{id} can be used to start a separate announce
+timer and to change the parameters of it later.
ETEXI
{
+++ /dev/null
-/*
- * Human Monitor Interface
- *
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef HMP_H
-#define HMP_H
-
-#include "qemu/readline.h"
-
-void hmp_info_name(Monitor *mon, const QDict *qdict);
-void hmp_info_version(Monitor *mon, const QDict *qdict);
-void hmp_info_kvm(Monitor *mon, const QDict *qdict);
-void hmp_info_status(Monitor *mon, const QDict *qdict);
-void hmp_info_uuid(Monitor *mon, const QDict *qdict);
-void hmp_info_chardev(Monitor *mon, const QDict *qdict);
-void hmp_info_mice(Monitor *mon, const QDict *qdict);
-void hmp_info_migrate(Monitor *mon, const QDict *qdict);
-void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict);
-void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict);
-void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict);
-void hmp_info_cpus(Monitor *mon, const QDict *qdict);
-void hmp_info_block(Monitor *mon, const QDict *qdict);
-void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
-void hmp_info_vnc(Monitor *mon, const QDict *qdict);
-void hmp_info_spice(Monitor *mon, const QDict *qdict);
-void hmp_info_balloon(Monitor *mon, const QDict *qdict);
-void hmp_info_irq(Monitor *mon, const QDict *qdict);
-void hmp_info_pic(Monitor *mon, const QDict *qdict);
-void hmp_info_rdma(Monitor *mon, const QDict *qdict);
-void hmp_info_pci(Monitor *mon, const QDict *qdict);
-void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
-void hmp_info_tpm(Monitor *mon, const QDict *qdict);
-void hmp_info_iothreads(Monitor *mon, const QDict *qdict);
-void hmp_quit(Monitor *mon, const QDict *qdict);
-void hmp_stop(Monitor *mon, const QDict *qdict);
-void hmp_sync_profile(Monitor *mon, const QDict *qdict);
-void hmp_system_reset(Monitor *mon, const QDict *qdict);
-void hmp_system_powerdown(Monitor *mon, const QDict *qdict);
-void hmp_exit_preconfig(Monitor *mon, const QDict *qdict);
-void hmp_announce_self(Monitor *mon, const QDict *qdict);
-void hmp_cpu(Monitor *mon, const QDict *qdict);
-void hmp_memsave(Monitor *mon, const QDict *qdict);
-void hmp_pmemsave(Monitor *mon, const QDict *qdict);
-void hmp_ringbuf_write(Monitor *mon, const QDict *qdict);
-void hmp_ringbuf_read(Monitor *mon, const QDict *qdict);
-void hmp_cont(Monitor *mon, const QDict *qdict);
-void hmp_system_wakeup(Monitor *mon, const QDict *qdict);
-void hmp_nmi(Monitor *mon, const QDict *qdict);
-void hmp_set_link(Monitor *mon, const QDict *qdict);
-void hmp_block_passwd(Monitor *mon, const QDict *qdict);
-void hmp_balloon(Monitor *mon, const QDict *qdict);
-void hmp_block_resize(Monitor *mon, const QDict *qdict);
-void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict);
-void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict);
-void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict);
-void hmp_drive_mirror(Monitor *mon, const QDict *qdict);
-void hmp_drive_backup(Monitor *mon, const QDict *qdict);
-void hmp_loadvm(Monitor *mon, const QDict *qdict);
-void hmp_savevm(Monitor *mon, const QDict *qdict);
-void hmp_delvm(Monitor *mon, const QDict *qdict);
-void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
-void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
-void hmp_migrate_continue(Monitor *mon, const QDict *qdict);
-void hmp_migrate_incoming(Monitor *mon, const QDict *qdict);
-void hmp_migrate_recover(Monitor *mon, const QDict *qdict);
-void hmp_migrate_pause(Monitor *mon, const QDict *qdict);
-void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict);
-void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict);
-void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict);
-void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict);
-void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict);
-void hmp_client_migrate_info(Monitor *mon, const QDict *qdict);
-void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict);
-void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict);
-void hmp_set_password(Monitor *mon, const QDict *qdict);
-void hmp_expire_password(Monitor *mon, const QDict *qdict);
-void hmp_eject(Monitor *mon, const QDict *qdict);
-void hmp_change(Monitor *mon, const QDict *qdict);
-void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict);
-void hmp_block_stream(Monitor *mon, const QDict *qdict);
-void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
-void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
-void hmp_block_job_pause(Monitor *mon, const QDict *qdict);
-void hmp_block_job_resume(Monitor *mon, const QDict *qdict);
-void hmp_block_job_complete(Monitor *mon, const QDict *qdict);
-void hmp_migrate(Monitor *mon, const QDict *qdict);
-void hmp_device_add(Monitor *mon, const QDict *qdict);
-void hmp_device_del(Monitor *mon, const QDict *qdict);
-void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict);
-void hmp_netdev_add(Monitor *mon, const QDict *qdict);
-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 hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
-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_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);
-void hmp_chardev_send_break(Monitor *mon, const QDict *qdict);
-void hmp_qemu_io(Monitor *mon, const QDict *qdict);
-void hmp_cpu_add(Monitor *mon, const QDict *qdict);
-void hmp_object_add(Monitor *mon, const QDict *qdict);
-void hmp_object_del(Monitor *mon, const QDict *qdict);
-void hmp_info_memdev(Monitor *mon, const QDict *qdict);
-void hmp_info_memory_devices(Monitor *mon, const QDict *qdict);
-void hmp_qom_list(Monitor *mon, const QDict *qdict);
-void hmp_qom_set(Monitor *mon, const QDict *qdict);
-void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
-void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
-void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
-void device_del_completion(ReadLineState *rs, int nb_args, const char *str);
-void sendkey_completion(ReadLineState *rs, int nb_args, const char *str);
-void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str);
-void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str);
-void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
-void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
-void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
-void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str);
-void info_trace_events_completion(ReadLineState *rs, int nb_args, const char *str);
-void trace_event_completion(ReadLineState *rs, int nb_args, const char *str);
-void watchdog_action_completion(ReadLineState *rs, int nb_args,
- const char *str);
-void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
- const char *str);
-void migrate_set_parameter_completion(ReadLineState *rs, int nb_args,
- const char *str);
-void delvm_completion(ReadLineState *rs, int nb_args, const char *str);
-void loadvm_completion(ReadLineState *rs, int nb_args, const char *str);
-void hmp_rocker(Monitor *mon, const QDict *qdict);
-void hmp_rocker_ports(Monitor *mon, const QDict *qdict);
-void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict);
-void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict);
-void hmp_info_dump(Monitor *mon, const QDict *qdict);
-void hmp_info_ramblock(Monitor *mon, const QDict *qdict);
-void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict);
-void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict);
-void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict);
-void hmp_info_sev(Monitor *mon, const QDict *qdict);
-
-#endif
#ifndef HW_9PFS_XEN_9PFS_H
#define HW_9PFS_XEN_9PFS_H
-#include <xen/io/protocols.h>
-#include "hw/xen/io/ring.h"
+#include "hw/xen/interface/io/protocols.h"
+#include "hw/xen/interface/io/ring.h"
/*
* Do not merge into xen-9p-backend.c: clang doesn't allow unused static
select DS1338 # I2C RTC+NVRAM
select USB_OHCI
+config SBSA_REF
+ bool
+ imply PCI_DEVICES
+ select AHCI
+ select ARM_SMMUV3
+ select GPIO_KEY
+ select PCI_EXPRESS
+ select PCI_EXPRESS_GENERIC_BRIDGE
+ select PFLASH_CFI01
+ select PL011 # UART
+ select PL031 # RTC
+ select PL061 # GPIO
+ select USB_EHCI_SYSBUS
+
config SABRELITE
bool
select FSL_IMX6
obj-$(CONFIG_TOSA) += tosa.o
obj-$(CONFIG_Z2) += z2.o
obj-$(CONFIG_REALVIEW) += realview.o
+obj-$(CONFIG_SBSA_REF) += sbsa-ref.o
obj-$(CONFIG_STELLARIS) += stellaris.o
obj-$(CONFIG_COLLIE) += collie.o
obj-$(CONFIG_VERSATILE) += versatilepb.o
#include "hw/misc/tmp105.h"
#include "qemu/log.h"
#include "sysemu/block-backend.h"
+#include "sysemu/sysemu.h"
#include "hw/loader.h"
#include "qemu/error-report.h"
#include "qemu/units.h"
static struct arm_boot_info aspeed_board_binfo = {
.board_id = -1, /* device-tree-only board */
- .nb_cpus = 1,
};
struct AspeedBoardState {
AspeedSoCState soc;
+ MemoryRegion ram_container;
MemoryRegion ram;
MemoryRegion max_ram;
};
SCU_AST2500_HW_STRAP_ACPI_ENABLE | \
SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER))
+/* Swift hardware value: 0xF11AD206 */
+#define SWIFT_BMC_HW_STRAP1 ( \
+ AST2500_HW_STRAP1_DEFAULTS | \
+ SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \
+ SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE | \
+ SCU_AST2500_HW_STRAP_UART_DEBUG | \
+ SCU_AST2500_HW_STRAP_DDR4_ENABLE | \
+ SCU_H_PLL_BYPASS_EN | \
+ SCU_AST2500_HW_STRAP_ACPI_ENABLE | \
+ SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER))
+
/* Witherspoon hardware value: 0xF10AD216 (but use romulus definition) */
#define WITHERSPOON_BMC_HW_STRAP1 ROMULUS_BMC_HW_STRAP1
ram_addr_t max_ram_size;
bmc = g_new0(AspeedBoardState, 1);
+
+ memory_region_init(&bmc->ram_container, NULL, "aspeed-ram-container",
+ UINT32_MAX);
+
object_initialize_child(OBJECT(machine), "soc", &bmc->soc,
(sizeof(bmc->soc)), cfg->soc_name, &error_abort,
NULL);
&error_abort);
object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs",
&error_abort);
+ object_property_set_int(OBJECT(&bmc->soc), smp_cpus, "num-cpus",
+ &error_abort);
if (machine->kernel_filename) {
/*
* When booting with a -kernel command line there is no u-boot
&error_abort);
memory_region_allocate_system_memory(&bmc->ram, NULL, "ram", ram_size);
- memory_region_add_subregion(get_system_memory(), sc->info->sdram_base,
- &bmc->ram);
- object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram),
- &error_abort);
+ memory_region_add_subregion(&bmc->ram_container, 0, &bmc->ram);
+ memory_region_add_subregion(get_system_memory(),
+ sc->info->memmap[ASPEED_SDRAM],
+ &bmc->ram_container);
max_ram_size = object_property_get_uint(OBJECT(&bmc->soc), "max-ram-size",
&error_abort);
memory_region_init_io(&bmc->max_ram, NULL, &max_ram_ops, NULL,
"max_ram", max_ram_size - ram_size);
- memory_region_add_subregion(get_system_memory(),
- sc->info->sdram_base + ram_size,
- &bmc->max_ram);
+ memory_region_add_subregion(&bmc->ram_container, ram_size, &bmc->max_ram);
aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort);
aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort);
aspeed_board_binfo.initrd_filename = machine->initrd_filename;
aspeed_board_binfo.kernel_cmdline = machine->kernel_cmdline;
aspeed_board_binfo.ram_size = ram_size;
- aspeed_board_binfo.loader_start = sc->info->sdram_base;
+ aspeed_board_binfo.loader_start = sc->info->memmap[ASPEED_SDRAM];
+ aspeed_board_binfo.nb_cpus = bmc->soc.num_cpus;
if (cfg->i2c_init) {
cfg->i2c_init(bmc);
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 0x32);
}
+static void swift_bmc_i2c_init(AspeedBoardState *bmc)
+{
+ AspeedSoCState *soc = &bmc->soc;
+
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60);
+
+ /* The swift board expects a TMP275 but a TMP105 is compatible */
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x48);
+ /* The swift board expects a pca9551 but a pca9552 is compatible */
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "pca9552", 0x60);
+
+ /* The swift board expects an Epson RX8900 RTC but a ds1338 is compatible */
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 8), "ds1338", 0x32);
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 8), "pca9552", 0x60);
+
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp423", 0x4c);
+ /* The swift board expects a pca9539 but a pca9552 is compatible */
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "pca9552", 0x74);
+
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 10), "tmp423", 0x4c);
+ /* The swift board expects a pca9539 but a pca9552 is compatible */
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 10), "pca9552",
+ 0x74);
+
+ /* The swift board expects a TMP275 but a TMP105 is compatible */
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 12), "tmp105", 0x48);
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 12), "tmp105", 0x4a);
+}
+
static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
{
AspeedSoCState *soc = &bmc->soc;
mc->desc = board->desc;
mc->init = aspeed_machine_init;
- mc->max_cpus = 1;
+ mc->max_cpus = ASPEED_CPUS_NUM;
mc->no_sdcard = 1;
mc->no_floppy = 1;
mc->no_cdrom = 1;
.num_cs = 2,
.i2c_init = romulus_bmc_i2c_init,
.ram = 512 * MiB,
+ }, {
+ .name = MACHINE_TYPE_NAME("swift-bmc"),
+ .desc = "OpenPOWER Swift BMC (ARM1176)",
+ .soc_name = "ast2500-a1",
+ .hw_strap1 = SWIFT_BMC_HW_STRAP1,
+ .fmc_model = "mx66l1g45g",
+ .spi_model = "mx66l1g45g",
+ .num_cs = 2,
+ .i2c_init = swift_bmc_i2c_init,
+ .ram = 512 * MiB,
}, {
.name = MACHINE_TYPE_NAME("witherspoon-bmc"),
.desc = "OpenPOWER Witherspoon BMC (ARM1176)",
#include "hw/char/serial.h"
#include "qemu/log.h"
#include "qemu/module.h"
+#include "qemu/error-report.h"
#include "hw/i2c/aspeed_i2c.h"
#include "net/net.h"
-#define ASPEED_SOC_UART_5_BASE 0x00184000
#define ASPEED_SOC_IOMEM_SIZE 0x00200000
-#define ASPEED_SOC_IOMEM_BASE 0x1E600000
-#define ASPEED_SOC_FMC_BASE 0x1E620000
-#define ASPEED_SOC_SPI_BASE 0x1E630000
-#define ASPEED_SOC_SPI2_BASE 0x1E631000
-#define ASPEED_SOC_VIC_BASE 0x1E6C0000
-#define ASPEED_SOC_SDMC_BASE 0x1E6E0000
-#define ASPEED_SOC_SCU_BASE 0x1E6E2000
-#define ASPEED_SOC_SRAM_BASE 0x1E720000
-#define ASPEED_SOC_TIMER_BASE 0x1E782000
-#define ASPEED_SOC_WDT_BASE 0x1E785000
-#define ASPEED_SOC_I2C_BASE 0x1E78A000
-#define ASPEED_SOC_ETH1_BASE 0x1E660000
-#define ASPEED_SOC_ETH2_BASE 0x1E680000
-
-static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
-static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
-
-#define AST2400_SDRAM_BASE 0x40000000
-#define AST2500_SDRAM_BASE 0x80000000
-
-static const hwaddr aspeed_soc_ast2400_spi_bases[] = { ASPEED_SOC_SPI_BASE };
-static const char *aspeed_soc_ast2400_typenames[] = { "aspeed.smc.spi" };
-static const hwaddr aspeed_soc_ast2500_spi_bases[] = { ASPEED_SOC_SPI_BASE,
- ASPEED_SOC_SPI2_BASE};
+static const hwaddr aspeed_soc_ast2400_memmap[] = {
+ [ASPEED_IOMEM] = 0x1E600000,
+ [ASPEED_FMC] = 0x1E620000,
+ [ASPEED_SPI1] = 0x1E630000,
+ [ASPEED_VIC] = 0x1E6C0000,
+ [ASPEED_SDMC] = 0x1E6E0000,
+ [ASPEED_SCU] = 0x1E6E2000,
+ [ASPEED_XDMA] = 0x1E6E7000,
+ [ASPEED_ADC] = 0x1E6E9000,
+ [ASPEED_SRAM] = 0x1E720000,
+ [ASPEED_GPIO] = 0x1E780000,
+ [ASPEED_RTC] = 0x1E781000,
+ [ASPEED_TIMER1] = 0x1E782000,
+ [ASPEED_WDT] = 0x1E785000,
+ [ASPEED_PWM] = 0x1E786000,
+ [ASPEED_LPC] = 0x1E789000,
+ [ASPEED_IBT] = 0x1E789140,
+ [ASPEED_I2C] = 0x1E78A000,
+ [ASPEED_ETH1] = 0x1E660000,
+ [ASPEED_ETH2] = 0x1E680000,
+ [ASPEED_UART1] = 0x1E783000,
+ [ASPEED_UART5] = 0x1E784000,
+ [ASPEED_VUART] = 0x1E787000,
+ [ASPEED_SDRAM] = 0x40000000,
+};
+
+static const hwaddr aspeed_soc_ast2500_memmap[] = {
+ [ASPEED_IOMEM] = 0x1E600000,
+ [ASPEED_FMC] = 0x1E620000,
+ [ASPEED_SPI1] = 0x1E630000,
+ [ASPEED_SPI2] = 0x1E631000,
+ [ASPEED_VIC] = 0x1E6C0000,
+ [ASPEED_SDMC] = 0x1E6E0000,
+ [ASPEED_SCU] = 0x1E6E2000,
+ [ASPEED_XDMA] = 0x1E6E7000,
+ [ASPEED_ADC] = 0x1E6E9000,
+ [ASPEED_SRAM] = 0x1E720000,
+ [ASPEED_GPIO] = 0x1E780000,
+ [ASPEED_RTC] = 0x1E781000,
+ [ASPEED_TIMER1] = 0x1E782000,
+ [ASPEED_WDT] = 0x1E785000,
+ [ASPEED_PWM] = 0x1E786000,
+ [ASPEED_LPC] = 0x1E789000,
+ [ASPEED_IBT] = 0x1E789140,
+ [ASPEED_I2C] = 0x1E78A000,
+ [ASPEED_ETH1] = 0x1E660000,
+ [ASPEED_ETH2] = 0x1E680000,
+ [ASPEED_UART1] = 0x1E783000,
+ [ASPEED_UART5] = 0x1E784000,
+ [ASPEED_VUART] = 0x1E787000,
+ [ASPEED_SDRAM] = 0x80000000,
+};
+
+static const int aspeed_soc_ast2400_irqmap[] = {
+ [ASPEED_UART1] = 9,
+ [ASPEED_UART2] = 32,
+ [ASPEED_UART3] = 33,
+ [ASPEED_UART4] = 34,
+ [ASPEED_UART5] = 10,
+ [ASPEED_VUART] = 8,
+ [ASPEED_FMC] = 19,
+ [ASPEED_SDMC] = 0,
+ [ASPEED_SCU] = 21,
+ [ASPEED_ADC] = 31,
+ [ASPEED_GPIO] = 20,
+ [ASPEED_RTC] = 22,
+ [ASPEED_TIMER1] = 16,
+ [ASPEED_TIMER2] = 17,
+ [ASPEED_TIMER3] = 18,
+ [ASPEED_TIMER4] = 35,
+ [ASPEED_TIMER5] = 36,
+ [ASPEED_TIMER6] = 37,
+ [ASPEED_TIMER7] = 38,
+ [ASPEED_TIMER8] = 39,
+ [ASPEED_WDT] = 27,
+ [ASPEED_PWM] = 28,
+ [ASPEED_LPC] = 8,
+ [ASPEED_IBT] = 8, /* LPC */
+ [ASPEED_I2C] = 12,
+ [ASPEED_ETH1] = 2,
+ [ASPEED_ETH2] = 3,
+ [ASPEED_XDMA] = 6,
+};
+
+#define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
+
+static const char *aspeed_soc_ast2400_typenames[] = { "aspeed.smc.spi" };
static const char *aspeed_soc_ast2500_typenames[] = {
"aspeed.smc.ast2500-spi1", "aspeed.smc.ast2500-spi2" };
.name = "ast2400-a0",
.cpu_type = ARM_CPU_TYPE_NAME("arm926"),
.silicon_rev = AST2400_A0_SILICON_REV,
- .sdram_base = AST2400_SDRAM_BASE,
.sram_size = 0x8000,
.spis_num = 1,
- .spi_bases = aspeed_soc_ast2400_spi_bases,
.fmc_typename = "aspeed.smc.fmc",
.spi_typename = aspeed_soc_ast2400_typenames,
.wdts_num = 2,
+ .irqmap = aspeed_soc_ast2400_irqmap,
+ .memmap = aspeed_soc_ast2400_memmap,
+ .num_cpus = 1,
}, {
.name = "ast2400-a1",
.cpu_type = ARM_CPU_TYPE_NAME("arm926"),
.silicon_rev = AST2400_A1_SILICON_REV,
- .sdram_base = AST2400_SDRAM_BASE,
.sram_size = 0x8000,
.spis_num = 1,
- .spi_bases = aspeed_soc_ast2400_spi_bases,
.fmc_typename = "aspeed.smc.fmc",
.spi_typename = aspeed_soc_ast2400_typenames,
.wdts_num = 2,
+ .irqmap = aspeed_soc_ast2400_irqmap,
+ .memmap = aspeed_soc_ast2400_memmap,
+ .num_cpus = 1,
}, {
.name = "ast2400",
.cpu_type = ARM_CPU_TYPE_NAME("arm926"),
.silicon_rev = AST2400_A0_SILICON_REV,
- .sdram_base = AST2400_SDRAM_BASE,
.sram_size = 0x8000,
.spis_num = 1,
- .spi_bases = aspeed_soc_ast2400_spi_bases,
.fmc_typename = "aspeed.smc.fmc",
.spi_typename = aspeed_soc_ast2400_typenames,
.wdts_num = 2,
+ .irqmap = aspeed_soc_ast2400_irqmap,
+ .memmap = aspeed_soc_ast2400_memmap,
+ .num_cpus = 1,
}, {
.name = "ast2500-a1",
.cpu_type = ARM_CPU_TYPE_NAME("arm1176"),
.silicon_rev = AST2500_A1_SILICON_REV,
- .sdram_base = AST2500_SDRAM_BASE,
.sram_size = 0x9000,
.spis_num = 2,
- .spi_bases = aspeed_soc_ast2500_spi_bases,
.fmc_typename = "aspeed.smc.ast2500-fmc",
.spi_typename = aspeed_soc_ast2500_typenames,
.wdts_num = 3,
+ .irqmap = aspeed_soc_ast2500_irqmap,
+ .memmap = aspeed_soc_ast2500_memmap,
+ .num_cpus = 1,
},
};
+static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
+{
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+
+ return qdev_get_gpio_in(DEVICE(&s->vic), sc->info->irqmap[ctrl]);
+}
+
static void aspeed_soc_init(Object *obj)
{
AspeedSoCState *s = ASPEED_SOC(obj);
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
int i;
- object_initialize_child(obj, "cpu", OBJECT(&s->cpu), sizeof(s->cpu),
- sc->info->cpu_type, &error_abort, NULL);
+ for (i = 0; i < sc->info->num_cpus; i++) {
+ object_initialize_child(obj, "cpu[*]", OBJECT(&s->cpu[i]),
+ sizeof(s->cpu[i]), sc->info->cpu_type,
+ &error_abort, NULL);
+ }
sysbus_init_child_obj(obj, "scu", OBJECT(&s->scu), sizeof(s->scu),
TYPE_ASPEED_SCU);
sysbus_init_child_obj(obj, "vic", OBJECT(&s->vic), sizeof(s->vic),
TYPE_ASPEED_VIC);
+ sysbus_init_child_obj(obj, "rtc", OBJECT(&s->rtc), sizeof(s->rtc),
+ TYPE_ASPEED_RTC);
+
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
sizeof(s->wdt[i]), TYPE_ASPEED_WDT);
qdev_prop_set_uint32(DEVICE(&s->wdt[i]), "silicon-rev",
sc->info->silicon_rev);
+ object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
+ OBJECT(&s->scu), &error_abort);
}
- sysbus_init_child_obj(obj, "ftgmac100", OBJECT(&s->ftgmac100),
- sizeof(s->ftgmac100), TYPE_FTGMAC100);
+ for (i = 0; i < ASPEED_MACS_NUM; i++) {
+ sysbus_init_child_obj(obj, "ftgmac100[*]", OBJECT(&s->ftgmac100[i]),
+ sizeof(s->ftgmac100[i]), TYPE_FTGMAC100);
+ }
+
+ sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
+ TYPE_ASPEED_XDMA);
}
static void aspeed_soc_realize(DeviceState *dev, Error **errp)
Error *err = NULL, *local_err = NULL;
/* IO space */
- create_unimplemented_device("aspeed_soc.io",
- ASPEED_SOC_IOMEM_BASE, ASPEED_SOC_IOMEM_SIZE);
+ create_unimplemented_device("aspeed_soc.io", sc->info->memmap[ASPEED_IOMEM],
+ ASPEED_SOC_IOMEM_SIZE);
+
+ if (s->num_cpus > sc->info->num_cpus) {
+ warn_report("%s: invalid number of CPUs %d, using default %d",
+ sc->info->name, s->num_cpus, sc->info->num_cpus);
+ s->num_cpus = sc->info->num_cpus;
+ }
/* CPU */
- object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
- if (err) {
- error_propagate(errp, err);
- return;
+ for (i = 0; i < s->num_cpus; i++) {
+ object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
}
/* SRAM */
error_propagate(errp, err);
return;
}
- memory_region_add_subregion(get_system_memory(), ASPEED_SOC_SRAM_BASE,
- &s->sram);
+ memory_region_add_subregion(get_system_memory(),
+ sc->info->memmap[ASPEED_SRAM], &s->sram);
/* SCU */
object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
error_propagate(errp, err);
return;
}
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, ASPEED_SOC_SCU_BASE);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->info->memmap[ASPEED_SCU]);
/* VIC */
object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
error_propagate(errp, err);
return;
}
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, ASPEED_SOC_VIC_BASE);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->info->memmap[ASPEED_VIC]);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
+ /* RTC */
+ object_property_set_bool(OBJECT(&s->rtc), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->info->memmap[ASPEED_RTC]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0,
+ aspeed_soc_get_irq(s, ASPEED_RTC));
+
/* Timer */
object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
if (err) {
error_propagate(errp, err);
return;
}
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, ASPEED_SOC_TIMER_BASE);
- for (i = 0; i < ARRAY_SIZE(timer_irqs); i++) {
- qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->vic), timer_irqs[i]);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0,
+ sc->info->memmap[ASPEED_TIMER1]);
+ for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
+ qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_TIMER1 + i);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
}
/* UART - attach an 8250 to the IO space as our UART5 */
if (serial_hd(0)) {
- qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
- serial_mm_init(get_system_memory(),
- ASPEED_SOC_IOMEM_BASE + ASPEED_SOC_UART_5_BASE, 2,
+ qemu_irq uart5 = aspeed_soc_get_irq(s, ASPEED_UART5);
+ serial_mm_init(get_system_memory(), sc->info->memmap[ASPEED_UART5], 2,
uart5, 38400, serial_hd(0), DEVICE_LITTLE_ENDIAN);
}
error_propagate(errp, err);
return;
}
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, ASPEED_SOC_I2C_BASE);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->info->memmap[ASPEED_I2C]);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
- qdev_get_gpio_in(DEVICE(&s->vic), 12));
+ aspeed_soc_get_irq(s, ASPEED_I2C));
/* FMC, The number of CS is set at the board level */
+ object_property_set_int(OBJECT(&s->fmc), sc->info->memmap[ASPEED_SDRAM],
+ "sdram-base", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
object_property_set_bool(OBJECT(&s->fmc), true, "realized", &err);
if (err) {
error_propagate(errp, err);
return;
}
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, ASPEED_SOC_FMC_BASE);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->info->memmap[ASPEED_FMC]);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1,
s->fmc.ctrl->flash_window_base);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
- qdev_get_gpio_in(DEVICE(&s->vic), 19));
+ aspeed_soc_get_irq(s, ASPEED_FMC));
/* SPI */
for (i = 0; i < sc->info->spis_num; i++) {
error_propagate(errp, err);
return;
}
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, sc->info->spi_bases[i]);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
+ sc->info->memmap[ASPEED_SPI1 + i]);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1,
s->spi[i].ctrl->flash_window_base);
}
error_propagate(errp, err);
return;
}
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, ASPEED_SOC_SDMC_BASE);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->info->memmap[ASPEED_SDMC]);
/* Watch dog */
for (i = 0; i < sc->info->wdts_num; i++) {
return;
}
sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
- ASPEED_SOC_WDT_BASE + i * 0x20);
+ sc->info->memmap[ASPEED_WDT] + i * 0x20);
}
/* Net */
- qdev_set_nic_properties(DEVICE(&s->ftgmac100), &nd_table[0]);
- object_property_set_bool(OBJECT(&s->ftgmac100), true, "aspeed", &err);
- object_property_set_bool(OBJECT(&s->ftgmac100), true, "realized",
- &local_err);
- error_propagate(&err, local_err);
+ for (i = 0; i < nb_nics; i++) {
+ qdev_set_nic_properties(DEVICE(&s->ftgmac100[i]), &nd_table[i]);
+ object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "aspeed",
+ &err);
+ object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "realized",
+ &local_err);
+ error_propagate(&err, local_err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
+ sc->info->memmap[ASPEED_ETH1 + i]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
+ aspeed_soc_get_irq(s, ASPEED_ETH1 + i));
+ }
+
+ /* XDMA */
+ object_property_set_bool(OBJECT(&s->xdma), true, "realized", &err);
if (err) {
error_propagate(errp, err);
return;
}
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100), 0, ASPEED_SOC_ETH1_BASE);
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100), 0,
- qdev_get_gpio_in(DEVICE(&s->vic), 2));
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0,
+ sc->info->memmap[ASPEED_XDMA]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0,
+ aspeed_soc_get_irq(s, ASPEED_XDMA));
}
+static Property aspeed_soc_properties[] = {
+ DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
static void aspeed_soc_class_init(ObjectClass *oc, void *data)
{
dc->realize = aspeed_soc_realize;
/* Reason: Uses serial_hds and nd_table in realize() directly */
dc->user_creatable = false;
+ dc->props = aspeed_soc_properties;
}
static const TypeInfo aspeed_soc_type_info = {
info->initrd_filename);
exit(1);
}
- if (info->initrd_start + initrd_size > info->ram_size) {
+ if (info->initrd_start + initrd_size > ram_end) {
error_report("could not load initrd '%s': "
"too big to fit into RAM after the kernel",
info->initrd_filename);
+ exit(1);
}
} else {
initrd_size = 0;
*/
create_unimplemented_device("lcdif", FSL_IMX7_LCDIF_ADDR,
FSL_IMX7_LCDIF_SIZE);
+
+ /*
+ * DMA APBH
+ */
+ create_unimplemented_device("dma-apbh", FSL_IMX7_DMA_APBH_ADDR,
+ FSL_IMX7_DMA_APBH_SIZE);
+ /*
+ * PCIe PHY
+ */
+ create_unimplemented_device("pcie-phy", FSL_IMX7_PCIE_PHY_ADDR,
+ FSL_IMX7_PCIE_PHY_SIZE);
}
static void fsl_imx7_class_init(ObjectClass *oc, void *data)
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
error_report("This board can only be used with CPU %s",
mc->default_cpu_type);
+ exit(1);
}
memory_region_init_ram(ddr, NULL, "ddr-ram", DDR_SIZE,
--- /dev/null
+/*
+ * ARM SBSA Reference Platform emulation
+ *
+ * Copyright (c) 2018 Linaro Limited
+ * Written by Hongbo Zhang <hongbo.zhang@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/units.h"
+#include "sysemu/device_tree.h"
+#include "sysemu/numa.h"
+#include "sysemu/sysemu.h"
+#include "exec/address-spaces.h"
+#include "exec/hwaddr.h"
+#include "kvm_arm.h"
+#include "hw/arm/boot.h"
+#include "hw/block/flash.h"
+#include "hw/boards.h"
+#include "hw/ide/internal.h"
+#include "hw/ide/ahci_internal.h"
+#include "hw/intc/arm_gicv3_common.h"
+#include "hw/loader.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/usb.h"
+#include "net/net.h"
+
+#define RAMLIMIT_GB 8192
+#define RAMLIMIT_BYTES (RAMLIMIT_GB * GiB)
+
+#define NUM_IRQS 256
+#define NUM_SMMU_IRQS 4
+#define NUM_SATA_PORTS 6
+
+#define VIRTUAL_PMU_IRQ 7
+#define ARCH_GIC_MAINT_IRQ 9
+#define ARCH_TIMER_VIRT_IRQ 11
+#define ARCH_TIMER_S_EL1_IRQ 13
+#define ARCH_TIMER_NS_EL1_IRQ 14
+#define ARCH_TIMER_NS_EL2_IRQ 10
+
+enum {
+ SBSA_FLASH,
+ SBSA_MEM,
+ SBSA_CPUPERIPHS,
+ SBSA_GIC_DIST,
+ SBSA_GIC_REDIST,
+ SBSA_SMMU,
+ SBSA_UART,
+ SBSA_RTC,
+ SBSA_PCIE,
+ SBSA_PCIE_MMIO,
+ SBSA_PCIE_MMIO_HIGH,
+ SBSA_PCIE_PIO,
+ SBSA_PCIE_ECAM,
+ SBSA_GPIO,
+ SBSA_SECURE_UART,
+ SBSA_SECURE_UART_MM,
+ SBSA_SECURE_MEM,
+ SBSA_AHCI,
+ SBSA_EHCI,
+};
+
+typedef struct MemMapEntry {
+ hwaddr base;
+ hwaddr size;
+} MemMapEntry;
+
+typedef struct {
+ MachineState parent;
+ struct arm_boot_info bootinfo;
+ int smp_cpus;
+ void *fdt;
+ int fdt_size;
+ int psci_conduit;
+ PFlashCFI01 *flash[2];
+} SBSAMachineState;
+
+#define TYPE_SBSA_MACHINE MACHINE_TYPE_NAME("sbsa-ref")
+#define SBSA_MACHINE(obj) \
+ OBJECT_CHECK(SBSAMachineState, (obj), TYPE_SBSA_MACHINE)
+
+static const MemMapEntry sbsa_ref_memmap[] = {
+ /* 512M boot ROM */
+ [SBSA_FLASH] = { 0, 0x20000000 },
+ /* 512M secure memory */
+ [SBSA_SECURE_MEM] = { 0x20000000, 0x20000000 },
+ /* Space reserved for CPU peripheral devices */
+ [SBSA_CPUPERIPHS] = { 0x40000000, 0x00040000 },
+ [SBSA_GIC_DIST] = { 0x40060000, 0x00010000 },
+ [SBSA_GIC_REDIST] = { 0x40080000, 0x04000000 },
+ [SBSA_UART] = { 0x60000000, 0x00001000 },
+ [SBSA_RTC] = { 0x60010000, 0x00001000 },
+ [SBSA_GPIO] = { 0x60020000, 0x00001000 },
+ [SBSA_SECURE_UART] = { 0x60030000, 0x00001000 },
+ [SBSA_SECURE_UART_MM] = { 0x60040000, 0x00001000 },
+ [SBSA_SMMU] = { 0x60050000, 0x00020000 },
+ /* Space here reserved for more SMMUs */
+ [SBSA_AHCI] = { 0x60100000, 0x00010000 },
+ [SBSA_EHCI] = { 0x60110000, 0x00010000 },
+ /* Space here reserved for other devices */
+ [SBSA_PCIE_PIO] = { 0x7fff0000, 0x00010000 },
+ /* 32-bit address PCIE MMIO space */
+ [SBSA_PCIE_MMIO] = { 0x80000000, 0x70000000 },
+ /* 256M PCIE ECAM space */
+ [SBSA_PCIE_ECAM] = { 0xf0000000, 0x10000000 },
+ /* ~1TB PCIE MMIO space (4GB to 1024GB boundary) */
+ [SBSA_PCIE_MMIO_HIGH] = { 0x100000000ULL, 0xFF00000000ULL },
+ [SBSA_MEM] = { 0x10000000000ULL, RAMLIMIT_BYTES },
+};
+
+static const int sbsa_ref_irqmap[] = {
+ [SBSA_UART] = 1,
+ [SBSA_RTC] = 2,
+ [SBSA_PCIE] = 3, /* ... to 6 */
+ [SBSA_GPIO] = 7,
+ [SBSA_SECURE_UART] = 8,
+ [SBSA_SECURE_UART_MM] = 9,
+ [SBSA_AHCI] = 10,
+ [SBSA_EHCI] = 11,
+};
+
+/*
+ * Firmware on this machine only uses ACPI table to load OS, these limited
+ * device tree nodes are just to let firmware know the info which varies from
+ * command line parameters, so it is not necessary to be fully compatible
+ * with the kernel CPU and NUMA binding rules.
+ */
+static void create_fdt(SBSAMachineState *sms)
+{
+ void *fdt = create_device_tree(&sms->fdt_size);
+ const MachineState *ms = MACHINE(sms);
+ int cpu;
+
+ if (!fdt) {
+ error_report("create_device_tree() failed");
+ exit(1);
+ }
+
+ sms->fdt = fdt;
+
+ qemu_fdt_setprop_string(fdt, "/", "compatible", "linux,sbsa-ref");
+ qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
+ qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
+
+ if (have_numa_distance) {
+ int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
+ uint32_t *matrix = g_malloc0(size);
+ int idx, i, j;
+
+ for (i = 0; i < nb_numa_nodes; i++) {
+ for (j = 0; j < nb_numa_nodes; j++) {
+ idx = (i * nb_numa_nodes + j) * 3;
+ matrix[idx + 0] = cpu_to_be32(i);
+ matrix[idx + 1] = cpu_to_be32(j);
+ matrix[idx + 2] = cpu_to_be32(numa_info[i].distance[j]);
+ }
+ }
+
+ qemu_fdt_add_subnode(fdt, "/distance-map");
+ qemu_fdt_setprop(fdt, "/distance-map", "distance-matrix",
+ matrix, size);
+ g_free(matrix);
+ }
+
+ qemu_fdt_add_subnode(sms->fdt, "/cpus");
+
+ for (cpu = sms->smp_cpus - 1; cpu >= 0; cpu--) {
+ char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
+ ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
+ CPUState *cs = CPU(armcpu);
+
+ qemu_fdt_add_subnode(sms->fdt, nodename);
+
+ if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) {
+ qemu_fdt_setprop_cell(sms->fdt, nodename, "numa-node-id",
+ ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
+ }
+
+ g_free(nodename);
+ }
+}
+
+#define SBSA_FLASH_SECTOR_SIZE (256 * KiB)
+
+static PFlashCFI01 *sbsa_flash_create1(SBSAMachineState *sms,
+ const char *name,
+ const char *alias_prop_name)
+{
+ /*
+ * Create a single flash device. We use the same parameters as
+ * the flash devices on the Versatile Express board.
+ */
+ DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
+
+ qdev_prop_set_uint64(dev, "sector-length", SBSA_FLASH_SECTOR_SIZE);
+ qdev_prop_set_uint8(dev, "width", 4);
+ qdev_prop_set_uint8(dev, "device-width", 2);
+ qdev_prop_set_bit(dev, "big-endian", false);
+ qdev_prop_set_uint16(dev, "id0", 0x89);
+ qdev_prop_set_uint16(dev, "id1", 0x18);
+ qdev_prop_set_uint16(dev, "id2", 0x00);
+ qdev_prop_set_uint16(dev, "id3", 0x00);
+ qdev_prop_set_string(dev, "name", name);
+ object_property_add_child(OBJECT(sms), name, OBJECT(dev),
+ &error_abort);
+ object_property_add_alias(OBJECT(sms), alias_prop_name,
+ OBJECT(dev), "drive", &error_abort);
+ return PFLASH_CFI01(dev);
+}
+
+static void sbsa_flash_create(SBSAMachineState *sms)
+{
+ sms->flash[0] = sbsa_flash_create1(sms, "sbsa.flash0", "pflash0");
+ sms->flash[1] = sbsa_flash_create1(sms, "sbsa.flash1", "pflash1");
+}
+
+static void sbsa_flash_map1(PFlashCFI01 *flash,
+ hwaddr base, hwaddr size,
+ MemoryRegion *sysmem)
+{
+ DeviceState *dev = DEVICE(flash);
+
+ assert(size % SBSA_FLASH_SECTOR_SIZE == 0);
+ assert(size / SBSA_FLASH_SECTOR_SIZE <= UINT32_MAX);
+ qdev_prop_set_uint32(dev, "num-blocks", size / SBSA_FLASH_SECTOR_SIZE);
+ qdev_init_nofail(dev);
+
+ memory_region_add_subregion(sysmem, base,
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
+ 0));
+}
+
+static void sbsa_flash_map(SBSAMachineState *sms,
+ MemoryRegion *sysmem,
+ MemoryRegion *secure_sysmem)
+{
+ /*
+ * Map two flash devices to fill the SBSA_FLASH space in the memmap.
+ * sysmem is the system memory space. secure_sysmem is the secure view
+ * of the system, and the first flash device should be made visible only
+ * there. The second flash device is visible to both secure and nonsecure.
+ * If sysmem == secure_sysmem this means there is no separate Secure
+ * address space and both flash devices are generally visible.
+ */
+ hwaddr flashsize = sbsa_ref_memmap[SBSA_FLASH].size / 2;
+ hwaddr flashbase = sbsa_ref_memmap[SBSA_FLASH].base;
+
+ sbsa_flash_map1(sms->flash[0], flashbase, flashsize,
+ secure_sysmem);
+ sbsa_flash_map1(sms->flash[1], flashbase + flashsize, flashsize,
+ sysmem);
+}
+
+static bool sbsa_firmware_init(SBSAMachineState *sms,
+ MemoryRegion *sysmem,
+ MemoryRegion *secure_sysmem)
+{
+ int i;
+ BlockBackend *pflash_blk0;
+
+ /* Map legacy -drive if=pflash to machine properties */
+ for (i = 0; i < ARRAY_SIZE(sms->flash); i++) {
+ pflash_cfi01_legacy_drive(sms->flash[i],
+ drive_get(IF_PFLASH, 0, i));
+ }
+
+ sbsa_flash_map(sms, sysmem, secure_sysmem);
+
+ pflash_blk0 = pflash_cfi01_get_blk(sms->flash[0]);
+
+ if (bios_name) {
+ char *fname;
+ MemoryRegion *mr;
+ int image_size;
+
+ if (pflash_blk0) {
+ error_report("The contents of the first flash device may be "
+ "specified with -bios or with -drive if=pflash... "
+ "but you cannot use both options at once");
+ exit(1);
+ }
+
+ /* Fall back to -bios */
+
+ fname = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ if (!fname) {
+ error_report("Could not find ROM image '%s'", bios_name);
+ exit(1);
+ }
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(sms->flash[0]), 0);
+ image_size = load_image_mr(fname, mr);
+ g_free(fname);
+ if (image_size < 0) {
+ error_report("Could not load ROM image '%s'", bios_name);
+ exit(1);
+ }
+ }
+
+ return pflash_blk0 || bios_name;
+}
+
+static void create_secure_ram(SBSAMachineState *sms,
+ MemoryRegion *secure_sysmem)
+{
+ MemoryRegion *secram = g_new(MemoryRegion, 1);
+ hwaddr base = sbsa_ref_memmap[SBSA_SECURE_MEM].base;
+ hwaddr size = sbsa_ref_memmap[SBSA_SECURE_MEM].size;
+
+ memory_region_init_ram(secram, NULL, "sbsa-ref.secure-ram", size,
+ &error_fatal);
+ memory_region_add_subregion(secure_sysmem, base, secram);
+}
+
+static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
+{
+ DeviceState *gicdev;
+ SysBusDevice *gicbusdev;
+ const char *gictype;
+ uint32_t redist0_capacity, redist0_count;
+ int i;
+
+ gictype = gicv3_class_name();
+
+ gicdev = qdev_create(NULL, gictype);
+ qdev_prop_set_uint32(gicdev, "revision", 3);
+ qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
+ /*
+ * Note that the num-irq property counts both internal and external
+ * interrupts; there are always 32 of the former (mandated by GIC spec).
+ */
+ qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
+ qdev_prop_set_bit(gicdev, "has-security-extensions", true);
+
+ redist0_capacity =
+ sbsa_ref_memmap[SBSA_GIC_REDIST].size / GICV3_REDIST_SIZE;
+ redist0_count = MIN(smp_cpus, redist0_capacity);
+
+ qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1);
+ qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
+
+ qdev_init_nofail(gicdev);
+ gicbusdev = SYS_BUS_DEVICE(gicdev);
+ sysbus_mmio_map(gicbusdev, 0, sbsa_ref_memmap[SBSA_GIC_DIST].base);
+ sysbus_mmio_map(gicbusdev, 1, sbsa_ref_memmap[SBSA_GIC_REDIST].base);
+
+ /*
+ * Wire the outputs from each CPU's generic timer and the GICv3
+ * maintenance interrupt signal to the appropriate GIC PPI inputs,
+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
+ */
+ for (i = 0; i < smp_cpus; i++) {
+ DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
+ int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
+ int irq;
+ /*
+ * Mapping from the output timer irq lines from the CPU to the
+ * GIC PPI inputs used for this board.
+ */
+ const int timer_irq[] = {
+ [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
+ [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
+ [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
+ [GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
+ };
+
+ for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
+ qdev_connect_gpio_out(cpudev, irq,
+ qdev_get_gpio_in(gicdev,
+ ppibase + timer_irq[irq]));
+ }
+
+ qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
+ qdev_get_gpio_in(gicdev, ppibase
+ + ARCH_GIC_MAINT_IRQ));
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
+ qdev_get_gpio_in(gicdev, ppibase
+ + VIRTUAL_PMU_IRQ));
+
+ sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
+ sysbus_connect_irq(gicbusdev, i + smp_cpus,
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
+ sysbus_connect_irq(gicbusdev, i + 2 * smp_cpus,
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
+ sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
+ }
+
+ for (i = 0; i < NUM_IRQS; i++) {
+ pic[i] = qdev_get_gpio_in(gicdev, i);
+ }
+}
+
+static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
+ MemoryRegion *mem, Chardev *chr)
+{
+ hwaddr base = sbsa_ref_memmap[uart].base;
+ int irq = sbsa_ref_irqmap[uart];
+ DeviceState *dev = qdev_create(NULL, "pl011");
+ SysBusDevice *s = SYS_BUS_DEVICE(dev);
+
+ qdev_prop_set_chr(dev, "chardev", chr);
+ qdev_init_nofail(dev);
+ memory_region_add_subregion(mem, base,
+ sysbus_mmio_get_region(s, 0));
+ sysbus_connect_irq(s, 0, pic[irq]);
+}
+
+static void create_rtc(const SBSAMachineState *sms, qemu_irq *pic)
+{
+ hwaddr base = sbsa_ref_memmap[SBSA_RTC].base;
+ int irq = sbsa_ref_irqmap[SBSA_RTC];
+
+ sysbus_create_simple("pl031", base, pic[irq]);
+}
+
+static DeviceState *gpio_key_dev;
+static void sbsa_ref_powerdown_req(Notifier *n, void *opaque)
+{
+ /* use gpio Pin 3 for power button event */
+ qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
+}
+
+static Notifier sbsa_ref_powerdown_notifier = {
+ .notify = sbsa_ref_powerdown_req
+};
+
+static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
+{
+ DeviceState *pl061_dev;
+ hwaddr base = sbsa_ref_memmap[SBSA_GPIO].base;
+ int irq = sbsa_ref_irqmap[SBSA_GPIO];
+
+ pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
+
+ gpio_key_dev = sysbus_create_simple("gpio-key", -1,
+ qdev_get_gpio_in(pl061_dev, 3));
+
+ /* connect powerdown request */
+ qemu_register_powerdown_notifier(&sbsa_ref_powerdown_notifier);
+}
+
+static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
+{
+ hwaddr base = sbsa_ref_memmap[SBSA_AHCI].base;
+ int irq = sbsa_ref_irqmap[SBSA_AHCI];
+ DeviceState *dev;
+ DriveInfo *hd[NUM_SATA_PORTS];
+ SysbusAHCIState *sysahci;
+ AHCIState *ahci;
+ int i;
+
+ dev = qdev_create(NULL, "sysbus-ahci");
+ qdev_prop_set_uint32(dev, "num-ports", NUM_SATA_PORTS);
+ qdev_init_nofail(dev);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
+
+ sysahci = SYSBUS_AHCI(dev);
+ ahci = &sysahci->ahci;
+ ide_drive_get(hd, ARRAY_SIZE(hd));
+ for (i = 0; i < ahci->ports; i++) {
+ if (hd[i] == NULL) {
+ continue;
+ }
+ ide_create_drive(&ahci->dev[i].port, 0, hd[i]);
+ }
+}
+
+static void create_ehci(const SBSAMachineState *sms, qemu_irq *pic)
+{
+ hwaddr base = sbsa_ref_memmap[SBSA_EHCI].base;
+ int irq = sbsa_ref_irqmap[SBSA_EHCI];
+
+ sysbus_create_simple("platform-ehci-usb", base, pic[irq]);
+}
+
+static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
+ PCIBus *bus)
+{
+ hwaddr base = sbsa_ref_memmap[SBSA_SMMU].base;
+ int irq = sbsa_ref_irqmap[SBSA_SMMU];
+ DeviceState *dev;
+ int i;
+
+ dev = qdev_create(NULL, "arm-smmuv3");
+
+ object_property_set_link(OBJECT(dev), OBJECT(bus), "primary-bus",
+ &error_abort);
+ qdev_init_nofail(dev);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
+ for (i = 0; i < NUM_SMMU_IRQS; i++) {
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
+ }
+}
+
+static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
+{
+ hwaddr base_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].base;
+ hwaddr size_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].size;
+ hwaddr base_mmio = sbsa_ref_memmap[SBSA_PCIE_MMIO].base;
+ hwaddr size_mmio = sbsa_ref_memmap[SBSA_PCIE_MMIO].size;
+ hwaddr base_mmio_high = sbsa_ref_memmap[SBSA_PCIE_MMIO_HIGH].base;
+ hwaddr size_mmio_high = sbsa_ref_memmap[SBSA_PCIE_MMIO_HIGH].size;
+ hwaddr base_pio = sbsa_ref_memmap[SBSA_PCIE_PIO].base;
+ int irq = sbsa_ref_irqmap[SBSA_PCIE];
+ MemoryRegion *mmio_alias, *mmio_alias_high, *mmio_reg;
+ MemoryRegion *ecam_alias, *ecam_reg;
+ DeviceState *dev;
+ PCIHostState *pci;
+ int i;
+
+ dev = qdev_create(NULL, TYPE_GPEX_HOST);
+ qdev_init_nofail(dev);
+
+ /* Map ECAM space */
+ ecam_alias = g_new0(MemoryRegion, 1);
+ ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
+ memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam",
+ ecam_reg, 0, size_ecam);
+ memory_region_add_subregion(get_system_memory(), base_ecam, ecam_alias);
+
+ /* Map the MMIO space */
+ mmio_alias = g_new0(MemoryRegion, 1);
+ mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
+ memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio",
+ mmio_reg, base_mmio, size_mmio);
+ memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias);
+
+ /* Map the MMIO_HIGH space */
+ mmio_alias_high = g_new0(MemoryRegion, 1);
+ memory_region_init_alias(mmio_alias_high, OBJECT(dev), "pcie-mmio-high",
+ mmio_reg, base_mmio_high, size_mmio_high);
+ memory_region_add_subregion(get_system_memory(), base_mmio_high,
+ mmio_alias_high);
+
+ /* Map IO port space */
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
+
+ for (i = 0; i < GPEX_NUM_IRQS; i++) {
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
+ gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
+ }
+
+ pci = PCI_HOST_BRIDGE(dev);
+ if (pci->bus) {
+ for (i = 0; i < nb_nics; i++) {
+ NICInfo *nd = &nd_table[i];
+
+ if (!nd->model) {
+ nd->model = g_strdup("e1000e");
+ }
+
+ pci_nic_init_nofail(nd, pci->bus, nd->model, NULL);
+ }
+ }
+
+ pci_create_simple(pci->bus, -1, "VGA");
+
+ create_smmu(sms, pic, pci->bus);
+}
+
+static void *sbsa_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size)
+{
+ const SBSAMachineState *board = container_of(binfo, SBSAMachineState,
+ bootinfo);
+
+ *fdt_size = board->fdt_size;
+ return board->fdt;
+}
+
+static void sbsa_ref_init(MachineState *machine)
+{
+ SBSAMachineState *sms = SBSA_MACHINE(machine);
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
+ MemoryRegion *sysmem = get_system_memory();
+ MemoryRegion *secure_sysmem = NULL;
+ MemoryRegion *ram = g_new(MemoryRegion, 1);
+ bool firmware_loaded;
+ const CPUArchIdList *possible_cpus;
+ int n, sbsa_max_cpus;
+ qemu_irq pic[NUM_IRQS];
+
+ if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a57"))) {
+ error_report("sbsa-ref: CPU type other than the built-in "
+ "cortex-a57 not supported");
+ exit(1);
+ }
+
+ if (kvm_enabled()) {
+ error_report("sbsa-ref: KVM is not supported for this machine");
+ exit(1);
+ }
+
+ /*
+ * The Secure view of the world is the same as the NonSecure,
+ * but with a few extra devices. Create it as a container region
+ * containing the system memory at low priority; any secure-only
+ * devices go in at higher priority and take precedence.
+ */
+ secure_sysmem = g_new(MemoryRegion, 1);
+ memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory",
+ UINT64_MAX);
+ memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1);
+
+ firmware_loaded = sbsa_firmware_init(sms, sysmem,
+ secure_sysmem ?: sysmem);
+
+ if (machine->kernel_filename && firmware_loaded) {
+ error_report("sbsa-ref: No fw_cfg device on this machine, "
+ "so -kernel option is not supported when firmware loaded, "
+ "please load OS from hard disk instead");
+ exit(1);
+ }
+
+ /*
+ * This machine has EL3 enabled, external firmware should supply PSCI
+ * implementation, so the QEMU's internal PSCI is disabled.
+ */
+ sms->psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
+
+ sbsa_max_cpus = sbsa_ref_memmap[SBSA_GIC_REDIST].size / GICV3_REDIST_SIZE;
+
+ if (max_cpus > sbsa_max_cpus) {
+ error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
+ "supported by machine 'sbsa-ref' (%d)",
+ max_cpus, sbsa_max_cpus);
+ exit(1);
+ }
+
+ sms->smp_cpus = smp_cpus;
+
+ if (machine->ram_size > sbsa_ref_memmap[SBSA_MEM].size) {
+ error_report("sbsa-ref: cannot model more than %dGB RAM", RAMLIMIT_GB);
+ exit(1);
+ }
+
+ possible_cpus = mc->possible_cpu_arch_ids(machine);
+ for (n = 0; n < possible_cpus->len; n++) {
+ Object *cpuobj;
+ CPUState *cs;
+
+ if (n >= smp_cpus) {
+ break;
+ }
+
+ cpuobj = object_new(possible_cpus->cpus[n].type);
+ object_property_set_int(cpuobj, possible_cpus->cpus[n].arch_id,
+ "mp-affinity", NULL);
+
+ cs = CPU(cpuobj);
+ cs->cpu_index = n;
+
+ numa_cpu_pre_plug(&possible_cpus->cpus[cs->cpu_index], DEVICE(cpuobj),
+ &error_fatal);
+
+ if (object_property_find(cpuobj, "reset-cbar", NULL)) {
+ object_property_set_int(cpuobj,
+ sbsa_ref_memmap[SBSA_CPUPERIPHS].base,
+ "reset-cbar", &error_abort);
+ }
+
+ object_property_set_link(cpuobj, OBJECT(sysmem), "memory",
+ &error_abort);
+
+ object_property_set_link(cpuobj, OBJECT(secure_sysmem),
+ "secure-memory", &error_abort);
+
+ object_property_set_bool(cpuobj, true, "realized", &error_fatal);
+ object_unref(cpuobj);
+ }
+
+ memory_region_allocate_system_memory(ram, NULL, "sbsa-ref.ram",
+ machine->ram_size);
+ memory_region_add_subregion(sysmem, sbsa_ref_memmap[SBSA_MEM].base, ram);
+
+ create_fdt(sms);
+
+ create_secure_ram(sms, secure_sysmem);
+
+ create_gic(sms, pic);
+
+ create_uart(sms, pic, SBSA_UART, sysmem, serial_hd(0));
+ create_uart(sms, pic, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
+ /* Second secure UART for RAS and MM from EL0 */
+ create_uart(sms, pic, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
+
+ create_rtc(sms, pic);
+
+ create_gpio(sms, pic);
+
+ create_ahci(sms, pic);
+
+ create_ehci(sms, pic);
+
+ create_pcie(sms, pic);
+
+ sms->bootinfo.ram_size = machine->ram_size;
+ sms->bootinfo.kernel_filename = machine->kernel_filename;
+ sms->bootinfo.nb_cpus = smp_cpus;
+ sms->bootinfo.board_id = -1;
+ sms->bootinfo.loader_start = sbsa_ref_memmap[SBSA_MEM].base;
+ sms->bootinfo.get_dtb = sbsa_ref_dtb;
+ sms->bootinfo.firmware_loaded = firmware_loaded;
+ arm_load_kernel(ARM_CPU(first_cpu), &sms->bootinfo);
+}
+
+static uint64_t sbsa_ref_cpu_mp_affinity(SBSAMachineState *sms, int idx)
+{
+ uint8_t clustersz = ARM_DEFAULT_CPUS_PER_CLUSTER;
+ return arm_cpu_mp_affinity(idx, clustersz);
+}
+
+static const CPUArchIdList *sbsa_ref_possible_cpu_arch_ids(MachineState *ms)
+{
+ SBSAMachineState *sms = SBSA_MACHINE(ms);
+ int n;
+
+ if (ms->possible_cpus) {
+ assert(ms->possible_cpus->len == max_cpus);
+ return ms->possible_cpus;
+ }
+
+ ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
+ sizeof(CPUArchId) * max_cpus);
+ ms->possible_cpus->len = max_cpus;
+ for (n = 0; n < ms->possible_cpus->len; n++) {
+ ms->possible_cpus->cpus[n].type = ms->cpu_type;
+ ms->possible_cpus->cpus[n].arch_id =
+ sbsa_ref_cpu_mp_affinity(sms, n);
+ ms->possible_cpus->cpus[n].props.has_thread_id = true;
+ ms->possible_cpus->cpus[n].props.thread_id = n;
+ }
+ return ms->possible_cpus;
+}
+
+static CpuInstanceProperties
+sbsa_ref_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
+{
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
+
+ assert(cpu_index < possible_cpus->len);
+ return possible_cpus->cpus[cpu_index].props;
+}
+
+static int64_t
+sbsa_ref_get_default_cpu_node_id(const MachineState *ms, int idx)
+{
+ return idx % nb_numa_nodes;
+}
+
+static void sbsa_ref_instance_init(Object *obj)
+{
+ SBSAMachineState *sms = SBSA_MACHINE(obj);
+
+ sbsa_flash_create(sms);
+}
+
+static void sbsa_ref_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->init = sbsa_ref_init;
+ mc->desc = "QEMU 'SBSA Reference' ARM Virtual Machine";
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57");
+ mc->max_cpus = 512;
+ mc->pci_allow_0_address = true;
+ mc->minimum_page_bits = 12;
+ mc->block_default_type = IF_IDE;
+ mc->no_cdrom = 1;
+ mc->default_ram_size = 1 * GiB;
+ mc->default_cpus = 4;
+ mc->possible_cpu_arch_ids = sbsa_ref_possible_cpu_arch_ids;
+ mc->cpu_index_to_instance_props = sbsa_ref_cpu_index_to_props;
+ mc->get_default_cpu_node_id = sbsa_ref_get_default_cpu_node_id;
+}
+
+static const TypeInfo sbsa_ref_info = {
+ .name = TYPE_SBSA_MACHINE,
+ .parent = TYPE_MACHINE,
+ .instance_init = sbsa_ref_instance_init,
+ .class_init = sbsa_ref_class_init,
+ .instance_size = sizeof(SBSAMachineState),
+};
+
+static void sbsa_ref_machine_init(void)
+{
+ type_register_static(&sbsa_ref_info);
+}
+
+type_init(sbsa_ref_machine_init);
};
static const char *valid_cpus[] = {
+ ARM_CPU_TYPE_NAME("cortex-a7"),
ARM_CPU_TYPE_NAME("cortex-a15"),
ARM_CPU_TYPE_NAME("cortex-a53"),
ARM_CPU_TYPE_NAME("cortex-a57"),
int requests_inflight;
unsigned int max_requests;
BlockBackend *blk;
+ unsigned int sector_size;
QEMUBH *bh;
IOThread *iothread;
AioContext *ctx;
goto err;
}
- request->start = request->req.sector_number * XEN_BLKIF_SECTOR_SIZE;
+ request->start = request->req.sector_number * dataplane->sector_size;
for (i = 0; i < request->req.nr_segments; i++) {
if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
error_report("error: nr_segments too big");
error_report("error: first > last sector");
goto err;
}
- if (request->req.seg[i].last_sect * XEN_BLKIF_SECTOR_SIZE >=
+ if (request->req.seg[i].last_sect * dataplane->sector_size >=
XC_PAGE_SIZE) {
error_report("error: page crossing");
goto err;
}
len = (request->req.seg[i].last_sect -
- request->req.seg[i].first_sect + 1) * XEN_BLKIF_SECTOR_SIZE;
+ request->req.seg[i].first_sect + 1) * dataplane->sector_size;
request->size += len;
}
if (request->start + request->size > blk_getlength(dataplane->blk)) {
if (to_domain) {
segs[i].dest.foreign.ref = request->req.seg[i].gref;
segs[i].dest.foreign.offset = request->req.seg[i].first_sect *
- XEN_BLKIF_SECTOR_SIZE;
+ dataplane->sector_size;
segs[i].source.virt = virt;
} else {
segs[i].source.foreign.ref = request->req.seg[i].gref;
segs[i].source.foreign.offset = request->req.seg[i].first_sect *
- XEN_BLKIF_SECTOR_SIZE;
+ dataplane->sector_size;
segs[i].dest.virt = virt;
}
segs[i].len = (request->req.seg[i].last_sect -
request->req.seg[i].first_sect + 1) *
- XEN_BLKIF_SECTOR_SIZE;
+ dataplane->sector_size;
virt += segs[i].len;
}
}
xen_block_release_request(request);
- qemu_bh_schedule(dataplane->bh);
+ if (dataplane->more_work) {
+ qemu_bh_schedule(dataplane->bh);
+ }
done:
aio_context_release(dataplane->ctx);
/* Wrap around, or overflowing byte limit? */
if (sec_start + sec_count < sec_count ||
- sec_start + sec_count > INT64_MAX / XEN_BLKIF_SECTOR_SIZE) {
+ sec_start + sec_count > INT64_MAX / dataplane->sector_size) {
return false;
}
- byte_offset = sec_start * XEN_BLKIF_SECTOR_SIZE;
- byte_remaining = sec_count * XEN_BLKIF_SECTOR_SIZE;
+ byte_offset = sec_start * dataplane->sector_size;
+ byte_remaining = sec_count * dataplane->sector_size;
do {
byte_chunk = byte_remaining > BDRV_REQUEST_MAX_BYTES ?
*/
#define IO_PLUG_THRESHOLD 1
-static void xen_block_handle_requests(XenBlockDataPlane *dataplane)
+static bool xen_block_handle_requests(XenBlockDataPlane *dataplane)
{
RING_IDX rc, rp;
XenBlockRequest *request;
int inflight_atstart = dataplane->requests_inflight;
int batched = 0;
+ bool done_something = false;
dataplane->more_work = 0;
}
xen_block_get_request(dataplane, request, rc);
dataplane->rings.common.req_cons = ++rc;
+ done_something = true;
/* parse them */
if (xen_block_parse_request(request) != 0) {
blk_io_unplug(dataplane->blk);
}
- if (dataplane->more_work &&
- dataplane->requests_inflight < dataplane->max_requests) {
- qemu_bh_schedule(dataplane->bh);
- }
+ return done_something;
}
static void xen_block_dataplane_bh(void *opaque)
aio_context_release(dataplane->ctx);
}
-static void xen_block_dataplane_event(void *opaque)
+static bool xen_block_dataplane_event(void *opaque)
{
XenBlockDataPlane *dataplane = opaque;
- qemu_bh_schedule(dataplane->bh);
+ return xen_block_handle_requests(dataplane);
}
XenBlockDataPlane *xen_block_dataplane_create(XenDevice *xendev,
- BlockConf *conf,
+ BlockBackend *blk,
+ unsigned int sector_size,
IOThread *iothread)
{
XenBlockDataPlane *dataplane = g_new0(XenBlockDataPlane, 1);
dataplane->xendev = xendev;
- dataplane->blk = conf->blk;
+ dataplane->blk = blk;
+ dataplane->sector_size = sector_size;
QLIST_INIT(&dataplane->inflight);
QLIST_INIT(&dataplane->freelist);
}
dataplane->event_channel =
- xen_device_bind_event_channel(xendev, event_channel,
+ xen_device_bind_event_channel(xendev, dataplane->ctx, event_channel,
xen_block_dataplane_event, dataplane,
&local_err);
if (local_err) {
typedef struct XenBlockDataPlane XenBlockDataPlane;
XenBlockDataPlane *xen_block_dataplane_create(XenDevice *xendev,
- BlockConf *conf,
+ BlockBackend *blk,
+ unsigned int sector_size,
IOThread *iothread);
void xen_block_dataplane_destroy(XenBlockDataPlane *dataplane);
void xen_block_dataplane_start(XenBlockDataPlane *dataplane,
n->bar.cap = 0;
NVME_CAP_SET_MQES(n->bar.cap, 0x7ff);
NVME_CAP_SET_CQR(n->bar.cap, 1);
- NVME_CAP_SET_AMS(n->bar.cap, 1);
NVME_CAP_SET_TO(n->bar.cap, 0xf);
NVME_CAP_SET_CSS(n->bar.cap, 1);
NVME_CAP_SET_MPSMAX(n->bar.cap, 4);
switch (width) {
case 1:
ret = p[offset];
- trace_pflash_data_read8(offset, ret);
break;
case 2:
if (be) {
ret = p[offset];
ret |= p[offset + 1] << 8;
}
- trace_pflash_data_read16(offset, ret);
break;
case 4:
if (be) {
ret |= p[offset + 2] << 16;
ret |= p[offset + 3] << 24;
}
- trace_pflash_data_read32(offset, ret);
break;
default:
DPRINTF("BUG in %s\n", __func__);
abort();
}
+ trace_pflash_data_read(offset, width << 1, ret);
return ret;
}
uint32_t ret;
ret = -1;
- trace_pflash_read(offset, pfl->cmd, width, pfl->wcycle);
switch (pfl->cmd) {
default:
/* This should never happen : reset state & treat it as a read */
break;
}
+ trace_pflash_io_read(offset, width, width << 1, ret, pfl->cmd, pfl->wcycle);
+
return ret;
}
{
uint8_t *p = pfl->storage;
- trace_pflash_data_write(offset, value, width, pfl->counter);
+ trace_pflash_data_write(offset, width << 1, value, pfl->counter);
switch (width) {
case 1:
p[offset] = value;
cmd = value;
- trace_pflash_write(offset, value, width, pfl->wcycle);
+ trace_pflash_io_write(offset, width, width << 1, value, pfl->wcycle);
if (!pfl->wcycle) {
/* Set the device in I/O access mode */
memory_region_rom_device_set_romd(&pfl->mem, false);
* - CFI queries
*
* It does not support flash interleaving.
- * It does not implement boot blocs with reduced size
* It does not implement software data protection as found in many real chips
- * It does not implement erase suspend/resume commands
- * It does not implement multiple sectors erase
*/
#include "qemu/osdep.h"
#include "hw/block/block.h"
#include "hw/block/flash.h"
#include "qapi/error.h"
+#include "qemu/bitmap.h"
#include "qemu/timer.h"
#include "sysemu/block-backend.h"
#include "qemu/host-utils.h"
#include "hw/sysbus.h"
#include "trace.h"
-//#define PFLASH_DEBUG
-#ifdef PFLASH_DEBUG
+#define PFLASH_DEBUG false
#define DPRINTF(fmt, ...) \
do { \
- fprintf(stderr, "PFLASH: " fmt , ## __VA_ARGS__); \
+ if (PFLASH_DEBUG) { \
+ fprintf(stderr, "PFLASH: " fmt, ## __VA_ARGS__); \
+ } \
} while (0)
-#else
-#define DPRINTF(fmt, ...) do { } while (0)
-#endif
#define PFLASH_LAZY_ROMD_THRESHOLD 42
+/*
+ * The size of the cfi_table indirectly depends on this and the start of the
+ * PRI table directly depends on it. 4 is the maximum size (and also what
+ * seems common) without changing the PRT table address.
+ */
+#define PFLASH_MAX_ERASE_REGIONS 4
+
+/* Special write cycles for CFI queries. */
+enum {
+ WCYCLE_CFI = 7,
+ WCYCLE_AUTOSELECT_CFI = 8,
+};
+
struct PFlashCFI02 {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
BlockBackend *blk;
- uint32_t sector_len;
- uint32_t nb_blocs;
+ uint32_t uniform_nb_blocs;
+ uint32_t uniform_sector_len;
+ uint32_t total_sectors;
+ uint32_t nb_blocs[PFLASH_MAX_ERASE_REGIONS];
+ uint32_t sector_len[PFLASH_MAX_ERASE_REGIONS];
uint32_t chip_len;
uint8_t mappings;
uint8_t width;
uint16_t ident3;
uint16_t unlock_addr0;
uint16_t unlock_addr1;
- uint8_t cfi_table[0x52];
+ uint8_t cfi_table[0x4d];
QEMUTimer timer;
/* The device replicates the flash memory across its memory space. Emulate
* that by having a container (.mem) filled with an array of aliases
MemoryRegion orig_mem;
int rom_mode;
int read_counter; /* used for lazy switch-back to rom mode */
+ int sectors_to_erase;
+ uint64_t erase_time_remaining;
+ unsigned long *sector_erase_map;
char *name;
void *storage;
};
+/*
+ * Toggle status bit DQ7.
+ */
+static inline void toggle_dq7(PFlashCFI02 *pfl)
+{
+ pfl->status ^= 0x80;
+}
+
+/*
+ * Set status bit DQ7 to bit 7 of value.
+ */
+static inline void set_dq7(PFlashCFI02 *pfl, uint8_t value)
+{
+ pfl->status &= 0x7F;
+ pfl->status |= value & 0x80;
+}
+
+/*
+ * Toggle status bit DQ6.
+ */
+static inline void toggle_dq6(PFlashCFI02 *pfl)
+{
+ pfl->status ^= 0x40;
+}
+
+/*
+ * Turn on DQ3.
+ */
+static inline void assert_dq3(PFlashCFI02 *pfl)
+{
+ pfl->status |= 0x08;
+}
+
+/*
+ * Turn off DQ3.
+ */
+static inline void reset_dq3(PFlashCFI02 *pfl)
+{
+ pfl->status &= ~0x08;
+}
+
+/*
+ * Toggle status bit DQ2.
+ */
+static inline void toggle_dq2(PFlashCFI02 *pfl)
+{
+ pfl->status ^= 0x04;
+}
+
/*
* Set up replicated mappings of the same region.
*/
pfl->rom_mode = rom_mode;
}
-static void pflash_timer (void *opaque)
+static size_t pflash_regions_count(PFlashCFI02 *pfl)
+{
+ return pfl->cfi_table[0x2c];
+}
+
+/*
+ * Returns the time it takes to erase the number of sectors scheduled for
+ * erasure based on CFI address 0x21 which is "Typical timeout per individual
+ * block erase 2^N ms."
+ */
+static uint64_t pflash_erase_time(PFlashCFI02 *pfl)
+{
+ /*
+ * If there are no sectors to erase (which can happen if all of the sectors
+ * to be erased are protected), then erase takes 100 us. Protected sectors
+ * aren't supported so this should never happen.
+ */
+ return ((1ULL << pfl->cfi_table[0x21]) * pfl->sectors_to_erase) * SCALE_US;
+}
+
+/*
+ * Returns true if the device is currently in erase suspend mode.
+ */
+static inline bool pflash_erase_suspend_mode(PFlashCFI02 *pfl)
+{
+ return pfl->erase_time_remaining > 0;
+}
+
+static void pflash_timer(void *opaque)
{
PFlashCFI02 *pfl = opaque;
trace_pflash_timer_expired(pfl->cmd);
+ if (pfl->cmd == 0x30) {
+ /*
+ * Sector erase. If DQ3 is 0 when the timer expires, then the 50
+ * us erase timeout has expired so we need to start the timer for the
+ * sector erase algorithm. Otherwise, the erase completed and we should
+ * go back to read array mode.
+ */
+ if ((pfl->status & 0x08) == 0) {
+ assert_dq3(pfl);
+ uint64_t timeout = pflash_erase_time(pfl);
+ timer_mod(&pfl->timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout);
+ DPRINTF("%s: erase timeout fired; erasing %d sectors\n",
+ __func__, pfl->sectors_to_erase);
+ return;
+ }
+ DPRINTF("%s: sector erase complete\n", __func__);
+ bitmap_zero(pfl->sector_erase_map, pfl->total_sectors);
+ pfl->sectors_to_erase = 0;
+ reset_dq3(pfl);
+ }
+
/* Reset flash */
- pfl->status ^= 0x80;
+ toggle_dq7(pfl);
if (pfl->bypass) {
pfl->wcycle = 2;
} else {
pfl->cmd = 0;
}
-static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr offset,
- int width, int be)
+/*
+ * Read data from flash.
+ */
+static uint64_t pflash_data_read(PFlashCFI02 *pfl, hwaddr offset,
+ unsigned int width)
+{
+ uint8_t *p = (uint8_t *)pfl->storage + offset;
+ uint64_t ret = pfl->be ? ldn_be_p(p, width) : ldn_le_p(p, width);
+ trace_pflash_data_read(offset, width << 1, ret);
+ return ret;
+}
+
+typedef struct {
+ uint32_t len;
+ uint32_t num;
+} SectorInfo;
+
+/*
+ * offset should be a byte offset of the QEMU device and _not_ a device
+ * offset.
+ */
+static SectorInfo pflash_sector_info(PFlashCFI02 *pfl, hwaddr offset)
{
+ assert(offset < pfl->chip_len);
+ hwaddr addr = 0;
+ uint32_t sector_num = 0;
+ for (int i = 0; i < pflash_regions_count(pfl); ++i) {
+ uint64_t region_size = (uint64_t)pfl->nb_blocs[i] * pfl->sector_len[i];
+ if (addr <= offset && offset < addr + region_size) {
+ return (SectorInfo) {
+ .len = pfl->sector_len[i],
+ .num = sector_num + (offset - addr) / pfl->sector_len[i],
+ };
+ }
+ sector_num += pfl->nb_blocs[i];
+ addr += region_size;
+ }
+ abort();
+}
+
+/*
+ * Returns true if the offset refers to a flash sector that is currently being
+ * erased.
+ */
+static bool pflash_sector_is_erasing(PFlashCFI02 *pfl, hwaddr offset)
+{
+ long sector_num = pflash_sector_info(pfl, offset).num;
+ return test_bit(sector_num, pfl->sector_erase_map);
+}
+
+static uint64_t pflash_read(void *opaque, hwaddr offset, unsigned int width)
+{
+ PFlashCFI02 *pfl = opaque;
hwaddr boff;
- uint32_t ret;
- uint8_t *p;
+ uint64_t ret;
ret = -1;
- trace_pflash_read(offset, pfl->cmd, width, pfl->wcycle);
/* Lazy reset to ROMD mode after a certain amount of read accesses */
if (!pfl->rom_mode && pfl->wcycle == 0 &&
++pfl->read_counter > PFLASH_LAZY_ROMD_THRESHOLD) {
}
offset &= pfl->chip_len - 1;
boff = offset & 0xFF;
- if (pfl->width == 2)
+ if (pfl->width == 2) {
boff = boff >> 1;
- else if (pfl->width == 4)
- boff = boff >> 2;
+ }
switch (pfl->cmd) {
default:
/* This should never happen : reset state & treat it as a read*/
pfl->wcycle = 0;
pfl->cmd = 0;
/* fall through to the read code */
- case 0x80:
+ case 0x80: /* Erase (unlock) */
/* We accept reads during second unlock sequence... */
case 0x00:
- flash_read:
- /* Flash area read */
- p = pfl->storage;
- switch (width) {
- case 1:
- ret = p[offset];
- trace_pflash_data_read8(offset, ret);
- break;
- case 2:
- if (be) {
- ret = p[offset] << 8;
- ret |= p[offset + 1];
- } else {
- ret = p[offset];
- ret |= p[offset + 1] << 8;
- }
- trace_pflash_data_read16(offset, ret);
- break;
- case 4:
- if (be) {
- ret = p[offset] << 24;
- ret |= p[offset + 1] << 16;
- ret |= p[offset + 2] << 8;
- ret |= p[offset + 3];
- } else {
- ret = p[offset];
- ret |= p[offset + 1] << 8;
- ret |= p[offset + 2] << 16;
- ret |= p[offset + 3] << 24;
- }
- trace_pflash_data_read32(offset, ret);
+ if (pflash_erase_suspend_mode(pfl) &&
+ pflash_sector_is_erasing(pfl, offset)) {
+ /* Toggle bit 2, but not 6. */
+ toggle_dq2(pfl);
+ /* Status register read */
+ ret = pfl->status;
+ DPRINTF("%s: status %" PRIx64 "\n", __func__, ret);
break;
}
+ /* Flash area read */
+ ret = pflash_data_read(pfl, offset, width);
break;
- case 0x90:
- /* flash ID read */
+ case 0x90: /* flash ID read */
switch (boff) {
case 0x00:
case 0x01:
case 0x0E:
case 0x0F:
ret = boff & 0x01 ? pfl->ident3 : pfl->ident2;
- if (ret == (uint8_t)-1) {
- goto flash_read;
+ if (ret != (uint8_t)-1) {
+ break;
}
- break;
+ /* Fall through to data read. */
default:
- goto flash_read;
+ ret = pflash_data_read(pfl, offset, width);
}
- DPRINTF("%s: ID " TARGET_FMT_plx " %x\n", __func__, boff, ret);
+ DPRINTF("%s: ID " TARGET_FMT_plx " %" PRIx64 "\n", __func__, boff, ret);
break;
- case 0xA0:
- case 0x10:
- case 0x30:
+ case 0x10: /* Chip Erase */
+ case 0x30: /* Sector Erase */
+ /* Toggle bit 2 during erase, but not program. */
+ toggle_dq2(pfl);
+ case 0xA0: /* Program */
+ /* Toggle bit 6 */
+ toggle_dq6(pfl);
/* Status register read */
ret = pfl->status;
- DPRINTF("%s: status %x\n", __func__, ret);
- /* Toggle bit 6 */
- pfl->status ^= 0x40;
+ DPRINTF("%s: status %" PRIx64 "\n", __func__, ret);
break;
case 0x98:
/* CFI query mode */
}
break;
}
+ trace_pflash_io_read(offset, width, width << 1, ret, pfl->cmd, pfl->wcycle);
return ret;
}
/* update flash content on disk */
-static void pflash_update(PFlashCFI02 *pfl, int offset,
- int size)
+static void pflash_update(PFlashCFI02 *pfl, int offset, int size)
{
int offset_end;
if (pfl->blk) {
}
}
-static void pflash_write(PFlashCFI02 *pfl, hwaddr offset,
- uint32_t value, int width, int be)
+static void pflash_sector_erase(PFlashCFI02 *pfl, hwaddr offset)
{
+ SectorInfo sector_info = pflash_sector_info(pfl, offset);
+ uint64_t sector_len = sector_info.len;
+ offset &= ~(sector_len - 1);
+ DPRINTF("%s: start sector erase at %0*" PRIx64 "-%0*" PRIx64 "\n",
+ __func__, pfl->width * 2, offset,
+ pfl->width * 2, offset + sector_len - 1);
+ if (!pfl->ro) {
+ uint8_t *p = pfl->storage;
+ memset(p + offset, 0xff, sector_len);
+ pflash_update(pfl, offset, sector_len);
+ }
+ set_dq7(pfl, 0x00);
+ ++pfl->sectors_to_erase;
+ set_bit(sector_info.num, pfl->sector_erase_map);
+ /* Set (or reset) the 50 us timer for additional erase commands. */
+ timer_mod(&pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 50000);
+}
+
+static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
+ unsigned int width)
+{
+ PFlashCFI02 *pfl = opaque;
hwaddr boff;
uint8_t *p;
uint8_t cmd;
+ trace_pflash_io_write(offset, width, width << 1, value, pfl->wcycle);
cmd = value;
- if (pfl->cmd != 0xA0 && cmd == 0xF0) {
-#if 0
- DPRINTF("%s: flash reset asked (%02x %02x)\n",
- __func__, pfl->cmd, cmd);
-#endif
- goto reset_flash;
+ if (pfl->cmd != 0xA0) {
+ /* Reset does nothing during chip erase and sector erase. */
+ if (cmd == 0xF0 && pfl->cmd != 0x10 && pfl->cmd != 0x30) {
+ if (pfl->wcycle == WCYCLE_AUTOSELECT_CFI) {
+ /* Return to autoselect mode. */
+ pfl->wcycle = 3;
+ pfl->cmd = 0x90;
+ return;
+ }
+ goto reset_flash;
+ }
}
- trace_pflash_write(offset, value, width, pfl->wcycle);
offset &= pfl->chip_len - 1;
- DPRINTF("%s: offset " TARGET_FMT_plx " %08x %d\n", __func__,
- offset, value, width);
- boff = offset & (pfl->sector_len - 1);
- if (pfl->width == 2)
+ boff = offset;
+ if (pfl->width == 2) {
boff = boff >> 1;
- else if (pfl->width == 4)
- boff = boff >> 2;
+ }
+ /* Only the least-significant 11 bits are used in most cases. */
+ boff &= 0x7FF;
switch (pfl->wcycle) {
case 0:
/* Set the device in I/O access mode if required */
/* We're in read mode */
check_unlock0:
if (boff == 0x55 && cmd == 0x98) {
- enter_CFI_mode:
/* Enter CFI query mode */
- pfl->wcycle = 7;
+ pfl->wcycle = WCYCLE_CFI;
pfl->cmd = 0x98;
return;
}
+ /* Handle erase resume in erase suspend mode, otherwise reset. */
+ if (cmd == 0x30) { /* Erase Resume */
+ if (pflash_erase_suspend_mode(pfl)) {
+ /* Resume the erase. */
+ timer_mod(&pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+ pfl->erase_time_remaining);
+ pfl->erase_time_remaining = 0;
+ pfl->wcycle = 6;
+ pfl->cmd = 0x30;
+ set_dq7(pfl, 0x00);
+ assert_dq3(pfl);
+ return;
+ }
+ goto reset_flash;
+ }
+ /* Ignore erase suspend. */
+ if (cmd == 0xB0) { /* Erase Suspend */
+ return;
+ }
if (boff != pfl->unlock_addr0 || cmd != 0xAA) {
DPRINTF("%s: unlock0 failed " TARGET_FMT_plx " %02x %04x\n",
__func__, boff, cmd, pfl->unlock_addr0);
case 0x20:
pfl->bypass = 1;
goto do_bypass;
- case 0x80:
- case 0x90:
- case 0xA0:
+ case 0x80: /* Erase */
+ case 0x90: /* Autoselect */
+ case 0xA0: /* Program */
pfl->cmd = cmd;
DPRINTF("%s: starting command %02x\n", __func__, cmd);
break;
break;
case 3:
switch (pfl->cmd) {
- case 0x80:
+ case 0x80: /* Erase */
/* We need another unlock sequence */
goto check_unlock0;
- case 0xA0:
- trace_pflash_data_write(offset, value, width, 0);
- p = pfl->storage;
+ case 0xA0: /* Program */
+ if (pflash_erase_suspend_mode(pfl) &&
+ pflash_sector_is_erasing(pfl, offset)) {
+ /* Ignore writes to erasing sectors. */
+ if (pfl->bypass) {
+ goto do_bypass;
+ }
+ goto reset_flash;
+ }
+ trace_pflash_data_write(offset, width << 1, value, 0);
if (!pfl->ro) {
- switch (width) {
- case 1:
- p[offset] &= value;
- pflash_update(pfl, offset, 1);
- break;
- case 2:
- if (be) {
- p[offset] &= value >> 8;
- p[offset + 1] &= value;
- } else {
- p[offset] &= value;
- p[offset + 1] &= value >> 8;
- }
- pflash_update(pfl, offset, 2);
- break;
- case 4:
- if (be) {
- p[offset] &= value >> 24;
- p[offset + 1] &= value >> 16;
- p[offset + 2] &= value >> 8;
- p[offset + 3] &= value;
- } else {
- p[offset] &= value;
- p[offset + 1] &= value >> 8;
- p[offset + 2] &= value >> 16;
- p[offset + 3] &= value >> 24;
- }
- pflash_update(pfl, offset, 4);
- break;
+ p = (uint8_t *)pfl->storage + offset;
+ if (pfl->be) {
+ uint64_t current = ldn_be_p(p, width);
+ stn_be_p(p, width, current & value);
+ } else {
+ uint64_t current = ldn_le_p(p, width);
+ stn_le_p(p, width, current & value);
}
+ pflash_update(pfl, offset, width);
}
- pfl->status = 0x00 | ~(value & 0x80);
+ /*
+ * While programming, status bit DQ7 should hold the opposite
+ * value from how it was programmed.
+ */
+ set_dq7(pfl, ~value);
/* Let's pretend write is immediate */
if (pfl->bypass)
goto do_bypass;
goto reset_flash;
- case 0x90:
+ case 0x90: /* Autoselect */
if (pfl->bypass && cmd == 0x00) {
/* Unlock bypass reset */
goto reset_flash;
}
- /* We can enter CFI query mode from autoselect mode */
- if (boff == 0x55 && cmd == 0x98)
- goto enter_CFI_mode;
+ /*
+ * We can enter CFI query mode from autoselect mode, but we must
+ * return to autoselect mode after a reset.
+ */
+ if (boff == 0x55 && cmd == 0x98) {
+ /* Enter autoselect CFI query mode */
+ pfl->wcycle = WCYCLE_AUTOSELECT_CFI;
+ pfl->cmd = 0x98;
+ return;
+ }
/* No break here */
default:
DPRINTF("%s: invalid write for command %02x\n",
}
case 4:
switch (pfl->cmd) {
- case 0xA0:
+ case 0xA0: /* Program */
/* Ignore writes while flash data write is occurring */
/* As we suppose write is immediate, this should never happen */
return;
- case 0x80:
+ case 0x80: /* Erase */
goto check_unlock1;
default:
/* Should never happen */
}
break;
case 5:
+ if (pflash_erase_suspend_mode(pfl)) {
+ /* Erasing is not supported in erase suspend mode. */
+ goto reset_flash;
+ }
switch (cmd) {
- case 0x10:
+ case 0x10: /* Chip Erase */
if (boff != pfl->unlock_addr0) {
DPRINTF("%s: chip erase: invalid address " TARGET_FMT_plx "\n",
__func__, offset);
/* Chip erase */
DPRINTF("%s: start chip erase\n", __func__);
if (!pfl->ro) {
- memset(pfl->storage, 0xFF, pfl->chip_len);
+ memset(pfl->storage, 0xff, pfl->chip_len);
pflash_update(pfl, 0, pfl->chip_len);
}
- pfl->status = 0x00;
- /* Let's wait 5 seconds before chip erase is done */
+ set_dq7(pfl, 0x00);
+ /* Wait the time specified at CFI address 0x22. */
timer_mod(&pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- (NANOSECONDS_PER_SECOND * 5));
+ (1ULL << pfl->cfi_table[0x22]) * SCALE_MS);
break;
- case 0x30:
- /* Sector erase */
- p = pfl->storage;
- offset &= ~(pfl->sector_len - 1);
- DPRINTF("%s: start sector erase at " TARGET_FMT_plx "\n", __func__,
- offset);
- if (!pfl->ro) {
- memset(p + offset, 0xFF, pfl->sector_len);
- pflash_update(pfl, offset, pfl->sector_len);
- }
- pfl->status = 0x00;
- /* Let's wait 1/2 second before sector erase is done */
- timer_mod(&pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- (NANOSECONDS_PER_SECOND / 2));
+ case 0x30: /* Sector erase */
+ pflash_sector_erase(pfl, offset);
break;
default:
DPRINTF("%s: invalid command %02x (wc 5)\n", __func__, cmd);
break;
case 6:
switch (pfl->cmd) {
- case 0x10:
+ case 0x10: /* Chip Erase */
/* Ignore writes during chip erase */
return;
- case 0x30:
- /* Ignore writes during sector erase */
+ case 0x30: /* Sector erase */
+ if (cmd == 0xB0) {
+ /*
+ * If erase suspend happens during the erase timeout (so DQ3 is
+ * 0), then the device suspends erasing immediately. Set the
+ * remaining time to be the total time to erase. Otherwise,
+ * there is a maximum amount of time it can take to enter
+ * suspend mode. Let's ignore that and suspend immediately and
+ * set the remaining time to the actual time remaining on the
+ * timer.
+ */
+ if ((pfl->status & 0x08) == 0) {
+ pfl->erase_time_remaining = pflash_erase_time(pfl);
+ } else {
+ int64_t delta = timer_expire_time_ns(&pfl->timer) -
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ /* Make sure we have a positive time remaining. */
+ pfl->erase_time_remaining = delta <= 0 ? 1 : delta;
+ }
+ reset_dq3(pfl);
+ timer_del(&pfl->timer);
+ pfl->wcycle = 0;
+ pfl->cmd = 0;
+ return;
+ }
+ /*
+ * If DQ3 is 0, additional sector erase commands can be
+ * written and anything else (other than an erase suspend) resets
+ * the device.
+ */
+ if ((pfl->status & 0x08) == 0) {
+ if (cmd == 0x30) {
+ pflash_sector_erase(pfl, offset);
+ } else {
+ goto reset_flash;
+ }
+ }
+ /* Ignore writes during the actual erase. */
return;
default:
/* Should never happen */
goto reset_flash;
}
break;
- case 7: /* Special value for CFI queries */
+ /* Special values for CFI queries */
+ case WCYCLE_CFI:
+ case WCYCLE_AUTOSELECT_CFI:
DPRINTF("%s: invalid write in CFI query mode\n", __func__);
goto reset_flash;
default:
pfl->cmd = 0;
}
-static uint64_t pflash_be_readfn(void *opaque, hwaddr addr, unsigned size)
-{
- return pflash_read(opaque, addr, size, 1);
-}
-
-static void pflash_be_writefn(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- pflash_write(opaque, addr, value, size, 1);
-}
-
-static uint64_t pflash_le_readfn(void *opaque, hwaddr addr, unsigned size)
-{
- return pflash_read(opaque, addr, size, 0);
-}
-
-static void pflash_le_writefn(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- pflash_write(opaque, addr, value, size, 0);
-}
-
-static const MemoryRegionOps pflash_cfi02_ops_be = {
- .read = pflash_be_readfn,
- .write = pflash_be_writefn,
- .valid.min_access_size = 1,
- .valid.max_access_size = 4,
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static const MemoryRegionOps pflash_cfi02_ops_le = {
- .read = pflash_le_readfn,
- .write = pflash_le_writefn,
+static const MemoryRegionOps pflash_cfi02_ops = {
+ .read = pflash_read,
+ .write = pflash_write,
+ .impl.max_access_size = 2,
.valid.min_access_size = 1,
.valid.max_access_size = 4,
.endianness = DEVICE_NATIVE_ENDIAN,
static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
{
PFlashCFI02 *pfl = PFLASH_CFI02(dev);
- uint32_t chip_len;
int ret;
Error *local_err = NULL;
- if (pfl->sector_len == 0) {
+ if (pfl->uniform_sector_len == 0 && pfl->sector_len[0] == 0) {
error_setg(errp, "attribute \"sector-length\" not specified or zero.");
return;
}
- if (pfl->nb_blocs == 0) {
+ if (pfl->uniform_nb_blocs == 0 && pfl->nb_blocs[0] == 0) {
error_setg(errp, "attribute \"num-blocks\" not specified or zero.");
return;
}
return;
}
- chip_len = pfl->sector_len * pfl->nb_blocs;
+ int nb_regions;
+ pfl->chip_len = 0;
+ pfl->total_sectors = 0;
+ for (nb_regions = 0; nb_regions < PFLASH_MAX_ERASE_REGIONS; ++nb_regions) {
+ if (pfl->nb_blocs[nb_regions] == 0) {
+ break;
+ }
+ pfl->total_sectors += pfl->nb_blocs[nb_regions];
+ uint64_t sector_len_per_device = pfl->sector_len[nb_regions];
+
+ /*
+ * The size of each flash sector must be a power of 2 and it must be
+ * aligned at the same power of 2.
+ */
+ if (sector_len_per_device & 0xff ||
+ sector_len_per_device >= (1 << 24) ||
+ !is_power_of_2(sector_len_per_device))
+ {
+ error_setg(errp, "unsupported configuration: "
+ "sector length[%d] per device = %" PRIx64 ".",
+ nb_regions, sector_len_per_device);
+ return;
+ }
+ if (pfl->chip_len & (sector_len_per_device - 1)) {
+ error_setg(errp, "unsupported configuration: "
+ "flash region %d not correctly aligned.",
+ nb_regions);
+ return;
+ }
+
+ pfl->chip_len += (uint64_t)pfl->sector_len[nb_regions] *
+ pfl->nb_blocs[nb_regions];
+ }
+
+ uint64_t uniform_len = (uint64_t)pfl->uniform_nb_blocs *
+ pfl->uniform_sector_len;
+ if (nb_regions == 0) {
+ nb_regions = 1;
+ pfl->nb_blocs[0] = pfl->uniform_nb_blocs;
+ pfl->sector_len[0] = pfl->uniform_sector_len;
+ pfl->chip_len = uniform_len;
+ pfl->total_sectors = pfl->uniform_nb_blocs;
+ } else if (uniform_len != 0 && uniform_len != pfl->chip_len) {
+ error_setg(errp, "\"num-blocks\"*\"sector-length\" "
+ "different from \"num-blocks0\"*\'sector-length0\" + ... + "
+ "\"num-blocks3\"*\"sector-length3\"");
+ return;
+ }
- memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl), pfl->be ?
- &pflash_cfi02_ops_be : &pflash_cfi02_ops_le,
- pfl, pfl->name, chip_len, &local_err);
+ memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl),
+ &pflash_cfi02_ops, pfl, pfl->name,
+ pfl->chip_len, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
pfl->storage = memory_region_get_ram_ptr(&pfl->orig_mem);
- pfl->chip_len = chip_len;
if (pfl->blk) {
uint64_t perm;
}
if (pfl->blk) {
- if (!blk_check_size_and_read_all(pfl->blk, pfl->storage, chip_len,
- errp)) {
+ if (!blk_check_size_and_read_all(pfl->blk, pfl->storage,
+ pfl->chip_len, errp)) {
vmstate_unregister_ram(&pfl->orig_mem, DEVICE(pfl));
return;
}
}
+ /* Only 11 bits are used in the comparison. */
+ pfl->unlock_addr0 &= 0x7FF;
+ pfl->unlock_addr1 &= 0x7FF;
+
+ /* Allocate memory for a bitmap for sectors being erased. */
+ pfl->sector_erase_map = bitmap_new(pfl->total_sectors);
+
pflash_setup_mappings(pfl);
pfl->rom_mode = 1;
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);
pfl->wcycle = 0;
pfl->cmd = 0;
pfl->status = 0;
+
/* Hardcoded CFI table (mostly from SG29 Spansion flash) */
+ const uint16_t pri_ofs = 0x40;
/* Standard "QRY" string */
pfl->cfi_table[0x10] = 'Q';
pfl->cfi_table[0x11] = 'R';
pfl->cfi_table[0x13] = 0x02;
pfl->cfi_table[0x14] = 0x00;
/* Primary extended table address */
- pfl->cfi_table[0x15] = 0x31;
- pfl->cfi_table[0x16] = 0x00;
+ pfl->cfi_table[0x15] = pri_ofs;
+ pfl->cfi_table[0x16] = pri_ofs >> 8;
/* Alternate command set (none) */
pfl->cfi_table[0x17] = 0x00;
pfl->cfi_table[0x18] = 0x00;
pfl->cfi_table[0x1D] = 0x00;
/* Vpp max (no Vpp pin) */
pfl->cfi_table[0x1E] = 0x00;
- /* Reserved */
+ /* Timeout per single byte/word write (128 ms) */
pfl->cfi_table[0x1F] = 0x07;
/* Timeout for min size buffer write (NA) */
pfl->cfi_table[0x20] = 0x00;
/* Max timeout for chip erase */
pfl->cfi_table[0x26] = 0x0D;
/* Device size */
- pfl->cfi_table[0x27] = ctz32(chip_len);
+ pfl->cfi_table[0x27] = ctz32(pfl->chip_len);
/* Flash device interface (8 & 16 bits) */
pfl->cfi_table[0x28] = 0x02;
pfl->cfi_table[0x29] = 0x00;
// pfl->cfi_table[0x2A] = 0x05;
pfl->cfi_table[0x2A] = 0x00;
pfl->cfi_table[0x2B] = 0x00;
- /* Number of erase block regions (uniform) */
- pfl->cfi_table[0x2C] = 0x01;
- /* Erase block region 1 */
- pfl->cfi_table[0x2D] = pfl->nb_blocs - 1;
- pfl->cfi_table[0x2E] = (pfl->nb_blocs - 1) >> 8;
- pfl->cfi_table[0x2F] = pfl->sector_len >> 8;
- pfl->cfi_table[0x30] = pfl->sector_len >> 16;
+ /* Number of erase block regions */
+ pfl->cfi_table[0x2c] = nb_regions;
+ /* Erase block regions */
+ for (int i = 0; i < nb_regions; ++i) {
+ uint32_t sector_len_per_device = pfl->sector_len[i];
+ pfl->cfi_table[0x2d + 4 * i] = pfl->nb_blocs[i] - 1;
+ pfl->cfi_table[0x2e + 4 * i] = (pfl->nb_blocs[i] - 1) >> 8;
+ pfl->cfi_table[0x2f + 4 * i] = sector_len_per_device >> 8;
+ pfl->cfi_table[0x30 + 4 * i] = sector_len_per_device >> 16;
+ }
+ assert(0x2c + 4 * nb_regions < pri_ofs);
/* Extended */
- pfl->cfi_table[0x31] = 'P';
- pfl->cfi_table[0x32] = 'R';
- pfl->cfi_table[0x33] = 'I';
-
- pfl->cfi_table[0x34] = '1';
- pfl->cfi_table[0x35] = '0';
-
- pfl->cfi_table[0x36] = 0x00;
- pfl->cfi_table[0x37] = 0x00;
- pfl->cfi_table[0x38] = 0x00;
- pfl->cfi_table[0x39] = 0x00;
-
- pfl->cfi_table[0x3a] = 0x00;
-
- pfl->cfi_table[0x3b] = 0x00;
- pfl->cfi_table[0x3c] = 0x00;
+ pfl->cfi_table[0x00 + pri_ofs] = 'P';
+ pfl->cfi_table[0x01 + pri_ofs] = 'R';
+ pfl->cfi_table[0x02 + pri_ofs] = 'I';
+
+ /* Extended version 1.0 */
+ pfl->cfi_table[0x03 + pri_ofs] = '1';
+ pfl->cfi_table[0x04 + pri_ofs] = '0';
+
+ /* Address sensitive unlock required. */
+ pfl->cfi_table[0x05 + pri_ofs] = 0x00;
+ /* Erase suspend to read/write. */
+ pfl->cfi_table[0x06 + pri_ofs] = 0x02;
+ /* Sector protect not supported. */
+ pfl->cfi_table[0x07 + pri_ofs] = 0x00;
+ /* Temporary sector unprotect not supported. */
+ pfl->cfi_table[0x08 + pri_ofs] = 0x00;
+
+ /* Sector protect/unprotect scheme. */
+ pfl->cfi_table[0x09 + pri_ofs] = 0x00;
+
+ /* Simultaneous operation not supported. */
+ pfl->cfi_table[0x0a + pri_ofs] = 0x00;
+ /* Burst mode not supported. */
+ pfl->cfi_table[0x0b + pri_ofs] = 0x00;
+ /* Page mode not supported. */
+ pfl->cfi_table[0x0c + pri_ofs] = 0x00;
+ assert(0x0c + pri_ofs < ARRAY_SIZE(pfl->cfi_table));
}
static Property pflash_cfi02_properties[] = {
DEFINE_PROP_DRIVE("drive", PFlashCFI02, blk),
- DEFINE_PROP_UINT32("num-blocks", PFlashCFI02, nb_blocs, 0),
- DEFINE_PROP_UINT32("sector-length", PFlashCFI02, sector_len, 0),
+ DEFINE_PROP_UINT32("num-blocks", PFlashCFI02, uniform_nb_blocs, 0),
+ DEFINE_PROP_UINT32("sector-length", PFlashCFI02, uniform_sector_len, 0),
+ DEFINE_PROP_UINT32("num-blocks0", PFlashCFI02, nb_blocs[0], 0),
+ DEFINE_PROP_UINT32("sector-length0", PFlashCFI02, sector_len[0], 0),
+ DEFINE_PROP_UINT32("num-blocks1", PFlashCFI02, nb_blocs[1], 0),
+ DEFINE_PROP_UINT32("sector-length1", PFlashCFI02, sector_len[1], 0),
+ DEFINE_PROP_UINT32("num-blocks2", PFlashCFI02, nb_blocs[2], 0),
+ DEFINE_PROP_UINT32("sector-length2", PFlashCFI02, sector_len[2], 0),
+ DEFINE_PROP_UINT32("num-blocks3", PFlashCFI02, nb_blocs[3], 0),
+ DEFINE_PROP_UINT32("sector-length3", PFlashCFI02, sector_len[3], 0),
DEFINE_PROP_UINT8("width", PFlashCFI02, width, 0),
DEFINE_PROP_UINT8("mappings", PFlashCFI02, mappings, 0),
DEFINE_PROP_UINT8("big-endian", PFlashCFI02, be, 0),
{
PFlashCFI02 *pfl = PFLASH_CFI02(dev);
timer_del(&pfl->timer);
+ g_free(pfl->sector_erase_map);
}
static void pflash_cfi02_class_init(ObjectClass *klass, void *data)
# pflash_cfi02.c
# pflash_cfi01.c
pflash_reset(void) "reset"
-pflash_read(uint64_t offset, uint8_t cmd, int width, uint8_t wcycle) "offset:0x%04"PRIx64" cmd:0x%02x width:%d wcycle:%u"
-pflash_write(uint64_t offset, uint32_t value, int width, uint8_t wcycle) "offset:0x%04"PRIx64" value:0x%03x width:%d wcycle:%u"
pflash_timer_expired(uint8_t cmd) "command 0x%02x done"
-pflash_data_read8(uint64_t offset, uint32_t value) "data offset:0x%04"PRIx64" value:0x%02x"
-pflash_data_read16(uint64_t offset, uint32_t value) "data offset:0x%04"PRIx64" value:0x%04x"
-pflash_data_read32(uint64_t offset, uint32_t value) "data offset:0x%04"PRIx64" value:0x%08x"
-pflash_data_write(uint64_t offset, uint32_t value, int width, uint64_t counter) "data offset:0x%04"PRIx64" value:0x%08x width:%d counter:0x%016"PRIx64
+pflash_io_read(uint64_t offset, int width, int fmt_width, uint32_t value, uint8_t cmd, uint8_t wcycle) "offset:0x%04"PRIx64" width:%d value:0x%0*x cmd:0x%02x wcycle:%u"
+pflash_io_write(uint64_t offset, int width, int fmt_width, uint32_t value, uint8_t wcycle) "offset:0x%04"PRIx64" width:%d value:0x%0*x wcycle:%u"
+pflash_data_read(uint64_t offset, int width, uint32_t value) "data offset:0x%04"PRIx64" value:0x%0*x"
+pflash_data_write(uint64_t offset, int width, uint32_t value, uint64_t counter) "data offset:0x%04"PRIx64" value:0x%0*x counter:0x%016"PRIx64
pflash_manufacturer_id(uint16_t id) "Read Manufacturer ID: 0x%04x"
pflash_device_id(uint16_t id) "Read Device ID: 0x%04x"
pflash_device_info(uint64_t offset) "Read Device Information offset:0x%04"PRIx64
#include "qemu/option.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-block-core.h"
-#include "qapi/qapi-commands-misc.h"
+#include "qapi/qapi-commands-qom.h"
#include "qapi/qapi-visit-block-core.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/visitor.h"
XenBlockDevice *blockdev = XEN_BLOCK_DEVICE(xendev);
const char *type = object_get_typename(OBJECT(blockdev));
XenBlockVdev *vdev = &blockdev->props.vdev;
+ BlockConf *conf = &blockdev->props.conf;
+ unsigned int feature_large_sector_size;
unsigned int order, nr_ring_ref, *ring_ref, event_channel, protocol;
char *str;
trace_xen_block_connect(type, vdev->disk, vdev->partition);
+ if (xen_device_frontend_scanf(xendev, "feature-large-sector-size", "%u",
+ &feature_large_sector_size) != 1) {
+ feature_large_sector_size = 0;
+ }
+
+ if (feature_large_sector_size != 1 &&
+ conf->logical_block_size != XEN_BLKIF_SECTOR_SIZE) {
+ error_setg(errp, "logical_block_size != %u not supported by frontend",
+ XEN_BLKIF_SECTOR_SIZE);
+ return;
+ }
+
if (xen_device_frontend_scanf(xendev, "ring-page-order", "%u",
&order) != 1) {
nr_ring_ref = 1;
const char *type = object_get_typename(OBJECT(blockdev));
XenBlockVdev *vdev = &blockdev->props.vdev;
BlockConf *conf = &blockdev->props.conf;
- int64_t sectors = blk_getlength(conf->blk) / XEN_BLKIF_SECTOR_SIZE;
+ int64_t sectors = blk_getlength(conf->blk) / conf->logical_block_size;
XenDevice *xendev = XEN_DEVICE(blockdev);
trace_xen_block_size(type, vdev->disk, vdev->partition, sectors);
const char *type = object_get_typename(OBJECT(blockdev));
XenBlockVdev *vdev = &blockdev->props.vdev;
BlockConf *conf = &blockdev->props.conf;
+ BlockBackend *blk = conf->blk;
Error *local_err = NULL;
if (vdev->type == XEN_BLOCK_VDEV_TYPE_INVALID) {
* The blkif protocol does not deal with removable media, so it must
* always be present, even for CDRom devices.
*/
- assert(conf->blk);
- if (!blk_is_inserted(conf->blk)) {
+ assert(blk);
+ if (!blk_is_inserted(blk)) {
error_setg(errp, "device needs media, but drive is empty");
return;
}
blkconf_blocksizes(conf);
- if (conf->logical_block_size != XEN_BLKIF_SECTOR_SIZE) {
- error_setg(errp, "logical_block_size != %u not supported",
- XEN_BLKIF_SECTOR_SIZE);
- return;
- }
-
if (conf->logical_block_size > conf->physical_block_size) {
error_setg(
errp, "logical_block_size > physical_block_size not supported");
return;
}
- blk_set_dev_ops(conf->blk, &xen_block_dev_ops, blockdev);
- blk_set_guest_block_size(conf->blk, conf->logical_block_size);
+ blk_set_dev_ops(blk, &xen_block_dev_ops, blockdev);
+ blk_set_guest_block_size(blk, conf->logical_block_size);
if (conf->discard_granularity == -1) {
conf->discard_granularity = conf->physical_block_size;
}
- if (blk_get_flags(conf->blk) & BDRV_O_UNMAP) {
+ if (blk_get_flags(blk) & BDRV_O_UNMAP) {
xen_device_backend_printf(xendev, "feature-discard", "%u", 1);
xen_device_backend_printf(xendev, "discard-granularity", "%u",
conf->discard_granularity);
blockdev->device_type);
xen_device_backend_printf(xendev, "sector-size", "%u",
- XEN_BLKIF_SECTOR_SIZE);
+ conf->logical_block_size);
xen_block_set_size(blockdev);
blockdev->dataplane =
- xen_block_dataplane_create(xendev, conf, blockdev->props.iothread);
+ xen_block_dataplane_create(xendev, blk, conf->logical_block_size,
+ blockdev->props.iothread);
}
static void xen_block_frontend_changed(XenDevice *xendev,
#ifndef XEN_BLKIF_H
#define XEN_BLKIF_H
-#include "hw/xen/io/ring.h"
-#include <xen/io/blkif.h>
-#include <xen/io/protocols.h>
+#include "hw/xen/interface/io/blkif.h"
+#include "hw/xen/interface/io/protocols.h"
/*
* Not a real protocol. Used to generate ring structs which contain
#include "chardev/char-fe.h"
#include "hw/xen/xen-legacy-backend.h"
-#include <xen/io/console.h>
+#include "hw/xen/interface/io/console.h"
struct buffer {
uint8_t *data;
common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
common-obj-$(CONFIG_SOFTMMU) += generic-loader.o
common-obj-$(CONFIG_SOFTMMU) += null-machine.o
+
+obj-$(CONFIG_SOFTMMU) += machine-qmp-cmds.o
+obj-$(CONFIG_SOFTMMU) += numa.o
+common-obj-$(CONFIG_SOFTMMU) += machine-hmp-cmds.o
--- /dev/null
+/*
+ * HMP commands related to machines and CPUs
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "monitor/hmp.h"
+#include "monitor/monitor.h"
+#include "qapi/error.h"
+#include "qapi/qapi-builtin-visit.h"
+#include "qapi/qapi-commands-machine.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/string-output-visitor.h"
+#include "qemu/error-report.h"
+#include "sysemu/numa.h"
+
+void hmp_info_cpus(Monitor *mon, const QDict *qdict)
+{
+ CpuInfoFastList *cpu_list, *cpu;
+
+ cpu_list = qmp_query_cpus_fast(NULL);
+
+ for (cpu = cpu_list; cpu; cpu = cpu->next) {
+ int active = ' ';
+
+ if (cpu->value->cpu_index == monitor_get_cpu_index()) {
+ active = '*';
+ }
+
+ monitor_printf(mon, "%c CPU #%" PRId64 ":", active,
+ cpu->value->cpu_index);
+ monitor_printf(mon, " thread_id=%" PRId64 "\n", cpu->value->thread_id);
+ }
+
+ qapi_free_CpuInfoFastList(cpu_list);
+}
+
+void hmp_cpu_add(Monitor *mon, const QDict *qdict)
+{
+ int cpuid;
+ Error *err = NULL;
+
+ error_report("cpu_add is deprecated, please use device_add instead");
+
+ cpuid = qdict_get_int(qdict, "id");
+ qmp_cpu_add(cpuid, &err);
+ hmp_handle_error(mon, &err);
+}
+
+void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
+{
+ Error *err = NULL;
+ HotpluggableCPUList *l = qmp_query_hotpluggable_cpus(&err);
+ HotpluggableCPUList *saved = l;
+ CpuInstanceProperties *c;
+
+ if (err != NULL) {
+ hmp_handle_error(mon, &err);
+ return;
+ }
+
+ monitor_printf(mon, "Hotpluggable CPUs:\n");
+ while (l) {
+ monitor_printf(mon, " type: \"%s\"\n", l->value->type);
+ monitor_printf(mon, " vcpus_count: \"%" PRIu64 "\"\n",
+ l->value->vcpus_count);
+ if (l->value->has_qom_path) {
+ monitor_printf(mon, " qom_path: \"%s\"\n", l->value->qom_path);
+ }
+
+ c = l->value->props;
+ monitor_printf(mon, " CPUInstance Properties:\n");
+ if (c->has_node_id) {
+ monitor_printf(mon, " node-id: \"%" PRIu64 "\"\n", c->node_id);
+ }
+ if (c->has_socket_id) {
+ monitor_printf(mon, " socket-id: \"%" PRIu64 "\"\n", c->socket_id);
+ }
+ if (c->has_core_id) {
+ monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id);
+ }
+ if (c->has_thread_id) {
+ monitor_printf(mon, " thread-id: \"%" PRIu64 "\"\n", c->thread_id);
+ }
+
+ l = l->next;
+ }
+
+ qapi_free_HotpluggableCPUList(saved);
+}
+
+void hmp_info_memdev(Monitor *mon, const QDict *qdict)
+{
+ Error *err = NULL;
+ MemdevList *memdev_list = qmp_query_memdev(&err);
+ MemdevList *m = memdev_list;
+ Visitor *v;
+ char *str;
+
+ while (m) {
+ v = string_output_visitor_new(false, &str);
+ visit_type_uint16List(v, NULL, &m->value->host_nodes, NULL);
+ monitor_printf(mon, "memory backend: %s\n", m->value->id);
+ monitor_printf(mon, " size: %" PRId64 "\n", m->value->size);
+ monitor_printf(mon, " merge: %s\n",
+ m->value->merge ? "true" : "false");
+ monitor_printf(mon, " dump: %s\n",
+ m->value->dump ? "true" : "false");
+ monitor_printf(mon, " prealloc: %s\n",
+ m->value->prealloc ? "true" : "false");
+ monitor_printf(mon, " policy: %s\n",
+ HostMemPolicy_str(m->value->policy));
+ visit_complete(v, &str);
+ monitor_printf(mon, " host nodes: %s\n", str);
+
+ g_free(str);
+ visit_free(v);
+ m = m->next;
+ }
+
+ monitor_printf(mon, "\n");
+
+ qapi_free_MemdevList(memdev_list);
+ hmp_handle_error(mon, &err);
+}
+
+void hmp_info_numa(Monitor *mon, const QDict *qdict)
+{
+ int i;
+ NumaNodeMem *node_mem;
+ CpuInfoList *cpu_list, *cpu;
+
+ cpu_list = qmp_query_cpus(&error_abort);
+ node_mem = g_new0(NumaNodeMem, nb_numa_nodes);
+
+ query_numa_node_mem(node_mem);
+ monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
+ for (i = 0; i < nb_numa_nodes; i++) {
+ monitor_printf(mon, "node %d cpus:", i);
+ for (cpu = cpu_list; cpu; cpu = cpu->next) {
+ if (cpu->value->has_props && cpu->value->props->has_node_id &&
+ cpu->value->props->node_id == i) {
+ monitor_printf(mon, " %" PRIi64, cpu->value->CPU);
+ }
+ }
+ monitor_printf(mon, "\n");
+ monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i,
+ node_mem[i].node_mem >> 20);
+ monitor_printf(mon, "node %d plugged: %" PRId64 " MB\n", i,
+ node_mem[i].node_plugged_mem >> 20);
+ }
+ qapi_free_CpuInfoList(cpu_list);
+ g_free(node_mem);
+}
--- /dev/null
+/*
+ * QMP commands related to machines and CPUs
+ *
+ * Copyright (C) 2014 Red Hat Inc
+ *
+ * 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 "cpu.h"
+#include "hw/boards.h"
+#include "qapi/error.h"
+#include "qapi/qapi-commands-machine.h"
+#include "qapi/qmp/qerror.h"
+#include "sysemu/hostmem.h"
+#include "sysemu/hw_accel.h"
+#include "sysemu/numa.h"
+#include "sysemu/sysemu.h"
+
+CpuInfoList *qmp_query_cpus(Error **errp)
+{
+ MachineState *ms = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+ CpuInfoList *head = NULL, *cur_item = NULL;
+ CPUState *cpu;
+
+ CPU_FOREACH(cpu) {
+ CpuInfoList *info;
+#if defined(TARGET_I386)
+ X86CPU *x86_cpu = X86_CPU(cpu);
+ CPUX86State *env = &x86_cpu->env;
+#elif defined(TARGET_PPC)
+ PowerPCCPU *ppc_cpu = POWERPC_CPU(cpu);
+ CPUPPCState *env = &ppc_cpu->env;
+#elif defined(TARGET_SPARC)
+ SPARCCPU *sparc_cpu = SPARC_CPU(cpu);
+ CPUSPARCState *env = &sparc_cpu->env;
+#elif defined(TARGET_RISCV)
+ RISCVCPU *riscv_cpu = RISCV_CPU(cpu);
+ CPURISCVState *env = &riscv_cpu->env;
+#elif defined(TARGET_MIPS)
+ MIPSCPU *mips_cpu = MIPS_CPU(cpu);
+ CPUMIPSState *env = &mips_cpu->env;
+#elif defined(TARGET_TRICORE)
+ TriCoreCPU *tricore_cpu = TRICORE_CPU(cpu);
+ CPUTriCoreState *env = &tricore_cpu->env;
+#elif defined(TARGET_S390X)
+ S390CPU *s390_cpu = S390_CPU(cpu);
+ CPUS390XState *env = &s390_cpu->env;
+#endif
+
+ cpu_synchronize_state(cpu);
+
+ info = g_malloc0(sizeof(*info));
+ info->value = g_malloc0(sizeof(*info->value));
+ info->value->CPU = cpu->cpu_index;
+ info->value->current = (cpu == first_cpu);
+ info->value->halted = cpu->halted;
+ info->value->qom_path = object_get_canonical_path(OBJECT(cpu));
+ info->value->thread_id = cpu->thread_id;
+#if defined(TARGET_I386)
+ info->value->arch = CPU_INFO_ARCH_X86;
+ info->value->u.x86.pc = env->eip + env->segs[R_CS].base;
+#elif defined(TARGET_PPC)
+ info->value->arch = CPU_INFO_ARCH_PPC;
+ info->value->u.ppc.nip = env->nip;
+#elif defined(TARGET_SPARC)
+ info->value->arch = CPU_INFO_ARCH_SPARC;
+ info->value->u.q_sparc.pc = env->pc;
+ info->value->u.q_sparc.npc = env->npc;
+#elif defined(TARGET_MIPS)
+ info->value->arch = CPU_INFO_ARCH_MIPS;
+ info->value->u.q_mips.PC = env->active_tc.PC;
+#elif defined(TARGET_TRICORE)
+ info->value->arch = CPU_INFO_ARCH_TRICORE;
+ info->value->u.tricore.PC = env->PC;
+#elif defined(TARGET_S390X)
+ info->value->arch = CPU_INFO_ARCH_S390;
+ info->value->u.s390.cpu_state = env->cpu_state;
+#elif defined(TARGET_RISCV)
+ info->value->arch = CPU_INFO_ARCH_RISCV;
+ info->value->u.riscv.pc = env->pc;
+#else
+ info->value->arch = CPU_INFO_ARCH_OTHER;
+#endif
+ info->value->has_props = !!mc->cpu_index_to_instance_props;
+ if (info->value->has_props) {
+ CpuInstanceProperties *props;
+ props = g_malloc0(sizeof(*props));
+ *props = mc->cpu_index_to_instance_props(ms, cpu->cpu_index);
+ info->value->props = props;
+ }
+
+ /* XXX: waiting for the qapi to support GSList */
+ if (!cur_item) {
+ head = cur_item = info;
+ } else {
+ cur_item->next = info;
+ cur_item = info;
+ }
+ }
+
+ return head;
+}
+
+static CpuInfoArch sysemu_target_to_cpuinfo_arch(SysEmuTarget target)
+{
+ /*
+ * The @SysEmuTarget -> @CpuInfoArch mapping below is based on the
+ * TARGET_ARCH -> TARGET_BASE_ARCH mapping in the "configure" script.
+ */
+ switch (target) {
+ case SYS_EMU_TARGET_I386:
+ case SYS_EMU_TARGET_X86_64:
+ return CPU_INFO_ARCH_X86;
+
+ case SYS_EMU_TARGET_PPC:
+ case SYS_EMU_TARGET_PPC64:
+ return CPU_INFO_ARCH_PPC;
+
+ case SYS_EMU_TARGET_SPARC:
+ case SYS_EMU_TARGET_SPARC64:
+ return CPU_INFO_ARCH_SPARC;
+
+ case SYS_EMU_TARGET_MIPS:
+ case SYS_EMU_TARGET_MIPSEL:
+ case SYS_EMU_TARGET_MIPS64:
+ case SYS_EMU_TARGET_MIPS64EL:
+ return CPU_INFO_ARCH_MIPS;
+
+ case SYS_EMU_TARGET_TRICORE:
+ return CPU_INFO_ARCH_TRICORE;
+
+ case SYS_EMU_TARGET_S390X:
+ return CPU_INFO_ARCH_S390;
+
+ case SYS_EMU_TARGET_RISCV32:
+ case SYS_EMU_TARGET_RISCV64:
+ return CPU_INFO_ARCH_RISCV;
+
+ default:
+ return CPU_INFO_ARCH_OTHER;
+ }
+}
+
+static void cpustate_to_cpuinfo_s390(CpuInfoS390 *info, const CPUState *cpu)
+{
+#ifdef TARGET_S390X
+ S390CPU *s390_cpu = S390_CPU(cpu);
+ CPUS390XState *env = &s390_cpu->env;
+
+ info->cpu_state = env->cpu_state;
+#else
+ abort();
+#endif
+}
+
+/*
+ * fast means: we NEVER interrupt vCPU threads to retrieve
+ * information from KVM.
+ */
+CpuInfoFastList *qmp_query_cpus_fast(Error **errp)
+{
+ MachineState *ms = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+ CpuInfoFastList *head = NULL, *cur_item = NULL;
+ SysEmuTarget target = qapi_enum_parse(&SysEmuTarget_lookup, TARGET_NAME,
+ -1, &error_abort);
+ CPUState *cpu;
+
+ CPU_FOREACH(cpu) {
+ CpuInfoFastList *info = g_malloc0(sizeof(*info));
+ info->value = g_malloc0(sizeof(*info->value));
+
+ info->value->cpu_index = cpu->cpu_index;
+ info->value->qom_path = object_get_canonical_path(OBJECT(cpu));
+ info->value->thread_id = cpu->thread_id;
+
+ info->value->has_props = !!mc->cpu_index_to_instance_props;
+ if (info->value->has_props) {
+ CpuInstanceProperties *props;
+ props = g_malloc0(sizeof(*props));
+ *props = mc->cpu_index_to_instance_props(ms, cpu->cpu_index);
+ info->value->props = props;
+ }
+
+ info->value->arch = sysemu_target_to_cpuinfo_arch(target);
+ info->value->target = target;
+ if (target == SYS_EMU_TARGET_S390X) {
+ cpustate_to_cpuinfo_s390(&info->value->u.s390x, cpu);
+ }
+
+ if (!cur_item) {
+ head = cur_item = info;
+ } else {
+ cur_item->next = info;
+ cur_item = info;
+ }
+ }
+
+ return head;
+}
+
+MachineInfoList *qmp_query_machines(Error **errp)
+{
+ GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
+ MachineInfoList *mach_list = NULL;
+
+ for (el = machines; el; el = el->next) {
+ MachineClass *mc = el->data;
+ MachineInfoList *entry;
+ MachineInfo *info;
+
+ info = g_malloc0(sizeof(*info));
+ if (mc->is_default) {
+ info->has_is_default = true;
+ info->is_default = true;
+ }
+
+ if (mc->alias) {
+ info->has_alias = true;
+ info->alias = g_strdup(mc->alias);
+ }
+
+ info->name = g_strdup(mc->name);
+ info->cpu_max = !mc->max_cpus ? 1 : mc->max_cpus;
+ info->hotpluggable_cpus = mc->has_hotpluggable_cpus;
+
+ entry = g_malloc0(sizeof(*entry));
+ entry->value = info;
+ entry->next = mach_list;
+ mach_list = entry;
+ }
+
+ g_slist_free(machines);
+ return mach_list;
+}
+
+CurrentMachineParams *qmp_query_current_machine(Error **errp)
+{
+ CurrentMachineParams *params = g_malloc0(sizeof(*params));
+ params->wakeup_suspend_support = qemu_wakeup_suspend_enabled();
+
+ return params;
+}
+
+HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp)
+{
+ MachineState *ms = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+
+ if (!mc->has_hotpluggable_cpus) {
+ error_setg(errp, QERR_FEATURE_DISABLED, "query-hotpluggable-cpus");
+ return NULL;
+ }
+
+ return machine_query_hotpluggable_cpus(ms);
+}
+
+void qmp_cpu_add(int64_t id, Error **errp)
+{
+ MachineClass *mc;
+
+ mc = MACHINE_GET_CLASS(current_machine);
+ if (mc->hot_add_cpu) {
+ mc->hot_add_cpu(id, errp);
+ } else {
+ error_setg(errp, "Not supported");
+ }
+}
+
+void qmp_set_numa_node(NumaOptions *cmd, Error **errp)
+{
+ if (!runstate_check(RUN_STATE_PRECONFIG)) {
+ error_setg(errp, "The command is permitted only in '%s' state",
+ RunState_str(RUN_STATE_PRECONFIG));
+ return;
+ }
+
+ set_numa_options(MACHINE(qdev_get_machine()), cmd, errp);
+}
+
+static int query_memdev(Object *obj, void *opaque)
+{
+ MemdevList **list = opaque;
+ MemdevList *m = NULL;
+
+ if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) {
+ m = g_malloc0(sizeof(*m));
+
+ m->value = g_malloc0(sizeof(*m->value));
+
+ m->value->id = object_get_canonical_path_component(obj);
+ m->value->has_id = !!m->value->id;
+
+ m->value->size = object_property_get_uint(obj, "size",
+ &error_abort);
+ m->value->merge = object_property_get_bool(obj, "merge",
+ &error_abort);
+ m->value->dump = object_property_get_bool(obj, "dump",
+ &error_abort);
+ m->value->prealloc = object_property_get_bool(obj,
+ "prealloc",
+ &error_abort);
+ m->value->policy = object_property_get_enum(obj,
+ "policy",
+ "HostMemPolicy",
+ &error_abort);
+ object_property_get_uint16List(obj, "host-nodes",
+ &m->value->host_nodes,
+ &error_abort);
+
+ m->next = *list;
+ *list = m;
+ }
+
+ return 0;
+}
+
+MemdevList *qmp_query_memdev(Error **errp)
+{
+ Object *obj = object_get_objects_root();
+ MemdevList *list = NULL;
+
+ object_child_foreach(obj, query_memdev, &list);
+ return list;
+}
--- /dev/null
+/*
+ * NUMA parameter parsing routines
+ *
+ * Copyright (c) 2014 Fujitsu Ltd.
+ *
+ * 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 "sysemu/numa.h"
+#include "exec/cpu-common.h"
+#include "exec/ramlist.h"
+#include "qemu/bitmap.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "qapi/opts-visitor.h"
+#include "qapi/qapi-visit-machine.h"
+#include "hw/mem/pc-dimm.h"
+#include "hw/mem/memory-device.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
+#include "qemu/cutils.h"
+
+QemuOptsList qemu_numa_opts = {
+ .name = "numa",
+ .implied_opt_name = "type",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_numa_opts.head),
+ .desc = { { 0 } } /* validated with OptsVisitor */
+};
+
+static int have_memdevs = -1;
+static int max_numa_nodeid; /* Highest specified NUMA node ID, plus one.
+ * For all nodes, nodeid < max_numa_nodeid
+ */
+int nb_numa_nodes;
+bool have_numa_distance;
+NodeInfo numa_info[MAX_NODES];
+
+
+static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
+ Error **errp)
+{
+ Error *err = NULL;
+ uint16_t nodenr;
+ uint16List *cpus = NULL;
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+
+ if (node->has_nodeid) {
+ nodenr = node->nodeid;
+ } else {
+ nodenr = nb_numa_nodes;
+ }
+
+ if (nodenr >= MAX_NODES) {
+ error_setg(errp, "Max number of NUMA nodes reached: %"
+ PRIu16 "", nodenr);
+ return;
+ }
+
+ if (numa_info[nodenr].present) {
+ error_setg(errp, "Duplicate NUMA nodeid: %" PRIu16, nodenr);
+ return;
+ }
+
+ if (!mc->cpu_index_to_instance_props || !mc->get_default_cpu_node_id) {
+ error_setg(errp, "NUMA is not supported by this machine-type");
+ return;
+ }
+ for (cpus = node->cpus; cpus; cpus = cpus->next) {
+ CpuInstanceProperties props;
+ if (cpus->value >= max_cpus) {
+ error_setg(errp,
+ "CPU index (%" PRIu16 ")"
+ " should be smaller than maxcpus (%d)",
+ cpus->value, max_cpus);
+ return;
+ }
+ props = mc->cpu_index_to_instance_props(ms, cpus->value);
+ props.node_id = nodenr;
+ props.has_node_id = true;
+ machine_set_cpu_numa_node(ms, &props, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ }
+
+ if (node->has_mem && node->has_memdev) {
+ error_setg(errp, "cannot specify both mem= and memdev=");
+ return;
+ }
+
+ if (have_memdevs == -1) {
+ have_memdevs = node->has_memdev;
+ }
+ if (node->has_memdev != have_memdevs) {
+ error_setg(errp, "memdev option must be specified for either "
+ "all or no nodes");
+ return;
+ }
+
+ if (node->has_mem) {
+ numa_info[nodenr].node_mem = node->mem;
+ }
+ if (node->has_memdev) {
+ Object *o;
+ o = object_resolve_path_type(node->memdev, TYPE_MEMORY_BACKEND, NULL);
+ if (!o) {
+ error_setg(errp, "memdev=%s is ambiguous", node->memdev);
+ return;
+ }
+
+ object_ref(o);
+ numa_info[nodenr].node_mem = object_property_get_uint(o, "size", NULL);
+ numa_info[nodenr].node_memdev = MEMORY_BACKEND(o);
+ }
+ numa_info[nodenr].present = true;
+ max_numa_nodeid = MAX(max_numa_nodeid, nodenr + 1);
+ nb_numa_nodes++;
+}
+
+static void parse_numa_distance(NumaDistOptions *dist, Error **errp)
+{
+ uint16_t src = dist->src;
+ uint16_t dst = dist->dst;
+ uint8_t val = dist->val;
+
+ if (src >= MAX_NODES || dst >= MAX_NODES) {
+ error_setg(errp, "Parameter '%s' expects an integer between 0 and %d",
+ src >= MAX_NODES ? "src" : "dst", MAX_NODES - 1);
+ return;
+ }
+
+ if (!numa_info[src].present || !numa_info[dst].present) {
+ error_setg(errp, "Source/Destination NUMA node is missing. "
+ "Please use '-numa node' option to declare it first.");
+ return;
+ }
+
+ if (val < NUMA_DISTANCE_MIN) {
+ error_setg(errp, "NUMA distance (%" PRIu8 ") is invalid, "
+ "it shouldn't be less than %d.",
+ val, NUMA_DISTANCE_MIN);
+ return;
+ }
+
+ if (src == dst && val != NUMA_DISTANCE_MIN) {
+ error_setg(errp, "Local distance of node %d should be %d.",
+ src, NUMA_DISTANCE_MIN);
+ return;
+ }
+
+ numa_info[src].distance[dst] = val;
+ have_numa_distance = true;
+}
+
+void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp)
+{
+ Error *err = NULL;
+
+ switch (object->type) {
+ case NUMA_OPTIONS_TYPE_NODE:
+ parse_numa_node(ms, &object->u.node, &err);
+ if (err) {
+ goto end;
+ }
+ break;
+ case NUMA_OPTIONS_TYPE_DIST:
+ parse_numa_distance(&object->u.dist, &err);
+ if (err) {
+ goto end;
+ }
+ break;
+ case NUMA_OPTIONS_TYPE_CPU:
+ if (!object->u.cpu.has_node_id) {
+ error_setg(&err, "Missing mandatory node-id property");
+ goto end;
+ }
+ if (!numa_info[object->u.cpu.node_id].present) {
+ error_setg(&err, "Invalid node-id=%" PRId64 ", NUMA node must be "
+ "defined with -numa node,nodeid=ID before it's used with "
+ "-numa cpu,node-id=ID", object->u.cpu.node_id);
+ goto end;
+ }
+
+ machine_set_cpu_numa_node(ms, qapi_NumaCpuOptions_base(&object->u.cpu),
+ &err);
+ break;
+ default:
+ abort();
+ }
+
+end:
+ error_propagate(errp, err);
+}
+
+static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
+{
+ NumaOptions *object = NULL;
+ MachineState *ms = MACHINE(opaque);
+ Error *err = NULL;
+ Visitor *v = opts_visitor_new(opts);
+
+ visit_type_NumaOptions(v, NULL, &object, &err);
+ visit_free(v);
+ if (err) {
+ goto end;
+ }
+
+ /* Fix up legacy suffix-less format */
+ if ((object->type == NUMA_OPTIONS_TYPE_NODE) && object->u.node.has_mem) {
+ const char *mem_str = qemu_opt_get(opts, "mem");
+ qemu_strtosz_MiB(mem_str, NULL, &object->u.node.mem);
+ }
+
+ set_numa_options(ms, object, &err);
+
+end:
+ qapi_free_NumaOptions(object);
+ if (err) {
+ error_propagate(errp, err);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* If all node pair distances are symmetric, then only distances
+ * in one direction are enough. If there is even one asymmetric
+ * pair, though, then all distances must be provided. The
+ * distance from a node to itself is always NUMA_DISTANCE_MIN,
+ * so providing it is never necessary.
+ */
+static void validate_numa_distance(void)
+{
+ int src, dst;
+ bool is_asymmetrical = false;
+
+ for (src = 0; src < nb_numa_nodes; src++) {
+ for (dst = src; dst < nb_numa_nodes; dst++) {
+ if (numa_info[src].distance[dst] == 0 &&
+ numa_info[dst].distance[src] == 0) {
+ if (src != dst) {
+ error_report("The distance between node %d and %d is "
+ "missing, at least one distance value "
+ "between each nodes should be provided.",
+ src, dst);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (numa_info[src].distance[dst] != 0 &&
+ numa_info[dst].distance[src] != 0 &&
+ numa_info[src].distance[dst] !=
+ numa_info[dst].distance[src]) {
+ is_asymmetrical = true;
+ }
+ }
+ }
+
+ if (is_asymmetrical) {
+ for (src = 0; src < nb_numa_nodes; src++) {
+ for (dst = 0; dst < nb_numa_nodes; dst++) {
+ if (src != dst && numa_info[src].distance[dst] == 0) {
+ error_report("At least one asymmetrical pair of "
+ "distances is given, please provide distances "
+ "for both directions of all node pairs.");
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+ }
+}
+
+static void complete_init_numa_distance(void)
+{
+ int src, dst;
+
+ /* Fixup NUMA distance by symmetric policy because if it is an
+ * asymmetric distance table, it should be a complete table and
+ * there would not be any missing distance except local node, which
+ * is verified by validate_numa_distance above.
+ */
+ for (src = 0; src < nb_numa_nodes; src++) {
+ for (dst = 0; dst < nb_numa_nodes; dst++) {
+ if (numa_info[src].distance[dst] == 0) {
+ if (src == dst) {
+ numa_info[src].distance[dst] = NUMA_DISTANCE_MIN;
+ } else {
+ numa_info[src].distance[dst] = numa_info[dst].distance[src];
+ }
+ }
+ }
+ }
+}
+
+void numa_legacy_auto_assign_ram(MachineClass *mc, NodeInfo *nodes,
+ int nb_nodes, ram_addr_t size)
+{
+ int i;
+ uint64_t usedmem = 0;
+
+ /* Align each node according to the alignment
+ * requirements of the machine class
+ */
+
+ for (i = 0; i < nb_nodes - 1; i++) {
+ nodes[i].node_mem = (size / nb_nodes) &
+ ~((1 << mc->numa_mem_align_shift) - 1);
+ usedmem += nodes[i].node_mem;
+ }
+ nodes[i].node_mem = size - usedmem;
+}
+
+void numa_default_auto_assign_ram(MachineClass *mc, NodeInfo *nodes,
+ int nb_nodes, ram_addr_t size)
+{
+ int i;
+ uint64_t usedmem = 0, node_mem;
+ uint64_t granularity = size / nb_nodes;
+ uint64_t propagate = 0;
+
+ for (i = 0; i < nb_nodes - 1; i++) {
+ node_mem = (granularity + propagate) &
+ ~((1 << mc->numa_mem_align_shift) - 1);
+ propagate = granularity + propagate - node_mem;
+ nodes[i].node_mem = node_mem;
+ usedmem += node_mem;
+ }
+ nodes[i].node_mem = size - usedmem;
+}
+
+void numa_complete_configuration(MachineState *ms)
+{
+ int i;
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+
+ /*
+ * If memory hotplug is enabled (slots > 0) but without '-numa'
+ * options explicitly on CLI, guestes will break.
+ *
+ * Windows: won't enable memory hotplug without SRAT table at all
+ *
+ * Linux: if QEMU is started with initial memory all below 4Gb
+ * and no SRAT table present, guest kernel will use nommu DMA ops,
+ * which breaks 32bit hw drivers when memory is hotplugged and
+ * guest tries to use it with that drivers.
+ *
+ * Enable NUMA implicitly by adding a new NUMA node automatically.
+ */
+ if (ms->ram_slots > 0 && nb_numa_nodes == 0 &&
+ mc->auto_enable_numa_with_memhp) {
+ NumaNodeOptions node = { };
+ parse_numa_node(ms, &node, &error_abort);
+ }
+
+ assert(max_numa_nodeid <= MAX_NODES);
+
+ /* No support for sparse NUMA node IDs yet: */
+ for (i = max_numa_nodeid - 1; i >= 0; i--) {
+ /* Report large node IDs first, to make mistakes easier to spot */
+ if (!numa_info[i].present) {
+ error_report("numa: Node ID missing: %d", i);
+ exit(1);
+ }
+ }
+
+ /* This must be always true if all nodes are present: */
+ assert(nb_numa_nodes == max_numa_nodeid);
+
+ if (nb_numa_nodes > 0) {
+ uint64_t numa_total;
+
+ if (nb_numa_nodes > MAX_NODES) {
+ nb_numa_nodes = MAX_NODES;
+ }
+
+ /* If no memory size is given for any node, assume the default case
+ * and distribute the available memory equally across all nodes
+ */
+ for (i = 0; i < nb_numa_nodes; i++) {
+ if (numa_info[i].node_mem != 0) {
+ break;
+ }
+ }
+ if (i == nb_numa_nodes) {
+ assert(mc->numa_auto_assign_ram);
+ mc->numa_auto_assign_ram(mc, numa_info, nb_numa_nodes, ram_size);
+ }
+
+ numa_total = 0;
+ for (i = 0; i < nb_numa_nodes; i++) {
+ numa_total += numa_info[i].node_mem;
+ }
+ if (numa_total != ram_size) {
+ error_report("total memory for NUMA nodes (0x%" PRIx64 ")"
+ " should equal RAM size (0x" RAM_ADDR_FMT ")",
+ numa_total, ram_size);
+ exit(1);
+ }
+
+ /* QEMU needs at least all unique node pair distances to build
+ * the whole NUMA distance table. QEMU treats the distance table
+ * as symmetric by default, i.e. distance A->B == distance B->A.
+ * Thus, QEMU is able to complete the distance table
+ * initialization even though only distance A->B is provided and
+ * distance B->A is not. QEMU knows the distance of a node to
+ * itself is always 10, so A->A distances may be omitted. When
+ * the distances of two nodes of a pair differ, i.e. distance
+ * A->B != distance B->A, then that means the distance table is
+ * asymmetric. In this case, the distances for both directions
+ * of all node pairs are required.
+ */
+ if (have_numa_distance) {
+ /* Validate enough NUMA distance information was provided. */
+ validate_numa_distance();
+
+ /* Validation succeeded, now fill in any missing distances. */
+ complete_init_numa_distance();
+ }
+ }
+}
+
+void parse_numa_opts(MachineState *ms)
+{
+ qemu_opts_foreach(qemu_find_opts("numa"), parse_numa, ms, &error_fatal);
+}
+
+void numa_cpu_pre_plug(const CPUArchId *slot, DeviceState *dev, Error **errp)
+{
+ int node_id = object_property_get_int(OBJECT(dev), "node-id", &error_abort);
+
+ if (node_id == CPU_UNSET_NUMA_NODE_ID) {
+ /* due to bug in libvirt, it doesn't pass node-id from props on
+ * device_add as expected, so we have to fix it up here */
+ if (slot->props.has_node_id) {
+ object_property_set_int(OBJECT(dev), slot->props.node_id,
+ "node-id", errp);
+ }
+ } else if (node_id != slot->props.node_id) {
+ error_setg(errp, "invalid node-id, must be %"PRId64,
+ slot->props.node_id);
+ }
+}
+
+static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner,
+ const char *name,
+ uint64_t ram_size)
+{
+ if (mem_path) {
+#ifdef __linux__
+ Error *err = NULL;
+ memory_region_init_ram_from_file(mr, owner, name, ram_size, 0, 0,
+ mem_path, &err);
+ if (err) {
+ error_report_err(err);
+ if (mem_prealloc) {
+ exit(1);
+ }
+ error_report("falling back to regular RAM allocation.");
+
+ /* Legacy behavior: if allocation failed, fall back to
+ * regular RAM allocation.
+ */
+ mem_path = NULL;
+ memory_region_init_ram_nomigrate(mr, owner, name, ram_size, &error_fatal);
+ }
+#else
+ fprintf(stderr, "-mem-path not supported on this host\n");
+ exit(1);
+#endif
+ } else {
+ memory_region_init_ram_nomigrate(mr, owner, name, ram_size, &error_fatal);
+ }
+ vmstate_register_ram_global(mr);
+}
+
+void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
+ const char *name,
+ uint64_t ram_size)
+{
+ uint64_t addr = 0;
+ int i;
+
+ if (nb_numa_nodes == 0 || !have_memdevs) {
+ allocate_system_memory_nonnuma(mr, owner, name, ram_size);
+ return;
+ }
+
+ memory_region_init(mr, owner, name, ram_size);
+ for (i = 0; i < nb_numa_nodes; i++) {
+ uint64_t size = numa_info[i].node_mem;
+ HostMemoryBackend *backend = numa_info[i].node_memdev;
+ if (!backend) {
+ continue;
+ }
+ MemoryRegion *seg = host_memory_backend_get_memory(backend);
+
+ if (memory_region_is_mapped(seg)) {
+ char *path = object_get_canonical_path_component(OBJECT(backend));
+ error_report("memory backend %s is used multiple times. Each "
+ "-numa option must use a different memdev value.",
+ path);
+ g_free(path);
+ exit(1);
+ }
+
+ host_memory_backend_set_mapped(backend, true);
+ memory_region_add_subregion(mr, addr, seg);
+ vmstate_register_ram_global(seg);
+ addr += size;
+ }
+}
+
+static void numa_stat_memory_devices(NumaNodeMem node_mem[])
+{
+ MemoryDeviceInfoList *info_list = qmp_memory_device_list();
+ MemoryDeviceInfoList *info;
+ PCDIMMDeviceInfo *pcdimm_info;
+
+ for (info = info_list; info; info = info->next) {
+ MemoryDeviceInfo *value = info->value;
+
+ if (value) {
+ switch (value->type) {
+ case MEMORY_DEVICE_INFO_KIND_DIMM:
+ pcdimm_info = value->u.dimm.data;
+ break;
+
+ case MEMORY_DEVICE_INFO_KIND_NVDIMM:
+ pcdimm_info = value->u.nvdimm.data;
+ break;
+
+ default:
+ pcdimm_info = NULL;
+ break;
+ }
+
+ if (pcdimm_info) {
+ node_mem[pcdimm_info->node].node_mem += pcdimm_info->size;
+ node_mem[pcdimm_info->node].node_plugged_mem +=
+ pcdimm_info->size;
+ }
+ }
+ }
+ qapi_free_MemoryDeviceInfoList(info_list);
+}
+
+void query_numa_node_mem(NumaNodeMem node_mem[])
+{
+ int i;
+
+ if (nb_numa_nodes <= 0) {
+ return;
+ }
+
+ numa_stat_memory_devices(node_mem);
+ for (i = 0; i < nb_numa_nodes; i++) {
+ node_mem[i].node_mem += numa_info[i].node_mem;
+ }
+}
+
+void ram_block_notifier_add(RAMBlockNotifier *n)
+{
+ QLIST_INSERT_HEAD(&ram_list.ramblock_notifiers, n, next);
+}
+
+void ram_block_notifier_remove(RAMBlockNotifier *n)
+{
+ QLIST_REMOVE(n, next);
+}
+
+void ram_block_notify_add(void *host, size_t size)
+{
+ RAMBlockNotifier *notifier;
+
+ QLIST_FOREACH(notifier, &ram_list.ramblock_notifiers, next) {
+ notifier->ram_block_added(notifier, host, size);
+ }
+}
+
+void ram_block_notify_remove(void *host, size_t size)
+{
+ RAMBlockNotifier *notifier;
+
+ QLIST_FOREACH(notifier, &ram_list.ramblock_notifiers, next) {
+ notifier->ram_block_removed(notifier, host, size);
+ }
+}
#include "hw/qdev.h"
#include "sysemu/sysemu.h"
#include "qapi/error.h"
-#include "qapi/qapi-events-misc.h"
+#include "qapi/qapi-events-qdev.h"
#include "qapi/qmp/qerror.h"
#include "qapi/visitor.h"
#include "qemu/error-report.h"
default y if PCI_DEVICES
depends on PCI
select VGA
+ select BITBANG_I2C
+ select DDC
#include "qapi/error.h"
#include "hw/hw.h"
#include "ui/console.h"
+#include "hw/display/i2c-ddc.h"
#include "trace.h"
#define ATI_DEBUG_HW_CURSOR 0
}
}
+static uint64_t ati_i2c(bitbang_i2c_interface *i2c, uint64_t data, int base)
+{
+ bool c = (data & BIT(base + 17) ? !!(data & BIT(base + 1)) : 1);
+ bool d = (data & BIT(base + 16) ? !!(data & BIT(base)) : 1);
+
+ bitbang_i2c_set(i2c, BITBANG_I2C_SCL, c);
+ d = bitbang_i2c_set(i2c, BITBANG_I2C_SDA, d);
+
+ data &= ~0xf00ULL;
+ if (c) {
+ data |= BIT(base + 9);
+ }
+ if (d) {
+ data |= BIT(base + 8);
+ }
+ return data;
+}
+
static inline uint64_t ati_reg_read_offs(uint32_t reg, int offs,
unsigned int size)
{
case DAC_CNTL:
val = s->regs.dac_cntl;
break;
-/* case GPIO_MONID: FIXME hook up DDC I2C here */
+ case GPIO_VGA_DDC:
+ val = s->regs.gpio_vga_ddc;
+ break;
+ case GPIO_DVI_DDC:
+ val = s->regs.gpio_dvi_ddc;
+ break;
+ case GPIO_MONID ... GPIO_MONID + 3:
+ val = ati_reg_read_offs(s->regs.gpio_monid,
+ addr - GPIO_MONID, size);
+ break;
case PALETTE_INDEX:
/* FIXME unaligned access */
val = vga_ioport_read(&s->vga, VGA_PEL_IR) << 16;
break;
case DEFAULT_OFFSET:
val = s->regs.default_offset;
+ if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ val >>= 10;
+ val |= s->regs.default_pitch << 16;
+ val |= s->regs.default_tile << 30;
+ }
break;
case DEFAULT_PITCH:
val = s->regs.default_pitch;
+ val |= s->regs.default_tile << 16;
break;
case DEFAULT_SC_BOTTOM_RIGHT:
val = s->regs.default_sc_bottom_right;
s->regs.dac_cntl = data & 0xffffe3ff;
s->vga.dac_8bit = !!(data & DAC_8BIT_EN);
break;
-/* case GPIO_MONID: FIXME hook up DDC I2C here */
+ case GPIO_VGA_DDC:
+ if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ /* FIXME: Maybe add a property to select VGA or DVI port? */
+ }
+ break;
+ case GPIO_DVI_DDC:
+ if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ s->regs.gpio_dvi_ddc = ati_i2c(&s->bbi2c, data, 0);
+ }
+ break;
+ case GPIO_MONID ... GPIO_MONID + 3:
+ /* FIXME What does Radeon have here? */
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ ati_reg_write_offs(&s->regs.gpio_monid,
+ addr - GPIO_MONID, data, size);
+ /*
+ * Rage128p accesses DDC used to get EDID via these bits.
+ * Only touch i2c when write overlaps 3rd byte because some
+ * drivers access this reg via multiple partial writes and
+ * without this spurious bits would be sent.
+ */
+ if ((s->regs.gpio_monid & BIT(25)) &&
+ addr <= GPIO_MONID + 2 && addr + size > GPIO_MONID + 2) {
+ s->regs.gpio_monid = ati_i2c(&s->bbi2c, s->regs.gpio_monid, 1);
+ }
+ }
+ break;
case PALETTE_INDEX ... PALETTE_INDEX + 3:
if (size == 4) {
vga_ioport_write(&s->vga, VGA_PEL_IR, (data >> 16) & 0xff);
break;
case SRC_PITCH_OFFSET:
if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
- s->regs.src_offset = (data & 0x1fffff) << 5;
- s->regs.src_pitch = (data >> 21) & 0x3ff;
+ s->regs.src_offset = (data & 0x1fffff) << 4;
+ s->regs.src_pitch = (data & 0x7fe00000) >> 21;
s->regs.src_tile = data >> 31;
} else {
- s->regs.src_offset = (data & 0x3fffff) << 11;
+ s->regs.src_offset = (data & 0x3fffff) << 10;
s->regs.src_pitch = (data & 0x3fc00000) >> 16;
s->regs.src_tile = (data >> 30) & 1;
}
break;
case DST_PITCH_OFFSET:
if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
- s->regs.dst_offset = (data & 0x1fffff) << 5;
- s->regs.dst_pitch = (data >> 21) & 0x3ff;
+ s->regs.dst_offset = (data & 0x1fffff) << 4;
+ s->regs.dst_pitch = (data & 0x7fe00000) >> 21;
s->regs.dst_tile = data >> 31;
} else {
- s->regs.dst_offset = (data & 0x3fffff) << 11;
+ s->regs.dst_offset = (data & 0x3fffff) << 10;
s->regs.dst_pitch = (data & 0x3fc00000) >> 16;
s->regs.dst_tile = data >> 30;
}
s->regs.dp_write_mask = data;
break;
case DEFAULT_OFFSET:
- data &= (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF ?
- 0x03fffc00 : 0xfffffc00);
- s->regs.default_offset = data;
+ if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ s->regs.default_offset = data & 0xfffffff0;
+ } else {
+ /* Radeon has DEFAULT_PITCH_OFFSET here like DST_PITCH_OFFSET */
+ s->regs.default_offset = (data & 0x3fffff) << 10;
+ s->regs.default_pitch = (data & 0x3fc00000) >> 16;
+ s->regs.default_tile = data >> 30;
+ }
break;
case DEFAULT_PITCH:
if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
- s->regs.default_pitch = data & 0x103ff;
+ s->regs.default_pitch = data & 0x3fff;
+ s->regs.default_tile = (data >> 16) & 1;
}
break;
case DEFAULT_SC_BOTTOM_RIGHT:
vga->cursor_draw_line = ati_cursor_draw_line;
}
+ /* ddc, edid */
+ I2CBus *i2cbus = i2c_init_bus(DEVICE(s), "ati-vga.ddc");
+ bitbang_i2c_init(&s->bbi2c, i2cbus);
+ I2CSlave *i2cddc = I2C_SLAVE(qdev_create(BUS(i2cbus), TYPE_I2CDDC));
+ i2c_set_slave_address(i2cddc, 0x50);
+
/* mmio register space */
memory_region_init_io(&s->mm, OBJECT(s), &ati_mm_ops, s,
"ati.mmregs", 0x4000);
k->class_id = PCI_CLASS_DISPLAY_VGA;
k->vendor_id = PCI_VENDOR_ID_ATI;
k->device_id = PCI_DEVICE_ID_ATI_RAGE128_PF;
- k->romfile = "vgabios-stdvga.bin";
+ k->romfile = "vgabios-ati.bin";
k->realize = ati_vga_realize;
k->exit = ati_vga_exit;
}
s->vga.vbe_start_addr, surface_data(ds), surface_stride(ds),
surface_bits_per_pixel(ds),
(s->regs.dp_mix & GMC_ROP3_MASK) >> 16);
- DPRINTF("%d %d, %d %d, (%d,%d) -> (%d,%d) %dx%d\n", s->regs.src_offset,
- s->regs.dst_offset, s->regs.src_pitch, s->regs.dst_pitch,
+ DPRINTF("%d %d %d, %d %d %d, (%d,%d) -> (%d,%d) %dx%d\n",
+ s->regs.src_offset, s->regs.dst_offset, s->regs.default_offset,
+ s->regs.src_pitch, s->regs.dst_pitch, s->regs.default_pitch,
s->regs.src_x, s->regs.src_y, s->regs.dst_x, s->regs.dst_y,
s->regs.dst_width, s->regs.dst_height);
switch (s->regs.dp_mix & GMC_ROP3_MASK) {
{
uint8_t *src_bits, *dst_bits, *end;
int src_stride, dst_stride, bpp = ati_bpp_from_datatype(s);
- src_bits = s->vga.vram_ptr + s->regs.src_offset;
- dst_bits = s->vga.vram_ptr + s->regs.dst_offset;
- src_stride = s->regs.src_pitch;
- dst_stride = s->regs.dst_pitch;
+ src_bits = s->vga.vram_ptr +
+ (s->regs.dp_gui_master_cntl & GMC_SRC_PITCH_OFFSET_CNTL ?
+ s->regs.src_offset : s->regs.default_offset);
+ dst_bits = s->vga.vram_ptr +
+ (s->regs.dp_gui_master_cntl & GMC_DST_PITCH_OFFSET_CNTL ?
+ s->regs.dst_offset : s->regs.default_offset);
+ src_stride = (s->regs.dp_gui_master_cntl & GMC_SRC_PITCH_OFFSET_CNTL ?
+ s->regs.src_pitch : s->regs.default_pitch);
+ dst_stride = (s->regs.dp_gui_master_cntl & GMC_DST_PITCH_OFFSET_CNTL ?
+ s->regs.dst_pitch : s->regs.default_pitch);
if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
src_bits += s->regs.crtc_offset & 0x07ffffff;
uint8_t *dst_bits, *end;
int dst_stride, bpp = ati_bpp_from_datatype(s);
uint32_t filler = 0;
- dst_bits = s->vga.vram_ptr + s->regs.dst_offset;
- dst_stride = s->regs.dst_pitch;
+ dst_bits = s->vga.vram_ptr +
+ (s->regs.dp_gui_master_cntl & GMC_DST_PITCH_OFFSET_CNTL ?
+ s->regs.dst_offset : s->regs.default_offset);
+ dst_stride = (s->regs.dp_gui_master_cntl & GMC_DST_PITCH_OFFSET_CNTL ?
+ s->regs.dst_pitch : s->regs.default_pitch);
if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
dst_bits += s->regs.crtc_offset & 0x07ffffff;
{"CRTC_GEN_CNTL", 0x0050},
{"CRTC_EXT_CNTL", 0x0054},
{"DAC_CNTL", 0x0058},
+ {"GPIO_VGA_DDC", 0x0060},
+ {"GPIO_DVI_DDC", 0x0064},
{"GPIO_MONID", 0x0068},
{"I2C_CNTL_1", 0x0094},
{"PALETTE_INDEX", 0x00b0},
#define ATI_INT_H
#include "hw/pci/pci.h"
+#include "hw/i2c/bitbang_i2c.h"
#include "vga_int.h"
/*#define DEBUG_ATI*/
uint32_t crtc_gen_cntl;
uint32_t crtc_ext_cntl;
uint32_t dac_cntl;
+ uint32_t gpio_vga_ddc;
+ uint32_t gpio_dvi_ddc;
+ uint32_t gpio_monid;
uint32_t crtc_h_total_disp;
uint32_t crtc_h_sync_strt_wid;
uint32_t crtc_v_total_disp;
uint32_t dp_write_mask;
uint32_t default_offset;
uint32_t default_pitch;
+ uint32_t default_tile;
uint32_t default_sc_bottom_right;
} ATIVGARegs;
uint16_t cursor_size;
uint32_t cursor_offset;
QEMUCursor *cursor;
+ bitbang_i2c_interface bbi2c;
MemoryRegion io;
MemoryRegion mm;
ATIVGARegs regs;
#define CRTC_GEN_CNTL 0x0050
#define CRTC_EXT_CNTL 0x0054
#define DAC_CNTL 0x0058
+#define GPIO_VGA_DDC 0x0060
+#define GPIO_DVI_DDC 0x0064
#define GPIO_MONID 0x0068
#define I2C_CNTL_1 0x0094
#define PALETTE_INDEX 0x00b0
#define BRUSH_SOLIDCOLOR 0x00000d00
/* DP_GUI_MASTER_CNTL bit constants */
-#define GMC_SRC_PITCH_OFFSET_DEFAULT 0x00000000
-#define GMC_DST_PITCH_OFFSET_DEFAULT 0x00000000
+#define GMC_SRC_PITCH_OFFSET_CNTL 0x00000001
+#define GMC_DST_PITCH_OFFSET_CNTL 0x00000002
#define GMC_SRC_CLIP_DEFAULT 0x00000000
#define GMC_DST_CLIP_DEFAULT 0x00000000
#define GMC_BRUSH_SOLIDCOLOR 0x000000d0
resource_id = qemu_get_be32(f);
while (resource_id != 0) {
+ res = virtio_gpu_find_resource(g, resource_id);
+ if (res) {
+ return -EINVAL;
+ }
+
res = g_new0(struct virtio_gpu_simple_resource, 1);
res->resource_id = resource_id;
res->width = qemu_get_be32(f);
if (res->iov[i].iov_base) {
dma_memory_unmap(VIRTIO_DEVICE(g)->dma_as,
res->iov[i].iov_base,
- res->iov[i].iov_len,
+ len,
DMA_DIRECTION_TO_DEVICE,
- res->iov[i].iov_len);
+ 0);
}
/* ...and the mappings for previous loop iterations */
res->iov_cnt = i;
#include "ui/console.h"
#include "hw/xen/xen-legacy-backend.h"
-#include <xen/event_channel.h>
-#include <xen/io/fbif.h>
-#include <xen/io/kbdif.h>
-#include <xen/io/protocols.h>
+#include "hw/xen/interface/io/fbif.h"
+#include "hw/xen/interface/io/kbdif.h"
+#include "hw/xen/interface/io/protocols.h"
#include "trace.h"
*/
#include "qemu/osdep.h"
+#include "qemu/units.h"
#include "hw/hw.h"
#include "hw/mips/mips.h"
#include "hw/sysbus.h"
#define TYPE_RC4030_IOMMU_MEMORY_REGION "rc4030-iommu-memory-region"
-typedef struct rc4030State
-{
+typedef struct rc4030State {
+
SysBusDevice parent;
uint32_t config; /* 0x0000: RC4030 config register */
case 0x0058:
val = s->cache_bmask;
/* HACK */
- if (s->cache_bmask == (uint32_t)-1)
+ if (s->cache_bmask == (uint32_t)-1) {
s->cache_bmask = 0;
+ }
break;
/* Remote Speed Registers */
case 0x0070:
s->memory_refresh_rate = 0x18186;
s->nvram_protect = 7;
- for (i = 0; i < 15; i++)
+ for (i = 0; i < 15; i++) {
s->rem_speed[i] = 7;
+ }
s->imr_jazz = 0x10; /* XXX: required by firmware, but why? */
s->isr_jazz = 0;
static int rc4030_post_load(void *opaque, int version_id)
{
- rc4030State* s = opaque;
+ rc4030State *s = opaque;
set_next_tick(s);
update_jazz_irq(s);
hwaddr dma_addr;
int dev_to_mem;
- s->dma_regs[n][DMA_REG_ENABLE] &= ~(DMA_FLAG_TC_INTR | DMA_FLAG_MEM_INTR | DMA_FLAG_ADDR_INTR);
+ s->dma_regs[n][DMA_REG_ENABLE] &=
+ ~(DMA_FLAG_TC_INTR | DMA_FLAG_MEM_INTR | DMA_FLAG_ADDR_INTR);
/* Check DMA channel consistency */
dev_to_mem = (s->dma_regs[n][DMA_REG_ENABLE] & DMA_FLAG_MEM_TO_DEV) ? 0 : 1;
}
/* Get start address and len */
- if (len > s->dma_regs[n][DMA_REG_COUNT])
+ if (len > s->dma_regs[n][DMA_REG_COUNT]) {
len = s->dma_regs[n][DMA_REG_COUNT];
+ }
dma_addr = s->dma_regs[n][DMA_REG_ADDRESS];
/* Read/write data at right place */
memory_region_init_iommu(&s->dma_mr, sizeof(s->dma_mr),
TYPE_RC4030_IOMMU_MEMORY_REGION,
- o, "rc4030.dma", UINT32_MAX);
+ o, "rc4030.dma", 4 * GiB);
address_space_init(&s->dma_as, MEMORY_REGION(&s->dma_mr), "rc4030-dma");
}
#include "qemu/osdep.h"
#include "hw/hw.h"
-#include "bitbang_i2c.h"
+#include "hw/i2c/bitbang_i2c.h"
#include "hw/sysbus.h"
#include "qemu/module.h"
#define DPRINTF(fmt, ...) do {} while(0)
#endif
-typedef enum bitbang_i2c_state {
- STOPPED = 0,
- SENDING_BIT7,
- SENDING_BIT6,
- SENDING_BIT5,
- SENDING_BIT4,
- SENDING_BIT3,
- SENDING_BIT2,
- SENDING_BIT1,
- SENDING_BIT0,
- WAITING_FOR_ACK,
- RECEIVING_BIT7,
- RECEIVING_BIT6,
- RECEIVING_BIT5,
- RECEIVING_BIT4,
- RECEIVING_BIT3,
- RECEIVING_BIT2,
- RECEIVING_BIT1,
- RECEIVING_BIT0,
- SENDING_ACK,
- SENT_NACK
-} bitbang_i2c_state;
-
-struct bitbang_i2c_interface {
- I2CBus *bus;
- bitbang_i2c_state state;
- int last_data;
- int last_clock;
- int device_out;
- uint8_t buffer;
- int current_addr;
-};
-
static void bitbang_i2c_enter_stop(bitbang_i2c_interface *i2c)
{
DPRINTF("STOP\n");
abort();
}
-bitbang_i2c_interface *bitbang_i2c_init(I2CBus *bus)
+void bitbang_i2c_init(bitbang_i2c_interface *s, I2CBus *bus)
{
- bitbang_i2c_interface *s;
-
- s = g_malloc0(sizeof(bitbang_i2c_interface));
-
s->bus = bus;
s->last_data = 1;
s->last_clock = 1;
s->device_out = 1;
-
- return s;
}
/* GPIO interface. */
SysBusDevice parent_obj;
MemoryRegion dummy_iomem;
- bitbang_i2c_interface *bitbang;
+ bitbang_i2c_interface bitbang;
int last_level;
qemu_irq out;
} GPIOI2CState;
{
GPIOI2CState *s = opaque;
- level = bitbang_i2c_set(s->bitbang, irq, level);
+ level = bitbang_i2c_set(&s->bitbang, irq, level);
if (level != s->last_level) {
s->last_level = level;
qemu_set_irq(s->out, level);
sysbus_init_mmio(sbd, &s->dummy_iomem);
bus = i2c_init_bus(dev, "i2c");
- s->bitbang = bitbang_i2c_init(bus);
+ bitbang_i2c_init(&s->bitbang, bus);
qdev_init_gpio_in(dev, bitbang_i2c_gpio_set, 2);
qdev_init_gpio_out(dev, &s->out, 1);
+++ /dev/null
-#ifndef BITBANG_I2C_H
-#define BITBANG_I2C_H
-
-#include "hw/i2c/i2c.h"
-
-#define BITBANG_I2C_SDA 0
-#define BITBANG_I2C_SCL 1
-
-bitbang_i2c_interface *bitbang_i2c_init(I2CBus *bus);
-int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level);
-
-#endif
#include "cpu.h"
#include "hw/hw.h"
#include "hw/i2c/ppc4xx_i2c.h"
-#include "bitbang_i2c.h"
#define PPC4xx_I2C_MEM_SIZE 18
case IIC_DIRECTCNTL:
i2c->directcntl = value & (IIC_DIRECTCNTL_SDAC & IIC_DIRECTCNTL_SCLC);
i2c->directcntl |= (value & IIC_DIRECTCNTL_SCLC ? 1 : 0);
- bitbang_i2c_set(i2c->bitbang, BITBANG_I2C_SCL,
+ bitbang_i2c_set(&i2c->bitbang, BITBANG_I2C_SCL,
i2c->directcntl & IIC_DIRECTCNTL_MSCL);
- i2c->directcntl |= bitbang_i2c_set(i2c->bitbang, BITBANG_I2C_SDA,
+ i2c->directcntl |= bitbang_i2c_set(&i2c->bitbang, BITBANG_I2C_SDA,
(value & IIC_DIRECTCNTL_SDAC) != 0) << 1;
break;
default:
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq);
s->bus = i2c_init_bus(DEVICE(s), "i2c");
- s->bitbang = bitbang_i2c_init(s->bus);
+ bitbang_i2c_init(&s->bitbang, s->bus);
}
static void ppc4xx_i2c_class_init(ObjectClass *klass, void *data)
#include "qemu/osdep.h"
#include "hw/sysbus.h"
-#include "bitbang_i2c.h"
+#include "hw/i2c/bitbang_i2c.h"
#include "qemu/log.h"
#include "qemu/module.h"
SysBusDevice parent_obj;
MemoryRegion iomem;
- bitbang_i2c_interface *bitbang;
+ bitbang_i2c_interface bitbang;
int out;
int in;
} VersatileI2CState;
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Bad offset 0x%x\n", __func__, (int)offset);
}
- bitbang_i2c_set(s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0);
- s->in = bitbang_i2c_set(s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0);
+ bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0);
+ s->in = bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0);
}
static const MemoryRegionOps versatile_i2c_ops = {
I2CBus *bus;
bus = i2c_init_bus(dev, "i2c");
- s->bitbang = bitbang_i2c_init(bus);
+ bitbang_i2c_init(&s->bitbang, bus);
memory_region_init_io(&s->iomem, obj, &versatile_i2c_ops, s,
"versatile_i2c", 0x1000);
sysbus_init_mmio(sbd, &s->iomem);
#include "exec/address-spaces.h"
#include <xen/hvm/ioreq.h>
-#include <xen/hvm/params.h>
#include <xen/hvm/e820.h>
//#define DEBUG_XEN_HVM
DeviceListener device_listener;
hwaddr free_phys_offset;
const XenPhysmap *log_for_dirtybit;
+ /* Buffer used by xen_sync_dirty_bitmap */
+ unsigned long *dirty_bitmap;
Notifier exit;
Notifier suspend;
QLIST_REMOVE(physmap, list);
if (state->log_for_dirtybit == physmap) {
state->log_for_dirtybit = NULL;
+ g_free(state->dirty_bitmap);
+ state->dirty_bitmap = NULL;
}
g_free(physmap);
{
hwaddr npages = size >> TARGET_PAGE_BITS;
const int width = sizeof(unsigned long) * 8;
- unsigned long bitmap[DIV_ROUND_UP(npages, width)];
+ size_t bitmap_size = DIV_ROUND_UP(npages, width);
int rc, i, j;
const XenPhysmap *physmap = NULL;
if (state->log_for_dirtybit == NULL) {
state->log_for_dirtybit = physmap;
+ state->dirty_bitmap = g_new(unsigned long, bitmap_size);
} else if (state->log_for_dirtybit != physmap) {
/* Only one range for dirty bitmap can be tracked. */
return;
}
rc = xen_track_dirty_vram(xen_domid, start_addr >> TARGET_PAGE_BITS,
- npages, bitmap);
+ npages, state->dirty_bitmap);
if (rc < 0) {
#ifndef ENODATA
#define ENODATA ENOENT
return;
}
- for (i = 0; i < ARRAY_SIZE(bitmap); i++) {
- unsigned long map = bitmap[i];
+ for (i = 0; i < bitmap_size; i++) {
+ unsigned long map = state->dirty_bitmap[i];
while (map != 0) {
j = ctzl(map);
map &= ~(1ul << j);
if (old & ~new & (1 << DIRTY_MEMORY_VGA)) {
state->log_for_dirtybit = NULL;
+ g_free(state->dirty_bitmap);
+ state->dirty_bitmap = NULL;
/* Disable dirty bit tracking */
xen_track_dirty_vram(xen_domid, 0, 0, NULL);
}
#include "hw/xen/xen-legacy-backend.h"
#include "qemu/bitmap.h"
-#include <xen/hvm/params.h>
-
#include "sysemu/xen-mapcache.h"
#include "trace.h"
static uint64_t aspeed_vic_read(void *opaque, hwaddr offset, unsigned size)
{
- uint64_t val;
- const bool high = !!(offset & 0x4);
- hwaddr n_offset = (offset & ~0x4);
AspeedVICState *s = (AspeedVICState *)opaque;
+ hwaddr n_offset;
+ uint64_t val;
+ bool high;
if (offset < AVIC_NEW_BASE_OFFSET) {
- qemu_log_mask(LOG_UNIMP, "%s: Ignoring read from legacy registers "
- "at 0x%" HWADDR_PRIx "[%u]\n", __func__, offset, size);
- return 0;
+ high = false;
+ n_offset = offset;
+ } else {
+ high = !!(offset & 0x4);
+ n_offset = (offset & ~0x4);
}
- n_offset -= AVIC_NEW_BASE_OFFSET;
-
switch (n_offset) {
- case 0x0: /* IRQ Status */
+ case 0x80: /* IRQ Status */
+ case 0x00:
val = s->raw & ~s->select & s->enable;
break;
- case 0x08: /* FIQ Status */
+ case 0x88: /* FIQ Status */
+ case 0x04:
val = s->raw & s->select & s->enable;
break;
- case 0x10: /* Raw Interrupt Status */
+ case 0x90: /* Raw Interrupt Status */
+ case 0x08:
val = s->raw;
break;
- case 0x18: /* Interrupt Selection */
+ case 0x98: /* Interrupt Selection */
+ case 0x0c:
val = s->select;
break;
- case 0x20: /* Interrupt Enable */
+ case 0xa0: /* Interrupt Enable */
+ case 0x10:
val = s->enable;
break;
- case 0x30: /* Software Interrupt */
+ case 0xb0: /* Software Interrupt */
+ case 0x18:
val = s->trigger;
break;
- case 0x40: /* Interrupt Sensitivity */
+ case 0xc0: /* Interrupt Sensitivity */
+ case 0x24:
val = s->sense;
break;
- case 0x48: /* Interrupt Both Edge Trigger Control */
+ case 0xc8: /* Interrupt Both Edge Trigger Control */
+ case 0x28:
val = s->dual_edge;
break;
- case 0x50: /* Interrupt Event */
+ case 0xd0: /* Interrupt Event */
+ case 0x2c:
val = s->event;
break;
- case 0x60: /* Edge Triggered Interrupt Status */
+ case 0xe0: /* Edge Triggered Interrupt Status */
val = s->raw & ~s->sense;
break;
/* Illegal */
- case 0x28: /* Interrupt Enable Clear */
- case 0x38: /* Software Interrupt Clear */
- case 0x58: /* Edge Triggered Interrupt Clear */
+ case 0xa8: /* Interrupt Enable Clear */
+ case 0xb8: /* Software Interrupt Clear */
+ case 0xd8: /* Edge Triggered Interrupt Clear */
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Read of write-only register with offset 0x%"
HWADDR_PRIx "\n", __func__, offset);
}
if (high) {
val = extract64(val, 32, 19);
+ } else {
+ val = extract64(val, 0, 32);
}
trace_aspeed_vic_read(offset, size, val);
return val;
static void aspeed_vic_write(void *opaque, hwaddr offset, uint64_t data,
unsigned size)
{
- const bool high = !!(offset & 0x4);
- hwaddr n_offset = (offset & ~0x4);
AspeedVICState *s = (AspeedVICState *)opaque;
+ hwaddr n_offset;
+ bool high;
if (offset < AVIC_NEW_BASE_OFFSET) {
- qemu_log_mask(LOG_UNIMP,
- "%s: Ignoring write to legacy registers at 0x%"
- HWADDR_PRIx "[%u] <- 0x%" PRIx64 "\n", __func__, offset,
- size, data);
- return;
+ high = false;
+ n_offset = offset;
+ } else {
+ high = !!(offset & 0x4);
+ n_offset = (offset & ~0x4);
}
- n_offset -= AVIC_NEW_BASE_OFFSET;
trace_aspeed_vic_write(offset, size, data);
/* Given we have members using separate enable/clear registers, deposit64()
}
switch (n_offset) {
- case 0x18: /* Interrupt Selection */
+ case 0x98: /* Interrupt Selection */
+ case 0x0c:
/* Register has deposit64() semantics - overwrite requested 32 bits */
if (high) {
s->select &= AVIC_L_MASK;
}
s->select |= data;
break;
- case 0x20: /* Interrupt Enable */
+ case 0xa0: /* Interrupt Enable */
+ case 0x10:
s->enable |= data;
break;
- case 0x28: /* Interrupt Enable Clear */
+ case 0xa8: /* Interrupt Enable Clear */
+ case 0x14:
s->enable &= ~data;
break;
- case 0x30: /* Software Interrupt */
+ case 0xb0: /* Software Interrupt */
+ case 0x18:
qemu_log_mask(LOG_UNIMP, "%s: Software interrupts unavailable. "
"IRQs requested: 0x%016" PRIx64 "\n", __func__, data);
break;
- case 0x38: /* Software Interrupt Clear */
+ case 0xb8: /* Software Interrupt Clear */
+ case 0x1c:
qemu_log_mask(LOG_UNIMP, "%s: Software interrupts unavailable. "
"IRQs to be cleared: 0x%016" PRIx64 "\n", __func__, data);
break;
- case 0x50: /* Interrupt Event */
+ case 0xd0: /* Interrupt Event */
/* Register has deposit64() semantics - overwrite the top four valid
* IRQ bits, as only the top four IRQs (GPIOs) can change their event
* type */
"Ignoring invalid write to interrupt event register");
}
break;
- case 0x58: /* Edge Triggered Interrupt Clear */
+ case 0xd8: /* Edge Triggered Interrupt Clear */
+ case 0x38:
s->raw &= ~(data & ~s->sense);
break;
- case 0x00: /* IRQ Status */
- case 0x08: /* FIQ Status */
- case 0x10: /* Raw Interrupt Status */
- case 0x40: /* Interrupt Sensitivity */
- case 0x48: /* Interrupt Both Edge Trigger Control */
- case 0x60: /* Edge Triggered Interrupt Status */
+ case 0x80: /* IRQ Status */
+ case 0x00:
+ case 0x88: /* FIQ Status */
+ case 0x04:
+ case 0x90: /* Raw Interrupt Status */
+ case 0x08:
+ case 0xc0: /* Interrupt Sensitivity */
+ case 0x24:
+ case 0xc8: /* Interrupt Both Edge Trigger Control */
+ case 0x28:
+ case 0xe0: /* Edge Triggered Interrupt Status */
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Write of read-only register with offset 0x%"
HWADDR_PRIx "\n", __func__, offset);
vsd = ldq_be_dma(&address_space_memory, vsd_addr);
if (!(vsd & VSD_ADDRESS_MASK)) {
- xive_error(xive, "VST: invalid %s entry %x !?", info->name, 0);
+ xive_error(xive, "VST: invalid %s entry %x !?", info->name, idx);
return 0;
}
vsd = ldq_be_dma(&address_space_memory, vsd_addr);
if (!(vsd & VSD_ADDRESS_MASK)) {
- xive_error(xive, "VST: invalid %s entry %x !?", info->name, 0);
+ xive_error(xive, "VST: invalid %s entry %x !?", info->name, idx);
return 0;
}
word_number);
}
-static int pnv_xive_end_update(PnvXive *xive, uint8_t blk, uint32_t idx)
+static int pnv_xive_end_update(PnvXive *xive)
{
+ uint8_t blk = GETFIELD(VC_EQC_CWATCH_BLOCKID,
+ xive->regs[(VC_EQC_CWATCH_SPEC >> 3)]);
+ uint32_t idx = GETFIELD(VC_EQC_CWATCH_OFFSET,
+ xive->regs[(VC_EQC_CWATCH_SPEC >> 3)]);
int i;
uint64_t eqc_watch[4];
XIVE_VST_WORD_ALL);
}
+static void pnv_xive_end_cache_load(PnvXive *xive)
+{
+ uint8_t blk = GETFIELD(VC_EQC_CWATCH_BLOCKID,
+ xive->regs[(VC_EQC_CWATCH_SPEC >> 3)]);
+ uint32_t idx = GETFIELD(VC_EQC_CWATCH_OFFSET,
+ xive->regs[(VC_EQC_CWATCH_SPEC >> 3)]);
+ uint64_t eqc_watch[4] = { 0 };
+ int i;
+
+ if (pnv_xive_vst_read(xive, VST_TSEL_EQDT, blk, idx, eqc_watch)) {
+ xive_error(xive, "VST: no END entry %x/%x !?", blk, idx);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(eqc_watch); i++) {
+ xive->regs[(VC_EQC_CWATCH_DAT0 >> 3) + i] = be64_to_cpu(eqc_watch[i]);
+ }
+}
+
static int pnv_xive_get_nvt(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
XiveNVT *nvt)
{
word_number);
}
-static int pnv_xive_nvt_update(PnvXive *xive, uint8_t blk, uint32_t idx)
+static int pnv_xive_nvt_update(PnvXive *xive)
{
+ uint8_t blk = GETFIELD(PC_VPC_CWATCH_BLOCKID,
+ xive->regs[(PC_VPC_CWATCH_SPEC >> 3)]);
+ uint32_t idx = GETFIELD(PC_VPC_CWATCH_OFFSET,
+ xive->regs[(PC_VPC_CWATCH_SPEC >> 3)]);
int i;
uint64_t vpc_watch[8];
XIVE_VST_WORD_ALL);
}
+static void pnv_xive_nvt_cache_load(PnvXive *xive)
+{
+ uint8_t blk = GETFIELD(PC_VPC_CWATCH_BLOCKID,
+ xive->regs[(PC_VPC_CWATCH_SPEC >> 3)]);
+ uint32_t idx = GETFIELD(PC_VPC_CWATCH_OFFSET,
+ xive->regs[(PC_VPC_CWATCH_SPEC >> 3)]);
+ uint64_t vpc_watch[8] = { 0 };
+ int i;
+
+ if (pnv_xive_vst_read(xive, VST_TSEL_VPDT, blk, idx, vpc_watch)) {
+ xive_error(xive, "VST: no NVT entry %x/%x !?", blk, idx);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(vpc_watch); i++) {
+ xive->regs[(PC_VPC_CWATCH_DAT0 >> 3) + i] = be64_to_cpu(vpc_watch[i]);
+ }
+}
+
static int pnv_xive_get_eas(XiveRouter *xrtr, uint8_t blk, uint32_t idx,
XiveEAS *eas)
{
return pnv_xive_vst_read(xive, VST_TSEL_IVT, blk, idx, eas);
}
-static int pnv_xive_eas_update(PnvXive *xive, uint8_t blk, uint32_t idx)
-{
- /* All done. */
- return 0;
-}
-
static XiveTCTX *pnv_xive_get_tctx(XiveRouter *xrtr, CPUState *cs)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
* support recently though)
*/
if (val & (VC_SBC_CONF_CPLX_CIST | VC_SBC_CONF_CIST_BOTH)) {
- object_property_set_int(OBJECT(&xive->ipi_source),
- XIVE_SRC_STORE_EOI, "flags", &error_fatal);
+ xive->ipi_source.esb_flags |= XIVE_SRC_STORE_EOI;
}
break;
* XIVE PC & VC cache updates for EAS, NVT and END
*/
case VC_IVC_SCRUB_MASK:
- break;
case VC_IVC_SCRUB_TRIG:
- pnv_xive_eas_update(xive, GETFIELD(PC_SCRUB_BLOCK_ID, val),
- GETFIELD(VC_SCRUB_OFFSET, val));
break;
- case VC_EQC_SCRUB_MASK:
case VC_EQC_CWATCH_SPEC:
- case VC_EQC_CWATCH_DAT0 ... VC_EQC_CWATCH_DAT3:
+ val &= ~VC_EQC_CWATCH_CONFLICT; /* HW resets this bit */
+ break;
+ case VC_EQC_CWATCH_DAT1 ... VC_EQC_CWATCH_DAT3:
break;
+ case VC_EQC_CWATCH_DAT0:
+ /* writing to DATA0 triggers the cache write */
+ xive->regs[reg] = val;
+ pnv_xive_end_update(xive);
+ break;
+ case VC_EQC_SCRUB_MASK:
case VC_EQC_SCRUB_TRIG:
- pnv_xive_end_update(xive, GETFIELD(VC_SCRUB_BLOCK_ID, val),
- GETFIELD(VC_SCRUB_OFFSET, val));
+ /*
+ * The scrubbing registers flush the cache in RAM and can also
+ * invalidate.
+ */
break;
- case PC_VPC_SCRUB_MASK:
case PC_VPC_CWATCH_SPEC:
- case PC_VPC_CWATCH_DAT0 ... PC_VPC_CWATCH_DAT7:
+ val &= ~PC_VPC_CWATCH_CONFLICT; /* HW resets this bit */
+ break;
+ case PC_VPC_CWATCH_DAT1 ... PC_VPC_CWATCH_DAT7:
break;
+ case PC_VPC_CWATCH_DAT0:
+ /* writing to DATA0 triggers the cache write */
+ xive->regs[reg] = val;
+ pnv_xive_nvt_update(xive);
+ break;
+ case PC_VPC_SCRUB_MASK:
case PC_VPC_SCRUB_TRIG:
- pnv_xive_nvt_update(xive, GETFIELD(PC_SCRUB_BLOCK_ID, val),
- GETFIELD(PC_SCRUB_OFFSET, val));
+ /*
+ * The scrubbing registers flush the cache in RAM and can also
+ * invalidate.
+ */
break;
case PC_GLOBAL_CONFIG:
case PC_VPC_SCRUB_MASK:
- case PC_VPC_CWATCH_SPEC:
- case PC_VPC_CWATCH_DAT0:
- case PC_VPC_CWATCH_DAT1:
- case PC_VPC_CWATCH_DAT2:
- case PC_VPC_CWATCH_DAT3:
- case PC_VPC_CWATCH_DAT4:
- case PC_VPC_CWATCH_DAT5:
- case PC_VPC_CWATCH_DAT6:
- case PC_VPC_CWATCH_DAT7:
case VC_GLOBAL_CONFIG:
case VC_AIB_TX_ORDER_TAG2:
case VC_IRQ_CONFIG_IPI_CASC:
case VC_EQC_SCRUB_MASK:
- case VC_EQC_CWATCH_DAT0:
- case VC_EQC_CWATCH_DAT1:
- case VC_EQC_CWATCH_DAT2:
- case VC_EQC_CWATCH_DAT3:
-
- case VC_EQC_CWATCH_SPEC:
case VC_IVC_SCRUB_MASK:
case VC_SBC_CONFIG:
case VC_AT_MACRO_KILL_MASK:
/*
* XIVE PC & VC cache updates for EAS, NVT and END
*/
+ case VC_EQC_CWATCH_SPEC:
+ xive->regs[reg] = ~(VC_EQC_CWATCH_FULL | VC_EQC_CWATCH_CONFLICT);
+ val = xive->regs[reg];
+ break;
+ case VC_EQC_CWATCH_DAT0:
+ /*
+ * Load DATA registers from cache with data requested by the
+ * SPEC register
+ */
+ pnv_xive_end_cache_load(xive);
+ val = xive->regs[reg];
+ break;
+ case VC_EQC_CWATCH_DAT1 ... VC_EQC_CWATCH_DAT3:
+ val = xive->regs[reg];
+ break;
+
+ case PC_VPC_CWATCH_SPEC:
+ xive->regs[reg] = ~(PC_VPC_CWATCH_FULL | PC_VPC_CWATCH_CONFLICT);
+ val = xive->regs[reg];
+ break;
+ case PC_VPC_CWATCH_DAT0:
+ /*
+ * Load DATA registers from cache with data requested by the
+ * SPEC register
+ */
+ pnv_xive_nvt_cache_load(xive);
+ val = xive->regs[reg];
+ break;
+ case PC_VPC_CWATCH_DAT1 ... PC_VPC_CWATCH_DAT7:
+ val = xive->regs[reg];
+ break;
+
case PC_VPC_SCRUB_TRIG:
case VC_IVC_SCRUB_TRIG:
case VC_EQC_SCRUB_TRIG:
}
}
-void spapr_xive_map_mmio(SpaprXive *xive)
-{
- sysbus_mmio_map(SYS_BUS_DEVICE(xive), 0, xive->vc_base);
- sysbus_mmio_map(SYS_BUS_DEVICE(xive), 1, xive->end_base);
- sysbus_mmio_map(SYS_BUS_DEVICE(xive), 2, xive->tm_base);
-}
-
void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable)
{
memory_region_set_enabled(&xive->source.esb_mmio, enable);
error_propagate(errp, local_err);
return;
}
+ sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xsrc->esb_mmio);
/*
* Initialize the END ESB source
error_propagate(errp, local_err);
return;
}
+ sysbus_init_mmio(SYS_BUS_DEVICE(xive), &end_xsrc->esb_mmio);
/* Set the mapping address of the END ESB pages after the source ESBs */
xive->end_base = xive->vc_base + (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
qemu_register_reset(spapr_xive_reset, dev);
- /* Define all XIVE MMIO regions on SysBus */
- sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xsrc->esb_mmio);
- sysbus_init_mmio(SYS_BUS_DEVICE(xive), &end_xsrc->esb_mmio);
- sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xive->tm_mmio);
-}
-
-void spapr_xive_init(SpaprXive *xive, Error **errp)
-{
- XiveSource *xsrc = &xive->source;
-
- /*
- * The emulated XIVE device can only be initialized once. If the
- * ESB memory region has been already mapped, it means we have been
- * through there.
- */
- if (memory_region_is_mapped(&xsrc->esb_mmio)) {
- return;
- }
-
/* TIMA initialization */
memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &xive_tm_ops, xive,
"xive.tima", 4ull << TM_SHIFT);
+ sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xive->tm_mmio);
- /* Map all regions */
- spapr_xive_map_mmio(xive);
+ /*
+ * Map all regions. These will be enabled or disabled at reset and
+ * can also be overridden by KVM memory regions if active
+ */
+ sysbus_mmio_map(SYS_BUS_DEVICE(xive), 0, xive->vc_base);
+ sysbus_mmio_map(SYS_BUS_DEVICE(xive), 1, xive->end_base);
+ sysbus_mmio_map(SYS_BUS_DEVICE(xive), 2, xive->tm_base);
}
static int spapr_xive_get_eas(XiveRouter *xrtr, uint8_t eas_blk,
xsrc->esb_mmap = kvmppc_xive_mmap(xive, KVM_XIVE_ESB_PAGE_OFFSET, esb_len,
&local_err);
if (local_err) {
- error_propagate(errp, local_err);
- return;
+ goto fail;
}
- memory_region_init_ram_device_ptr(&xsrc->esb_mmio, OBJECT(xsrc),
+ memory_region_init_ram_device_ptr(&xsrc->esb_mmio_kvm, OBJECT(xsrc),
"xive.esb", esb_len, xsrc->esb_mmap);
+ memory_region_add_subregion_overlap(&xsrc->esb_mmio, 0,
+ &xsrc->esb_mmio_kvm, 1);
/*
* 2. END ESB pages (No KVM support yet)
xive->tm_mmap = kvmppc_xive_mmap(xive, KVM_XIVE_TIMA_PAGE_OFFSET, tima_len,
&local_err);
if (local_err) {
- error_propagate(errp, local_err);
- return;
+ goto fail;
}
- memory_region_init_ram_device_ptr(&xive->tm_mmio, OBJECT(xive),
+ memory_region_init_ram_device_ptr(&xive->tm_mmio_kvm, OBJECT(xive),
"xive.tima", tima_len, xive->tm_mmap);
+ memory_region_add_subregion_overlap(&xive->tm_mmio, 0,
+ &xive->tm_mmio_kvm, 1);
xive->change = qemu_add_vm_change_state_handler(
kvmppc_xive_change_state_handler, xive);
kvmppc_xive_cpu_connect(spapr_cpu_state(cpu)->tctx, &local_err);
if (local_err) {
- error_propagate(errp, local_err);
- return;
+ goto fail;
}
}
/* Update the KVM sources */
kvmppc_xive_source_reset(xsrc, &local_err);
if (local_err) {
- error_propagate(errp, local_err);
- return;
+ goto fail;
}
kvm_kernel_irqchip = true;
kvm_msi_via_irqfd_allowed = true;
kvm_gsi_direct_mapping = true;
+ return;
- /* Map all regions */
- spapr_xive_map_mmio(xive);
+fail:
+ error_propagate(errp, local_err);
+ kvmppc_xive_disconnect(xive, NULL);
}
void kvmppc_xive_disconnect(SpaprXive *xive, Error **errp)
xsrc = &xive->source;
esb_len = (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
- sysbus_mmio_unmap(SYS_BUS_DEVICE(xive), 0);
- munmap(xsrc->esb_mmap, esb_len);
-
- sysbus_mmio_unmap(SYS_BUS_DEVICE(xive), 1);
+ if (xsrc->esb_mmap) {
+ memory_region_del_subregion(&xsrc->esb_mmio, &xsrc->esb_mmio_kvm);
+ object_unparent(OBJECT(&xsrc->esb_mmio_kvm));
+ munmap(xsrc->esb_mmap, esb_len);
+ xsrc->esb_mmap = NULL;
+ }
- sysbus_mmio_unmap(SYS_BUS_DEVICE(xive), 2);
- munmap(xive->tm_mmap, 4ull << TM_SHIFT);
+ if (xive->tm_mmap) {
+ memory_region_del_subregion(&xive->tm_mmio, &xive->tm_mmio_kvm);
+ object_unparent(OBJECT(&xive->tm_mmio_kvm));
+ munmap(xive->tm_mmap, 4ull << TM_SHIFT);
+ xive->tm_mmap = NULL;
+ }
/*
* When the KVM device fd is closed, the KVM device is destroyed
* and removed from the list of devices of the VM. The VCPU
* presenters are also detached from the device.
*/
- close(xive->fd);
- xive->fd = -1;
+ if (xive->fd != -1) {
+ close(xive->fd);
+ xive->fd = -1;
+ }
kvm_kernel_irqchip = false;
kvm_msi_via_irqfd_allowed = false;
kvm_cpu_disable_all();
/* VM Change state handler is not needed anymore */
- qemu_del_vm_change_state_handler(xive->change);
+ if (xive->change) {
+ qemu_del_vm_change_state_handler(xive->change);
+ xive->change = NULL;
+ }
}
ICPState *icp = opaque;
if (kvm_irqchip_in_kernel()) {
- return icp_set_kvm_state(icp);
+ Error *local_err = NULL;
+ int ret;
+
+ ret = icp_set_kvm_state(icp, &local_err);
+ if (ret < 0) {
+ error_report_err(local_err);
+ return ret;
+ }
}
return 0;
qemu_set_irq(icp->output, 0);
if (kvm_irqchip_in_kernel()) {
- icp_set_kvm_state(ICP(dev));
+ Error *local_err = NULL;
+
+ icp_set_kvm_state(ICP(dev), &local_err);
+ if (local_err) {
+ error_report_err(local_err);
+ }
}
}
return;
}
+ /* Connect the presenter to the VCPU (required for CPU hotplug) */
if (kvm_irqchip_in_kernel()) {
icp_kvm_realize(dev, &err);
if (err) {
icsc->parent_reset(dev);
if (kvm_irqchip_in_kernel()) {
- ics_set_kvm_state(ICS_BASE(dev));
+ Error *local_err = NULL;
+
+ ics_set_kvm_state(ICS_BASE(dev), &local_err);
+ if (local_err) {
+ error_report_err(local_err);
+ }
}
}
ICSState *ics = opaque;
if (kvm_irqchip_in_kernel()) {
- return ics_set_kvm_state(ics);
+ Error *local_err = NULL;
+ int ret;
+
+ ret = ics_set_kvm_state(ics, &local_err);
+ if (ret < 0) {
+ error_report_err(local_err);
+ return ret;
+ }
}
return 0;
lsi ? XICS_FLAGS_IRQ_LSI : XICS_FLAGS_IRQ_MSI;
if (kvm_irqchip_in_kernel()) {
+ Error *local_err = NULL;
+
ics_reset_irq(ics->irqs + srcno);
- ics_set_kvm_state_one(ics, srcno);
+ ics_set_kvm_state_one(ics, srcno, &local_err);
+ if (local_err) {
+ error_report_err(local_err);
+ }
}
}
}
}
-int icp_set_kvm_state(ICPState *icp)
+int icp_set_kvm_state(ICPState *icp, Error **errp)
{
uint64_t state;
int ret;
| ((uint64_t)icp->pending_priority << KVM_REG_PPC_ICP_PPRI_SHIFT);
ret = kvm_set_one_reg(icp->cs, KVM_REG_PPC_ICP_STATE, &state);
- if (ret != 0) {
- error_report("Unable to restore KVM interrupt controller state (0x%"
- PRIx64 ") for CPU %ld: %s", state, kvm_arch_vcpu_id(icp->cs),
- strerror(errno));
+ if (ret < 0) {
+ error_setg_errno(errp, -ret,
+ "Unable to restore KVM interrupt controller state (0x%"
+ PRIx64 ") for CPU %ld", state,
+ kvm_arch_vcpu_id(icp->cs));
return ret;
}
ics_get_kvm_state(ics);
}
-int ics_set_kvm_state_one(ICSState *ics, int srcno)
+int ics_set_kvm_state_one(ICSState *ics, int srcno, Error **errp)
{
uint64_t state;
- Error *local_err = NULL;
ICSIRQState *irq = &ics->irqs[srcno];
int ret;
}
ret = kvm_device_access(kernel_xics_fd, KVM_DEV_XICS_GRP_SOURCES,
- srcno + ics->offset, &state, true, &local_err);
- if (local_err) {
- error_report_err(local_err);
+ srcno + ics->offset, &state, true, errp);
+ if (ret < 0) {
return ret;
}
return 0;
}
-int ics_set_kvm_state(ICSState *ics)
+int ics_set_kvm_state(ICSState *ics, Error **errp)
{
int i;
}
for (i = 0; i < ics->nr_irqs; i++) {
+ Error *local_err = NULL;
int ret;
- ret = ics_set_kvm_state_one(ics, i);
- if (ret) {
+ ret = ics_set_kvm_state_one(ics, i, &local_err);
+ if (ret < 0) {
+ error_propagate(errp, local_err);
return ret;
}
}
}
}
-static void rtas_dummy(PowerPCCPU *cpu, SpaprMachineState *spapr,
- uint32_t token,
- uint32_t nargs, target_ulong args,
- uint32_t nret, target_ulong rets)
-{
- error_report("pseries: %s must never be called for in-kernel XICS",
- __func__);
-}
-
-int xics_kvm_init(SpaprMachineState *spapr, Error **errp)
+int xics_kvm_connect(SpaprMachineState *spapr, Error **errp)
{
int rc;
CPUState *cs;
if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_IRQ_XICS)) {
error_setg(errp,
"KVM and IRQ_XICS capability must be present for in-kernel XICS");
- goto fail;
+ return -1;
}
- spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_dummy);
- spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_dummy);
- spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_dummy);
- spapr_rtas_register(RTAS_IBM_INT_ON, "ibm,int-on", rtas_dummy);
-
rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_SET_XIVE, "ibm,set-xive");
if (rc < 0) {
- error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,set-xive");
+ error_setg_errno(&local_err, -rc,
+ "kvmppc_define_rtas_kernel_token: ibm,set-xive");
goto fail;
}
rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_GET_XIVE, "ibm,get-xive");
if (rc < 0) {
- error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,get-xive");
+ error_setg_errno(&local_err, -rc,
+ "kvmppc_define_rtas_kernel_token: ibm,get-xive");
goto fail;
}
rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_INT_ON, "ibm,int-on");
if (rc < 0) {
- error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,int-on");
+ error_setg_errno(&local_err, -rc,
+ "kvmppc_define_rtas_kernel_token: ibm,int-on");
goto fail;
}
rc = kvmppc_define_rtas_kernel_token(RTAS_IBM_INT_OFF, "ibm,int-off");
if (rc < 0) {
- error_setg(errp, "kvmppc_define_rtas_kernel_token: ibm,int-off");
+ error_setg_errno(&local_err, -rc,
+ "kvmppc_define_rtas_kernel_token: ibm,int-off");
goto fail;
}
/* Create the KVM XICS device */
rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
if (rc < 0) {
- error_setg_errno(errp, -rc, "Error on KVM_CREATE_DEVICE for XICS");
+ error_setg_errno(&local_err, -rc, "Error on KVM_CREATE_DEVICE for XICS");
goto fail;
}
icp_kvm_realize(DEVICE(spapr_cpu_state(cpu)->icp), &local_err);
if (local_err) {
- error_propagate(errp, local_err);
goto fail;
}
}
/* Update the KVM sources */
- ics_set_kvm_state(spapr->ics);
+ ics_set_kvm_state(spapr->ics, &local_err);
+ if (local_err) {
+ goto fail;
+ }
/* Connect the presenters to the initial VCPUs of the machine */
CPU_FOREACH(cs) {
PowerPCCPU *cpu = POWERPC_CPU(cs);
- icp_set_kvm_state(spapr_cpu_state(cpu)->icp);
+ icp_set_kvm_state(spapr_cpu_state(cpu)->icp, &local_err);
+ if (local_err) {
+ goto fail;
+ }
}
return 0;
fail:
- kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
- kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
- kvmppc_define_rtas_kernel_token(0, "ibm,int-on");
- kvmppc_define_rtas_kernel_token(0, "ibm,int-off");
+ error_propagate(errp, local_err);
+ xics_kvm_disconnect(spapr, NULL);
return -1;
}
* removed from the list of devices of the VM. The VCPU presenters
* are also detached from the device.
*/
- close(kernel_xics_fd);
- kernel_xics_fd = -1;
-
- spapr_rtas_unregister(RTAS_IBM_SET_XIVE);
- spapr_rtas_unregister(RTAS_IBM_GET_XIVE);
- spapr_rtas_unregister(RTAS_IBM_INT_OFF);
- spapr_rtas_unregister(RTAS_IBM_INT_ON);
+ if (kernel_xics_fd != -1) {
+ close(kernel_xics_fd);
+ kernel_xics_fd = -1;
+ }
kvmppc_define_rtas_kernel_token(0, "ibm,set-xive");
kvmppc_define_rtas_kernel_token(0, "ibm,get-xive");
/* Clear the presenter from the VCPUs */
kvm_disable_icps();
}
+
+/*
+ * This is a heuristic to detect older KVMs on POWER9 hosts that don't
+ * support destruction of a KVM XICS device while the VM is running.
+ * Required to start a spapr machine with ic-mode=dual,kernel-irqchip=on.
+ */
+bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr)
+{
+ int rc;
+
+ rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
+ if (rc < 0) {
+ /*
+ * The error is ignored on purpose. The KVM XICS setup code
+ * will catch it again anyway. The goal here is to see if
+ * close() actually destroys the device or not.
+ */
+ return false;
+ }
+
+ close(rc);
+
+ rc = kvm_create_device(kvm_state, KVM_DEV_TYPE_XICS, false);
+ if (rc >= 0) {
+ close(rc);
+ return false;
+ }
+
+ return errno == EEXIST;
+}
* Guest interfaces
*/
+static bool check_emulated_xics(SpaprMachineState *spapr, const char *func)
+{
+ if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT) ||
+ kvm_irqchip_in_kernel()) {
+ error_report("pseries: %s must only be called for emulated XICS",
+ func);
+ return false;
+ }
+
+ return true;
+}
+
+#define CHECK_EMULATED_XICS_HCALL(spapr) \
+ do { \
+ if (!check_emulated_xics((spapr), __func__)) { \
+ return H_HARDWARE; \
+ } \
+ } while (0)
+
static target_ulong h_cppr(PowerPCCPU *cpu, SpaprMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
target_ulong cppr = args[0];
+ CHECK_EMULATED_XICS_HCALL(spapr);
+
icp_set_cppr(spapr_cpu_state(cpu)->icp, cppr);
return H_SUCCESS;
}
target_ulong mfrr = args[1];
ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), args[0]);
+ CHECK_EMULATED_XICS_HCALL(spapr);
+
if (!icp) {
return H_PARAMETER;
}
{
uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
+ CHECK_EMULATED_XICS_HCALL(spapr);
+
args[0] = xirr;
return H_SUCCESS;
}
{
uint32_t xirr = icp_accept(spapr_cpu_state(cpu)->icp);
+ CHECK_EMULATED_XICS_HCALL(spapr);
+
args[0] = xirr;
args[1] = cpu_get_host_ticks();
return H_SUCCESS;
{
target_ulong xirr = args[0];
+ CHECK_EMULATED_XICS_HCALL(spapr);
+
icp_eoi(spapr_cpu_state(cpu)->icp, xirr);
return H_SUCCESS;
}
uint32_t mfrr;
uint32_t xirr;
+ CHECK_EMULATED_XICS_HCALL(spapr);
+
if (!icp) {
return H_PARAMETER;
}
return H_SUCCESS;
}
+#define CHECK_EMULATED_XICS_RTAS(spapr, rets) \
+ do { \
+ if (!check_emulated_xics((spapr), __func__)) { \
+ rtas_st((rets), 0, RTAS_OUT_HW_ERROR); \
+ return; \
+ } \
+ } while (0)
+
static void rtas_set_xive(PowerPCCPU *cpu, SpaprMachineState *spapr,
uint32_t token,
uint32_t nargs, target_ulong args,
ICSState *ics = spapr->ics;
uint32_t nr, srcno, server, priority;
+ CHECK_EMULATED_XICS_RTAS(spapr, rets);
+
if ((nargs != 3) || (nret != 1)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
ICSState *ics = spapr->ics;
uint32_t nr, srcno;
+ CHECK_EMULATED_XICS_RTAS(spapr, rets);
+
if ((nargs != 1) || (nret != 3)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
ICSState *ics = spapr->ics;
uint32_t nr, srcno;
+ CHECK_EMULATED_XICS_RTAS(spapr, rets);
+
if ((nargs != 1) || (nret != 1)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
ICSState *ics = spapr->ics;
uint32_t nr, srcno;
+ CHECK_EMULATED_XICS_RTAS(spapr, rets);
+
if ((nargs != 1) || (nret != 1)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
void xics_spapr_init(SpaprMachineState *spapr)
{
- /* Emulated mode can only be initialized once. */
- if (spapr->ics->init) {
- return;
- }
-
- spapr->ics->init = true;
-
- /* Registration of global state belongs into realize */
spapr_rtas_register(RTAS_IBM_SET_XIVE, "ibm,set-xive", rtas_set_xive);
spapr_rtas_register(RTAS_IBM_GET_XIVE, "ibm,get-xive", rtas_get_xive);
spapr_rtas_register(RTAS_IBM_INT_OFF, "ibm,int-off", rtas_int_off);
xive_tctx_notify(tctx, ring);
}
+static inline uint32_t xive_tctx_word2(uint8_t *ring)
+{
+ return *((uint32_t *) &ring[TM_WORD2]);
+}
+
/*
* XIVE Thread Interrupt Management Area (TIMA)
*/
static uint64_t xive_tm_pull_pool_ctx(XiveTCTX *tctx, hwaddr offset,
unsigned size)
{
- uint64_t ret;
+ uint32_t qw2w2_prev = xive_tctx_word2(&tctx->regs[TM_QW2_HV_POOL]);
+ uint32_t qw2w2;
- ret = tctx->regs[TM_QW2_HV_POOL + TM_WORD2] & TM_QW2W2_POOL_CAM;
- tctx->regs[TM_QW2_HV_POOL + TM_WORD2] &= ~TM_QW2W2_POOL_CAM;
- return ret;
+ qw2w2 = xive_set_field32(TM_QW2W2_VP, qw2w2_prev, 0);
+ memcpy(&tctx->regs[TM_QW2_HV_POOL + TM_WORD2], &qw2w2, 4);
+ return qw2w2;
}
static void xive_tm_vt_push(XiveTCTX *tctx, hwaddr offset,
*/
static const uint8_t xive_tm_hw_view[] = {
- /* QW-0 User */ 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0,
- /* QW-1 OS */ 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0,
- /* QW-2 POOL */ 0, 0, 3, 3, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0,
- /* QW-3 PHYS */ 3, 3, 3, 3, 0, 3, 0, 3, 3, 0, 0, 3, 3, 3, 3, 0,
+ 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, /* QW-0 User */
+ 3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 3, 3, 0, 0, 0, 0, /* QW-1 OS */
+ 0, 0, 3, 3, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, /* QW-2 POOL */
+ 3, 3, 3, 3, 0, 3, 0, 2, 3, 0, 0, 3, 3, 3, 3, 0, /* QW-3 PHYS */
};
static const uint8_t xive_tm_hv_view[] = {
- /* QW-0 User */ 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0,
- /* QW-1 OS */ 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0,
- /* QW-2 POOL */ 0, 0, 3, 3, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0,
- /* QW-3 PHYS */ 3, 3, 3, 3, 0, 3, 0, 3, 3, 0, 0, 3, 0, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, /* QW-0 User */
+ 3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 3, 3, 0, 0, 0, 0, /* QW-1 OS */
+ 0, 0, 3, 3, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, /* QW-2 POOL */
+ 3, 3, 3, 3, 0, 3, 0, 2, 3, 0, 0, 3, 0, 0, 0, 0, /* QW-3 PHYS */
};
static const uint8_t xive_tm_os_view[] = {
- /* QW-0 User */ 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0,
- /* QW-1 OS */ 2, 3, 2, 2, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
- /* QW-2 POOL */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /* QW-3 PHYS */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, /* QW-0 User */
+ 2, 3, 2, 2, 2, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, /* QW-1 OS */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* QW-2 POOL */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* QW-3 PHYS */
};
static const uint8_t xive_tm_user_view[] = {
- /* QW-0 User */ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /* QW-1 OS */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /* QW-2 POOL */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- /* QW-3 PHYS */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* QW-0 User */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* QW-1 OS */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* QW-2 POOL */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* QW-3 PHYS */
};
/*
},
};
-static inline uint32_t xive_tctx_word2(uint8_t *ring)
-{
- return *((uint32_t *) &ring[TM_WORD2]);
-}
-
static char *xive_tctx_ring_print(uint8_t *ring)
{
uint32_t w2 = xive_tctx_word2(ring);
}
/*
- * By default on P9, the HW CAM line (23bits) is hardwired to :
- *
- * 0x000||0b1||4Bit chip number||7Bit Thread number.
+ * Encode the HW CAM line in the block group mode format :
*
- * When the block grouping is enabled, the CAM line is changed to :
- *
- * 4Bit chip number||0x001||7Bit Thread number.
+ * chip << 19 | 0000000 0 0001 thread (7Bit)
*/
-static uint32_t hw_cam_line(uint8_t chip_id, uint8_t tid)
-{
- return 1 << 11 | (chip_id & 0xf) << 7 | (tid & 0x7f);
-}
-
-static bool xive_presenter_tctx_match_hw(XiveTCTX *tctx,
- uint8_t nvt_blk, uint32_t nvt_idx)
+static uint32_t xive_tctx_hw_cam_line(XiveTCTX *tctx)
{
CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env;
uint32_t pir = env->spr_cb[SPR_PIR].default_value;
- return hw_cam_line((pir >> 8) & 0xf, pir & 0x7f) ==
- hw_cam_line(nvt_blk, nvt_idx);
+ return xive_nvt_cam_line((pir >> 8) & 0xf, 1 << 7 | (pir & 0x7f));
}
/*
/* PHYS ring */
if ((be32_to_cpu(qw3w2) & TM_QW3W2_VT) &&
- xive_presenter_tctx_match_hw(tctx, nvt_blk, nvt_idx)) {
+ cam == xive_tctx_hw_cam_line(tctx)) {
return TM_QW3_HV_PHYS;
}
config R4K
bool
+ select ISA_BUS
+ select SERIAL_ISA
+ select I8259
+ select I8254
+ select MC146818RTC
+ imply VGA_ISA
+ imply NE2000_ISA
+ select IDE_ISA
+ select PCKBD
+ select PFLASH_CFI01
config MALTA
bool
config MIPSSIM
bool
+ select ISA_BUS
+ select SERIAL_ISA
+ select MIPSNET
config JAZZ
bool
+ select ISA_BUS
+ select RC4030
+ select I8259
+ select I8254
+ select I8257
+ select PCSPK
+ select VGA_ISA_MM
+ select G364FB
+ select DP8393X
+ select ESP
+ select FDC
+ select MC146818RTC
+ select PCKBD
+ select SERIAL
+ select PARALLEL
+ select DS1225Y
+ select JAZZ_LED
config FULONG
bool
*/
#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu/log.h"
#include "hw/hw.h"
#include "hw/mips/mips.h"
#include "hw/pci/pci.h"
#include "hw/pci/pci_host.h"
#include "hw/i386/pc.h"
#include "exec/address-spaces.h"
+#include "trace.h"
-//#define DEBUG
-
-#ifdef DEBUG
-#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__)
-#else
-#define DPRINTF(fmt, ...)
-#endif
-
-#define GT_REGS (0x1000 >> 2)
+#define GT_REGS (0x1000 >> 2)
/* CPU Configuration */
-#define GT_CPU (0x000 >> 2)
-#define GT_MULTI (0x120 >> 2)
+#define GT_CPU (0x000 >> 2)
+#define GT_MULTI (0x120 >> 2)
/* CPU Address Decode */
-#define GT_SCS10LD (0x008 >> 2)
-#define GT_SCS10HD (0x010 >> 2)
-#define GT_SCS32LD (0x018 >> 2)
-#define GT_SCS32HD (0x020 >> 2)
-#define GT_CS20LD (0x028 >> 2)
-#define GT_CS20HD (0x030 >> 2)
-#define GT_CS3BOOTLD (0x038 >> 2)
-#define GT_CS3BOOTHD (0x040 >> 2)
-#define GT_PCI0IOLD (0x048 >> 2)
-#define GT_PCI0IOHD (0x050 >> 2)
-#define GT_PCI0M0LD (0x058 >> 2)
-#define GT_PCI0M0HD (0x060 >> 2)
-#define GT_PCI0M1LD (0x080 >> 2)
-#define GT_PCI0M1HD (0x088 >> 2)
-#define GT_PCI1IOLD (0x090 >> 2)
-#define GT_PCI1IOHD (0x098 >> 2)
-#define GT_PCI1M0LD (0x0a0 >> 2)
-#define GT_PCI1M0HD (0x0a8 >> 2)
-#define GT_PCI1M1LD (0x0b0 >> 2)
-#define GT_PCI1M1HD (0x0b8 >> 2)
-#define GT_ISD (0x068 >> 2)
-
-#define GT_SCS10AR (0x0d0 >> 2)
-#define GT_SCS32AR (0x0d8 >> 2)
-#define GT_CS20R (0x0e0 >> 2)
-#define GT_CS3BOOTR (0x0e8 >> 2)
-
-#define GT_PCI0IOREMAP (0x0f0 >> 2)
-#define GT_PCI0M0REMAP (0x0f8 >> 2)
-#define GT_PCI0M1REMAP (0x100 >> 2)
-#define GT_PCI1IOREMAP (0x108 >> 2)
-#define GT_PCI1M0REMAP (0x110 >> 2)
-#define GT_PCI1M1REMAP (0x118 >> 2)
+#define GT_SCS10LD (0x008 >> 2)
+#define GT_SCS10HD (0x010 >> 2)
+#define GT_SCS32LD (0x018 >> 2)
+#define GT_SCS32HD (0x020 >> 2)
+#define GT_CS20LD (0x028 >> 2)
+#define GT_CS20HD (0x030 >> 2)
+#define GT_CS3BOOTLD (0x038 >> 2)
+#define GT_CS3BOOTHD (0x040 >> 2)
+#define GT_PCI0IOLD (0x048 >> 2)
+#define GT_PCI0IOHD (0x050 >> 2)
+#define GT_PCI0M0LD (0x058 >> 2)
+#define GT_PCI0M0HD (0x060 >> 2)
+#define GT_PCI0M1LD (0x080 >> 2)
+#define GT_PCI0M1HD (0x088 >> 2)
+#define GT_PCI1IOLD (0x090 >> 2)
+#define GT_PCI1IOHD (0x098 >> 2)
+#define GT_PCI1M0LD (0x0a0 >> 2)
+#define GT_PCI1M0HD (0x0a8 >> 2)
+#define GT_PCI1M1LD (0x0b0 >> 2)
+#define GT_PCI1M1HD (0x0b8 >> 2)
+#define GT_ISD (0x068 >> 2)
+
+#define GT_SCS10AR (0x0d0 >> 2)
+#define GT_SCS32AR (0x0d8 >> 2)
+#define GT_CS20R (0x0e0 >> 2)
+#define GT_CS3BOOTR (0x0e8 >> 2)
+
+#define GT_PCI0IOREMAP (0x0f0 >> 2)
+#define GT_PCI0M0REMAP (0x0f8 >> 2)
+#define GT_PCI0M1REMAP (0x100 >> 2)
+#define GT_PCI1IOREMAP (0x108 >> 2)
+#define GT_PCI1M0REMAP (0x110 >> 2)
+#define GT_PCI1M1REMAP (0x118 >> 2)
/* CPU Error Report */
-#define GT_CPUERR_ADDRLO (0x070 >> 2)
-#define GT_CPUERR_ADDRHI (0x078 >> 2)
-#define GT_CPUERR_DATALO (0x128 >> 2) /* GT-64120A only */
-#define GT_CPUERR_DATAHI (0x130 >> 2) /* GT-64120A only */
-#define GT_CPUERR_PARITY (0x138 >> 2) /* GT-64120A only */
+#define GT_CPUERR_ADDRLO (0x070 >> 2)
+#define GT_CPUERR_ADDRHI (0x078 >> 2)
+#define GT_CPUERR_DATALO (0x128 >> 2) /* GT-64120A only */
+#define GT_CPUERR_DATAHI (0x130 >> 2) /* GT-64120A only */
+#define GT_CPUERR_PARITY (0x138 >> 2) /* GT-64120A only */
/* CPU Sync Barrier */
-#define GT_PCI0SYNC (0x0c0 >> 2)
-#define GT_PCI1SYNC (0x0c8 >> 2)
+#define GT_PCI0SYNC (0x0c0 >> 2)
+#define GT_PCI1SYNC (0x0c8 >> 2)
/* SDRAM and Device Address Decode */
-#define GT_SCS0LD (0x400 >> 2)
-#define GT_SCS0HD (0x404 >> 2)
-#define GT_SCS1LD (0x408 >> 2)
-#define GT_SCS1HD (0x40c >> 2)
-#define GT_SCS2LD (0x410 >> 2)
-#define GT_SCS2HD (0x414 >> 2)
-#define GT_SCS3LD (0x418 >> 2)
-#define GT_SCS3HD (0x41c >> 2)
-#define GT_CS0LD (0x420 >> 2)
-#define GT_CS0HD (0x424 >> 2)
-#define GT_CS1LD (0x428 >> 2)
-#define GT_CS1HD (0x42c >> 2)
-#define GT_CS2LD (0x430 >> 2)
-#define GT_CS2HD (0x434 >> 2)
-#define GT_CS3LD (0x438 >> 2)
-#define GT_CS3HD (0x43c >> 2)
-#define GT_BOOTLD (0x440 >> 2)
-#define GT_BOOTHD (0x444 >> 2)
-#define GT_ADERR (0x470 >> 2)
+#define GT_SCS0LD (0x400 >> 2)
+#define GT_SCS0HD (0x404 >> 2)
+#define GT_SCS1LD (0x408 >> 2)
+#define GT_SCS1HD (0x40c >> 2)
+#define GT_SCS2LD (0x410 >> 2)
+#define GT_SCS2HD (0x414 >> 2)
+#define GT_SCS3LD (0x418 >> 2)
+#define GT_SCS3HD (0x41c >> 2)
+#define GT_CS0LD (0x420 >> 2)
+#define GT_CS0HD (0x424 >> 2)
+#define GT_CS1LD (0x428 >> 2)
+#define GT_CS1HD (0x42c >> 2)
+#define GT_CS2LD (0x430 >> 2)
+#define GT_CS2HD (0x434 >> 2)
+#define GT_CS3LD (0x438 >> 2)
+#define GT_CS3HD (0x43c >> 2)
+#define GT_BOOTLD (0x440 >> 2)
+#define GT_BOOTHD (0x444 >> 2)
+#define GT_ADERR (0x470 >> 2)
/* SDRAM Configuration */
-#define GT_SDRAM_CFG (0x448 >> 2)
-#define GT_SDRAM_OPMODE (0x474 >> 2)
-#define GT_SDRAM_BM (0x478 >> 2)
-#define GT_SDRAM_ADDRDECODE (0x47c >> 2)
+#define GT_SDRAM_CFG (0x448 >> 2)
+#define GT_SDRAM_OPMODE (0x474 >> 2)
+#define GT_SDRAM_BM (0x478 >> 2)
+#define GT_SDRAM_ADDRDECODE (0x47c >> 2)
/* SDRAM Parameters */
-#define GT_SDRAM_B0 (0x44c >> 2)
-#define GT_SDRAM_B1 (0x450 >> 2)
-#define GT_SDRAM_B2 (0x454 >> 2)
-#define GT_SDRAM_B3 (0x458 >> 2)
+#define GT_SDRAM_B0 (0x44c >> 2)
+#define GT_SDRAM_B1 (0x450 >> 2)
+#define GT_SDRAM_B2 (0x454 >> 2)
+#define GT_SDRAM_B3 (0x458 >> 2)
/* Device Parameters */
-#define GT_DEV_B0 (0x45c >> 2)
-#define GT_DEV_B1 (0x460 >> 2)
-#define GT_DEV_B2 (0x464 >> 2)
-#define GT_DEV_B3 (0x468 >> 2)
-#define GT_DEV_BOOT (0x46c >> 2)
+#define GT_DEV_B0 (0x45c >> 2)
+#define GT_DEV_B1 (0x460 >> 2)
+#define GT_DEV_B2 (0x464 >> 2)
+#define GT_DEV_B3 (0x468 >> 2)
+#define GT_DEV_BOOT (0x46c >> 2)
/* ECC */
-#define GT_ECC_ERRDATALO (0x480 >> 2) /* GT-64120A only */
-#define GT_ECC_ERRDATAHI (0x484 >> 2) /* GT-64120A only */
-#define GT_ECC_MEM (0x488 >> 2) /* GT-64120A only */
-#define GT_ECC_CALC (0x48c >> 2) /* GT-64120A only */
-#define GT_ECC_ERRADDR (0x490 >> 2) /* GT-64120A only */
+#define GT_ECC_ERRDATALO (0x480 >> 2) /* GT-64120A only */
+#define GT_ECC_ERRDATAHI (0x484 >> 2) /* GT-64120A only */
+#define GT_ECC_MEM (0x488 >> 2) /* GT-64120A only */
+#define GT_ECC_CALC (0x48c >> 2) /* GT-64120A only */
+#define GT_ECC_ERRADDR (0x490 >> 2) /* GT-64120A only */
/* DMA Record */
-#define GT_DMA0_CNT (0x800 >> 2)
-#define GT_DMA1_CNT (0x804 >> 2)
-#define GT_DMA2_CNT (0x808 >> 2)
-#define GT_DMA3_CNT (0x80c >> 2)
-#define GT_DMA0_SA (0x810 >> 2)
-#define GT_DMA1_SA (0x814 >> 2)
-#define GT_DMA2_SA (0x818 >> 2)
-#define GT_DMA3_SA (0x81c >> 2)
-#define GT_DMA0_DA (0x820 >> 2)
-#define GT_DMA1_DA (0x824 >> 2)
-#define GT_DMA2_DA (0x828 >> 2)
-#define GT_DMA3_DA (0x82c >> 2)
-#define GT_DMA0_NEXT (0x830 >> 2)
-#define GT_DMA1_NEXT (0x834 >> 2)
-#define GT_DMA2_NEXT (0x838 >> 2)
-#define GT_DMA3_NEXT (0x83c >> 2)
-#define GT_DMA0_CUR (0x870 >> 2)
-#define GT_DMA1_CUR (0x874 >> 2)
-#define GT_DMA2_CUR (0x878 >> 2)
-#define GT_DMA3_CUR (0x87c >> 2)
+#define GT_DMA0_CNT (0x800 >> 2)
+#define GT_DMA1_CNT (0x804 >> 2)
+#define GT_DMA2_CNT (0x808 >> 2)
+#define GT_DMA3_CNT (0x80c >> 2)
+#define GT_DMA0_SA (0x810 >> 2)
+#define GT_DMA1_SA (0x814 >> 2)
+#define GT_DMA2_SA (0x818 >> 2)
+#define GT_DMA3_SA (0x81c >> 2)
+#define GT_DMA0_DA (0x820 >> 2)
+#define GT_DMA1_DA (0x824 >> 2)
+#define GT_DMA2_DA (0x828 >> 2)
+#define GT_DMA3_DA (0x82c >> 2)
+#define GT_DMA0_NEXT (0x830 >> 2)
+#define GT_DMA1_NEXT (0x834 >> 2)
+#define GT_DMA2_NEXT (0x838 >> 2)
+#define GT_DMA3_NEXT (0x83c >> 2)
+#define GT_DMA0_CUR (0x870 >> 2)
+#define GT_DMA1_CUR (0x874 >> 2)
+#define GT_DMA2_CUR (0x878 >> 2)
+#define GT_DMA3_CUR (0x87c >> 2)
/* DMA Channel Control */
-#define GT_DMA0_CTRL (0x840 >> 2)
-#define GT_DMA1_CTRL (0x844 >> 2)
-#define GT_DMA2_CTRL (0x848 >> 2)
-#define GT_DMA3_CTRL (0x84c >> 2)
+#define GT_DMA0_CTRL (0x840 >> 2)
+#define GT_DMA1_CTRL (0x844 >> 2)
+#define GT_DMA2_CTRL (0x848 >> 2)
+#define GT_DMA3_CTRL (0x84c >> 2)
/* DMA Arbiter */
-#define GT_DMA_ARB (0x860 >> 2)
+#define GT_DMA_ARB (0x860 >> 2)
/* Timer/Counter */
-#define GT_TC0 (0x850 >> 2)
-#define GT_TC1 (0x854 >> 2)
-#define GT_TC2 (0x858 >> 2)
-#define GT_TC3 (0x85c >> 2)
-#define GT_TC_CONTROL (0x864 >> 2)
+#define GT_TC0 (0x850 >> 2)
+#define GT_TC1 (0x854 >> 2)
+#define GT_TC2 (0x858 >> 2)
+#define GT_TC3 (0x85c >> 2)
+#define GT_TC_CONTROL (0x864 >> 2)
/* PCI Internal */
-#define GT_PCI0_CMD (0xc00 >> 2)
-#define GT_PCI0_TOR (0xc04 >> 2)
-#define GT_PCI0_BS_SCS10 (0xc08 >> 2)
-#define GT_PCI0_BS_SCS32 (0xc0c >> 2)
-#define GT_PCI0_BS_CS20 (0xc10 >> 2)
-#define GT_PCI0_BS_CS3BT (0xc14 >> 2)
-#define GT_PCI1_IACK (0xc30 >> 2)
-#define GT_PCI0_IACK (0xc34 >> 2)
-#define GT_PCI0_BARE (0xc3c >> 2)
-#define GT_PCI0_PREFMBR (0xc40 >> 2)
-#define GT_PCI0_SCS10_BAR (0xc48 >> 2)
-#define GT_PCI0_SCS32_BAR (0xc4c >> 2)
-#define GT_PCI0_CS20_BAR (0xc50 >> 2)
-#define GT_PCI0_CS3BT_BAR (0xc54 >> 2)
-#define GT_PCI0_SSCS10_BAR (0xc58 >> 2)
-#define GT_PCI0_SSCS32_BAR (0xc5c >> 2)
-#define GT_PCI0_SCS3BT_BAR (0xc64 >> 2)
-#define GT_PCI1_CMD (0xc80 >> 2)
-#define GT_PCI1_TOR (0xc84 >> 2)
-#define GT_PCI1_BS_SCS10 (0xc88 >> 2)
-#define GT_PCI1_BS_SCS32 (0xc8c >> 2)
-#define GT_PCI1_BS_CS20 (0xc90 >> 2)
-#define GT_PCI1_BS_CS3BT (0xc94 >> 2)
-#define GT_PCI1_BARE (0xcbc >> 2)
-#define GT_PCI1_PREFMBR (0xcc0 >> 2)
-#define GT_PCI1_SCS10_BAR (0xcc8 >> 2)
-#define GT_PCI1_SCS32_BAR (0xccc >> 2)
-#define GT_PCI1_CS20_BAR (0xcd0 >> 2)
-#define GT_PCI1_CS3BT_BAR (0xcd4 >> 2)
-#define GT_PCI1_SSCS10_BAR (0xcd8 >> 2)
-#define GT_PCI1_SSCS32_BAR (0xcdc >> 2)
-#define GT_PCI1_SCS3BT_BAR (0xce4 >> 2)
-#define GT_PCI1_CFGADDR (0xcf0 >> 2)
-#define GT_PCI1_CFGDATA (0xcf4 >> 2)
-#define GT_PCI0_CFGADDR (0xcf8 >> 2)
-#define GT_PCI0_CFGDATA (0xcfc >> 2)
+#define GT_PCI0_CMD (0xc00 >> 2)
+#define GT_PCI0_TOR (0xc04 >> 2)
+#define GT_PCI0_BS_SCS10 (0xc08 >> 2)
+#define GT_PCI0_BS_SCS32 (0xc0c >> 2)
+#define GT_PCI0_BS_CS20 (0xc10 >> 2)
+#define GT_PCI0_BS_CS3BT (0xc14 >> 2)
+#define GT_PCI1_IACK (0xc30 >> 2)
+#define GT_PCI0_IACK (0xc34 >> 2)
+#define GT_PCI0_BARE (0xc3c >> 2)
+#define GT_PCI0_PREFMBR (0xc40 >> 2)
+#define GT_PCI0_SCS10_BAR (0xc48 >> 2)
+#define GT_PCI0_SCS32_BAR (0xc4c >> 2)
+#define GT_PCI0_CS20_BAR (0xc50 >> 2)
+#define GT_PCI0_CS3BT_BAR (0xc54 >> 2)
+#define GT_PCI0_SSCS10_BAR (0xc58 >> 2)
+#define GT_PCI0_SSCS32_BAR (0xc5c >> 2)
+#define GT_PCI0_SCS3BT_BAR (0xc64 >> 2)
+#define GT_PCI1_CMD (0xc80 >> 2)
+#define GT_PCI1_TOR (0xc84 >> 2)
+#define GT_PCI1_BS_SCS10 (0xc88 >> 2)
+#define GT_PCI1_BS_SCS32 (0xc8c >> 2)
+#define GT_PCI1_BS_CS20 (0xc90 >> 2)
+#define GT_PCI1_BS_CS3BT (0xc94 >> 2)
+#define GT_PCI1_BARE (0xcbc >> 2)
+#define GT_PCI1_PREFMBR (0xcc0 >> 2)
+#define GT_PCI1_SCS10_BAR (0xcc8 >> 2)
+#define GT_PCI1_SCS32_BAR (0xccc >> 2)
+#define GT_PCI1_CS20_BAR (0xcd0 >> 2)
+#define GT_PCI1_CS3BT_BAR (0xcd4 >> 2)
+#define GT_PCI1_SSCS10_BAR (0xcd8 >> 2)
+#define GT_PCI1_SSCS32_BAR (0xcdc >> 2)
+#define GT_PCI1_SCS3BT_BAR (0xce4 >> 2)
+#define GT_PCI1_CFGADDR (0xcf0 >> 2)
+#define GT_PCI1_CFGDATA (0xcf4 >> 2)
+#define GT_PCI0_CFGADDR (0xcf8 >> 2)
+#define GT_PCI0_CFGDATA (0xcfc >> 2)
/* Interrupts */
-#define GT_INTRCAUSE (0xc18 >> 2)
-#define GT_INTRMASK (0xc1c >> 2)
-#define GT_PCI0_ICMASK (0xc24 >> 2)
-#define GT_PCI0_SERR0MASK (0xc28 >> 2)
-#define GT_CPU_INTSEL (0xc70 >> 2)
-#define GT_PCI0_INTSEL (0xc74 >> 2)
-#define GT_HINTRCAUSE (0xc98 >> 2)
-#define GT_HINTRMASK (0xc9c >> 2)
-#define GT_PCI0_HICMASK (0xca4 >> 2)
-#define GT_PCI1_SERR1MASK (0xca8 >> 2)
+#define GT_INTRCAUSE (0xc18 >> 2)
+#define GT_INTRMASK (0xc1c >> 2)
+#define GT_PCI0_ICMASK (0xc24 >> 2)
+#define GT_PCI0_SERR0MASK (0xc28 >> 2)
+#define GT_CPU_INTSEL (0xc70 >> 2)
+#define GT_PCI0_INTSEL (0xc74 >> 2)
+#define GT_HINTRCAUSE (0xc98 >> 2)
+#define GT_HINTRMASK (0xc9c >> 2)
+#define GT_PCI0_HICMASK (0xca4 >> 2)
+#define GT_PCI1_SERR1MASK (0xca8 >> 2)
#define PCI_MAPPING_ENTRY(regname) \
hwaddr regname ##_start; \
} GT64120State;
/* Adjust range to avoid touching space which isn't mappable via PCI */
-/* XXX: Hardcoded values for Malta: 0x1e000000 - 0x1f100000
- 0x1fc00000 - 0x1fd00000 */
-static void check_reserved_space (hwaddr *start,
- hwaddr *length)
+/*
+ * XXX: Hardcoded values for Malta: 0x1e000000 - 0x1f100000
+ * 0x1fc00000 - 0x1fd00000
+ */
+static void check_reserved_space(hwaddr *start, hwaddr *length)
{
hwaddr begin = *start;
hwaddr end = *start + *length;
- if (end >= 0x1e000000LL && end < 0x1f100000LL)
+ if (end >= 0x1e000000LL && end < 0x1f100000LL) {
end = 0x1e000000LL;
- if (begin >= 0x1e000000LL && begin < 0x1f100000LL)
+ }
+ if (begin >= 0x1e000000LL && begin < 0x1f100000LL) {
begin = 0x1f100000LL;
- if (end >= 0x1fc00000LL && end < 0x1fd00000LL)
+ }
+ if (end >= 0x1fc00000LL && end < 0x1fd00000LL) {
end = 0x1fc00000LL;
- if (begin >= 0x1fc00000LL && begin < 0x1fd00000LL)
+ }
+ if (begin >= 0x1fc00000LL && begin < 0x1fd00000LL) {
begin = 0x1fd00000LL;
+ }
/* XXX: This is broken when a reserved range splits the requested range */
- if (end >= 0x1f100000LL && begin < 0x1e000000LL)
+ if (end >= 0x1f100000LL && begin < 0x1e000000LL) {
end = 0x1e000000LL;
- if (end >= 0x1fd00000LL && begin < 0x1fc00000LL)
+ }
+ if (end >= 0x1fd00000LL && begin < 0x1fc00000LL) {
end = 0x1fc00000LL;
+ }
*start = begin;
*length = end - begin;
check_reserved_space(&start, &length);
length = 0x1000;
/* Map new address */
- DPRINTF("ISD: "TARGET_FMT_plx"@"TARGET_FMT_plx
- " -> "TARGET_FMT_plx"@"TARGET_FMT_plx"\n",
- s->ISD_length, s->ISD_start, length, start);
+ trace_gt64120_isd_remap(s->ISD_length, s->ISD_start, length, start);
s->ISD_start = start;
s->ISD_length = length;
memory_region_add_subregion(get_system_memory(), s->ISD_start, &s->ISD_mem);
}
};
-static void gt64120_writel (void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
+static void gt64120_writel(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
{
GT64120State *s = opaque;
PCIHostState *phb = PCI_HOST_BRIDGE(s);
uint32_t saddr;
- if (!(s->regs[GT_CPU] & 0x00001000))
+ if (!(s->regs[GT_CPU] & 0x00001000)) {
val = bswap32(val);
+ }
saddr = (addr & 0xfff) >> 2;
switch (saddr) {
case GT_CPUERR_DATAHI:
case GT_CPUERR_PARITY:
/* Read-only registers, do nothing */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "gt64120: Read-only register write "
+ "reg:0x03%x size:%u value:0x%0*" PRIx64 "\n",
+ saddr << 2, size, size << 1, val);
break;
/* CPU Sync Barrier */
case GT_PCI0SYNC:
case GT_PCI1SYNC:
/* Read-only registers, do nothing */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "gt64120: Read-only register write "
+ "reg:0x03%x size:%u value:0x%0*" PRIx64 "\n",
+ saddr << 2, size, size << 1, val);
break;
/* SDRAM and Device Address Decode */
case GT_DEV_B3:
case GT_DEV_BOOT:
/* Not implemented */
- DPRINTF ("Unimplemented device register offset 0x%x\n", saddr << 2);
+ qemu_log_mask(LOG_UNIMP,
+ "gt64120: Unimplemented device register write "
+ "reg:0x03%x size:%u value:0x%0*" PRIx64 "\n",
+ saddr << 2, size, size << 1, val);
break;
/* ECC */
case GT_ECC_CALC:
case GT_ECC_ERRADDR:
/* Read-only registers, do nothing */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "gt64120: Read-only register write "
+ "reg:0x03%x size:%u value:0x%0*" PRIx64 "\n",
+ saddr << 2, size, size << 1, val);
break;
/* DMA Record */
case GT_DMA1_CUR:
case GT_DMA2_CUR:
case GT_DMA3_CUR:
- /* Not implemented */
- DPRINTF ("Unimplemented DMA register offset 0x%x\n", saddr << 2);
- break;
/* DMA Channel Control */
case GT_DMA0_CTRL:
case GT_DMA1_CTRL:
case GT_DMA2_CTRL:
case GT_DMA3_CTRL:
- /* Not implemented */
- DPRINTF ("Unimplemented DMA register offset 0x%x\n", saddr << 2);
- break;
/* DMA Arbiter */
case GT_DMA_ARB:
/* Not implemented */
- DPRINTF ("Unimplemented DMA register offset 0x%x\n", saddr << 2);
+ qemu_log_mask(LOG_UNIMP,
+ "gt64120: Unimplemented DMA register write "
+ "reg:0x03%x size:%u value:0x%0*" PRIx64 "\n",
+ saddr << 2, size, size << 1, val);
break;
/* Timer/Counter */
case GT_TC3:
case GT_TC_CONTROL:
/* Not implemented */
- DPRINTF ("Unimplemented timer register offset 0x%x\n", saddr << 2);
+ qemu_log_mask(LOG_UNIMP,
+ "gt64120: Unimplemented timer register write "
+ "reg:0x03%x size:%u value:0x%0*" PRIx64 "\n",
+ saddr << 2, size, size << 1, val);
break;
/* PCI Internal */
case GT_PCI1_CFGADDR:
case GT_PCI1_CFGDATA:
/* not implemented */
+ qemu_log_mask(LOG_UNIMP,
+ "gt64120: Unimplemented timer register write "
+ "reg:0x03%x size:%u value:0x%0*" PRIx64 "\n",
+ saddr << 2, size, size << 1, val);
break;
case GT_PCI0_CFGADDR:
phb->config_reg = val & 0x80fffffc;
/* not really implemented */
s->regs[saddr] = ~(~(s->regs[saddr]) | ~(val & 0xfffffffe));
s->regs[saddr] |= !!(s->regs[saddr] & 0xfffffffe);
- DPRINTF("INTRCAUSE %" PRIx64 "\n", val);
+ trace_gt64120_write("INTRCAUSE", size << 1, val);
break;
case GT_INTRMASK:
s->regs[saddr] = val & 0x3c3ffffe;
- DPRINTF("INTRMASK %" PRIx64 "\n", val);
+ trace_gt64120_write("INTRMASK", size << 1, val);
break;
case GT_PCI0_ICMASK:
s->regs[saddr] = val & 0x03fffffe;
- DPRINTF("ICMASK %" PRIx64 "\n", val);
+ trace_gt64120_write("ICMASK", size << 1, val);
break;
case GT_PCI0_SERR0MASK:
s->regs[saddr] = val & 0x0000003f;
- DPRINTF("SERR0MASK %" PRIx64 "\n", val);
+ trace_gt64120_write("SERR0MASK", size << 1, val);
break;
/* Reserved when only PCI_0 is configured. */
case GT_SDRAM_B1:
case GT_SDRAM_B2:
case GT_SDRAM_B3:
- /* We don't simulate electrical parameters of the SDRAM.
- Accept, but ignore the values. */
+ /*
+ * We don't simulate electrical parameters of the SDRAM.
+ * Accept, but ignore the values.
+ */
s->regs[saddr] = val;
break;
default:
- DPRINTF ("Bad register offset 0x%x\n", (int)addr);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "gt64120: Illegal register write "
+ "reg:0x03%x size:%u value:0x%0*" PRIx64 "\n",
+ saddr << 2, size, size << 1, val);
break;
}
}
-static uint64_t gt64120_readl (void *opaque,
- hwaddr addr, unsigned size)
+static uint64_t gt64120_readl(void *opaque,
+ hwaddr addr, unsigned size)
{
GT64120State *s = opaque;
PCIHostState *phb = PCI_HOST_BRIDGE(s);
/* CPU Configuration */
case GT_MULTI:
- /* Only one GT64xxx is present on the CPU bus, return
- the initial value */
+ /*
+ * Only one GT64xxx is present on the CPU bus, return
+ * the initial value.
+ */
val = s->regs[saddr];
break;
case GT_CPUERR_DATALO:
case GT_CPUERR_DATAHI:
case GT_CPUERR_PARITY:
- /* Emulated memory has no error, always return the initial
- values */
+ /* Emulated memory has no error, always return the initial values. */
val = s->regs[saddr];
break;
/* CPU Sync Barrier */
case GT_PCI0SYNC:
case GT_PCI1SYNC:
- /* Reading those register should empty all FIFO on the PCI
- bus, which are not emulated. The return value should be
- a random value that should be ignored. */
+ /*
+ * Reading those register should empty all FIFO on the PCI
+ * bus, which are not emulated. The return value should be
+ * a random value that should be ignored.
+ */
val = 0xc000ffee;
break;
case GT_ECC_MEM:
case GT_ECC_CALC:
case GT_ECC_ERRADDR:
- /* Emulated memory has no error, always return the initial
- values */
+ /* Emulated memory has no error, always return the initial values. */
val = s->regs[saddr];
break;
case GT_SDRAM_B1:
case GT_SDRAM_B2:
case GT_SDRAM_B3:
- /* We don't simulate electrical parameters of the SDRAM.
- Just return the last written value. */
+ /*
+ * We don't simulate electrical parameters of the SDRAM.
+ * Just return the last written value.
+ */
val = s->regs[saddr];
break;
/* Interrupts */
case GT_INTRCAUSE:
val = s->regs[saddr];
- DPRINTF("INTRCAUSE %x\n", val);
+ trace_gt64120_read("INTRCAUSE", size << 1, val);
break;
case GT_INTRMASK:
val = s->regs[saddr];
- DPRINTF("INTRMASK %x\n", val);
+ trace_gt64120_read("INTRMASK", size << 1, val);
break;
case GT_PCI0_ICMASK:
val = s->regs[saddr];
- DPRINTF("ICMASK %x\n", val);
+ trace_gt64120_read("ICMASK", size << 1, val);
break;
case GT_PCI0_SERR0MASK:
val = s->regs[saddr];
- DPRINTF("SERR0MASK %x\n", val);
+ trace_gt64120_read("SERR0MASK", size << 1, val);
break;
/* Reserved when only PCI_0 is configured. */
default:
val = s->regs[saddr];
- DPRINTF ("Bad register offset 0x%x\n", (int)addr);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "gt64120: Illegal register read "
+ "reg:0x03%x size:%u value:0x%0*x\n",
+ saddr << 2, size, size << 1, val);
break;
}
- if (!(s->regs[GT_CPU] & 0x00001000))
+ if (!(s->regs[GT_CPU] & 0x00001000)) {
val = bswap32(val);
+ }
return val;
}
slot = (pci_dev->devfn >> 3);
switch (slot) {
- /* PIIX4 USB */
- case 10:
+ /* PIIX4 USB */
+ case 10:
return 3;
- /* AMD 79C973 Ethernet */
- case 11:
+ /* AMD 79C973 Ethernet */
+ case 11:
return 1;
- /* Crystal 4281 Sound */
- case 12:
+ /* Crystal 4281 Sound */
+ case 12:
return 2;
- /* PCI slot 1 to 4 */
- case 18 ... 21:
+ /* PCI slot 1 to 4 */
+ case 18 ... 21:
return ((slot - 18) + irq_num) & 0x03;
- /* Unknown device, don't do any translation */
- default:
+ /* Unknown device, don't do any translation */
+ default:
return irq_num;
}
}
/* XXX: optimize */
pic_irq = piix4_dev->config[0x60 + irq_num];
if (pic_irq < 16) {
- /* The pic level is the logical OR of all the PCI irqs mapped
- to it */
+ /* The pic level is the logical OR of all the PCI irqs mapped to it. */
pic_level = 0;
for (i = 0; i < 4; i++) {
- if (pic_irq == piix4_dev->config[0x60 + i])
+ if (pic_irq == piix4_dev->config[0x60 + i]) {
pic_level |= pci_irq_levels[i];
+ }
}
qemu_set_irq(pic[pic_irq], pic_level);
}
dev = qdev_create(NULL, TYPE_GT64120_PCI_HOST_BRIDGE);
d = GT64120_PCI_HOST_BRIDGE(dev);
phb = PCI_HOST_BRIDGE(dev);
- memory_region_init(&d->pci0_mem, OBJECT(dev), "pci0-mem", UINT32_MAX);
+ memory_region_init(&d->pci0_mem, OBJECT(dev), "pci0-mem", 4 * GiB);
address_space_init(&d->pci0_mem_as, &d->pci0_mem, "pci0-mem");
phb->bus = pci_register_root_bus(dev, "pci",
gt64120_pci_set_irq, gt64120_pci_map_irq,
get_system_io(),
PCI_DEVFN(18, 0), 4, TYPE_PCI_BUS);
qdev_init_nofail(dev);
- memory_region_init_io(&d->ISD_mem, OBJECT(dev), &isd_mem_ops, d, "isd-mem", 0x1000);
+ memory_region_init_io(&d->ISD_mem, OBJECT(dev), &isd_mem_ops, d,
+ "isd-mem", 0x1000);
pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "gt64120_pci");
return phb->bus;
--- /dev/null
+# gt64xxx.c
+gt64120_read(const char *regname, int width, uint64_t value) "gt64120 read %s value:0x%0*" PRIx64
+gt64120_write(const char *regname, int width, uint64_t value) "gt64120 write %s value:0x%0*" PRIx64
+gt64120_isd_remap(uint64_t from_length, uint64_t from_addr, uint64_t to_length, uint64_t to_addr) "ISD: 0x%08" PRIx64 "@0x%08" PRIx64 " -> 0x%08" PRIx64 "@0x%08" PRIx64
obj-$(CONFIG_PVPANIC) += pvpanic.o
obj-$(CONFIG_AUX) += auxbus.o
+obj-$(CONFIG_ASPEED_SOC) += aspeed_xdma.o
obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
obj-$(CONFIG_MSF2) += msf2-sysreg.o
obj-$(CONFIG_NRF51_SOC) += nrf51_rng.o
--- /dev/null
+/*
+ * ASPEED XDMA Controller
+ * Eddie James <eajames@linux.ibm.com>
+ *
+ * Copyright (C) 2019 IBM Corp
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/error-report.h"
+#include "hw/misc/aspeed_xdma.h"
+#include "qapi/error.h"
+
+#include "trace.h"
+
+#define XDMA_BMC_CMDQ_ADDR 0x10
+#define XDMA_BMC_CMDQ_ENDP 0x14
+#define XDMA_BMC_CMDQ_WRP 0x18
+#define XDMA_BMC_CMDQ_W_MASK 0x0003FFFF
+#define XDMA_BMC_CMDQ_RDP 0x1C
+#define XDMA_BMC_CMDQ_RDP_MAGIC 0xEE882266
+#define XDMA_IRQ_ENG_CTRL 0x20
+#define XDMA_IRQ_ENG_CTRL_US_COMP BIT(4)
+#define XDMA_IRQ_ENG_CTRL_DS_COMP BIT(5)
+#define XDMA_IRQ_ENG_CTRL_W_MASK 0xBFEFF07F
+#define XDMA_IRQ_ENG_STAT 0x24
+#define XDMA_IRQ_ENG_STAT_US_COMP BIT(4)
+#define XDMA_IRQ_ENG_STAT_DS_COMP BIT(5)
+#define XDMA_IRQ_ENG_STAT_RESET 0xF8000000
+#define XDMA_MEM_SIZE 0x1000
+
+#define TO_REG(addr) ((addr) / sizeof(uint32_t))
+
+static uint64_t aspeed_xdma_read(void *opaque, hwaddr addr, unsigned int size)
+{
+ uint32_t val = 0;
+ AspeedXDMAState *xdma = opaque;
+
+ if (addr < ASPEED_XDMA_REG_SIZE) {
+ val = xdma->regs[TO_REG(addr)];
+ }
+
+ return (uint64_t)val;
+}
+
+static void aspeed_xdma_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned int size)
+{
+ unsigned int idx;
+ uint32_t val32 = (uint32_t)val;
+ AspeedXDMAState *xdma = opaque;
+
+ if (addr >= ASPEED_XDMA_REG_SIZE) {
+ return;
+ }
+
+ switch (addr) {
+ case XDMA_BMC_CMDQ_ENDP:
+ xdma->regs[TO_REG(addr)] = val32 & XDMA_BMC_CMDQ_W_MASK;
+ break;
+ case XDMA_BMC_CMDQ_WRP:
+ idx = TO_REG(addr);
+ xdma->regs[idx] = val32 & XDMA_BMC_CMDQ_W_MASK;
+ xdma->regs[TO_REG(XDMA_BMC_CMDQ_RDP)] = xdma->regs[idx];
+
+ trace_aspeed_xdma_write(addr, val);
+
+ if (xdma->bmc_cmdq_readp_set) {
+ xdma->bmc_cmdq_readp_set = 0;
+ } else {
+ xdma->regs[TO_REG(XDMA_IRQ_ENG_STAT)] |=
+ XDMA_IRQ_ENG_STAT_US_COMP | XDMA_IRQ_ENG_STAT_DS_COMP;
+
+ if (xdma->regs[TO_REG(XDMA_IRQ_ENG_CTRL)] &
+ (XDMA_IRQ_ENG_CTRL_US_COMP | XDMA_IRQ_ENG_CTRL_DS_COMP))
+ qemu_irq_raise(xdma->irq);
+ }
+ break;
+ case XDMA_BMC_CMDQ_RDP:
+ trace_aspeed_xdma_write(addr, val);
+
+ if (val32 == XDMA_BMC_CMDQ_RDP_MAGIC) {
+ xdma->bmc_cmdq_readp_set = 1;
+ }
+ break;
+ case XDMA_IRQ_ENG_CTRL:
+ xdma->regs[TO_REG(addr)] = val32 & XDMA_IRQ_ENG_CTRL_W_MASK;
+ break;
+ case XDMA_IRQ_ENG_STAT:
+ trace_aspeed_xdma_write(addr, val);
+
+ idx = TO_REG(addr);
+ if (val32 & (XDMA_IRQ_ENG_STAT_US_COMP | XDMA_IRQ_ENG_STAT_DS_COMP)) {
+ xdma->regs[idx] &=
+ ~(XDMA_IRQ_ENG_STAT_US_COMP | XDMA_IRQ_ENG_STAT_DS_COMP);
+ qemu_irq_lower(xdma->irq);
+ }
+ break;
+ default:
+ xdma->regs[TO_REG(addr)] = val32;
+ break;
+ }
+}
+
+static const MemoryRegionOps aspeed_xdma_ops = {
+ .read = aspeed_xdma_read,
+ .write = aspeed_xdma_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid.min_access_size = 4,
+ .valid.max_access_size = 4,
+};
+
+static void aspeed_xdma_realize(DeviceState *dev, Error **errp)
+{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ AspeedXDMAState *xdma = ASPEED_XDMA(dev);
+
+ sysbus_init_irq(sbd, &xdma->irq);
+ memory_region_init_io(&xdma->iomem, OBJECT(xdma), &aspeed_xdma_ops, xdma,
+ TYPE_ASPEED_XDMA, XDMA_MEM_SIZE);
+ sysbus_init_mmio(sbd, &xdma->iomem);
+}
+
+static void aspeed_xdma_reset(DeviceState *dev)
+{
+ AspeedXDMAState *xdma = ASPEED_XDMA(dev);
+
+ xdma->bmc_cmdq_readp_set = 0;
+ memset(xdma->regs, 0, ASPEED_XDMA_REG_SIZE);
+ xdma->regs[TO_REG(XDMA_IRQ_ENG_STAT)] = XDMA_IRQ_ENG_STAT_RESET;
+
+ qemu_irq_lower(xdma->irq);
+}
+
+static const VMStateDescription aspeed_xdma_vmstate = {
+ .name = TYPE_ASPEED_XDMA,
+ .version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(regs, AspeedXDMAState, ASPEED_XDMA_NUM_REGS),
+ VMSTATE_END_OF_LIST(),
+ },
+};
+
+static void aspeed_xdma_class_init(ObjectClass *classp, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(classp);
+
+ dc->realize = aspeed_xdma_realize;
+ dc->reset = aspeed_xdma_reset;
+ dc->vmsd = &aspeed_xdma_vmstate;
+}
+
+static const TypeInfo aspeed_xdma_info = {
+ .name = TYPE_ASPEED_XDMA,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(AspeedXDMAState),
+ .class_init = aspeed_xdma_class_init,
+};
+
+static void aspeed_xdma_register_type(void)
+{
+ type_register_static(&aspeed_xdma_info);
+}
+type_init(aspeed_xdma_register_type);
# armsse-mhu.c
armsse_mhu_read(uint64_t offset, uint64_t data, unsigned size) "SSE-200 MHU read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
armsse_mhu_write(uint64_t offset, uint64_t data, unsigned size) "SSE-200 MHU write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+
+# aspeed_xdma.c
+aspeed_xdma_write(uint64_t offset, uint64_t data) "XDMA write: offset 0x%" PRIx64 " data 0x%" PRIx64
sysbus_init_irq(sbd, &s->irq);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
- s->conf.peers.ncs[0] = nd_table[0].netdev;
-
s->nic = qemu_new_nic(&net_ftgmac100_info, &s->conf,
object_get_typename(OBJECT(dev)), DEVICE(dev)->id,
s);
#define HME_SEBI_STAT 0x100
#define HME_SEBI_STAT_LINUXBUG 0x108
#define HME_SEB_STAT_RXTOHOST 0x10000
+#define HME_SEB_STAT_NORXD 0x20000
#define HME_SEB_STAT_MIFIRQ 0x800000
#define HME_SEB_STAT_HOSTTOTX 0x1000000
#define HME_SEB_STAT_TXALL 0x2000000
}
level = (seb ? 1 : 0);
+ trace_sunhme_update_irq(mifmask, mif, sebmask, seb, level);
+
pci_set_irq(d, level);
}
uint64_t val, unsigned size)
{
SunHMEState *s = SUNHME(opaque);
+ uint64_t oldval = s->macregs[addr >> 2];
trace_sunhme_mac_write(addr, val);
s->macregs[addr >> 2] = val;
+
+ switch (addr) {
+ case HME_MACI_RXCFG:
+ if (!(oldval & HME_MAC_RXCFG_ENABLE) &&
+ (val & HME_MAC_RXCFG_ENABLE)) {
+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
+ }
+ break;
+ }
}
static uint64_t sunhme_mac_read(void *opaque, hwaddr addr,
{
SunHMEState *s = qemu_get_nic_opaque(nc);
- return s->macregs[HME_MAC_RXCFG_ENABLE >> 2] & HME_MAC_RXCFG_ENABLE;
+ return s->macregs[HME_MACI_RXCFG >> 2] & HME_MAC_RXCFG_ENABLE;
}
static void sunhme_link_status_changed(NetClientState *nc)
/* Do nothing if MAC RX disabled */
if (!(s->macregs[HME_MACI_RXCFG >> 2] & HME_MAC_RXCFG_ENABLE)) {
- return -1;
+ return 0;
}
trace_sunhme_rx_filter_destmac(buf[0], buf[1], buf[2],
/* Didn't match hash filter */
trace_sunhme_rx_filter_hash_nomatch();
trace_sunhme_rx_filter_reject();
- return 0;
+ return -1;
} else {
trace_sunhme_rx_filter_hash_match();
}
} else {
/* Not for us */
trace_sunhme_rx_filter_reject();
- return 0;
+ return -1;
}
} else {
trace_sunhme_rx_filter_promisc_match();
pci_dma_read(d, rb + cr * HME_DESC_SIZE, &status, 4);
pci_dma_read(d, rb + cr * HME_DESC_SIZE + 4, &buffer, 4);
+ /* If we don't own the current descriptor then indicate overflow error */
+ if (!(status & HME_XD_OWN)) {
+ s->sebregs[HME_SEBI_STAT >> 2] |= HME_SEB_STAT_NORXD;
+ sunhme_update_irq(s);
+ trace_sunhme_rx_norxd();
+ return -1;
+ }
+
rxoffset = (s->erxregs[HME_ERXI_CFG >> 2] & HME_ERX_CFG_BYTEOFFSET) >>
HME_ERX_CFG_BYTEOFFSET_SHIFT;
sunhme_rx_filter_accept(void) "accepting incoming frame"
sunhme_rx_desc(uint32_t addr, int offset, uint32_t status, int len, int cr, int nr) "addr 0x%"PRIx32"(+0x%x) status 0x%"PRIx32 " len %d (ring %d/%d)"
sunhme_rx_xsum_calc(uint16_t xsum) "calculated incoming xsum as 0x%x"
+sunhme_rx_norxd(void) "no free rx descriptors available"
+sunhme_update_irq(uint32_t mifmask, uint32_t mif, uint32_t sebmask, uint32_t seb, int level) "mifmask: 0x%x mif: 0x%x sebmask: 0x%x seb: 0x%x level: %d"
# virtio-net.c
virtio_net_announce_notify(void) ""
timer_mod(n->announce_timer.tm,
qemu_clock_get_ms(n->announce_timer.type));
} else {
- qemu_announce_timer_del(&n->announce_timer);
+ qemu_announce_timer_del(&n->announce_timer, false);
}
}
virtio_net_del_queue(n, i);
}
- qemu_announce_timer_del(&n->announce_timer);
+ qemu_announce_timer_del(&n->announce_timer, false);
g_free(n->vqs);
qemu_del_nic(n->nic);
virtio_net_rsc_cleanup(n);
#include "net/util.h"
#include "hw/xen/xen-legacy-backend.h"
-#include <xen/io/netif.h>
+#include "hw/xen/interface/io/netif.h"
/* ------------------------------------------------------------- */
#define DESIGNWARE_PCIE_ATU_DEVFN(x) (((x) >> 16) & 0xff)
#define DESIGNWARE_PCIE_ATU_UPPER_TARGET 0x91C
+#define DESIGNWARE_PCIE_IRQ_MSI 3
+
static DesignwarePCIEHost *
designware_pcie_root_to_host(DesignwarePCIERoot *root)
{
root->msi.intr[0].status |= BIT(val) & root->msi.intr[0].enable;
if (root->msi.intr[0].status & ~root->msi.intr[0].mask) {
- qemu_set_irq(host->pci.irqs[0], 1);
+ qemu_set_irq(host->pci.irqs[DESIGNWARE_PCIE_IRQ_MSI], 1);
}
}
case DESIGNWARE_PCIE_MSI_ADDR_LO:
root->msi.base &= 0xFFFFFFFF00000000ULL;
root->msi.base |= val;
+ designware_pcie_root_update_msi_mapping(root);
break;
case DESIGNWARE_PCIE_MSI_ADDR_HI:
root->msi.base &= 0x00000000FFFFFFFFULL;
root->msi.base |= (uint64_t)val << 32;
+ designware_pcie_root_update_msi_mapping(root);
break;
- case DESIGNWARE_PCIE_MSI_INTR0_ENABLE: {
- const bool update_msi_mapping = !root->msi.intr[0].enable ^ !!val;
-
+ case DESIGNWARE_PCIE_MSI_INTR0_ENABLE:
root->msi.intr[0].enable = val;
-
- if (update_msi_mapping) {
- designware_pcie_root_update_msi_mapping(root);
- }
+ designware_pcie_root_update_msi_mapping(root);
break;
- }
case DESIGNWARE_PCIE_MSI_INTR0_MASK:
root->msi.intr[0].mask = val;
case DESIGNWARE_PCIE_MSI_INTR0_STATUS:
root->msi.intr[0].status ^= val;
if (!root->msi.intr[0].status) {
- qemu_set_irq(host->pci.irqs[0], 0);
+ qemu_set_irq(host->pci.irqs[DESIGNWARE_PCIE_IRQ_MSI], 0);
}
break;
}
/* The NewWorld NVRAM is not located in the MacIO device */
-#ifdef CONFIG_KVM
if (kvm_enabled() && getpagesize() > 4096) {
/* We can't combine read-write and read-only in a single page, so
move the NVRAM out of ROM again for KVM */
nvram_addr = 0xFFE00000;
}
-#endif
dev = qdev_create(NULL, TYPE_MACIO_NVRAM);
qdev_prop_set_uint32(dev, "size", 0x2000);
qdev_prop_set_uint32(dev, "it_shift", 1);
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
if (kvm_enabled()) {
-#ifdef CONFIG_KVM
uint8_t *hypercall;
hypercall = g_malloc(16);
kvmppc_get_hypercall(env, hypercall, 16);
fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
-#endif
}
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, tbfreq);
/* Mac OS X requires a "known good" clock-frequency value; pass it one. */
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
if (kvm_enabled()) {
-#ifdef CONFIG_KVM
uint8_t *hypercall;
hypercall = g_malloc(16);
kvmppc_get_hypercall(env, hypercall, 16);
fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
-#endif
}
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, tbfreq);
/* Mac OS X requires a "known good" clock-frequency value; pass it one. */
Pnv8Psi *psi8 = &chip8->psi;
Error *local_err = NULL;
+ /* XSCOM bridge is first */
+ pnv_xscom_realize(chip, PNV_XSCOM_SIZE, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(chip), 0, PNV_XSCOM_BASE(chip));
+
pcc->parent_realize(dev, &local_err);
if (local_err) {
error_propagate(errp, local_err);
k->isa_create = pnv_chip_power8_isa_create;
k->dt_populate = pnv_chip_power8_dt_populate;
k->pic_print_info = pnv_chip_power8_pic_print_info;
- k->xscom_base = 0x003fc0000000000ull;
dc->desc = "PowerNV Chip POWER8E";
device_class_set_parent_realize(dc, pnv_chip_power8_realize,
k->isa_create = pnv_chip_power8_isa_create;
k->dt_populate = pnv_chip_power8_dt_populate;
k->pic_print_info = pnv_chip_power8_pic_print_info;
- k->xscom_base = 0x003fc0000000000ull;
dc->desc = "PowerNV Chip POWER8";
device_class_set_parent_realize(dc, pnv_chip_power8_realize,
k->isa_create = pnv_chip_power8nvl_isa_create;
k->dt_populate = pnv_chip_power8_dt_populate;
k->pic_print_info = pnv_chip_power8_pic_print_info;
- k->xscom_base = 0x003fc0000000000ull;
dc->desc = "PowerNV Chip POWER8NVL";
device_class_set_parent_realize(dc, pnv_chip_power8_realize,
Pnv9Psi *psi9 = &chip9->psi;
Error *local_err = NULL;
+ /* XSCOM bridge is first */
+ pnv_xscom_realize(chip, PNV9_XSCOM_SIZE, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ sysbus_mmio_map(SYS_BUS_DEVICE(chip), 0, PNV9_XSCOM_BASE(chip));
+
pcc->parent_realize(dev, &local_err);
if (local_err) {
error_propagate(errp, local_err);
k->isa_create = pnv_chip_power9_isa_create;
k->dt_populate = pnv_chip_power9_dt_populate;
k->pic_print_info = pnv_chip_power9_pic_print_info;
- k->xscom_base = 0x00603fc00000000ull;
dc->desc = "PowerNV Chip POWER9";
device_class_set_parent_realize(dc, pnv_chip_power9_realize,
}
}
-static void pnv_chip_instance_init(Object *obj)
-{
- PNV_CHIP(obj)->xscom_base = PNV_CHIP_GET_CLASS(obj)->xscom_base;
-}
-
static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
{
Error *error = NULL;
PnvChip *chip = PNV_CHIP(dev);
Error *error = NULL;
- /* XSCOM bridge */
- pnv_xscom_realize(chip, &error);
- if (error) {
- error_propagate(errp, error);
- return;
- }
- sysbus_mmio_map(SYS_BUS_DEVICE(chip), 0, PNV_XSCOM_BASE(chip));
-
/* Cores */
pnv_chip_core_realize(chip, &error);
if (error) {
.name = TYPE_PNV_CHIP,
.parent = TYPE_SYS_BUS_DEVICE,
.class_init = pnv_chip_class_init,
- .instance_init = pnv_chip_instance_init,
.instance_size = sizeof(PnvChip),
.class_size = sizeof(PnvChipClass),
.abstract = true,
.endianness = DEVICE_BIG_ENDIAN,
};
-void pnv_xscom_realize(PnvChip *chip, Error **errp)
+void pnv_xscom_realize(PnvChip *chip, uint64_t size, Error **errp)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(chip);
char *name;
name = g_strdup_printf("xscom-%x", chip->chip_id);
memory_region_init_io(&chip->xscom_mmio, OBJECT(chip), &pnv_xscom_ops,
- chip, name, PNV_XSCOM_SIZE);
+ chip, name, size);
sysbus_init_mmio(sbd, &chip->xscom_mmio);
- memory_region_init(&chip->xscom, OBJECT(chip), name, PNV_XSCOM_SIZE);
+ memory_region_init(&chip->xscom, OBJECT(chip), name, size);
address_space_init(&chip->xscom_as, &chip->xscom, name);
g_free(name);
}
int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset)
{
- uint64_t reg[] = { cpu_to_be64(PNV_XSCOM_BASE(chip)),
- cpu_to_be64(PNV_XSCOM_SIZE) };
+ uint64_t reg[2];
int xscom_offset;
ForeachPopulateArgs args;
char *name;
+ if (pnv_chip_is_power9(chip)) {
+ reg[0] = cpu_to_be64(PNV9_XSCOM_BASE(chip));
+ reg[1] = cpu_to_be64(PNV9_XSCOM_SIZE);
+ } else {
+ reg[0] = cpu_to_be64(PNV_XSCOM_BASE(chip));
+ reg[1] = cpu_to_be64(PNV_XSCOM_SIZE);
+ }
+
name = g_strdup_printf("xscom@%" PRIx64, be64_to_cpu(reg[0]));
xscom_offset = fdt_add_subnode(fdt, root_offset, name);
_FDT(xscom_offset);
}
if (old_pending != env->pending_interrupts) {
-#ifdef CONFIG_KVM
kvmppc_set_interrupt(cpu, n_IRQ, level);
-#endif
}
CPU_FOREACH(cpu) {
PowerPCCPU *pcpu = POWERPC_CPU(cpu);
pcpu->env.tb_env->tb_offset = tb_off_adj;
-#if defined(CONFIG_KVM)
- kvm_set_one_reg(cpu, KVM_REG_PPC_TB_OFFSET,
- &pcpu->env.tb_env->tb_offset);
-#endif
+ kvmppc_set_reg_tb_offset(pcpu, pcpu->env.tb_env->tb_offset);
}
}
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled());
if (kvm_enabled()) {
-#ifdef CONFIG_KVM
uint8_t *hypercall;
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq());
kvmppc_get_hypercall(env, hypercall, 16);
fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
-#endif
} else {
fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, NANOSECONDS_PER_SECOND);
}
bitmap_clear(spapr->irq_map, 0, spapr->irq_map_nr);
}
-static void spapr_irq_init_device(SpaprMachineState *spapr,
+static void spapr_irq_init_kvm(SpaprMachineState *spapr,
SpaprIrq *irq, Error **errp)
{
MachineState *machine = MACHINE(spapr);
error_prepend(&local_err, "kernel_irqchip allowed but unavailable: ");
warn_report_err(local_err);
}
-
- irq->init_emu(spapr, errp);
}
/*
}
spapr->ics = ICS_BASE(obj);
+
+ xics_spapr_init(spapr);
}
#define ICS_IRQ_FREE(ics, srcno) \
{
Error *local_err = NULL;
- spapr_irq_init_device(spapr, &spapr_irq_xics, &local_err);
+ spapr_irq_init_kvm(spapr, &spapr_irq_xics, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
return XICS_NODENAME;
}
-static void spapr_irq_init_emu_xics(SpaprMachineState *spapr, Error **errp)
-{
- xics_spapr_init(spapr);
-}
-
static void spapr_irq_init_kvm_xics(SpaprMachineState *spapr, Error **errp)
{
if (kvm_enabled()) {
- xics_kvm_init(spapr, errp);
+ xics_kvm_connect(spapr, errp);
}
}
.reset = spapr_irq_reset_xics,
.set_irq = spapr_irq_set_irq_xics,
.get_nodename = spapr_irq_get_nodename_xics,
- .init_emu = spapr_irq_init_emu_xics,
.init_kvm = spapr_irq_init_kvm_xics,
};
spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx);
}
- spapr_irq_init_device(spapr, &spapr_irq_xive, &local_err);
+ spapr_irq_init_kvm(spapr, &spapr_irq_xive, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
return spapr->xive->nodename;
}
-static void spapr_irq_init_emu_xive(SpaprMachineState *spapr, Error **errp)
-{
- spapr_xive_init(spapr->xive, errp);
-}
-
static void spapr_irq_init_kvm_xive(SpaprMachineState *spapr, Error **errp)
{
if (kvm_enabled()) {
.reset = spapr_irq_reset_xive,
.set_irq = spapr_irq_set_irq_xive,
.get_nodename = spapr_irq_get_nodename_xive,
- .init_emu = spapr_irq_init_emu_xive,
.init_kvm = spapr_irq_init_kvm_xive,
};
.reset = spapr_irq_reset_dual,
.set_irq = spapr_irq_set_irq_dual,
.get_nodename = spapr_irq_get_nodename_dual,
- .init_emu = NULL, /* should not be used */
.init_kvm = NULL, /* should not be used */
};
return;
}
}
+
+ /*
+ * On a POWER9 host, some older KVM XICS devices cannot be destroyed and
+ * re-created. Detect that early to avoid QEMU to exit later when the
+ * guest reboots.
+ */
+ if (kvm_enabled() &&
+ spapr->irq == &spapr_irq_dual &&
+ machine_kernel_irqchip_required(machine) &&
+ xics_kvm_has_broken_disconnect(spapr)) {
+ error_setg(errp, "KVM is too old to support ic-mode=dual,kernel-irqchip=on");
+ return;
+ }
}
/*
.reset = spapr_irq_reset_xics,
.set_irq = spapr_irq_set_irq_xics,
.get_nodename = spapr_irq_get_nodename_xics,
- .init_emu = spapr_irq_init_emu_xics,
.init_kvm = spapr_irq_init_kvm_xics,
};
static int spapr_dt_pci_bus(SpaprPhbState *sphb, PCIBus *bus,
void *fdt, int offset)
{
+ Object *owner;
PciWalkFdt cbinfo = {
.fdt = fdt,
.offset = offset,
_FDT(fdt_setprop_cell(fdt, offset, "#size-cells",
RESOURCE_CELLS_SIZE));
- if (bus) {
- pci_for_each_device_reverse(bus, pci_bus_num(bus),
- spapr_dt_pci_device_cb, &cbinfo);
- if (cbinfo.err) {
- return cbinfo.err;
- }
+ assert(bus);
+ pci_for_each_device_reverse(bus, pci_bus_num(bus),
+ spapr_dt_pci_device_cb, &cbinfo);
+ if (cbinfo.err) {
+ return cbinfo.err;
}
- ret = spapr_dt_drc(fdt, offset, OBJECT(bus->parent_dev),
+ if (pci_bus_is_root(bus)) {
+ owner = OBJECT(sphb);
+ } else {
+ owner = OBJECT(pci_bridge_get_device(bus));
+ }
+
+ ret = spapr_dt_drc(fdt, offset, owner,
SPAPR_DR_CONNECTOR_TYPE_PCI);
if (ret) {
return ret;
memory_region_del_subregion(&sphb->iommu_root, &sphb->msiwindow);
+ /*
+ * An attached PCI device may have memory listeners, eg. VFIO PCI. We have
+ * unmapped all sections. Remove the listeners now, before destroying the
+ * address space.
+ */
+ address_space_remove_listeners(&sphb->iommu_as);
address_space_destroy(&sphb->iommu_as);
qbus_set_hotplug_handler(BUS(phb->bus), NULL, &error_abort);
* For KVM we want to ensure that this memory is a full page so that
* our memory slot is of page size granularity.
*/
-#ifdef CONFIG_KVM
if (kvm_enabled()) {
msi_window_size = getpagesize();
}
-#endif
memory_region_init_io(&sphb->msiwindow, OBJECT(sphb), &spapr_msi_ops, spapr,
"msi", msi_window_size);
#include "sysemu/sysemu.h"
#include "hw/ppc/spapr.h"
#include "qapi/error.h"
-#include "qapi/qapi-events-target.h"
+#include "qapi/qapi-events-misc-target.h"
#include "qemu/cutils.h"
#include "qemu/module.h"
+obj-y += boot.o
obj-$(CONFIG_SPIKE) += riscv_htif.o
obj-$(CONFIG_HART) += riscv_hart.o
obj-$(CONFIG_SIFIVE_E) += sifive_e.o
--- /dev/null
+/*
+ * QEMU RISC-V Boot Helper
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ * Copyright (c) 2019 Alistair Francis <alistair.francis@wdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu/error-report.h"
+#include "exec/cpu-defs.h"
+#include "hw/loader.h"
+#include "hw/riscv/boot.h"
+#include "hw/boards.h"
+#include "elf.h"
+
+#if defined(TARGET_RISCV32)
+# define KERNEL_BOOT_ADDRESS 0x80400000
+#else
+# define KERNEL_BOOT_ADDRESS 0x80200000
+#endif
+
+target_ulong riscv_load_firmware(const char *firmware_filename,
+ hwaddr firmware_load_addr)
+{
+ uint64_t firmware_entry, firmware_start, firmware_end;
+
+ if (load_elf(firmware_filename, NULL, NULL, NULL, &firmware_entry,
+ &firmware_start, &firmware_end, 0, EM_RISCV, 1, 0) > 0) {
+ return firmware_entry;
+ }
+
+ if (load_image_targphys_as(firmware_filename, firmware_load_addr,
+ ram_size, NULL) > 0) {
+ return firmware_load_addr;
+ }
+
+ error_report("could not load firmware '%s'", firmware_filename);
+ exit(1);
+}
+
+target_ulong riscv_load_kernel(const char *kernel_filename)
+{
+ uint64_t kernel_entry, kernel_high;
+
+ if (load_elf(kernel_filename, NULL, NULL, NULL,
+ &kernel_entry, NULL, &kernel_high, 0, EM_RISCV, 1, 0) > 0) {
+ return kernel_entry;
+ }
+
+ if (load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL,
+ NULL, NULL, NULL) > 0) {
+ return kernel_entry;
+ }
+
+ if (load_image_targphys_as(kernel_filename, KERNEL_BOOT_ADDRESS,
+ ram_size, NULL) > 0) {
+ return KERNEL_BOOT_ADDRESS;
+ }
+
+ error_report("could not load kernel '%s'", kernel_filename);
+ exit(1);
+}
+
+hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
+ uint64_t kernel_entry, hwaddr *start)
+{
+ int size;
+
+ /*
+ * We want to put the initrd far enough into RAM that when the
+ * kernel is uncompressed it will not clobber the initrd. However
+ * on boards without much RAM we must ensure that we still leave
+ * enough room for a decent sized initrd, and on boards with large
+ * amounts of RAM we must avoid the initrd being so far up in RAM
+ * that it is outside lowmem and inaccessible to the kernel.
+ * So for boards with less than 256MB of RAM we put the initrd
+ * halfway into RAM, and for boards with 256MB of RAM or more we put
+ * the initrd at 128MB.
+ */
+ *start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
+
+ size = load_ramdisk(filename, *start, mem_size - *start);
+ if (size == -1) {
+ size = load_image_targphys(filename, *start, mem_size - *start);
+ if (size == -1) {
+ error_report("could not load ramdisk '%s'", filename);
+ exit(1);
+ }
+ }
+
+ return *start + size;
+}
#include "hw/riscv/sifive_prci.h"
#include "hw/riscv/sifive_uart.h"
#include "hw/riscv/sifive_e.h"
+#include "hw/riscv/boot.h"
#include "chardev/char.h"
#include "sysemu/arch_init.h"
#include "exec/address-spaces.h"
-#include "elf.h"
static const struct MemmapEntry {
hwaddr base;
[SIFIVE_E_DTIM] = { 0x80000000, 0x4000 }
};
-static target_ulong load_kernel(const char *kernel_filename)
-{
- uint64_t kernel_entry, kernel_high;
-
- if (load_elf(kernel_filename, NULL, NULL, NULL,
- &kernel_entry, NULL, &kernel_high,
- 0, EM_RISCV, 1, 0) < 0) {
- error_report("could not load kernel '%s'", kernel_filename);
- exit(1);
- }
- return kernel_entry;
-}
-
static void sifive_mmio_emulate(MemoryRegion *parent, const char *name,
uintptr_t offset, uintptr_t length)
{
memmap[SIFIVE_E_MROM].base, &address_space_memory);
if (machine->kernel_filename) {
- load_kernel(machine->kernel_filename);
+ riscv_load_kernel(machine->kernel_filename);
}
}
SiFiveESoCState *s = RISCV_E_SOC(dev);
MemoryRegion *sys_mem = get_system_memory();
- MemoryRegion *xip_mem = g_new(MemoryRegion, 1);
- MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
object_property_set_bool(OBJECT(&s->cpus), true, "realized",
&error_abort);
/* Mask ROM */
- memory_region_init_rom(mask_rom, NULL, "riscv.sifive.e.mrom",
+ memory_region_init_rom(&s->mask_rom, NULL, "riscv.sifive.e.mrom",
memmap[SIFIVE_E_MROM].size, &error_fatal);
memory_region_add_subregion(sys_mem,
- memmap[SIFIVE_E_MROM].base, mask_rom);
+ memmap[SIFIVE_E_MROM].base, &s->mask_rom);
/* MMIO */
s->plic = sifive_plic_create(memmap[SIFIVE_E_PLIC].base,
memmap[SIFIVE_E_PWM2].base, memmap[SIFIVE_E_PWM2].size);
/* Flash memory */
- memory_region_init_ram(xip_mem, NULL, "riscv.sifive.e.xip",
+ memory_region_init_ram(&s->xip_mem, NULL, "riscv.sifive.e.xip",
memmap[SIFIVE_E_XIP].size, &error_fatal);
- memory_region_set_readonly(xip_mem, true);
- memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_XIP].base, xip_mem);
+ memory_region_set_readonly(&s->xip_mem, true);
+ memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_XIP].base,
+ &s->xip_mem);
}
static void riscv_sifive_e_machine_init(MachineClass *mc)
#include "target/riscv/cpu.h"
#include "hw/riscv/sifive_prci.h"
-/* currently implements enough to mock freedom-e-sdk BSP clock programming */
-
static uint64_t sifive_prci_read(void *opaque, hwaddr addr, unsigned int size)
{
- if (addr == 0 /* PRCI_HFROSCCFG */) {
- return 1 << 31; /* ROSC_RDY */
- }
- if (addr == 8 /* PRCI_PLLCFG */) {
- return 1 << 31; /* PLL_LOCK */
+ SiFivePRCIState *s = opaque;
+ switch (addr) {
+ case SIFIVE_PRCI_HFROSCCFG:
+ return s->hfrosccfg;
+ case SIFIVE_PRCI_HFXOSCCFG:
+ return s->hfxosccfg;
+ case SIFIVE_PRCI_PLLCFG:
+ return s->pllcfg;
+ case SIFIVE_PRCI_PLLOUTDIV:
+ return s->plloutdiv;
}
hw_error("%s: read: addr=0x%x\n", __func__, (int)addr);
return 0;
static void sifive_prci_write(void *opaque, hwaddr addr,
uint64_t val64, unsigned int size)
{
- /* discard writes */
+ SiFivePRCIState *s = opaque;
+ switch (addr) {
+ case SIFIVE_PRCI_HFROSCCFG:
+ s->hfrosccfg = (uint32_t) val64;
+ /* OSC stays ready */
+ s->hfrosccfg |= SIFIVE_PRCI_HFROSCCFG_RDY;
+ break;
+ case SIFIVE_PRCI_HFXOSCCFG:
+ s->hfxosccfg = (uint32_t) val64;
+ /* OSC stays ready */
+ s->hfxosccfg |= SIFIVE_PRCI_HFXOSCCFG_RDY;
+ break;
+ case SIFIVE_PRCI_PLLCFG:
+ s->pllcfg = (uint32_t) val64;
+ /* PLL stays locked */
+ s->pllcfg |= SIFIVE_PRCI_PLLCFG_LOCK;
+ break;
+ case SIFIVE_PRCI_PLLOUTDIV:
+ s->plloutdiv = (uint32_t) val64;
+ break;
+ default:
+ hw_error("%s: bad write: addr=0x%x v=0x%x\n",
+ __func__, (int)addr, (int)val64);
+ }
}
static const MemoryRegionOps sifive_prci_ops = {
memory_region_init_io(&s->mmio, obj, &sifive_prci_ops, s,
TYPE_SIFIVE_PRCI, 0x8000);
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+
+ s->hfrosccfg = (SIFIVE_PRCI_HFROSCCFG_RDY | SIFIVE_PRCI_HFROSCCFG_EN);
+ s->hfxosccfg = (SIFIVE_PRCI_HFROSCCFG_RDY | SIFIVE_PRCI_HFROSCCFG_EN);
+ s->pllcfg = (SIFIVE_PRCI_PLLCFG_REFSEL | SIFIVE_PRCI_PLLCFG_BYPASS |
+ SIFIVE_PRCI_PLLCFG_LOCK);
+ s->plloutdiv = SIFIVE_PRCI_PLLOUTDIV_DIV1;
+
}
static const TypeInfo sifive_prci_info = {
#include "hw/riscv/sifive_uart.h"
#include "hw/riscv/sifive_prci.h"
#include "hw/riscv/sifive_u.h"
+#include "hw/riscv/boot.h"
#include "chardev/char.h"
#include "sysemu/arch_init.h"
#include "sysemu/device_tree.h"
#include "exec/address-spaces.h"
-#include "elf.h"
#include <libfdt.h>
#define GEM_REVISION 0x10070109
-static target_ulong load_kernel(const char *kernel_filename)
-{
- uint64_t kernel_entry, kernel_high;
-
- if (load_elf(kernel_filename, NULL, NULL, NULL,
- &kernel_entry, NULL, &kernel_high,
- 0, EM_RISCV, 1, 0) < 0) {
- error_report("could not load kernel '%s'", kernel_filename);
- exit(1);
- }
- return kernel_entry;
-}
-
static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
uint64_t mem_size, const char *cmdline)
{
uint32_t *cells;
char *nodename;
char ethclk_names[] = "pclk\0hclk\0tx_clk";
- uint32_t plic_phandle, ethclk_phandle;
+ uint32_t plic_phandle, ethclk_phandle, phandle = 1;
fdt = s->fdt = create_device_tree(&s->fdt_size);
if (!fdt) {
qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
for (cpu = s->soc.cpus.num_harts - 1; cpu >= 0; cpu--) {
+ int cpu_phandle = phandle++;
nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
char *isa = riscv_isa_string(&s->soc.cpus.harts[cpu]);
qemu_fdt_setprop_cell(fdt, nodename, "reg", cpu);
qemu_fdt_setprop_string(fdt, nodename, "device_type", "cpu");
qemu_fdt_add_subnode(fdt, intc);
- qemu_fdt_setprop_cell(fdt, intc, "phandle", 1);
- qemu_fdt_setprop_cell(fdt, intc, "linux,phandle", 1);
+ qemu_fdt_setprop_cell(fdt, intc, "phandle", cpu_phandle);
+ qemu_fdt_setprop_cell(fdt, intc, "linux,phandle", cpu_phandle);
qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
g_free(cells);
g_free(nodename);
+ plic_phandle = phandle++;
cells = g_new0(uint32_t, s->soc.cpus.num_harts * 4);
for (cpu = 0; cpu < s->soc.cpus.num_harts; cpu++) {
nodename =
qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
- qemu_fdt_setprop_cells(fdt, nodename, "phandle", 2);
- qemu_fdt_setprop_cells(fdt, nodename, "linux,phandle", 2);
+ qemu_fdt_setprop_cells(fdt, nodename, "phandle", plic_phandle);
+ qemu_fdt_setprop_cells(fdt, nodename, "linux,phandle", plic_phandle);
plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
g_free(cells);
g_free(nodename);
+ ethclk_phandle = phandle++;
nodename = g_strdup_printf("/soc/ethclk");
qemu_fdt_add_subnode(fdt, nodename);
qemu_fdt_setprop_string(fdt, nodename, "compatible", "fixed-clock");
qemu_fdt_setprop_cell(fdt, nodename, "#clock-cells", 0x0);
qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
SIFIVE_U_GEM_CLOCK_FREQ);
- qemu_fdt_setprop_cell(fdt, nodename, "phandle", 3);
- qemu_fdt_setprop_cell(fdt, nodename, "linux,phandle", 3);
+ qemu_fdt_setprop_cell(fdt, nodename, "phandle", ethclk_phandle);
+ qemu_fdt_setprop_cell(fdt, nodename, "linux,phandle", ethclk_phandle);
ethclk_phandle = qemu_fdt_get_phandle(fdt, nodename);
g_free(nodename);
/* create device tree */
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
+ if (machine->firmware) {
+ riscv_load_firmware(machine->firmware, memmap[SIFIVE_U_DRAM].base);
+ }
+
if (machine->kernel_filename) {
- load_kernel(machine->kernel_filename);
+ riscv_load_kernel(machine->kernel_filename);
}
/* reset vector */
MemoryRegion *system_memory = get_system_memory();
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
qemu_irq plic_gpios[SIFIVE_U_PLIC_NUM_SOURCES];
+ char *plic_hart_config;
+ size_t plic_hart_config_len;
int i;
Error *err = NULL;
NICInfo *nd = &nd_table[0];
memory_region_add_subregion(system_memory, memmap[SIFIVE_U_MROM].base,
mask_rom);
+ /* create PLIC hart topology configuration string */
+ plic_hart_config_len = (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 1) * smp_cpus;
+ plic_hart_config = g_malloc0(plic_hart_config_len);
+ for (i = 0; i < smp_cpus; i++) {
+ if (i != 0) {
+ strncat(plic_hart_config, ",", plic_hart_config_len);
+ }
+ strncat(plic_hart_config, SIFIVE_U_PLIC_HART_CONFIG,
+ plic_hart_config_len);
+ plic_hart_config_len -= (strlen(SIFIVE_U_PLIC_HART_CONFIG) + 1);
+ }
+
/* MMIO */
s->plic = sifive_plic_create(memmap[SIFIVE_U_PLIC].base,
- (char *)SIFIVE_U_PLIC_HART_CONFIG,
+ plic_hart_config,
SIFIVE_U_PLIC_NUM_SOURCES,
SIFIVE_U_PLIC_NUM_PRIORITIES,
SIFIVE_U_PLIC_PRIORITY_BASE,
#include "hw/riscv/riscv_hart.h"
#include "hw/riscv/sifive_clint.h"
#include "hw/riscv/spike.h"
+#include "hw/riscv/boot.h"
#include "chardev/char.h"
#include "sysemu/arch_init.h"
#include "sysemu/device_tree.h"
#include "sysemu/qtest.h"
#include "exec/address-spaces.h"
-#include "elf.h"
#include <libfdt.h>
[SPIKE_DRAM] = { 0x80000000, 0x0 },
};
-static target_ulong load_kernel(const char *kernel_filename)
-{
- uint64_t kernel_entry, kernel_high;
-
- if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
- &kernel_entry, NULL, &kernel_high, 0, EM_RISCV, 1, 0,
- NULL, true, htif_symbol_callback) < 0) {
- error_report("could not load kernel '%s'", kernel_filename);
- exit(1);
- }
- return kernel_entry;
-}
-
static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap,
uint64_t mem_size, const char *cmdline)
{
mask_rom);
if (machine->kernel_filename) {
- load_kernel(machine->kernel_filename);
+ riscv_load_kernel(machine->kernel_filename);
}
/* reset vector */
mask_rom);
if (machine->kernel_filename) {
- load_kernel(machine->kernel_filename);
+ riscv_load_kernel(machine->kernel_filename);
}
/* reset vector */
mask_rom);
if (machine->kernel_filename) {
- load_kernel(machine->kernel_filename);
+ riscv_load_kernel(machine->kernel_filename);
}
/* reset vector */
#include "hw/riscv/sifive_clint.h"
#include "hw/riscv/sifive_test.h"
#include "hw/riscv/virt.h"
+#include "hw/riscv/boot.h"
#include "chardev/char.h"
#include "sysemu/arch_init.h"
#include "sysemu/device_tree.h"
#include "exec/address-spaces.h"
#include "hw/pci/pci.h"
#include "hw/pci-host/gpex.h"
-#include "elf.h"
#include <libfdt.h>
[VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 },
};
-static target_ulong load_kernel(const char *kernel_filename)
-{
- uint64_t kernel_entry, kernel_high;
-
- if (load_elf(kernel_filename, NULL, NULL, NULL,
- &kernel_entry, NULL, &kernel_high,
- 0, EM_RISCV, 1, 0) < 0) {
- error_report("could not load kernel '%s'", kernel_filename);
- exit(1);
- }
- return kernel_entry;
-}
-
-static hwaddr load_initrd(const char *filename, uint64_t mem_size,
- uint64_t kernel_entry, hwaddr *start)
-{
- int size;
-
- /* We want to put the initrd far enough into RAM that when the
- * kernel is uncompressed it will not clobber the initrd. However
- * on boards without much RAM we must ensure that we still leave
- * enough room for a decent sized initrd, and on boards with large
- * amounts of RAM we must avoid the initrd being so far up in RAM
- * that it is outside lowmem and inaccessible to the kernel.
- * So for boards with less than 256MB of RAM we put the initrd
- * halfway into RAM, and for boards with 256MB of RAM or more we put
- * the initrd at 128MB.
- */
- *start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
-
- size = load_ramdisk(filename, *start, mem_size - *start);
- if (size == -1) {
- size = load_image_targphys(filename, *start, mem_size - *start);
- if (size == -1) {
- error_report("could not load ramdisk '%s'", filename);
- exit(1);
- }
- }
- return *start + size;
-}
-
static void create_pcie_irq_map(void *fdt, char *nodename,
uint32_t plic_phandle)
{
for (cpu = s->soc.num_harts - 1; cpu >= 0; cpu--) {
int cpu_phandle = phandle++;
+ int intc_phandle;
nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
char *isa = riscv_isa_string(&s->soc.harts[cpu]);
qemu_fdt_setprop_string(fdt, nodename, "status", "okay");
qemu_fdt_setprop_cell(fdt, nodename, "reg", cpu);
qemu_fdt_setprop_string(fdt, nodename, "device_type", "cpu");
+ qemu_fdt_setprop_cell(fdt, nodename, "phandle", cpu_phandle);
+ qemu_fdt_setprop_cell(fdt, nodename, "linux,phandle", cpu_phandle);
+ intc_phandle = phandle++;
qemu_fdt_add_subnode(fdt, intc);
- qemu_fdt_setprop_cell(fdt, intc, "phandle", cpu_phandle);
- qemu_fdt_setprop_cell(fdt, intc, "linux,phandle", cpu_phandle);
+ qemu_fdt_setprop_cell(fdt, intc, "phandle", intc_phandle);
+ qemu_fdt_setprop_cell(fdt, intc, "linux,phandle", intc_phandle);
qemu_fdt_setprop_string(fdt, intc, "compatible", "riscv,cpu-intc");
qemu_fdt_setprop(fdt, intc, "interrupt-controller", NULL, 0);
qemu_fdt_setprop_cell(fdt, intc, "#interrupt-cells", 1);
g_free(nodename);
}
+ /* Add cpu-topology node */
+ qemu_fdt_add_subnode(fdt, "/cpus/cpu-map");
+ qemu_fdt_add_subnode(fdt, "/cpus/cpu-map/cluster0");
+ for (cpu = s->soc.num_harts - 1; cpu >= 0; cpu--) {
+ char *core_nodename = g_strdup_printf("/cpus/cpu-map/cluster0/core%d",
+ cpu);
+ char *cpu_nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
+ uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, cpu_nodename);
+ qemu_fdt_add_subnode(fdt, core_nodename);
+ qemu_fdt_setprop_cell(fdt, core_nodename, "cpu", intc_phandle);
+ g_free(core_nodename);
+ g_free(cpu_nodename);
+ }
+
cells = g_new0(uint32_t, s->soc.num_harts * 4);
for (cpu = 0; cpu < s->soc.num_harts; cpu++) {
nodename =
qemu_fdt_setprop_string(fdt, nodename, "device_type", "pci");
qemu_fdt_setprop_cell(fdt, nodename, "linux,pci-domain", 0);
qemu_fdt_setprop_cells(fdt, nodename, "bus-range", 0,
- memmap[VIRT_PCIE_ECAM].base /
+ memmap[VIRT_PCIE_ECAM].size /
PCIE_MMCFG_SIZE_MIN - 1);
qemu_fdt_setprop(fdt, nodename, "dma-coherent", NULL, 0);
qemu_fdt_setprop_cells(fdt, nodename, "reg", 0, memmap[VIRT_PCIE_ECAM].base,
memory_region_add_subregion(system_memory, memmap[VIRT_MROM].base,
mask_rom);
+ if (machine->firmware) {
+ riscv_load_firmware(machine->firmware, memmap[VIRT_DRAM].base);
+ }
+
if (machine->kernel_filename) {
- uint64_t kernel_entry = load_kernel(machine->kernel_filename);
+ uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename);
if (machine->initrd_filename) {
hwaddr start;
- hwaddr end = load_initrd(machine->initrd_filename,
- machine->ram_size, kernel_entry,
- &start);
+ hwaddr end = riscv_load_initrd(machine->initrd_filename,
+ machine->ram_size, kernel_entry,
+ &start);
qemu_fdt_setprop_cell(fdt, "/chosen",
"linux,initrd-start", start);
qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
#include "trace.h"
#include "hw/s390x/s390_flic.h"
#include "hw/s390x/s390-virtio-ccw.h"
+#include "hw/s390x/s390-ccw.h"
typedef struct CrwContainer {
CRW crw;
}
+static void sch_handle_halt_func_passthrough(SubchDev *sch)
+{
+ int ret;
+
+ ret = s390_ccw_halt(sch);
+ if (ret == -ENOSYS) {
+ sch_handle_halt_func(sch);
+ }
+}
+
+static void sch_handle_clear_func_passthrough(SubchDev *sch)
+{
+ int ret;
+
+ ret = s390_ccw_clear(sch);
+ if (ret == -ENOSYS) {
+ sch_handle_clear_func(sch);
+ }
+}
+
static IOInstEnding sch_handle_start_func_passthrough(SubchDev *sch)
{
SCHIB *schib = &sch->curr_status;
SCHIB *schib = &sch->curr_status;
if (schib->scsw.ctrl & SCSW_FCTL_CLEAR_FUNC) {
- /* TODO: Clear handling */
- sch_handle_clear_func(sch);
+ sch_handle_clear_func_passthrough(sch);
} else if (schib->scsw.ctrl & SCSW_FCTL_HALT_FUNC) {
- /* TODO: Halt handling */
- sch_handle_halt_func(sch);
+ sch_handle_halt_func_passthrough(sch);
} else if (schib->scsw.ctrl & SCSW_FCTL_START_FUNC) {
return sch_handle_start_func_passthrough(sch);
}
return cdc->handle_request(sch);
}
+int s390_ccw_halt(SubchDev *sch)
+{
+ S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(sch->driver_data);
+
+ if (!cdc->handle_halt) {
+ return -ENOSYS;
+ }
+ return cdc->handle_halt(sch);
+}
+
+int s390_ccw_clear(SubchDev *sch)
+{
+ S390CCWDeviceClass *cdc = S390_CCW_DEVICE_GET_CLASS(sch->driver_data);
+
+ if (!cdc->handle_clear) {
+ return -ENOSYS;
+ }
+ return cdc->handle_clear(sch);
+}
+
static void s390_ccw_get_dev_info(S390CCWDevice *cdev,
char *sysfsdev,
Error **errp)
#include "hw/boards.h"
#include "hw/s390x/storage-keys.h"
#include "qapi/error.h"
-#include "qapi/qapi-commands-target.h"
+#include "qapi/qapi-commands-misc-target.h"
#include "qapi/qmp/qdict.h"
#include "qemu/error-report.h"
#include "sysemu/kvm.h"
mc->is_default = 1;
mc->default_boot_order = "c";
mc->default_cpu_type = SPARC_CPU_TYPE_NAME("Fujitsu-MB86904");
+ mc->default_display = "tcx";
}
static const TypeInfo ss5_type = {
mc->max_cpus = 4;
mc->default_boot_order = "c";
mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-SuperSparc-II");
+ mc->default_display = "tcx";
}
static const TypeInfo ss10_type = {
mc->max_cpus = 4;
mc->default_boot_order = "c";
mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-SuperSparc-II");
+ mc->default_display = "tcx";
}
static const TypeInfo ss600mp_type = {
mc->max_cpus = 4;
mc->default_boot_order = "c";
mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-SuperSparc-II");
+ mc->default_display = "tcx";
}
static const TypeInfo ss20_type = {
mc->block_default_type = IF_SCSI;
mc->default_boot_order = "c";
mc->default_cpu_type = SPARC_CPU_TYPE_NAME("Fujitsu-MB86904");
+ mc->default_display = "tcx";
}
static const TypeInfo voyager_type = {
mc->block_default_type = IF_SCSI;
mc->default_boot_order = "c";
mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-MicroSparc-I");
+ mc->default_display = "tcx";
}
static const TypeInfo ss_lx_type = {
mc->block_default_type = IF_SCSI;
mc->default_boot_order = "c";
mc->default_cpu_type = SPARC_CPU_TYPE_NAME("Fujitsu-MB86904");
+ mc->default_display = "tcx";
}
static const TypeInfo ss4_type = {
mc->block_default_type = IF_SCSI;
mc->default_boot_order = "c";
mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-MicroSparc-I");
+ mc->default_display = "tcx";
}
static const TypeInfo scls_type = {
mc->block_default_type = IF_SCSI;
mc->default_boot_order = "c";
mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-MicroSparc-I");
+ mc->default_display = "tcx";
}
static const TypeInfo sbook_type = {
static Property aspeed_smc_properties[] = {
DEFINE_PROP_UINT32("num-cs", AspeedSMCState, num_cs, 1),
+ DEFINE_PROP_UINT64("sdram-base", AspeedSMCState, sdram_base, 0),
DEFINE_PROP_END_OF_LIST(),
};
obj-$(CONFIG_ALLWINNER_A10_PIT) += allwinner-a10-pit.o
common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
-common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
+common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o aspeed_rtc.o
common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
--- /dev/null
+/*
+ * ASPEED Real Time Clock
+ * Joel Stanley <joel@jms.id.au>
+ *
+ * Copyright 2019 IBM Corp
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/timer/aspeed_rtc.h"
+#include "qemu/log.h"
+#include "qemu/timer.h"
+
+#include "trace.h"
+
+#define COUNTER1 (0x00 / 4)
+#define COUNTER2 (0x04 / 4)
+#define ALARM (0x08 / 4)
+#define CONTROL (0x10 / 4)
+#define ALARM_STATUS (0x14 / 4)
+
+#define RTC_UNLOCKED BIT(1)
+#define RTC_ENABLED BIT(0)
+
+static void aspeed_rtc_calc_offset(AspeedRtcState *rtc)
+{
+ struct tm tm;
+ uint32_t year, cent;
+ uint32_t reg1 = rtc->reg[COUNTER1];
+ uint32_t reg2 = rtc->reg[COUNTER2];
+
+ tm.tm_mday = (reg1 >> 24) & 0x1f;
+ tm.tm_hour = (reg1 >> 16) & 0x1f;
+ tm.tm_min = (reg1 >> 8) & 0x3f;
+ tm.tm_sec = (reg1 >> 0) & 0x3f;
+
+ cent = (reg2 >> 16) & 0x1f;
+ year = (reg2 >> 8) & 0x7f;
+ tm.tm_mon = ((reg2 >> 0) & 0x0f) - 1;
+ tm.tm_year = year + (cent * 100) - 1900;
+
+ rtc->offset = qemu_timedate_diff(&tm);
+}
+
+static uint32_t aspeed_rtc_get_counter(AspeedRtcState *rtc, int r)
+{
+ uint32_t year, cent;
+ struct tm now;
+
+ qemu_get_timedate(&now, rtc->offset);
+
+ switch (r) {
+ case COUNTER1:
+ return (now.tm_mday << 24) | (now.tm_hour << 16) |
+ (now.tm_min << 8) | now.tm_sec;
+ case COUNTER2:
+ cent = (now.tm_year + 1900) / 100;
+ year = now.tm_year % 100;
+ return ((cent & 0x1f) << 16) | ((year & 0x7f) << 8) |
+ ((now.tm_mon + 1) & 0xf);
+ default:
+ g_assert_not_reached();
+ }
+}
+
+static uint64_t aspeed_rtc_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+ AspeedRtcState *rtc = opaque;
+ uint64_t val;
+ uint32_t r = addr >> 2;
+
+ switch (r) {
+ case COUNTER1:
+ case COUNTER2:
+ if (rtc->reg[CONTROL] & RTC_ENABLED) {
+ rtc->reg[r] = aspeed_rtc_get_counter(rtc, r);
+ }
+ /* fall through */
+ case CONTROL:
+ val = rtc->reg[r];
+ break;
+ case ALARM:
+ case ALARM_STATUS:
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx "\n", __func__, addr);
+ return 0;
+ }
+
+ trace_aspeed_rtc_read(addr, val);
+
+ return val;
+}
+
+static void aspeed_rtc_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ AspeedRtcState *rtc = opaque;
+ uint32_t r = addr >> 2;
+
+ switch (r) {
+ case COUNTER1:
+ case COUNTER2:
+ if (!(rtc->reg[CONTROL] & RTC_UNLOCKED)) {
+ break;
+ }
+ /* fall through */
+ case CONTROL:
+ rtc->reg[r] = val;
+ aspeed_rtc_calc_offset(rtc);
+ break;
+ case ALARM:
+ case ALARM_STATUS:
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx "\n", __func__, addr);
+ break;
+ }
+ trace_aspeed_rtc_write(addr, val);
+}
+
+static void aspeed_rtc_reset(DeviceState *d)
+{
+ AspeedRtcState *rtc = ASPEED_RTC(d);
+
+ rtc->offset = 0;
+ memset(rtc->reg, 0, sizeof(rtc->reg));
+}
+
+static const MemoryRegionOps aspeed_rtc_ops = {
+ .read = aspeed_rtc_read,
+ .write = aspeed_rtc_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static const VMStateDescription vmstate_aspeed_rtc = {
+ .name = TYPE_ASPEED_RTC,
+ .version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(reg, AspeedRtcState, 0x18),
+ VMSTATE_INT32(offset, AspeedRtcState),
+ VMSTATE_INT32(offset, AspeedRtcState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void aspeed_rtc_realize(DeviceState *dev, Error **errp)
+{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ AspeedRtcState *s = ASPEED_RTC(dev);
+
+ sysbus_init_irq(sbd, &s->irq);
+
+ memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_rtc_ops, s,
+ "aspeed-rtc", 0x18ULL);
+ sysbus_init_mmio(sbd, &s->iomem);
+}
+
+static void aspeed_rtc_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = aspeed_rtc_realize;
+ dc->vmsd = &vmstate_aspeed_rtc;
+ dc->reset = aspeed_rtc_reset;
+}
+
+static const TypeInfo aspeed_rtc_info = {
+ .name = TYPE_ASPEED_RTC,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(AspeedRtcState),
+ .class_init = aspeed_rtc_class_init,
+};
+
+static void aspeed_rtc_register_types(void)
+{
+ type_register_static(&aspeed_rtc_info);
+}
+
+type_init(aspeed_rtc_register_types)
return t->start + delta_ns;
}
+static inline uint32_t calculate_match(struct AspeedTimer *t, int i)
+{
+ return t->match[i] < t->reload ? t->match[i] : 0;
+}
+
static uint64_t calculate_next(struct AspeedTimer *t)
{
- uint64_t next = 0;
- uint32_t rate = calculate_rate(t);
+ uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ uint64_t next;
- while (!next) {
- /* We don't know the relationship between the values in the match
- * registers, so sort using MAX/MIN/zero. We sort in that order as the
- * timer counts down to zero. */
- uint64_t seq[] = {
- calculate_time(t, MAX(t->match[0], t->match[1])),
- calculate_time(t, MIN(t->match[0], t->match[1])),
- calculate_time(t, 0),
- };
- uint64_t reload_ns;
- uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-
- if (now < seq[0]) {
- next = seq[0];
- } else if (now < seq[1]) {
- next = seq[1];
- } else if (now < seq[2]) {
- next = seq[2];
- } else if (t->reload) {
- reload_ns = muldiv64(t->reload, NANOSECONDS_PER_SECOND, rate);
- t->start = now - ((now - t->start) % reload_ns);
- } else {
- /* no reload value, return 0 */
- break;
- }
+ /*
+ * We don't know the relationship between the values in the match
+ * registers, so sort using MAX/MIN/zero. We sort in that order as
+ * the timer counts down to zero.
+ */
+
+ next = calculate_time(t, MAX(calculate_match(t, 0), calculate_match(t, 1)));
+ if (now < next) {
+ return next;
+ }
+
+ next = calculate_time(t, MIN(calculate_match(t, 0), calculate_match(t, 1)));
+ if (now < next) {
+ return next;
}
- return next;
+ next = calculate_time(t, 0);
+ if (now < next) {
+ return next;
+ }
+
+ /* We've missed all deadlines, fire interrupt and try again */
+ timer_del(&t->timer);
+
+ if (timer_overflow_interrupt(t)) {
+ t->level = !t->level;
+ qemu_set_irq(t->irq, t->level);
+ }
+
+ next = MAX(MAX(calculate_match(t, 0), calculate_match(t, 1)), 0);
+ t->start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+
+ return calculate_time(t, next);
}
static void aspeed_timer_mod(AspeedTimer *t)
switch (reg) {
case TIMER_REG_STATUS:
- value = calculate_ticks(t, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+ if (timer_enabled(t)) {
+ value = calculate_ticks(t, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
+ } else {
+ value = t->reload;
+ }
break;
case TIMER_REG_RELOAD:
value = t->reload;
int64_t delta = (int64_t) value - (int64_t) calculate_ticks(t, now);
uint32_t rate = calculate_rate(t);
- t->start += muldiv64(delta, NANOSECONDS_PER_SECOND, rate);
+ if (delta >= 0) {
+ t->start += muldiv64(delta, NANOSECONDS_PER_SECOND, rate);
+ } else {
+ t->start -= muldiv64(-delta, NANOSECONDS_PER_SECOND, rate);
+ }
aspeed_timer_mod(t);
}
break;
#include "sysemu/replay.h"
#include "hw/timer/mc146818rtc.h"
#include "qapi/error.h"
-#include "qapi/qapi-commands-target.h"
-#include "qapi/qapi-events-target.h"
+#include "qapi/qapi-commands-misc-target.h"
+#include "qapi/qapi-events-misc-target.h"
#include "qapi/visitor.h"
#include "exec/address-spaces.h"
cmsdk_apb_dualtimer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB dualtimer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
cmsdk_apb_dualtimer_reset(void) "CMSDK APB dualtimer: reset"
+# hw/timer/aspeed-rtc.c
+aspeed_rtc_read(uint64_t addr, uint64_t value) "addr 0x%02" PRIx64 " value 0x%08" PRIx64
+aspeed_rtc_write(uint64_t addr, uint64_t value) "addr 0x%02" PRIx64 " value 0x%08" PRIx64
+
# sun4v-rtc.c
sun4v_rtc_read(uint64_t addr, uint64_t value) "read: addr 0x%" PRIx64 " value 0x%" PRIx64
sun4v_rtc_write(uint64_t addr, uint64_t value) "write: addr 0x%" PRIx64 " value 0x%" PRIx64
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
-#include "hw/xen/io/ring.h"
-#include <xen/io/usbif.h>
+#include "hw/xen/interface/io/usbif.h"
/*
* Check for required support of usbif.h: USBIF_SHORT_NOT_OK was the last
* vfio based subchannel assignment support
*
* Copyright 2017 IBM Corp.
+ * Copyright 2019 Red Hat, Inc.
+ *
* Author(s): Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
* Xiao Feng Ren <renxiaof@linux.vnet.ibm.com>
* Pierre Morel <pmorel@linux.vnet.ibm.com>
+ * Cornelia Huck <cohuck@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at
* your option) any later version. See the COPYING file in the top-level
uint64_t io_region_size;
uint64_t io_region_offset;
struct ccw_io_region *io_region;
+ uint64_t async_cmd_region_size;
+ uint64_t async_cmd_region_offset;
+ struct ccw_cmd_region *async_cmd_region;
EventNotifier io_notifier;
bool force_orb_pfch;
bool warned_orb_pfch;
}
}
+static int vfio_ccw_handle_clear(SubchDev *sch)
+{
+ S390CCWDevice *cdev = sch->driver_data;
+ VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+ struct ccw_cmd_region *region = vcdev->async_cmd_region;
+ int ret;
+
+ if (!vcdev->async_cmd_region) {
+ /* Async command region not available, fall back to emulation */
+ return -ENOSYS;
+ }
+
+ memset(region, 0, sizeof(*region));
+ region->command = VFIO_CCW_ASYNC_CMD_CSCH;
+
+again:
+ ret = pwrite(vcdev->vdev.fd, region,
+ vcdev->async_cmd_region_size, vcdev->async_cmd_region_offset);
+ if (ret != vcdev->async_cmd_region_size) {
+ if (errno == EAGAIN) {
+ goto again;
+ }
+ error_report("vfio-ccw: write cmd region failed with errno=%d", errno);
+ ret = -errno;
+ } else {
+ ret = region->ret_code;
+ }
+ switch (ret) {
+ case 0:
+ case -ENODEV:
+ case -EACCES:
+ return 0;
+ case -EFAULT:
+ default:
+ sch_gen_unit_exception(sch);
+ css_inject_io_interrupt(sch);
+ return 0;
+ }
+}
+
+static int vfio_ccw_handle_halt(SubchDev *sch)
+{
+ S390CCWDevice *cdev = sch->driver_data;
+ VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+ struct ccw_cmd_region *region = vcdev->async_cmd_region;
+ int ret;
+
+ if (!vcdev->async_cmd_region) {
+ /* Async command region not available, fall back to emulation */
+ return -ENOSYS;
+ }
+
+ memset(region, 0, sizeof(*region));
+ region->command = VFIO_CCW_ASYNC_CMD_HSCH;
+
+again:
+ ret = pwrite(vcdev->vdev.fd, region,
+ vcdev->async_cmd_region_size, vcdev->async_cmd_region_offset);
+ if (ret != vcdev->async_cmd_region_size) {
+ if (errno == EAGAIN) {
+ goto again;
+ }
+ error_report("vfio-ccw: write cmd region failed with errno=%d", errno);
+ ret = -errno;
+ } else {
+ ret = region->ret_code;
+ }
+ switch (ret) {
+ case 0:
+ case -EBUSY:
+ case -ENODEV:
+ case -EACCES:
+ return 0;
+ case -EFAULT:
+ default:
+ sch_gen_unit_exception(sch);
+ css_inject_io_interrupt(sch);
+ return 0;
+ }
+}
+
static void vfio_ccw_reset(DeviceState *dev)
{
CcwDevice *ccw_dev = DO_UPCAST(CcwDevice, parent_obj, dev);
{
VFIODevice *vdev = &vcdev->vdev;
struct vfio_irq_info *irq_info;
- struct vfio_irq_set *irq_set;
size_t argsz;
- int32_t *pfd;
+ int fd;
if (vdev->num_irqs < VFIO_CCW_IO_IRQ_INDEX + 1) {
error_setg(errp, "vfio: unexpected number of io irqs %u",
goto out_free_info;
}
- argsz = sizeof(*irq_set) + sizeof(*pfd);
- irq_set = g_malloc0(argsz);
- irq_set->argsz = argsz;
- irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
- VFIO_IRQ_SET_ACTION_TRIGGER;
- irq_set->index = VFIO_CCW_IO_IRQ_INDEX;
- irq_set->start = 0;
- irq_set->count = 1;
- pfd = (int32_t *) &irq_set->data;
-
- *pfd = event_notifier_get_fd(&vcdev->io_notifier);
- qemu_set_fd_handler(*pfd, vfio_ccw_io_notifier_handler, NULL, vcdev);
- if (ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
- error_setg(errp, "vfio: Failed to set up io notification");
- qemu_set_fd_handler(*pfd, NULL, NULL, vcdev);
+ fd = event_notifier_get_fd(&vcdev->io_notifier);
+ qemu_set_fd_handler(fd, vfio_ccw_io_notifier_handler, NULL, vcdev);
+
+ if (vfio_set_irq_signaling(vdev, VFIO_CCW_IO_IRQ_INDEX, 0,
+ VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) {
+ qemu_set_fd_handler(fd, NULL, NULL, vcdev);
event_notifier_cleanup(&vcdev->io_notifier);
}
- g_free(irq_set);
-
out_free_info:
g_free(irq_info);
}
static void vfio_ccw_unregister_io_notifier(VFIOCCWDevice *vcdev)
{
- struct vfio_irq_set *irq_set;
- size_t argsz;
- int32_t *pfd;
-
- argsz = sizeof(*irq_set) + sizeof(*pfd);
- irq_set = g_malloc0(argsz);
- irq_set->argsz = argsz;
- irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
- VFIO_IRQ_SET_ACTION_TRIGGER;
- irq_set->index = VFIO_CCW_IO_IRQ_INDEX;
- irq_set->start = 0;
- irq_set->count = 1;
- pfd = (int32_t *) &irq_set->data;
- *pfd = -1;
+ Error *err = NULL;
- if (ioctl(vcdev->vdev.fd, VFIO_DEVICE_SET_IRQS, irq_set)) {
- error_report("vfio: Failed to de-assign device io fd: %m");
+ vfio_set_irq_signaling(&vcdev->vdev, VFIO_CCW_IO_IRQ_INDEX, 0,
+ VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err);
+ if (err) {
+ error_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name);
}
qemu_set_fd_handler(event_notifier_get_fd(&vcdev->io_notifier),
NULL, NULL, vcdev);
event_notifier_cleanup(&vcdev->io_notifier);
-
- g_free(irq_set);
}
static void vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp)
return;
}
+ /*
+ * We always expect at least the I/O region to be present. We also
+ * may have a variable number of regions governed by capabilities.
+ */
if (vdev->num_regions < VFIO_CCW_CONFIG_REGION_INDEX + 1) {
- error_setg(errp, "vfio: Unexpected number of the I/O region %u",
- vdev->num_regions);
+ error_setg(errp, "vfio: too few regions (%u), expected at least %u",
+ vdev->num_regions, VFIO_CCW_CONFIG_REGION_INDEX + 1);
return;
}
vcdev->io_region_offset = info->offset;
vcdev->io_region = g_malloc0(info->size);
+ /* check for the optional async command region */
+ ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW,
+ VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD, &info);
+ if (!ret) {
+ vcdev->async_cmd_region_size = info->size;
+ if (sizeof(*vcdev->async_cmd_region) != vcdev->async_cmd_region_size) {
+ error_setg(errp, "vfio: Unexpected size of the async cmd region");
+ g_free(vcdev->io_region);
+ g_free(info);
+ return;
+ }
+ vcdev->async_cmd_region_offset = info->offset;
+ vcdev->async_cmd_region = g_malloc0(info->size);
+ }
+
g_free(info);
}
static void vfio_ccw_put_region(VFIOCCWDevice *vcdev)
{
+ g_free(vcdev->async_cmd_region);
g_free(vcdev->io_region);
}
dc->reset = vfio_ccw_reset;
cdc->handle_request = vfio_ccw_handle_request;
+ cdc->handle_halt = vfio_ccw_handle_halt;
+ cdc->handle_clear = vfio_ccw_handle_clear;
}
static const TypeInfo vfio_ccw_info = {
*/
if (vector->virq >= 0) {
int32_t fd = event_notifier_get_fd(&vector->interrupt);
+ Error *err = NULL;
- vfio_set_irq_signaling(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX, nr,
- VFIO_IRQ_SET_ACTION_TRIGGER, fd, NULL);
+ if (vfio_set_irq_signaling(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX, nr,
+ VFIO_IRQ_SET_ACTION_TRIGGER, fd, &err)) {
+ error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name);
+ }
}
}
#define WDT_RESTART_MAGIC 0x4755
+#define SCU_RESET_CONTROL1 (0x04 / 4)
+#define SCU_RESET_SDRAM BIT(0)
+
static bool aspeed_wdt_is_enabled(const AspeedWDTState *s)
{
return s->regs[WDT_CTRL] & WDT_CTRL_ENABLE;
{
AspeedWDTState *s = ASPEED_WDT(dev);
+ /* Do not reset on SDRAM controller reset */
+ if (s->scu->regs[SCU_RESET_CONTROL1] & SCU_RESET_SDRAM) {
+ timer_del(s->timer);
+ s->regs[WDT_CTRL] = 0;
+ return;
+ }
+
qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n");
watchdog_perform_action();
timer_del(s->timer);
{
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
AspeedWDTState *s = ASPEED_WDT(dev);
+ Error *err = NULL;
+ Object *obj;
+
+ obj = object_property_get_link(OBJECT(dev), "scu", &err);
+ if (!obj) {
+ error_propagate(errp, err);
+ error_prepend(errp, "required link 'scu' not found: ");
+ return;
+ }
+ s->scu = ASPEED_SCU(obj);
if (!is_supported_silicon_rev(s->silicon_rev)) {
error_setg(errp, "Unknown silicon revision: 0x%" PRIx32,
}
struct XenEventChannel {
+ QLIST_ENTRY(XenEventChannel) list;
+ AioContext *ctx;
+ xenevtchn_handle *xeh;
evtchn_port_t local_port;
XenEventHandler handler;
void *opaque;
- Notifier notifier;
};
-static void event_notify(Notifier *n, void *data)
+static bool xen_device_poll(void *opaque)
+{
+ XenEventChannel *channel = opaque;
+
+ return channel->handler(channel->opaque);
+}
+
+static void xen_device_event(void *opaque)
{
- XenEventChannel *channel = container_of(n, XenEventChannel, notifier);
- unsigned long port = (unsigned long)data;
+ XenEventChannel *channel = opaque;
+ unsigned long port = xenevtchn_pending(channel->xeh);
if (port == channel->local_port) {
- channel->handler(channel->opaque);
+ xen_device_poll(channel);
+
+ xenevtchn_unmask(channel->xeh, port);
}
}
XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
+ AioContext *ctx,
unsigned int port,
XenEventHandler handler,
void *opaque, Error **errp)
XenEventChannel *channel = g_new0(XenEventChannel, 1);
xenevtchn_port_or_error_t local_port;
- local_port = xenevtchn_bind_interdomain(xendev->xeh,
+ channel->xeh = xenevtchn_open(NULL, 0);
+ if (!channel->xeh) {
+ error_setg_errno(errp, errno, "failed xenevtchn_open");
+ goto fail;
+ }
+
+ local_port = xenevtchn_bind_interdomain(channel->xeh,
xendev->frontend_id,
port);
if (local_port < 0) {
error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed");
-
- g_free(channel);
- return NULL;
+ goto fail;
}
channel->local_port = local_port;
channel->handler = handler;
channel->opaque = opaque;
- channel->notifier.notify = event_notify;
- notifier_list_add(&xendev->event_notifiers, &channel->notifier);
+ channel->ctx = ctx;
+ aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true,
+ xen_device_event, NULL, xen_device_poll, channel);
+
+ QLIST_INSERT_HEAD(&xendev->event_channels, channel, list);
return channel;
+
+fail:
+ if (channel->xeh) {
+ xenevtchn_close(channel->xeh);
+ }
+
+ g_free(channel);
+
+ return NULL;
}
void xen_device_notify_event_channel(XenDevice *xendev,
return;
}
- if (xenevtchn_notify(xendev->xeh, channel->local_port) < 0) {
+ if (xenevtchn_notify(channel->xeh, channel->local_port) < 0) {
error_setg_errno(errp, errno, "xenevtchn_notify failed");
}
}
return;
}
- notifier_remove(&channel->notifier);
+ QLIST_REMOVE(channel, list);
+
+ aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true,
+ NULL, NULL, NULL, NULL);
- if (xenevtchn_unbind(xendev->xeh, channel->local_port) < 0) {
+ if (xenevtchn_unbind(channel->xeh, channel->local_port) < 0) {
error_setg_errno(errp, errno, "xenevtchn_unbind failed");
}
+ xenevtchn_close(channel->xeh);
g_free(channel);
}
XenDevice *xendev = XEN_DEVICE(dev);
XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
const char *type = object_get_typename(OBJECT(xendev));
+ XenEventChannel *channel, *next;
if (!xendev->name) {
return;
xendev_class->unrealize(xendev, errp);
}
+ /* Make sure all event channels are cleaned up */
+ QLIST_FOREACH_SAFE(channel, &xendev->event_channels, list, next) {
+ xen_device_unbind_event_channel(xendev, channel, NULL);
+ }
+
xen_device_frontend_destroy(xendev);
xen_device_backend_destroy(xendev);
- if (xendev->xeh) {
- qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), NULL, NULL, NULL);
- xenevtchn_close(xendev->xeh);
- xendev->xeh = NULL;
- }
-
if (xendev->xgth) {
xengnttab_close(xendev->xgth);
xendev->xgth = NULL;
xen_device_unrealize(DEVICE(xendev), &error_abort);
}
-static void xen_device_event(void *opaque)
-{
- XenDevice *xendev = opaque;
- unsigned long port = xenevtchn_pending(xendev->xeh);
-
- notifier_list_notify(&xendev->event_notifiers, (void *)port);
-
- xenevtchn_unmask(xendev->xeh, port);
-}
-
static void xen_device_realize(DeviceState *dev, Error **errp)
{
XenDevice *xendev = XEN_DEVICE(dev);
xendev->feature_grant_copy =
(xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0);
- xendev->xeh = xenevtchn_open(NULL, 0);
- if (!xendev->xeh) {
- error_setg_errno(errp, errno, "failed xenevtchn_open");
- goto unrealize;
- }
-
- notifier_list_init(&xendev->event_notifiers);
- qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), xen_device_event, NULL,
- xendev);
-
xen_device_backend_create(xendev, &local_err);
if (local_err) {
error_propagate(errp, local_err);
#include "hw/xen/xen_pvdev.h"
#include "monitor/qdev.h"
-#include <xen/grant_table.h>
-
DeviceState *xen_sysdev;
BusState *xen_sysbus;
int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
int64_t *pnum);
int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
- int64_t offset, int64_t bytes, int64_t *pnum);
+ bool include_base, int64_t offset, int64_t bytes,
+ int64_t *pnum);
bool bdrv_is_read_only(BlockDriverState *bs);
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
*/
void address_space_destroy(AddressSpace *as);
+/**
+ * address_space_remove_listeners: unregister all listeners of an address space
+ *
+ * Removes all callbacks previously registered with memory_listener_register()
+ * for @as.
+ *
+ * @as: an initialized #AddressSpace
+ */
+void address_space_remove_listeners(AddressSpace *as);
+
/**
* address_space_rw: read from or write to an address space.
*
#include "hw/intc/aspeed_vic.h"
#include "hw/misc/aspeed_scu.h"
#include "hw/misc/aspeed_sdmc.h"
+#include "hw/misc/aspeed_xdma.h"
#include "hw/timer/aspeed_timer.h"
+#include "hw/timer/aspeed_rtc.h"
#include "hw/i2c/aspeed_i2c.h"
#include "hw/ssi/aspeed_smc.h"
#include "hw/watchdog/wdt_aspeed.h"
#define ASPEED_SPIS_NUM 2
#define ASPEED_WDTS_NUM 3
+#define ASPEED_CPUS_NUM 2
+#define ASPEED_MACS_NUM 2
typedef struct AspeedSoCState {
/*< private >*/
DeviceState parent;
/*< public >*/
- ARMCPU cpu;
+ ARMCPU cpu[ASPEED_CPUS_NUM];
+ uint32_t num_cpus;
MemoryRegion sram;
AspeedVICState vic;
+ AspeedRtcState rtc;
AspeedTimerCtrlState timerctrl;
AspeedI2CState i2c;
AspeedSCUState scu;
+ AspeedXDMAState xdma;
AspeedSMCState fmc;
AspeedSMCState spi[ASPEED_SPIS_NUM];
AspeedSDMCState sdmc;
AspeedWDTState wdt[ASPEED_WDTS_NUM];
- FTGMAC100State ftgmac100;
+ FTGMAC100State ftgmac100[ASPEED_MACS_NUM];
} AspeedSoCState;
#define TYPE_ASPEED_SOC "aspeed-soc"
const char *name;
const char *cpu_type;
uint32_t silicon_rev;
- hwaddr sdram_base;
uint64_t sram_size;
int spis_num;
- const hwaddr *spi_bases;
const char *fmc_typename;
const char **spi_typename;
int wdts_num;
+ const int *irqmap;
+ const hwaddr *memmap;
+ uint32_t num_cpus;
} AspeedSoCInfo;
typedef struct AspeedSoCClass {
#define ASPEED_SOC_GET_CLASS(obj) \
OBJECT_GET_CLASS(AspeedSoCClass, (obj), TYPE_ASPEED_SOC)
+enum {
+ ASPEED_IOMEM,
+ ASPEED_UART1,
+ ASPEED_UART2,
+ ASPEED_UART3,
+ ASPEED_UART4,
+ ASPEED_UART5,
+ ASPEED_VUART,
+ ASPEED_FMC,
+ ASPEED_SPI1,
+ ASPEED_SPI2,
+ ASPEED_VIC,
+ ASPEED_SDMC,
+ ASPEED_SCU,
+ ASPEED_ADC,
+ ASPEED_SRAM,
+ ASPEED_GPIO,
+ ASPEED_RTC,
+ ASPEED_TIMER1,
+ ASPEED_TIMER2,
+ ASPEED_TIMER3,
+ ASPEED_TIMER4,
+ ASPEED_TIMER5,
+ ASPEED_TIMER6,
+ ASPEED_TIMER7,
+ ASPEED_TIMER8,
+ ASPEED_WDT,
+ ASPEED_PWM,
+ ASPEED_LPC,
+ ASPEED_IBT,
+ ASPEED_I2C,
+ ASPEED_ETH1,
+ ASPEED_ETH2,
+ ASPEED_SDRAM,
+ ASPEED_XDMA,
+};
+
#endif /* ASPEED_SOC_H */
FSL_IMX7_ADC2_ADDR = 0x30620000,
FSL_IMX7_ADCn_SIZE = 0x1000,
+ FSL_IMX7_PCIE_PHY_ADDR = 0x306D0000,
+ FSL_IMX7_PCIE_PHY_SIZE = 0x10000,
+
FSL_IMX7_GPC_ADDR = 0x303A0000,
FSL_IMX7_I2C1_ADDR = 0x30A20000,
FSL_IMX7_PCIE_REG_SIZE = 16 * 1024,
FSL_IMX7_GPR_ADDR = 0x30340000,
+
+ FSL_IMX7_DMA_APBH_ADDR = 0x33000000,
+ FSL_IMX7_DMA_APBH_SIZE = 0x2000,
};
enum FslIMX7IRQs {
FSL_IMX7_USB2_IRQ = 42,
FSL_IMX7_USB3_IRQ = 40,
- FSL_IMX7_PCI_INTA_IRQ = 122,
- FSL_IMX7_PCI_INTB_IRQ = 123,
- FSL_IMX7_PCI_INTC_IRQ = 124,
- FSL_IMX7_PCI_INTD_IRQ = 125,
+ FSL_IMX7_PCI_INTA_IRQ = 125,
+ FSL_IMX7_PCI_INTB_IRQ = 124,
+ FSL_IMX7_PCI_INTC_IRQ = 123,
+ FSL_IMX7_PCI_INTD_IRQ = 122,
FSL_IMX7_UART7_IRQ = 126,
#include "sysemu/blockdev.h"
#include "sysemu/accel.h"
#include "hw/qdev.h"
+#include "qapi/qapi-types-machine.h"
#include "qemu/module.h"
#include "qom/object.h"
#include "qom/cpu.h"
--- /dev/null
+#ifndef BITBANG_I2C_H
+#define BITBANG_I2C_H
+
+#include "hw/i2c/i2c.h"
+
+typedef struct bitbang_i2c_interface bitbang_i2c_interface;
+
+#define BITBANG_I2C_SDA 0
+#define BITBANG_I2C_SCL 1
+
+typedef enum bitbang_i2c_state {
+ STOPPED = 0,
+ SENDING_BIT7,
+ SENDING_BIT6,
+ SENDING_BIT5,
+ SENDING_BIT4,
+ SENDING_BIT3,
+ SENDING_BIT2,
+ SENDING_BIT1,
+ SENDING_BIT0,
+ WAITING_FOR_ACK,
+ RECEIVING_BIT7,
+ RECEIVING_BIT6,
+ RECEIVING_BIT5,
+ RECEIVING_BIT4,
+ RECEIVING_BIT3,
+ RECEIVING_BIT2,
+ RECEIVING_BIT1,
+ RECEIVING_BIT0,
+ SENDING_ACK,
+ SENT_NACK
+} bitbang_i2c_state;
+
+struct bitbang_i2c_interface {
+ I2CBus *bus;
+ bitbang_i2c_state state;
+ int last_data;
+ int last_clock;
+ int device_out;
+ uint8_t buffer;
+ int current_addr;
+};
+
+/**
+ * bitbang_i2c_init: in-place initialize the bitbang_i2c_interface struct
+ */
+void bitbang_i2c_init(bitbang_i2c_interface *s, I2CBus *bus);
+int bitbang_i2c_set(bitbang_i2c_interface *i2c, int line, int level);
+
+#endif
DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr);
-typedef struct bitbang_i2c_interface bitbang_i2c_interface;
-
/* lm832x.c */
void lm832x_key_event(DeviceState *dev, int key, int state);
#define PPC4XX_I2C_H
#include "hw/sysbus.h"
-#include "hw/i2c/i2c.h"
+#include "hw/i2c/bitbang_i2c.h"
#define TYPE_PPC4xx_I2C "ppc4xx-i2c"
#define PPC4xx_I2C(obj) OBJECT_CHECK(PPC4xxI2CState, (obj), TYPE_PPC4xx_I2C)
I2CBus *bus;
qemu_irq irq;
MemoryRegion iomem;
- bitbang_i2c_interface *bitbang;
+ bitbang_i2c_interface bitbang;
int mdidx;
uint8_t mdata[4];
uint8_t lmadr;
--- /dev/null
+/*
+ * ASPEED XDMA Controller
+ * Eddie James <eajames@linux.ibm.com>
+ *
+ * Copyright (C) 2019 IBM Corp.
+ * SPDX-License-Identifer: GPL-2.0-or-later
+ */
+
+#ifndef ASPEED_XDMA_H
+#define ASPEED_XDMA_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_ASPEED_XDMA "aspeed.xdma"
+#define ASPEED_XDMA(obj) OBJECT_CHECK(AspeedXDMAState, (obj), TYPE_ASPEED_XDMA)
+
+#define ASPEED_XDMA_NUM_REGS (ASPEED_XDMA_REG_SIZE / sizeof(uint32_t))
+#define ASPEED_XDMA_REG_SIZE 0x7C
+
+typedef struct AspeedXDMAState {
+ SysBusDevice parent;
+
+ MemoryRegion iomem;
+ qemu_irq irq;
+
+ char bmc_cmdq_readp_set;
+ uint32_t regs[ASPEED_XDMA_NUM_REGS];
+} AspeedXDMAState;
+
+#endif /* ASPEED_XDMA_H */
uint64_t cores_mask;
void *cores;
- hwaddr xscom_base;
MemoryRegion xscom_mmio;
MemoryRegion xscom;
AddressSpace xscom_as;
uint64_t chip_cfam_id;
uint64_t cores_mask;
- hwaddr xscom_base;
-
DeviceRealize parent_realize;
uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id);
*/
#define PNV_XSCOM_SIZE 0x800000000ull
#define PNV_XSCOM_BASE(chip) \
- (chip->xscom_base + ((uint64_t)(chip)->chip_id) * PNV_XSCOM_SIZE)
+ (0x0003fc0000000000ull + ((uint64_t)(chip)->chip_id) * PNV_XSCOM_SIZE)
/*
* XSCOM 0x20109CA defines the ICP BAR:
#define PNV9_PSIHB_ESB_SIZE 0x0000000000010000ull
#define PNV9_PSIHB_ESB_BASE(chip) PNV9_CHIP_BASE(chip, 0x00060302031c0000ull)
+#define PNV9_XSCOM_SIZE 0x0000000400000000ull
+#define PNV9_XSCOM_BASE(chip) PNV9_CHIP_BASE(chip, 0x00603fc00000000ull)
+
#endif /* PPC_PNV_H */
#define PNV9_XSCOM_XIVE_BASE 0x5013000
#define PNV9_XSCOM_XIVE_SIZE 0x300
-extern void pnv_xscom_realize(PnvChip *chip, Error **errp);
+extern void pnv_xscom_realize(PnvChip *chip, uint64_t size, Error **errp);
extern int pnv_dt_xscom(PnvChip *chip, void *fdt, int offset);
extern void pnv_xscom_add_subregion(PnvChip *chip, hwaddr offset,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets);
void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn);
-static inline void spapr_rtas_unregister(int token)
-{
- spapr_rtas_register(token, NULL, NULL);
-}
target_ulong spapr_rtas_call(PowerPCCPU *cpu, SpaprMachineState *sm,
uint32_t token, uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets);
void (*reset)(SpaprMachineState *spapr, Error **errp);
void (*set_irq)(void *opaque, int srcno, int val);
const char *(*get_nodename)(SpaprMachineState *spapr);
- void (*init_emu)(SpaprMachineState *spapr, Error **errp);
void (*init_kvm)(SpaprMachineState *spapr, Error **errp);
} SpaprIrq;
/* KVM support */
int fd;
void *tm_mmap;
+ MemoryRegion tm_mmio_kvm;
VMChangeStateEntry *change;
} SpaprXive;
int spapr_xive_end_to_target(uint8_t end_blk, uint32_t end_idx,
uint32_t *out_server, uint8_t *out_prio);
-void spapr_xive_init(SpaprXive *xive, Error **errp);
/*
* KVM XIVE device helpers
uint32_t offset;
ICSIRQState *irqs;
XICSFabric *xics;
- bool init; /* sPAPR ICS device initialized */
};
#define ICS_PROP_XICS "xics"
/* KVM */
void icp_get_kvm_state(ICPState *icp);
-int icp_set_kvm_state(ICPState *icp);
+int icp_set_kvm_state(ICPState *icp, Error **errp);
void icp_synchronize_state(ICPState *icp);
void icp_kvm_realize(DeviceState *dev, Error **errp);
void ics_get_kvm_state(ICSState *ics);
-int ics_set_kvm_state_one(ICSState *ics, int srcno);
-int ics_set_kvm_state(ICSState *ics);
+int ics_set_kvm_state_one(ICSState *ics, int srcno, Error **errp);
+int ics_set_kvm_state(ICSState *ics, Error **errp);
void ics_synchronize_state(ICSState *ics);
void ics_kvm_set_irq(ICSState *ics, int srcno, int val);
void spapr_dt_xics(SpaprMachineState *spapr, uint32_t nr_servers, void *fdt,
uint32_t phandle);
-int xics_kvm_init(SpaprMachineState *spapr, Error **errp);
+int xics_kvm_connect(SpaprMachineState *spapr, Error **errp);
void xics_kvm_disconnect(SpaprMachineState *spapr, Error **errp);
+bool xics_kvm_has_broken_disconnect(SpaprMachineState *spapr);
void xics_spapr_init(SpaprMachineState *spapr);
#endif /* XICS_SPAPR_H */
/* KVM support */
void *esb_mmap;
+ MemoryRegion esb_mmio_kvm;
XiveNotifier *xive;
} XiveSource;
--- /dev/null
+/*
+ * QEMU RISC-V Boot Helper
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ * Copyright (c) 2019 Alistair Francis <alistair.francis@wdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef RISCV_BOOT_H
+#define RISCV_BOOT_H
+
+target_ulong riscv_load_firmware(const char *firmware_filename,
+ hwaddr firmware_load_addr);
+target_ulong riscv_load_kernel(const char *kernel_filename);
+hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
+ uint64_t kernel_entry, hwaddr *start);
+
+#endif /* RISCV_BOOT_H */
RISCVHartArrayState cpus;
DeviceState *plic;
SIFIVEGPIOState gpio;
+ MemoryRegion xip_mem;
+ MemoryRegion mask_rom;
} SiFiveESoCState;
typedef struct SiFiveEState {
#ifndef HW_SIFIVE_PRCI_H
#define HW_SIFIVE_PRCI_H
+enum {
+ SIFIVE_PRCI_HFROSCCFG = 0x0,
+ SIFIVE_PRCI_HFXOSCCFG = 0x4,
+ SIFIVE_PRCI_PLLCFG = 0x8,
+ SIFIVE_PRCI_PLLOUTDIV = 0xC
+};
+
+enum {
+ SIFIVE_PRCI_HFROSCCFG_RDY = (1 << 31),
+ SIFIVE_PRCI_HFROSCCFG_EN = (1 << 30)
+};
+
+enum {
+ SIFIVE_PRCI_HFXOSCCFG_RDY = (1 << 31),
+ SIFIVE_PRCI_HFXOSCCFG_EN = (1 << 30)
+};
+
+enum {
+ SIFIVE_PRCI_PLLCFG_PLLSEL = (1 << 16),
+ SIFIVE_PRCI_PLLCFG_REFSEL = (1 << 17),
+ SIFIVE_PRCI_PLLCFG_BYPASS = (1 << 18),
+ SIFIVE_PRCI_PLLCFG_LOCK = (1 << 31)
+};
+
+enum {
+ SIFIVE_PRCI_PLLOUTDIV_DIV1 = (1 << 8)
+};
+
#define TYPE_SIFIVE_PRCI "riscv.sifive.prci"
#define SIFIVE_PRCI(obj) \
/*< public >*/
MemoryRegion mmio;
+ uint32_t hfrosccfg;
+ uint32_t hfxosccfg;
+ uint32_t pllcfg;
+ uint32_t plloutdiv;
} SiFivePRCIState;
DeviceState *sifive_prci_create(hwaddr addr);
IOInstEnding do_subchannel_work_virtual(SubchDev *sub);
IOInstEnding do_subchannel_work_passthrough(SubchDev *sub);
+int s390_ccw_halt(SubchDev *sch);
+int s390_ccw_clear(SubchDev *sch);
+
typedef enum {
CSS_IO_ADAPTER_VIRTIO = 0,
CSS_IO_ADAPTER_PCI = 1,
void (*realize)(S390CCWDevice *dev, char *sysfsdev, Error **errp);
void (*unrealize)(S390CCWDevice *dev, Error **errp);
IOInstEnding (*handle_request) (SubchDev *sch);
+ int (*handle_halt) (SubchDev *sch);
+ int (*handle_clear) (SubchDev *sch);
} S390CCWDeviceClass;
#endif
uint8_t r_timings;
uint8_t conf_enable_w0;
+ /* for DMA support */
+ uint64_t sdram_base;
+
AspeedSMCFlash *flashes;
uint8_t snoop_index;
--- /dev/null
+/*
+ * ASPEED Real Time Clock
+ * Joel Stanley <joel@jms.id.au>
+ *
+ * Copyright 2019 IBM Corp
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef ASPEED_RTC_H
+#define ASPEED_RTC_H
+
+#include <stdint.h>
+
+#include "hw/hw.h"
+#include "hw/irq.h"
+#include "hw/sysbus.h"
+
+typedef struct AspeedRtcState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion iomem;
+ qemu_irq irq;
+
+ uint32_t reg[0x18];
+ int offset;
+
+} AspeedRtcState;
+
+#define TYPE_ASPEED_RTC "aspeed.rtc"
+#define ASPEED_RTC(obj) OBJECT_CHECK(AspeedRtcState, (obj), TYPE_ASPEED_RTC)
+
+#endif /* ASPEED_RTC_H */
int error;
bool initialized;
unsigned long pgsizes;
- /*
- * This assumes the host IOMMU can support only a single
- * contiguous IOVA window. We may need to generalize that in
- * future
- */
QLIST_HEAD(, VFIOGuestIOMMU) giommu_list;
QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list;
QLIST_HEAD(, VFIOGroup) group_list;
MemoryRegion iomem;
uint32_t regs[ASPEED_WDT_REGS_MAX];
+ AspeedSCUState *scu;
uint32_t pclk_freq;
uint32_t silicon_rev;
uint32_t ext_pulse_width_mask;
--- /dev/null
+/******************************************************************************
+ * grant_table.h
+ *
+ * Interface for granting foreign access to page frames, and receiving
+ * page-ownership transfers.
+ *
+ * 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.
+ *
+ * Copyright (c) 2004, K A Fraser
+ */
+
+#ifndef __XEN_PUBLIC_GRANT_TABLE_H__
+#define __XEN_PUBLIC_GRANT_TABLE_H__
+
+/*
+ * Reference to a grant entry in a specified domain's grant table.
+ */
+typedef uint32_t grant_ref_t;
+
+#endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */
--- /dev/null
+/******************************************************************************
+ * blkif.h
+ *
+ * Unified block-device I/O interface for Xen guest OSes.
+ *
+ * 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.
+ *
+ * Copyright (c) 2003-2004, Keir Fraser
+ * Copyright (c) 2012, Spectra Logic Corporation
+ */
+
+#ifndef __XEN_PUBLIC_IO_BLKIF_H__
+#define __XEN_PUBLIC_IO_BLKIF_H__
+
+#include "ring.h"
+#include "../grant_table.h"
+
+/*
+ * Front->back notifications: When enqueuing a new request, sending a
+ * notification can be made conditional on req_event (i.e., the generic
+ * hold-off mechanism provided by the ring macros). Backends must set
+ * req_event appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()).
+ *
+ * Back->front notifications: When enqueuing a new response, sending a
+ * notification can be made conditional on rsp_event (i.e., the generic
+ * hold-off mechanism provided by the ring macros). Frontends must set
+ * rsp_event appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).
+ */
+
+#ifndef blkif_vdev_t
+#define blkif_vdev_t uint16_t
+#endif
+#define blkif_sector_t uint64_t
+
+/*
+ * Feature and Parameter Negotiation
+ * =================================
+ * The two halves of a Xen block driver utilize nodes within the XenStore to
+ * communicate capabilities and to negotiate operating parameters. This
+ * section enumerates these nodes which reside in the respective front and
+ * backend portions of the XenStore, following the XenBus convention.
+ *
+ * All data in the XenStore is stored as strings. Nodes specifying numeric
+ * values are encoded in decimal. Integer value ranges listed below are
+ * expressed as fixed sized integer types capable of storing the conversion
+ * of a properly formated node string, without loss of information.
+ *
+ * Any specified default value is in effect if the corresponding XenBus node
+ * is not present in the XenStore.
+ *
+ * XenStore nodes in sections marked "PRIVATE" are solely for use by the
+ * driver side whose XenBus tree contains them.
+ *
+ * XenStore nodes marked "DEPRECATED" in their notes section should only be
+ * used to provide interoperability with legacy implementations.
+ *
+ * See the XenBus state transition diagram below for details on when XenBus
+ * nodes must be published and when they can be queried.
+ *
+ *****************************************************************************
+ * Backend XenBus Nodes
+ *****************************************************************************
+ *
+ *------------------ Backend Device Identification (PRIVATE) ------------------
+ *
+ * mode
+ * Values: "r" (read only), "w" (writable)
+ *
+ * The read or write access permissions to the backing store to be
+ * granted to the frontend.
+ *
+ * params
+ * Values: string
+ *
+ * A free formatted string providing sufficient information for the
+ * hotplug script to attach the device and provide a suitable
+ * handler (ie: a block device) for blkback to use.
+ *
+ * physical-device
+ * Values: "MAJOR:MINOR"
+ * Notes: 11
+ *
+ * MAJOR and MINOR are the major number and minor number of the
+ * backing device respectively.
+ *
+ * physical-device-path
+ * Values: path string
+ *
+ * A string that contains the absolute path to the disk image. On
+ * NetBSD and Linux this is always a block device, while on FreeBSD
+ * it can be either a block device or a regular file.
+ *
+ * type
+ * Values: "file", "phy", "tap"
+ *
+ * The type of the backing device/object.
+ *
+ *
+ * direct-io-safe
+ * Values: 0/1 (boolean)
+ * Default Value: 0
+ *
+ * The underlying storage is not affected by the direct IO memory
+ * lifetime bug. See:
+ * http://lists.xen.org/archives/html/xen-devel/2012-12/msg01154.html
+ *
+ * Therefore this option gives the backend permission to use
+ * O_DIRECT, notwithstanding that bug.
+ *
+ * That is, if this option is enabled, use of O_DIRECT is safe,
+ * in circumstances where we would normally have avoided it as a
+ * workaround for that bug. This option is not relevant for all
+ * backends, and even not necessarily supported for those for
+ * which it is relevant. A backend which knows that it is not
+ * affected by the bug can ignore this option.
+ *
+ * This option doesn't require a backend to use O_DIRECT, so it
+ * should not be used to try to control the caching behaviour.
+ *
+ *--------------------------------- Features ---------------------------------
+ *
+ * feature-barrier
+ * Values: 0/1 (boolean)
+ * Default Value: 0
+ *
+ * A value of "1" indicates that the backend can process requests
+ * containing the BLKIF_OP_WRITE_BARRIER request opcode. Requests
+ * of this type may still be returned at any time with the
+ * BLKIF_RSP_EOPNOTSUPP result code.
+ *
+ * feature-flush-cache
+ * Values: 0/1 (boolean)
+ * Default Value: 0
+ *
+ * A value of "1" indicates that the backend can process requests
+ * containing the BLKIF_OP_FLUSH_DISKCACHE request opcode. Requests
+ * of this type may still be returned at any time with the
+ * BLKIF_RSP_EOPNOTSUPP result code.
+ *
+ * feature-discard
+ * Values: 0/1 (boolean)
+ * Default Value: 0
+ *
+ * A value of "1" indicates that the backend can process requests
+ * containing the BLKIF_OP_DISCARD request opcode. Requests
+ * of this type may still be returned at any time with the
+ * BLKIF_RSP_EOPNOTSUPP result code.
+ *
+ * feature-persistent
+ * Values: 0/1 (boolean)
+ * Default Value: 0
+ * Notes: 7
+ *
+ * A value of "1" indicates that the backend can keep the grants used
+ * by the frontend driver mapped, so the same set of grants should be
+ * used in all transactions. The maximum number of grants the backend
+ * can map persistently depends on the implementation, but ideally it
+ * should be RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST. Using this
+ * feature the backend doesn't need to unmap each grant, preventing
+ * costly TLB flushes. The backend driver should only map grants
+ * persistently if the frontend supports it. If a backend driver chooses
+ * to use the persistent protocol when the frontend doesn't support it,
+ * it will probably hit the maximum number of persistently mapped grants
+ * (due to the fact that the frontend won't be reusing the same grants),
+ * and fall back to non-persistent mode. Backend implementations may
+ * shrink or expand the number of persistently mapped grants without
+ * notifying the frontend depending on memory constraints (this might
+ * cause a performance degradation).
+ *
+ * If a backend driver wants to limit the maximum number of persistently
+ * mapped grants to a value less than RING_SIZE *
+ * BLKIF_MAX_SEGMENTS_PER_REQUEST a LRU strategy should be used to
+ * discard the grants that are less commonly used. Using a LRU in the
+ * backend driver paired with a LIFO queue in the frontend will
+ * allow us to have better performance in this scenario.
+ *
+ *----------------------- Request Transport Parameters ------------------------
+ *
+ * max-ring-page-order
+ * Values: <uint32_t>
+ * Default Value: 0
+ * Notes: 1, 3
+ *
+ * The maximum supported size of the request ring buffer in units of
+ * lb(machine pages). (e.g. 0 == 1 page, 1 = 2 pages, 2 == 4 pages,
+ * etc.).
+ *
+ * max-ring-pages
+ * Values: <uint32_t>
+ * Default Value: 1
+ * Notes: DEPRECATED, 2, 3
+ *
+ * The maximum supported size of the request ring buffer in units of
+ * machine pages. The value must be a power of 2.
+ *
+ *------------------------- Backend Device Properties -------------------------
+ *
+ * discard-enable
+ * Values: 0/1 (boolean)
+ * Default Value: 1
+ *
+ * This optional property, set by the toolstack, instructs the backend
+ * to offer (or not to offer) discard to the frontend. If the property
+ * is missing the backend should offer discard if the backing storage
+ * actually supports it.
+ *
+ * discard-alignment
+ * Values: <uint32_t>
+ * Default Value: 0
+ * Notes: 4, 5
+ *
+ * The offset, in bytes from the beginning of the virtual block device,
+ * to the first, addressable, discard extent on the underlying device.
+ *
+ * discard-granularity
+ * Values: <uint32_t>
+ * Default Value: <"sector-size">
+ * Notes: 4
+ *
+ * The size, in bytes, of the individually addressable discard extents
+ * of the underlying device.
+ *
+ * discard-secure
+ * Values: 0/1 (boolean)
+ * Default Value: 0
+ * Notes: 10
+ *
+ * A value of "1" indicates that the backend can process BLKIF_OP_DISCARD
+ * requests with the BLKIF_DISCARD_SECURE flag set.
+ *
+ * info
+ * Values: <uint32_t> (bitmap)
+ *
+ * A collection of bit flags describing attributes of the backing
+ * device. The VDISK_* macros define the meaning of each bit
+ * location.
+ *
+ * sector-size
+ * Values: <uint32_t>
+ *
+ * The logical block size, in bytes, of the underlying storage. This
+ * must be a power of two with a minimum value of 512.
+ *
+ * NOTE: Because of implementation bugs in some frontends this must be
+ * set to 512, unless the frontend advertizes a non-zero value
+ * in its "feature-large-sector-size" xenbus node. (See below).
+ *
+ * physical-sector-size
+ * Values: <uint32_t>
+ * Default Value: <"sector-size">
+ *
+ * The physical block size, in bytes, of the backend storage. This
+ * must be an integer multiple of "sector-size".
+ *
+ * sectors
+ * Values: <uint64_t>
+ *
+ * The size of the backend device, expressed in units of "sector-size".
+ * The product of "sector-size" and "sectors" must also be an integer
+ * multiple of "physical-sector-size", if that node is present.
+ *
+ *****************************************************************************
+ * Frontend XenBus Nodes
+ *****************************************************************************
+ *
+ *----------------------- Request Transport Parameters -----------------------
+ *
+ * event-channel
+ * Values: <uint32_t>
+ *
+ * The identifier of the Xen event channel used to signal activity
+ * in the ring buffer.
+ *
+ * ring-ref
+ * Values: <uint32_t>
+ * Notes: 6
+ *
+ * The Xen grant reference granting permission for the backend to map
+ * the sole page in a single page sized ring buffer.
+ *
+ * ring-ref%u
+ * Values: <uint32_t>
+ * Notes: 6
+ *
+ * For a frontend providing a multi-page ring, a "number of ring pages"
+ * sized list of nodes, each containing a Xen grant reference granting
+ * permission for the backend to map the page of the ring located
+ * at page index "%u". Page indexes are zero based.
+ *
+ * protocol
+ * Values: string (XEN_IO_PROTO_ABI_*)
+ * Default Value: XEN_IO_PROTO_ABI_NATIVE
+ *
+ * The machine ABI rules governing the format of all ring request and
+ * response structures.
+ *
+ * ring-page-order
+ * Values: <uint32_t>
+ * Default Value: 0
+ * Maximum Value: MAX(ffs(max-ring-pages) - 1, max-ring-page-order)
+ * Notes: 1, 3
+ *
+ * The size of the frontend allocated request ring buffer in units
+ * of lb(machine pages). (e.g. 0 == 1 page, 1 = 2 pages, 2 == 4 pages,
+ * etc.).
+ *
+ * num-ring-pages
+ * Values: <uint32_t>
+ * Default Value: 1
+ * Maximum Value: MAX(max-ring-pages,(0x1 << max-ring-page-order))
+ * Notes: DEPRECATED, 2, 3
+ *
+ * The size of the frontend allocated request ring buffer in units of
+ * machine pages. The value must be a power of 2.
+ *
+ *--------------------------------- Features ---------------------------------
+ *
+ * feature-persistent
+ * Values: 0/1 (boolean)
+ * Default Value: 0
+ * Notes: 7, 8, 9
+ *
+ * A value of "1" indicates that the frontend will reuse the same grants
+ * for all transactions, allowing the backend to map them with write
+ * access (even when it should be read-only). If the frontend hits the
+ * maximum number of allowed persistently mapped grants, it can fallback
+ * to non persistent mode. This will cause a performance degradation,
+ * since the the backend driver will still try to map those grants
+ * persistently. Since the persistent grants protocol is compatible with
+ * the previous protocol, a frontend driver can choose to work in
+ * persistent mode even when the backend doesn't support it.
+ *
+ * It is recommended that the frontend driver stores the persistently
+ * mapped grants in a LIFO queue, so a subset of all persistently mapped
+ * grants gets used commonly. This is done in case the backend driver
+ * decides to limit the maximum number of persistently mapped grants
+ * to a value less than RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST.
+ *
+ * feature-large-sector-size
+ * Values: 0/1 (boolean)
+ * Default Value: 0
+ *
+ * A value of "1" indicates that the frontend will correctly supply and
+ * interpret all sector-based quantities in terms of the "sector-size"
+ * value supplied in the backend info, whatever that may be set to.
+ * If this node is not present or its value is "0" then it is assumed
+ * that the frontend requires that the logical block size is 512 as it
+ * is hardcoded (which is the case in some frontend implementations).
+ *
+ *------------------------- Virtual Device Properties -------------------------
+ *
+ * device-type
+ * Values: "disk", "cdrom", "floppy", etc.
+ *
+ * virtual-device
+ * Values: <uint32_t>
+ *
+ * A value indicating the physical device to virtualize within the
+ * frontend's domain. (e.g. "The first ATA disk", "The third SCSI
+ * disk", etc.)
+ *
+ * See docs/misc/vbd-interface.txt for details on the format of this
+ * value.
+ *
+ * Notes
+ * -----
+ * (1) Multi-page ring buffer scheme first developed in the Citrix XenServer
+ * PV drivers.
+ * (2) Multi-page ring buffer scheme first used in some RedHat distributions
+ * including a distribution deployed on certain nodes of the Amazon
+ * EC2 cluster.
+ * (3) Support for multi-page ring buffers was implemented independently,
+ * in slightly different forms, by both Citrix and RedHat/Amazon.
+ * For full interoperability, block front and backends should publish
+ * identical ring parameters, adjusted for unit differences, to the
+ * XenStore nodes used in both schemes.
+ * (4) Devices that support discard functionality may internally allocate space
+ * (discardable extents) in units that are larger than the exported logical
+ * block size. If the backing device has such discardable extents the
+ * backend should provide both discard-granularity and discard-alignment.
+ * Providing just one of the two may be considered an error by the frontend.
+ * Backends supporting discard should include discard-granularity and
+ * discard-alignment even if it supports discarding individual sectors.
+ * Frontends should assume discard-alignment == 0 and discard-granularity
+ * == sector size if these keys are missing.
+ * (5) The discard-alignment parameter allows a physical device to be
+ * partitioned into virtual devices that do not necessarily begin or
+ * end on a discardable extent boundary.
+ * (6) When there is only a single page allocated to the request ring,
+ * 'ring-ref' is used to communicate the grant reference for this
+ * page to the backend. When using a multi-page ring, the 'ring-ref'
+ * node is not created. Instead 'ring-ref0' - 'ring-refN' are used.
+ * (7) When using persistent grants data has to be copied from/to the page
+ * where the grant is currently mapped. The overhead of doing this copy
+ * however doesn't suppress the speed improvement of not having to unmap
+ * the grants.
+ * (8) The frontend driver has to allow the backend driver to map all grants
+ * with write access, even when they should be mapped read-only, since
+ * further requests may reuse these grants and require write permissions.
+ * (9) Linux implementation doesn't have a limit on the maximum number of
+ * grants that can be persistently mapped in the frontend driver, but
+ * due to the frontent driver implementation it should never be bigger
+ * than RING_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST.
+ *(10) The discard-secure property may be present and will be set to 1 if the
+ * backing device supports secure discard.
+ *(11) Only used by Linux and NetBSD.
+ */
+
+/*
+ * Multiple hardware queues/rings:
+ * If supported, the backend will write the key "multi-queue-max-queues" to
+ * the directory for that vbd, and set its value to the maximum supported
+ * number of queues.
+ * Frontends that are aware of this feature and wish to use it can write the
+ * key "multi-queue-num-queues" with the number they wish to use, which must be
+ * greater than zero, and no more than the value reported by the backend in
+ * "multi-queue-max-queues".
+ *
+ * For frontends requesting just one queue, the usual event-channel and
+ * ring-ref keys are written as before, simplifying the backend processing
+ * to avoid distinguishing between a frontend that doesn't understand the
+ * multi-queue feature, and one that does, but requested only one queue.
+ *
+ * Frontends requesting two or more queues must not write the toplevel
+ * event-channel and ring-ref keys, instead writing those keys under sub-keys
+ * having the name "queue-N" where N is the integer ID of the queue/ring for
+ * which those keys belong. Queues are indexed from zero.
+ * For example, a frontend with two queues must write the following set of
+ * queue-related keys:
+ *
+ * /local/domain/1/device/vbd/0/multi-queue-num-queues = "2"
+ * /local/domain/1/device/vbd/0/queue-0 = ""
+ * /local/domain/1/device/vbd/0/queue-0/ring-ref = "<ring-ref#0>"
+ * /local/domain/1/device/vbd/0/queue-0/event-channel = "<evtchn#0>"
+ * /local/domain/1/device/vbd/0/queue-1 = ""
+ * /local/domain/1/device/vbd/0/queue-1/ring-ref = "<ring-ref#1>"
+ * /local/domain/1/device/vbd/0/queue-1/event-channel = "<evtchn#1>"
+ *
+ * It is also possible to use multiple queues/rings together with
+ * feature multi-page ring buffer.
+ * For example, a frontend requests two queues/rings and the size of each ring
+ * buffer is two pages must write the following set of related keys:
+ *
+ * /local/domain/1/device/vbd/0/multi-queue-num-queues = "2"
+ * /local/domain/1/device/vbd/0/ring-page-order = "1"
+ * /local/domain/1/device/vbd/0/queue-0 = ""
+ * /local/domain/1/device/vbd/0/queue-0/ring-ref0 = "<ring-ref#0>"
+ * /local/domain/1/device/vbd/0/queue-0/ring-ref1 = "<ring-ref#1>"
+ * /local/domain/1/device/vbd/0/queue-0/event-channel = "<evtchn#0>"
+ * /local/domain/1/device/vbd/0/queue-1 = ""
+ * /local/domain/1/device/vbd/0/queue-1/ring-ref0 = "<ring-ref#2>"
+ * /local/domain/1/device/vbd/0/queue-1/ring-ref1 = "<ring-ref#3>"
+ * /local/domain/1/device/vbd/0/queue-1/event-channel = "<evtchn#1>"
+ *
+ */
+
+/*
+ * STATE DIAGRAMS
+ *
+ *****************************************************************************
+ * Startup *
+ *****************************************************************************
+ *
+ * Tool stack creates front and back nodes with state XenbusStateInitialising.
+ *
+ * Front Back
+ * ================================= =====================================
+ * XenbusStateInitialising XenbusStateInitialising
+ * o Query virtual device o Query backend device identification
+ * properties. data.
+ * o Setup OS device instance. o Open and validate backend device.
+ * o Publish backend features and
+ * transport parameters.
+ * |
+ * |
+ * V
+ * XenbusStateInitWait
+ *
+ * o Query backend features and
+ * transport parameters.
+ * o Allocate and initialize the
+ * request ring.
+ * o Publish transport parameters
+ * that will be in effect during
+ * this connection.
+ * |
+ * |
+ * V
+ * XenbusStateInitialised
+ *
+ * o Query frontend transport parameters.
+ * o Connect to the request ring and
+ * event channel.
+ * o Publish backend device properties.
+ * |
+ * |
+ * V
+ * XenbusStateConnected
+ *
+ * o Query backend device properties.
+ * o Finalize OS virtual device
+ * instance.
+ * |
+ * |
+ * V
+ * XenbusStateConnected
+ *
+ * Note: Drivers that do not support any optional features, or the negotiation
+ * of transport parameters, can skip certain states in the state machine:
+ *
+ * o A frontend may transition to XenbusStateInitialised without
+ * waiting for the backend to enter XenbusStateInitWait. In this
+ * case, default transport parameters are in effect and any
+ * transport parameters published by the frontend must contain
+ * their default values.
+ *
+ * o A backend may transition to XenbusStateInitialised, bypassing
+ * XenbusStateInitWait, without waiting for the frontend to first
+ * enter the XenbusStateInitialised state. In this case, default
+ * transport parameters are in effect and any transport parameters
+ * published by the backend must contain their default values.
+ *
+ * Drivers that support optional features and/or transport parameter
+ * negotiation must tolerate these additional state transition paths.
+ * In general this means performing the work of any skipped state
+ * transition, if it has not already been performed, in addition to the
+ * work associated with entry into the current state.
+ */
+
+/*
+ * REQUEST CODES.
+ */
+#define BLKIF_OP_READ 0
+#define BLKIF_OP_WRITE 1
+/*
+ * All writes issued prior to a request with the BLKIF_OP_WRITE_BARRIER
+ * operation code ("barrier request") must be completed prior to the
+ * execution of the barrier request. All writes issued after the barrier
+ * request must not execute until after the completion of the barrier request.
+ *
+ * Optional. See "feature-barrier" XenBus node documentation above.
+ */
+#define BLKIF_OP_WRITE_BARRIER 2
+/*
+ * Commit any uncommitted contents of the backing device's volatile cache
+ * to stable storage.
+ *
+ * Optional. See "feature-flush-cache" XenBus node documentation above.
+ */
+#define BLKIF_OP_FLUSH_DISKCACHE 3
+/*
+ * Used in SLES sources for device specific command packet
+ * contained within the request. Reserved for that purpose.
+ */
+#define BLKIF_OP_RESERVED_1 4
+/*
+ * Indicate to the backend device that a region of storage is no longer in
+ * use, and may be discarded at any time without impact to the client. If
+ * the BLKIF_DISCARD_SECURE flag is set on the request, all copies of the
+ * discarded region on the device must be rendered unrecoverable before the
+ * command returns.
+ *
+ * This operation is analogous to performing a trim (ATA) or unamp (SCSI),
+ * command on a native device.
+ *
+ * More information about trim/unmap operations can be found at:
+ * http://t13.org/Documents/UploadedDocuments/docs2008/
+ * e07154r6-Data_Set_Management_Proposal_for_ATA-ACS2.doc
+ * http://www.seagate.com/staticfiles/support/disc/manuals/
+ * Interface%20manuals/100293068c.pdf
+ *
+ * Optional. See "feature-discard", "discard-alignment",
+ * "discard-granularity", and "discard-secure" in the XenBus node
+ * documentation above.
+ */
+#define BLKIF_OP_DISCARD 5
+
+/*
+ * Recognized if "feature-max-indirect-segments" in present in the backend
+ * xenbus info. The "feature-max-indirect-segments" node contains the maximum
+ * number of segments allowed by the backend per request. If the node is
+ * present, the frontend might use blkif_request_indirect structs in order to
+ * issue requests with more than BLKIF_MAX_SEGMENTS_PER_REQUEST (11). The
+ * maximum number of indirect segments is fixed by the backend, but the
+ * frontend can issue requests with any number of indirect segments as long as
+ * it's less than the number provided by the backend. The indirect_grefs field
+ * in blkif_request_indirect should be filled by the frontend with the
+ * grant references of the pages that are holding the indirect segments.
+ * These pages are filled with an array of blkif_request_segment that hold the
+ * information about the segments. The number of indirect pages to use is
+ * determined by the number of segments an indirect request contains. Every
+ * indirect page can contain a maximum of
+ * (PAGE_SIZE / sizeof(struct blkif_request_segment)) segments, so to
+ * calculate the number of indirect pages to use we have to do
+ * ceil(indirect_segments / (PAGE_SIZE / sizeof(struct blkif_request_segment))).
+ *
+ * If a backend does not recognize BLKIF_OP_INDIRECT, it should *not*
+ * create the "feature-max-indirect-segments" node!
+ */
+#define BLKIF_OP_INDIRECT 6
+
+/*
+ * Maximum scatter/gather segments per request.
+ * This is carefully chosen so that sizeof(blkif_ring_t) <= PAGE_SIZE.
+ * NB. This could be 12 if the ring indexes weren't stored in the same page.
+ */
+#define BLKIF_MAX_SEGMENTS_PER_REQUEST 11
+
+/*
+ * Maximum number of indirect pages to use per request.
+ */
+#define BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST 8
+
+/*
+ * NB. 'first_sect' and 'last_sect' in blkif_request_segment, as well as
+ * 'sector_number' in blkif_request, blkif_request_discard and
+ * blkif_request_indirect are sector-based quantities. See the description
+ * of the "feature-large-sector-size" frontend xenbus node above for
+ * more information.
+ */
+struct blkif_request_segment {
+ grant_ref_t gref; /* reference to I/O buffer frame */
+ /* @first_sect: first sector in frame to transfer (inclusive). */
+ /* @last_sect: last sector in frame to transfer (inclusive). */
+ uint8_t first_sect, last_sect;
+};
+
+/*
+ * Starting ring element for any I/O request.
+ */
+struct blkif_request {
+ uint8_t operation; /* BLKIF_OP_??? */
+ uint8_t nr_segments; /* number of segments */
+ blkif_vdev_t handle; /* only for read/write requests */
+ uint64_t id; /* private guest value, echoed in resp */
+ blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
+ struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+};
+typedef struct blkif_request blkif_request_t;
+
+/*
+ * Cast to this structure when blkif_request.operation == BLKIF_OP_DISCARD
+ * sizeof(struct blkif_request_discard) <= sizeof(struct blkif_request)
+ */
+struct blkif_request_discard {
+ uint8_t operation; /* BLKIF_OP_DISCARD */
+ uint8_t flag; /* BLKIF_DISCARD_SECURE or zero */
+#define BLKIF_DISCARD_SECURE (1<<0) /* ignored if discard-secure=0 */
+ blkif_vdev_t handle; /* same as for read/write requests */
+ uint64_t id; /* private guest value, echoed in resp */
+ blkif_sector_t sector_number;/* start sector idx on disk */
+ uint64_t nr_sectors; /* number of contiguous sectors to discard*/
+};
+typedef struct blkif_request_discard blkif_request_discard_t;
+
+struct blkif_request_indirect {
+ uint8_t operation; /* BLKIF_OP_INDIRECT */
+ uint8_t indirect_op; /* BLKIF_OP_{READ/WRITE} */
+ uint16_t nr_segments; /* number of segments */
+ uint64_t id; /* private guest value, echoed in resp */
+ blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
+ blkif_vdev_t handle; /* same as for read/write requests */
+ grant_ref_t indirect_grefs[BLKIF_MAX_INDIRECT_PAGES_PER_REQUEST];
+#ifdef __i386__
+ uint64_t pad; /* Make it 64 byte aligned on i386 */
+#endif
+};
+typedef struct blkif_request_indirect blkif_request_indirect_t;
+
+struct blkif_response {
+ uint64_t id; /* copied from request */
+ uint8_t operation; /* copied from request */
+ int16_t status; /* BLKIF_RSP_??? */
+};
+typedef struct blkif_response blkif_response_t;
+
+/*
+ * STATUS RETURN CODES.
+ */
+ /* Operation not supported (only happens on barrier writes). */
+#define BLKIF_RSP_EOPNOTSUPP -2
+ /* Operation failed for some unspecified reason (-EIO). */
+#define BLKIF_RSP_ERROR -1
+ /* Operation completed successfully. */
+#define BLKIF_RSP_OKAY 0
+
+/*
+ * Generate blkif ring structures and types.
+ */
+DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response);
+
+#define VDISK_CDROM 0x1
+#define VDISK_REMOVABLE 0x2
+#define VDISK_READONLY 0x4
+
+#endif /* __XEN_PUBLIC_IO_BLKIF_H__ */
--- /dev/null
+/******************************************************************************
+ * console.h
+ *
+ * Console I/O interface for Xen guest OSes.
+ *
+ * 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.
+ *
+ * Copyright (c) 2005, Keir Fraser
+ */
+
+#ifndef __XEN_PUBLIC_IO_CONSOLE_H__
+#define __XEN_PUBLIC_IO_CONSOLE_H__
+
+typedef uint32_t XENCONS_RING_IDX;
+
+#define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1))
+
+struct xencons_interface {
+ char in[1024];
+ char out[2048];
+ XENCONS_RING_IDX in_cons, in_prod;
+ XENCONS_RING_IDX out_cons, out_prod;
+};
+
+#ifdef XEN_WANT_FLEX_CONSOLE_RING
+#include "ring.h"
+DEFINE_XEN_FLEX_RING(xencons);
+#endif
+
+#endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */
--- /dev/null
+/*
+ * fbif.h -- Xen virtual frame buffer device
+ *
+ * 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.
+ *
+ * Copyright (C) 2005 Anthony Liguori <aliguori@us.ibm.com>
+ * Copyright (C) 2006 Red Hat, Inc., Markus Armbruster <armbru@redhat.com>
+ */
+
+#ifndef __XEN_PUBLIC_IO_FBIF_H__
+#define __XEN_PUBLIC_IO_FBIF_H__
+
+/* Out events (frontend -> backend) */
+
+/*
+ * Out events may be sent only when requested by backend, and receipt
+ * of an unknown out event is an error.
+ */
+
+/* Event type 1 currently not used */
+/*
+ * Framebuffer update notification event
+ * Capable frontend sets feature-update in xenstore.
+ * Backend requests it by setting request-update in xenstore.
+ */
+#define XENFB_TYPE_UPDATE 2
+
+struct xenfb_update
+{
+ uint8_t type; /* XENFB_TYPE_UPDATE */
+ int32_t x; /* source x */
+ int32_t y; /* source y */
+ int32_t width; /* rect width */
+ int32_t height; /* rect height */
+};
+
+/*
+ * Framebuffer resize notification event
+ * Capable backend sets feature-resize in xenstore.
+ */
+#define XENFB_TYPE_RESIZE 3
+
+struct xenfb_resize
+{
+ uint8_t type; /* XENFB_TYPE_RESIZE */
+ int32_t width; /* width in pixels */
+ int32_t height; /* height in pixels */
+ int32_t stride; /* stride in bytes */
+ int32_t depth; /* depth in bits */
+ int32_t offset; /* offset of the framebuffer in bytes */
+};
+
+#define XENFB_OUT_EVENT_SIZE 40
+
+union xenfb_out_event
+{
+ uint8_t type;
+ struct xenfb_update update;
+ struct xenfb_resize resize;
+ char pad[XENFB_OUT_EVENT_SIZE];
+};
+
+/* In events (backend -> frontend) */
+
+/*
+ * Frontends should ignore unknown in events.
+ */
+
+/*
+ * Framebuffer refresh period advice
+ * Backend sends it to advise the frontend their preferred period of
+ * refresh. Frontends that keep the framebuffer constantly up-to-date
+ * just ignore it. Frontends that use the advice should immediately
+ * refresh the framebuffer (and send an update notification event if
+ * those have been requested), then use the update frequency to guide
+ * their periodical refreshs.
+ */
+#define XENFB_TYPE_REFRESH_PERIOD 1
+#define XENFB_NO_REFRESH 0
+
+struct xenfb_refresh_period
+{
+ uint8_t type; /* XENFB_TYPE_UPDATE_PERIOD */
+ uint32_t period; /* period of refresh, in ms,
+ * XENFB_NO_REFRESH if no refresh is needed */
+};
+
+#define XENFB_IN_EVENT_SIZE 40
+
+union xenfb_in_event
+{
+ uint8_t type;
+ struct xenfb_refresh_period refresh_period;
+ char pad[XENFB_IN_EVENT_SIZE];
+};
+
+/* shared page */
+
+#define XENFB_IN_RING_SIZE 1024
+#define XENFB_IN_RING_LEN (XENFB_IN_RING_SIZE / XENFB_IN_EVENT_SIZE)
+#define XENFB_IN_RING_OFFS 1024
+#define XENFB_IN_RING(page) \
+ ((union xenfb_in_event *)((char *)(page) + XENFB_IN_RING_OFFS))
+#define XENFB_IN_RING_REF(page, idx) \
+ (XENFB_IN_RING((page))[(idx) % XENFB_IN_RING_LEN])
+
+#define XENFB_OUT_RING_SIZE 2048
+#define XENFB_OUT_RING_LEN (XENFB_OUT_RING_SIZE / XENFB_OUT_EVENT_SIZE)
+#define XENFB_OUT_RING_OFFS (XENFB_IN_RING_OFFS + XENFB_IN_RING_SIZE)
+#define XENFB_OUT_RING(page) \
+ ((union xenfb_out_event *)((char *)(page) + XENFB_OUT_RING_OFFS))
+#define XENFB_OUT_RING_REF(page, idx) \
+ (XENFB_OUT_RING((page))[(idx) % XENFB_OUT_RING_LEN])
+
+struct xenfb_page
+{
+ uint32_t in_cons, in_prod;
+ uint32_t out_cons, out_prod;
+
+ int32_t width; /* the width of the framebuffer (in pixels) */
+ int32_t height; /* the height of the framebuffer (in pixels) */
+ uint32_t line_length; /* the length of a row of pixels (in bytes) */
+ uint32_t mem_length; /* the length of the framebuffer (in bytes) */
+ uint8_t depth; /* the depth of a pixel (in bits) */
+
+ /*
+ * Framebuffer page directory
+ *
+ * Each directory page holds PAGE_SIZE / sizeof(*pd)
+ * framebuffer pages, and can thus map up to PAGE_SIZE *
+ * PAGE_SIZE / sizeof(*pd) bytes. With PAGE_SIZE == 4096 and
+ * sizeof(unsigned long) == 4/8, that's 4 Megs 32 bit and 2 Megs
+ * 64 bit. 256 directories give enough room for a 512 Meg
+ * framebuffer with a max resolution of 12,800x10,240. Should
+ * be enough for a while with room leftover for expansion.
+ */
+ unsigned long pd[256];
+};
+
+#endif
--- /dev/null
+/*
+ * kbdif.h -- Xen virtual keyboard/mouse
+ *
+ * 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.
+ *
+ * Copyright (C) 2005 Anthony Liguori <aliguori@us.ibm.com>
+ * Copyright (C) 2006 Red Hat, Inc., Markus Armbruster <armbru@redhat.com>
+ */
+
+#ifndef __XEN_PUBLIC_IO_KBDIF_H__
+#define __XEN_PUBLIC_IO_KBDIF_H__
+
+/*
+ *****************************************************************************
+ * Feature and Parameter Negotiation
+ *****************************************************************************
+ *
+ * The two halves of a para-virtual driver utilize nodes within
+ * XenStore to communicate capabilities and to negotiate operating parameters.
+ * This section enumerates these nodes which reside in the respective front and
+ * backend portions of XenStore, following XenBus convention.
+ *
+ * All data in XenStore is stored as strings. Nodes specifying numeric
+ * values are encoded in decimal. Integer value ranges listed below are
+ * expressed as fixed sized integer types capable of storing the conversion
+ * of a properly formated node string, without loss of information.
+ *
+ *****************************************************************************
+ * Backend XenBus Nodes
+ *****************************************************************************
+ *
+ *---------------------------- Features supported ----------------------------
+ *
+ * Capable backend advertises supported features by publishing
+ * corresponding entries in XenStore and puts 1 as the value of the entry.
+ * If a feature is not supported then 0 must be set or feature entry omitted.
+ *
+ * feature-disable-keyboard
+ * Values: <uint>
+ *
+ * If there is no need to expose a virtual keyboard device by the
+ * frontend then this must be set to 1.
+ *
+ * feature-disable-pointer
+ * Values: <uint>
+ *
+ * If there is no need to expose a virtual pointer device by the
+ * frontend then this must be set to 1.
+ *
+ * feature-abs-pointer
+ * Values: <uint>
+ *
+ * Backends, which support reporting of absolute coordinates for pointer
+ * device should set this to 1.
+ *
+ * feature-multi-touch
+ * Values: <uint>
+ *
+ * Backends, which support reporting of multi-touch events
+ * should set this to 1.
+ *
+ * feature-raw-pointer
+ * Values: <uint>
+ *
+ * Backends, which support reporting raw (unscaled) absolute coordinates
+ * for pointer devices should set this to 1. Raw (unscaled) values have
+ * a range of [0, 0x7fff].
+ *
+ *----------------------- Device Instance Parameters ------------------------
+ *
+ * unique-id
+ * Values: <string>
+ *
+ * After device instance initialization it is assigned a unique ID,
+ * so every instance of the frontend can be identified by the backend
+ * by this ID. This can be UUID or such.
+ *
+ *------------------------- Pointer Device Parameters ------------------------
+ *
+ * width
+ * Values: <uint>
+ *
+ * Maximum X coordinate (width) to be used by the frontend
+ * while reporting input events, pixels, [0; UINT32_MAX].
+ *
+ * height
+ * Values: <uint>
+ *
+ * Maximum Y coordinate (height) to be used by the frontend
+ * while reporting input events, pixels, [0; UINT32_MAX].
+ *
+ *----------------------- Multi-touch Device Parameters ----------------------
+ *
+ * multi-touch-num-contacts
+ * Values: <uint>
+ *
+ * Number of simultaneous touches reported.
+ *
+ * multi-touch-width
+ * Values: <uint>
+ *
+ * Width of the touch area to be used by the frontend
+ * while reporting input events, pixels, [0; UINT32_MAX].
+ *
+ * multi-touch-height
+ * Values: <uint>
+ *
+ * Height of the touch area to be used by the frontend
+ * while reporting input events, pixels, [0; UINT32_MAX].
+ *
+ *****************************************************************************
+ * Frontend XenBus Nodes
+ *****************************************************************************
+ *
+ *------------------------------ Feature request -----------------------------
+ *
+ * Capable frontend requests features from backend via setting corresponding
+ * entries to 1 in XenStore. Requests for features not advertised as supported
+ * by the backend have no effect.
+ *
+ * request-abs-pointer
+ * Values: <uint>
+ *
+ * Request backend to report absolute pointer coordinates
+ * (XENKBD_TYPE_POS) instead of relative ones (XENKBD_TYPE_MOTION).
+ *
+ * request-multi-touch
+ * Values: <uint>
+ *
+ * Request backend to report multi-touch events.
+ *
+ * request-raw-pointer
+ * Values: <uint>
+ *
+ * Request backend to report raw unscaled absolute pointer coordinates.
+ * This option is only valid if request-abs-pointer is also set.
+ * Raw unscaled coordinates have the range [0, 0x7fff]
+ *
+ *----------------------- Request Transport Parameters -----------------------
+ *
+ * event-channel
+ * Values: <uint>
+ *
+ * The identifier of the Xen event channel used to signal activity
+ * in the ring buffer.
+ *
+ * page-gref
+ * Values: <uint>
+ *
+ * The Xen grant reference granting permission for the backend to map
+ * a sole page in a single page sized event ring buffer.
+ *
+ * page-ref
+ * Values: <uint>
+ *
+ * OBSOLETE, not recommended for use.
+ * PFN of the shared page.
+ */
+
+/*
+ * EVENT CODES.
+ */
+
+#define XENKBD_TYPE_MOTION 1
+#define XENKBD_TYPE_RESERVED 2
+#define XENKBD_TYPE_KEY 3
+#define XENKBD_TYPE_POS 4
+#define XENKBD_TYPE_MTOUCH 5
+
+/* Multi-touch event sub-codes */
+
+#define XENKBD_MT_EV_DOWN 0
+#define XENKBD_MT_EV_UP 1
+#define XENKBD_MT_EV_MOTION 2
+#define XENKBD_MT_EV_SYN 3
+#define XENKBD_MT_EV_SHAPE 4
+#define XENKBD_MT_EV_ORIENT 5
+
+/*
+ * CONSTANTS, XENSTORE FIELD AND PATH NAME STRINGS, HELPERS.
+ */
+
+#define XENKBD_DRIVER_NAME "vkbd"
+
+#define XENKBD_FIELD_FEAT_DSBL_KEYBRD "feature-disable-keyboard"
+#define XENKBD_FIELD_FEAT_DSBL_POINTER "feature-disable-pointer"
+#define XENKBD_FIELD_FEAT_ABS_POINTER "feature-abs-pointer"
+#define XENKBD_FIELD_FEAT_RAW_POINTER "feature-raw-pointer"
+#define XENKBD_FIELD_FEAT_MTOUCH "feature-multi-touch"
+#define XENKBD_FIELD_REQ_ABS_POINTER "request-abs-pointer"
+#define XENKBD_FIELD_REQ_RAW_POINTER "request-raw-pointer"
+#define XENKBD_FIELD_REQ_MTOUCH "request-multi-touch"
+#define XENKBD_FIELD_RING_GREF "page-gref"
+#define XENKBD_FIELD_EVT_CHANNEL "event-channel"
+#define XENKBD_FIELD_WIDTH "width"
+#define XENKBD_FIELD_HEIGHT "height"
+#define XENKBD_FIELD_MT_WIDTH "multi-touch-width"
+#define XENKBD_FIELD_MT_HEIGHT "multi-touch-height"
+#define XENKBD_FIELD_MT_NUM_CONTACTS "multi-touch-num-contacts"
+#define XENKBD_FIELD_UNIQUE_ID "unique-id"
+
+/* OBSOLETE, not recommended for use */
+#define XENKBD_FIELD_RING_REF "page-ref"
+
+/*
+ *****************************************************************************
+ * Description of the protocol between frontend and backend driver.
+ *****************************************************************************
+ *
+ * The two halves of a Para-virtual driver communicate with
+ * each other using a shared page and an event channel.
+ * Shared page contains a ring with event structures.
+ *
+ * All reserved fields in the structures below must be 0.
+ *
+ *****************************************************************************
+ * Backend to frontend events
+ *****************************************************************************
+ *
+ * Frontends should ignore unknown in events.
+ * All event packets have the same length (40 octets)
+ * All event packets have common header:
+ *
+ * 0 octet
+ * +-----------------+
+ * | type |
+ * +-----------------+
+ * type - uint8_t, event code, XENKBD_TYPE_???
+ *
+ *
+ * Pointer relative movement event
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MOTION | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | rel_x | 8
+ * +----------------+----------------+----------------+----------------+
+ * | rel_y | 12
+ * +----------------+----------------+----------------+----------------+
+ * | rel_z | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * rel_x - int32_t, relative X motion
+ * rel_y - int32_t, relative Y motion
+ * rel_z - int32_t, relative Z motion (wheel)
+ */
+
+struct xenkbd_motion
+{
+ uint8_t type;
+ int32_t rel_x;
+ int32_t rel_y;
+ int32_t rel_z;
+};
+
+/*
+ * Key event (includes pointer buttons)
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_KEY | pressed | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | keycode | 8
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 12
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * pressed - uint8_t, 1 if pressed; 0 otherwise
+ * keycode - uint32_t, KEY_* from linux/input.h
+ */
+
+struct xenkbd_key
+{
+ uint8_t type;
+ uint8_t pressed;
+ uint32_t keycode;
+};
+
+/*
+ * Pointer absolute position event
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_POS | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | abs_x | 8
+ * +----------------+----------------+----------------+----------------+
+ * | abs_y | 12
+ * +----------------+----------------+----------------+----------------+
+ * | rel_z | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * abs_x - int32_t, absolute X position (in FB pixels)
+ * abs_y - int32_t, absolute Y position (in FB pixels)
+ * rel_z - int32_t, relative Z motion (wheel)
+ */
+
+struct xenkbd_position
+{
+ uint8_t type;
+ int32_t abs_x;
+ int32_t abs_y;
+ int32_t rel_z;
+};
+
+/*
+ * Multi-touch event and its sub-types
+ *
+ * All multi-touch event packets have common header:
+ *
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MTOUCH | event_type | contact_id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ *
+ * event_type - unt8_t, multi-touch event sub-type, XENKBD_MT_EV_???
+ * contact_id - unt8_t, ID of the contact
+ *
+ * Touch interactions can consist of one or more contacts.
+ * For each contact, a series of events is generated, starting
+ * with a down event, followed by zero or more motion events,
+ * and ending with an up event. Events relating to the same
+ * contact point can be identified by the ID of the sequence: contact ID.
+ * Contact ID may be reused after XENKBD_MT_EV_UP event and
+ * is in the [0; XENKBD_FIELD_NUM_CONTACTS - 1] range.
+ *
+ * For further information please refer to documentation on Wayland [1],
+ * Linux [2] and Windows [3] multi-touch support.
+ *
+ * [1] https://cgit.freedesktop.org/wayland/wayland/tree/protocol/wayland.xml
+ * [2] https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt
+ * [3] https://msdn.microsoft.com/en-us/library/jj151564(v=vs.85).aspx
+ *
+ *
+ * Multi-touch down event - sent when a new touch is made: touch is assigned
+ * a unique contact ID, sent with this and consequent events related
+ * to this touch.
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MTOUCH | _MT_EV_DOWN | contact_id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | abs_x | 12
+ * +----------------+----------------+----------------+----------------+
+ * | abs_y | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * abs_x - int32_t, absolute X position, in pixels
+ * abs_y - int32_t, absolute Y position, in pixels
+ *
+ * Multi-touch contact release event
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MTOUCH | _MT_EV_UP | contact_id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Multi-touch motion event
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MTOUCH | _MT_EV_MOTION | contact_id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | abs_x | 12
+ * +----------------+----------------+----------------+----------------+
+ * | abs_y | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * abs_x - int32_t, absolute X position, in pixels,
+ * abs_y - int32_t, absolute Y position, in pixels,
+ *
+ * Multi-touch input synchronization event - shows end of a set of events
+ * which logically belong together.
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MTOUCH | _MT_EV_SYN | contact_id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Multi-touch shape event - touch point's shape has changed its shape.
+ * Shape is approximated by an ellipse through the major and minor axis
+ * lengths: major is the longer diameter of the ellipse and minor is the
+ * shorter one. Center of the ellipse is reported via
+ * XENKBD_MT_EV_DOWN/XENKBD_MT_EV_MOTION events.
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MTOUCH | _MT_EV_SHAPE | contact_id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | major | 12
+ * +----------------+----------------+----------------+----------------+
+ * | minor | 16
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * major - unt32_t, length of the major axis, pixels
+ * minor - unt32_t, length of the minor axis, pixels
+ *
+ * Multi-touch orientation event - touch point's shape has changed
+ * its orientation: calculated as a clockwise angle between the major axis
+ * of the ellipse and positive Y axis in degrees, [-180; +180].
+ * 0 1 2 3 octet
+ * +----------------+----------------+----------------+----------------+
+ * | _TYPE_MTOUCH | _MT_EV_ORIENT | contact_id | reserved | 4
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 8
+ * +----------------+----------------+----------------+----------------+
+ * | orientation | reserved | 12
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 16
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * | reserved | 40
+ * +----------------+----------------+----------------+----------------+
+ *
+ * orientation - int16_t, clockwise angle of the major axis
+ */
+
+struct xenkbd_mtouch {
+ uint8_t type; /* XENKBD_TYPE_MTOUCH */
+ uint8_t event_type; /* XENKBD_MT_EV_??? */
+ uint8_t contact_id;
+ uint8_t reserved[5]; /* reserved for the future use */
+ union {
+ struct {
+ int32_t abs_x; /* absolute X position, pixels */
+ int32_t abs_y; /* absolute Y position, pixels */
+ } pos;
+ struct {
+ uint32_t major; /* length of the major axis, pixels */
+ uint32_t minor; /* length of the minor axis, pixels */
+ } shape;
+ int16_t orientation; /* clockwise angle of the major axis */
+ } u;
+};
+
+#define XENKBD_IN_EVENT_SIZE 40
+
+union xenkbd_in_event
+{
+ uint8_t type;
+ struct xenkbd_motion motion;
+ struct xenkbd_key key;
+ struct xenkbd_position pos;
+ struct xenkbd_mtouch mtouch;
+ char pad[XENKBD_IN_EVENT_SIZE];
+};
+
+/*
+ *****************************************************************************
+ * Frontend to backend events
+ *****************************************************************************
+ *
+ * Out events may be sent only when requested by backend, and receipt
+ * of an unknown out event is an error.
+ * No out events currently defined.
+
+ * All event packets have the same length (40 octets)
+ * All event packets have common header:
+ * 0 octet
+ * +-----------------+
+ * | type |
+ * +-----------------+
+ * type - uint8_t, event code
+ */
+
+#define XENKBD_OUT_EVENT_SIZE 40
+
+union xenkbd_out_event
+{
+ uint8_t type;
+ char pad[XENKBD_OUT_EVENT_SIZE];
+};
+
+/*
+ *****************************************************************************
+ * Shared page
+ *****************************************************************************
+ */
+
+#define XENKBD_IN_RING_SIZE 2048
+#define XENKBD_IN_RING_LEN (XENKBD_IN_RING_SIZE / XENKBD_IN_EVENT_SIZE)
+#define XENKBD_IN_RING_OFFS 1024
+#define XENKBD_IN_RING(page) \
+ ((union xenkbd_in_event *)((char *)(page) + XENKBD_IN_RING_OFFS))
+#define XENKBD_IN_RING_REF(page, idx) \
+ (XENKBD_IN_RING((page))[(idx) % XENKBD_IN_RING_LEN])
+
+#define XENKBD_OUT_RING_SIZE 1024
+#define XENKBD_OUT_RING_LEN (XENKBD_OUT_RING_SIZE / XENKBD_OUT_EVENT_SIZE)
+#define XENKBD_OUT_RING_OFFS (XENKBD_IN_RING_OFFS + XENKBD_IN_RING_SIZE)
+#define XENKBD_OUT_RING(page) \
+ ((union xenkbd_out_event *)((char *)(page) + XENKBD_OUT_RING_OFFS))
+#define XENKBD_OUT_RING_REF(page, idx) \
+ (XENKBD_OUT_RING((page))[(idx) % XENKBD_OUT_RING_LEN])
+
+struct xenkbd_page
+{
+ uint32_t in_cons, in_prod;
+ uint32_t out_cons, out_prod;
+};
+
+#endif /* __XEN_PUBLIC_IO_KBDIF_H__ */
--- /dev/null
+/******************************************************************************
+ * netif.h
+ *
+ * Unified network-device I/O interface for Xen guest OSes.
+ *
+ * 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.
+ *
+ * Copyright (c) 2003-2004, Keir Fraser
+ */
+
+#ifndef __XEN_PUBLIC_IO_NETIF_H__
+#define __XEN_PUBLIC_IO_NETIF_H__
+
+#include "ring.h"
+#include "../grant_table.h"
+
+/*
+ * Older implementation of Xen network frontend / backend has an
+ * implicit dependency on the MAX_SKB_FRAGS as the maximum number of
+ * ring slots a skb can use. Netfront / netback may not work as
+ * expected when frontend and backend have different MAX_SKB_FRAGS.
+ *
+ * A better approach is to add mechanism for netfront / netback to
+ * negotiate this value. However we cannot fix all possible
+ * frontends, so we need to define a value which states the minimum
+ * slots backend must support.
+ *
+ * The minimum value derives from older Linux kernel's MAX_SKB_FRAGS
+ * (18), which is proved to work with most frontends. Any new backend
+ * which doesn't negotiate with frontend should expect frontend to
+ * send a valid packet using slots up to this value.
+ */
+#define XEN_NETIF_NR_SLOTS_MIN 18
+
+/*
+ * Notifications after enqueuing any type of message should be conditional on
+ * the appropriate req_event or rsp_event field in the shared ring.
+ * If the client sends notification for rx requests then it should specify
+ * feature 'feature-rx-notify' via xenbus. Otherwise the backend will assume
+ * that it cannot safely queue packets (as it may not be kicked to send them).
+ */
+
+/*
+ * "feature-split-event-channels" is introduced to separate guest TX
+ * and RX notification. Backend either doesn't support this feature or
+ * advertises it via xenstore as 0 (disabled) or 1 (enabled).
+ *
+ * To make use of this feature, frontend should allocate two event
+ * channels for TX and RX, advertise them to backend as
+ * "event-channel-tx" and "event-channel-rx" respectively. If frontend
+ * doesn't want to use this feature, it just writes "event-channel"
+ * node as before.
+ */
+
+/*
+ * Multiple transmit and receive queues:
+ * If supported, the backend will write the key "multi-queue-max-queues" to
+ * the directory for that vif, and set its value to the maximum supported
+ * number of queues.
+ * Frontends that are aware of this feature and wish to use it can write the
+ * key "multi-queue-num-queues", set to the number they wish to use, which
+ * must be greater than zero, and no more than the value reported by the backend
+ * in "multi-queue-max-queues".
+ *
+ * Queues replicate the shared rings and event channels.
+ * "feature-split-event-channels" may optionally be used when using
+ * multiple queues, but is not mandatory.
+ *
+ * Each queue consists of one shared ring pair, i.e. there must be the same
+ * number of tx and rx rings.
+ *
+ * For frontends requesting just one queue, the usual event-channel and
+ * ring-ref keys are written as before, simplifying the backend processing
+ * to avoid distinguishing between a frontend that doesn't understand the
+ * multi-queue feature, and one that does, but requested only one queue.
+ *
+ * Frontends requesting two or more queues must not write the toplevel
+ * event-channel (or event-channel-{tx,rx}) and {tx,rx}-ring-ref keys,
+ * instead writing those keys under sub-keys having the name "queue-N" where
+ * N is the integer ID of the queue for which those keys belong. Queues
+ * are indexed from zero. For example, a frontend with two queues and split
+ * event channels must write the following set of queue-related keys:
+ *
+ * /local/domain/1/device/vif/0/multi-queue-num-queues = "2"
+ * /local/domain/1/device/vif/0/queue-0 = ""
+ * /local/domain/1/device/vif/0/queue-0/tx-ring-ref = "<ring-ref-tx0>"
+ * /local/domain/1/device/vif/0/queue-0/rx-ring-ref = "<ring-ref-rx0>"
+ * /local/domain/1/device/vif/0/queue-0/event-channel-tx = "<evtchn-tx0>"
+ * /local/domain/1/device/vif/0/queue-0/event-channel-rx = "<evtchn-rx0>"
+ * /local/domain/1/device/vif/0/queue-1 = ""
+ * /local/domain/1/device/vif/0/queue-1/tx-ring-ref = "<ring-ref-tx1>"
+ * /local/domain/1/device/vif/0/queue-1/rx-ring-ref = "<ring-ref-rx1"
+ * /local/domain/1/device/vif/0/queue-1/event-channel-tx = "<evtchn-tx1>"
+ * /local/domain/1/device/vif/0/queue-1/event-channel-rx = "<evtchn-rx1>"
+ *
+ * If there is any inconsistency in the XenStore data, the backend may
+ * choose not to connect any queues, instead treating the request as an
+ * error. This includes scenarios where more (or fewer) queues were
+ * requested than the frontend provided details for.
+ *
+ * Mapping of packets to queues is considered to be a function of the
+ * transmitting system (backend or frontend) and is not negotiated
+ * between the two. Guests are free to transmit packets on any queue
+ * they choose, provided it has been set up correctly. Guests must be
+ * prepared to receive packets on any queue they have requested be set up.
+ */
+
+/*
+ * "feature-no-csum-offload" should be used to turn IPv4 TCP/UDP checksum
+ * offload off or on. If it is missing then the feature is assumed to be on.
+ * "feature-ipv6-csum-offload" should be used to turn IPv6 TCP/UDP checksum
+ * offload on or off. If it is missing then the feature is assumed to be off.
+ */
+
+/*
+ * "feature-gso-tcpv4" and "feature-gso-tcpv6" advertise the capability to
+ * handle large TCP packets (in IPv4 or IPv6 form respectively). Neither
+ * frontends nor backends are assumed to be capable unless the flags are
+ * present.
+ */
+
+/*
+ * "feature-multicast-control" and "feature-dynamic-multicast-control"
+ * advertise the capability to filter ethernet multicast packets in the
+ * backend. If the frontend wishes to take advantage of this feature then
+ * it may set "request-multicast-control". If the backend only advertises
+ * "feature-multicast-control" then "request-multicast-control" must be set
+ * before the frontend moves into the connected state. The backend will
+ * sample the value on this state transition and any subsequent change in
+ * value will have no effect. However, if the backend also advertises
+ * "feature-dynamic-multicast-control" then "request-multicast-control"
+ * may be set by the frontend at any time. In this case, the backend will
+ * watch the value and re-sample on watch events.
+ *
+ * If the sampled value of "request-multicast-control" is set then the
+ * backend transmit side should no longer flood multicast packets to the
+ * frontend, it should instead drop any multicast packet that does not
+ * match in a filter list.
+ * The list is amended by the frontend by sending dummy transmit requests
+ * containing XEN_NETIF_EXTRA_TYPE_MCAST_{ADD,DEL} extra-info fragments as
+ * specified below.
+ * Note that the filter list may be amended even if the sampled value of
+ * "request-multicast-control" is not set, however the filter should only
+ * be applied if it is set.
+ */
+
+/*
+ * Control ring
+ * ============
+ *
+ * Some features, such as hashing (detailed below), require a
+ * significant amount of out-of-band data to be passed from frontend to
+ * backend. Use of xenstore is not suitable for large quantities of data
+ * because of quota limitations and so a dedicated 'control ring' is used.
+ * The ability of the backend to use a control ring is advertised by
+ * setting:
+ *
+ * /local/domain/X/backend/<domid>/<vif>/feature-ctrl-ring = "1"
+ *
+ * The frontend provides a control ring to the backend by setting:
+ *
+ * /local/domain/<domid>/device/vif/<vif>/ctrl-ring-ref = <gref>
+ * /local/domain/<domid>/device/vif/<vif>/event-channel-ctrl = <port>
+ *
+ * where <gref> is the grant reference of the shared page used to
+ * implement the control ring and <port> is an event channel to be used
+ * as a mailbox interrupt. These keys must be set before the frontend
+ * moves into the connected state.
+ *
+ * The control ring uses a fixed request/response message size and is
+ * balanced (i.e. one request to one response), so operationally it is much
+ * the same as a transmit or receive ring.
+ * Note that there is no requirement that responses are issued in the same
+ * order as requests.
+ */
+
+/*
+ * Hash types
+ * ==========
+ *
+ * For the purposes of the definitions below, 'Packet[]' is an array of
+ * octets containing an IP packet without options, 'Array[X..Y]' means a
+ * sub-array of 'Array' containing bytes X thru Y inclusive, and '+' is
+ * used to indicate concatenation of arrays.
+ */
+
+/*
+ * A hash calculated over an IP version 4 header as follows:
+ *
+ * Buffer[0..8] = Packet[12..15] (source address) +
+ * Packet[16..19] (destination address)
+ *
+ * Result = Hash(Buffer, 8)
+ */
+#define _XEN_NETIF_CTRL_HASH_TYPE_IPV4 0
+#define XEN_NETIF_CTRL_HASH_TYPE_IPV4 \
+ (1 << _XEN_NETIF_CTRL_HASH_TYPE_IPV4)
+
+/*
+ * A hash calculated over an IP version 4 header and TCP header as
+ * follows:
+ *
+ * Buffer[0..12] = Packet[12..15] (source address) +
+ * Packet[16..19] (destination address) +
+ * Packet[20..21] (source port) +
+ * Packet[22..23] (destination port)
+ *
+ * Result = Hash(Buffer, 12)
+ */
+#define _XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP 1
+#define XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP \
+ (1 << _XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP)
+
+/*
+ * A hash calculated over an IP version 6 header as follows:
+ *
+ * Buffer[0..32] = Packet[8..23] (source address ) +
+ * Packet[24..39] (destination address)
+ *
+ * Result = Hash(Buffer, 32)
+ */
+#define _XEN_NETIF_CTRL_HASH_TYPE_IPV6 2
+#define XEN_NETIF_CTRL_HASH_TYPE_IPV6 \
+ (1 << _XEN_NETIF_CTRL_HASH_TYPE_IPV6)
+
+/*
+ * A hash calculated over an IP version 6 header and TCP header as
+ * follows:
+ *
+ * Buffer[0..36] = Packet[8..23] (source address) +
+ * Packet[24..39] (destination address) +
+ * Packet[40..41] (source port) +
+ * Packet[42..43] (destination port)
+ *
+ * Result = Hash(Buffer, 36)
+ */
+#define _XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP 3
+#define XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP \
+ (1 << _XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP)
+
+/*
+ * Hash algorithms
+ * ===============
+ */
+
+#define XEN_NETIF_CTRL_HASH_ALGORITHM_NONE 0
+
+/*
+ * Toeplitz hash:
+ */
+
+#define XEN_NETIF_CTRL_HASH_ALGORITHM_TOEPLITZ 1
+
+/*
+ * Control requests (struct xen_netif_ctrl_request)
+ * ================================================
+ *
+ * All requests have the following format:
+ *
+ * 0 1 2 3 4 5 6 7 octet
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | id | type | data[0] |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | data[1] | data[2] |
+ * +-----+-----+-----+-----+-----------------------+
+ *
+ * id: the request identifier, echoed in response.
+ * type: the type of request (see below)
+ * data[]: any data associated with the request (determined by type)
+ */
+
+struct xen_netif_ctrl_request {
+ uint16_t id;
+ uint16_t type;
+
+#define XEN_NETIF_CTRL_TYPE_INVALID 0
+#define XEN_NETIF_CTRL_TYPE_GET_HASH_FLAGS 1
+#define XEN_NETIF_CTRL_TYPE_SET_HASH_FLAGS 2
+#define XEN_NETIF_CTRL_TYPE_SET_HASH_KEY 3
+#define XEN_NETIF_CTRL_TYPE_GET_HASH_MAPPING_SIZE 4
+#define XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING_SIZE 5
+#define XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING 6
+#define XEN_NETIF_CTRL_TYPE_SET_HASH_ALGORITHM 7
+#define XEN_NETIF_CTRL_TYPE_GET_GREF_MAPPING_SIZE 8
+#define XEN_NETIF_CTRL_TYPE_ADD_GREF_MAPPING 9
+#define XEN_NETIF_CTRL_TYPE_DEL_GREF_MAPPING 10
+
+ uint32_t data[3];
+};
+
+/*
+ * Control responses (struct xen_netif_ctrl_response)
+ * ==================================================
+ *
+ * All responses have the following format:
+ *
+ * 0 1 2 3 4 5 6 7 octet
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | id | type | status |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | data |
+ * +-----+-----+-----+-----+
+ *
+ * id: the corresponding request identifier
+ * type: the type of the corresponding request
+ * status: the status of request processing
+ * data: any data associated with the response (determined by type and
+ * status)
+ */
+
+struct xen_netif_ctrl_response {
+ uint16_t id;
+ uint16_t type;
+ uint32_t status;
+
+#define XEN_NETIF_CTRL_STATUS_SUCCESS 0
+#define XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED 1
+#define XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER 2
+#define XEN_NETIF_CTRL_STATUS_BUFFER_OVERFLOW 3
+
+ uint32_t data;
+};
+
+/*
+ * Static Grants (struct xen_netif_gref)
+ * =====================================
+ *
+ * A frontend may provide a fixed set of grant references to be mapped on
+ * the backend. The message of type XEN_NETIF_CTRL_TYPE_ADD_GREF_MAPPING
+ * prior its usage in the command ring allows for creation of these mappings.
+ * The backend will maintain a fixed amount of these mappings.
+ *
+ * XEN_NETIF_CTRL_TYPE_GET_GREF_MAPPING_SIZE lets a frontend query how many
+ * of these mappings can be kept.
+ *
+ * Each entry in the XEN_NETIF_CTRL_TYPE_{ADD,DEL}_GREF_MAPPING input table has
+ * the following format:
+ *
+ * 0 1 2 3 4 5 6 7 octet
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | grant ref | flags | status |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ *
+ * grant ref: grant reference (IN)
+ * flags: flags describing the control operation (IN)
+ * status: XEN_NETIF_CTRL_STATUS_* (OUT)
+ *
+ * 'status' is an output parameter which does not require to be set to zero
+ * prior to its usage in the corresponding control messages.
+ */
+
+struct xen_netif_gref {
+ grant_ref_t ref;
+ uint16_t flags;
+
+#define _XEN_NETIF_CTRLF_GREF_readonly 0
+#define XEN_NETIF_CTRLF_GREF_readonly (1U<<_XEN_NETIF_CTRLF_GREF_readonly)
+
+ uint16_t status;
+};
+
+/*
+ * Control messages
+ * ================
+ *
+ * XEN_NETIF_CTRL_TYPE_SET_HASH_ALGORITHM
+ * --------------------------------------
+ *
+ * This is sent by the frontend to set the desired hash algorithm.
+ *
+ * Request:
+ *
+ * type = XEN_NETIF_CTRL_TYPE_SET_HASH_ALGORITHM
+ * data[0] = a XEN_NETIF_CTRL_HASH_ALGORITHM_* value
+ * data[1] = 0
+ * data[2] = 0
+ *
+ * Response:
+ *
+ * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not
+ * supported
+ * XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER - The algorithm is not
+ * supported
+ * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful
+ *
+ * NOTE: Setting data[0] to XEN_NETIF_CTRL_HASH_ALGORITHM_NONE disables
+ * hashing and the backend is free to choose how it steers packets
+ * to queues (which is the default behaviour).
+ *
+ * XEN_NETIF_CTRL_TYPE_GET_HASH_FLAGS
+ * ----------------------------------
+ *
+ * This is sent by the frontend to query the types of hash supported by
+ * the backend.
+ *
+ * Request:
+ *
+ * type = XEN_NETIF_CTRL_TYPE_GET_HASH_FLAGS
+ * data[0] = 0
+ * data[1] = 0
+ * data[2] = 0
+ *
+ * Response:
+ *
+ * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not supported
+ * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful
+ * data = supported hash types (if operation was successful)
+ *
+ * NOTE: A valid hash algorithm must be selected before this operation can
+ * succeed.
+ *
+ * XEN_NETIF_CTRL_TYPE_SET_HASH_FLAGS
+ * ----------------------------------
+ *
+ * This is sent by the frontend to set the types of hash that the backend
+ * should calculate. (See above for hash type definitions).
+ * Note that the 'maximal' type of hash should always be chosen. For
+ * example, if the frontend sets both IPV4 and IPV4_TCP hash types then
+ * the latter hash type should be calculated for any TCP packet and the
+ * former only calculated for non-TCP packets.
+ *
+ * Request:
+ *
+ * type = XEN_NETIF_CTRL_TYPE_SET_HASH_FLAGS
+ * data[0] = bitwise OR of XEN_NETIF_CTRL_HASH_TYPE_* values
+ * data[1] = 0
+ * data[2] = 0
+ *
+ * Response:
+ *
+ * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not
+ * supported
+ * XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER - One or more flag
+ * value is invalid or
+ * unsupported
+ * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful
+ * data = 0
+ *
+ * NOTE: A valid hash algorithm must be selected before this operation can
+ * succeed.
+ * Also, setting data[0] to zero disables hashing and the backend
+ * is free to choose how it steers packets to queues.
+ *
+ * XEN_NETIF_CTRL_TYPE_SET_HASH_KEY
+ * --------------------------------
+ *
+ * This is sent by the frontend to set the key of the hash if the algorithm
+ * requires it. (See hash algorithms above).
+ *
+ * Request:
+ *
+ * type = XEN_NETIF_CTRL_TYPE_SET_HASH_KEY
+ * data[0] = grant reference of page containing the key (assumed to
+ * start at beginning of grant)
+ * data[1] = size of key in octets
+ * data[2] = 0
+ *
+ * Response:
+ *
+ * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not
+ * supported
+ * XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER - Key size is invalid
+ * XEN_NETIF_CTRL_STATUS_BUFFER_OVERFLOW - Key size is larger
+ * than the backend
+ * supports
+ * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful
+ * data = 0
+ *
+ * NOTE: Any key octets not specified are assumed to be zero (the key
+ * is assumed to be empty by default) and specifying a new key
+ * invalidates any previous key, hence specifying a key size of
+ * zero will clear the key (which ensures that the calculated hash
+ * will always be zero).
+ * The maximum size of key is algorithm and backend specific, but
+ * is also limited by the single grant reference.
+ * The grant reference may be read-only and must remain valid until
+ * the response has been processed.
+ *
+ * XEN_NETIF_CTRL_TYPE_GET_HASH_MAPPING_SIZE
+ * -----------------------------------------
+ *
+ * This is sent by the frontend to query the maximum size of mapping
+ * table supported by the backend. The size is specified in terms of
+ * table entries.
+ *
+ * Request:
+ *
+ * type = XEN_NETIF_CTRL_TYPE_GET_HASH_MAPPING_SIZE
+ * data[0] = 0
+ * data[1] = 0
+ * data[2] = 0
+ *
+ * Response:
+ *
+ * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not supported
+ * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful
+ * data = maximum number of entries allowed in the mapping table
+ * (if operation was successful) or zero if a mapping table is
+ * not supported (i.e. hash mapping is done only by modular
+ * arithmetic).
+ *
+ * XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING_SIZE
+ * -------------------------------------
+ *
+ * This is sent by the frontend to set the actual size of the mapping
+ * table to be used by the backend. The size is specified in terms of
+ * table entries.
+ * Any previous table is invalidated by this message and any new table
+ * is assumed to be zero filled.
+ *
+ * Request:
+ *
+ * type = XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING_SIZE
+ * data[0] = number of entries in mapping table
+ * data[1] = 0
+ * data[2] = 0
+ *
+ * Response:
+ *
+ * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not
+ * supported
+ * XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER - Table size is invalid
+ * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful
+ * data = 0
+ *
+ * NOTE: Setting data[0] to 0 means that hash mapping should be done
+ * using modular arithmetic.
+ *
+ * XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING
+ * ------------------------------------
+ *
+ * This is sent by the frontend to set the content of the table mapping
+ * hash value to queue number. The backend should calculate the hash from
+ * the packet header, use it as an index into the table (modulo the size
+ * of the table) and then steer the packet to the queue number found at
+ * that index.
+ *
+ * Request:
+ *
+ * type = XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING
+ * data[0] = grant reference of page containing the mapping (sub-)table
+ * (assumed to start at beginning of grant)
+ * data[1] = size of (sub-)table in entries
+ * data[2] = offset, in entries, of sub-table within overall table
+ *
+ * Response:
+ *
+ * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not
+ * supported
+ * XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER - Table size or content
+ * is invalid
+ * XEN_NETIF_CTRL_STATUS_BUFFER_OVERFLOW - Table size is larger
+ * than the backend
+ * supports
+ * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful
+ * data = 0
+ *
+ * NOTE: The overall table has the following format:
+ *
+ * 0 1 2 3 4 5 6 7 octet
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | mapping[0] | mapping[1] |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | . |
+ * | . |
+ * | . |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | mapping[N-2] | mapping[N-1] |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ *
+ * where N is specified by a XEN_NETIF_CTRL_TYPE_SET_HASH_MAPPING_SIZE
+ * message and each mapping must specifies a queue between 0 and
+ * "multi-queue-num-queues" (see above).
+ * The backend may support a mapping table larger than can be
+ * mapped by a single grant reference. Thus sub-tables within a
+ * larger table can be individually set by sending multiple messages
+ * with differing offset values. Specifying a new sub-table does not
+ * invalidate any table data outside that range.
+ * The grant reference may be read-only and must remain valid until
+ * the response has been processed.
+ *
+ * XEN_NETIF_CTRL_TYPE_GET_GREF_MAPPING_SIZE
+ * -----------------------------------------
+ *
+ * This is sent by the frontend to fetch the number of grefs that can be kept
+ * mapped in the backend.
+ *
+ * Request:
+ *
+ * type = XEN_NETIF_CTRL_TYPE_GET_GREF_MAPPING_SIZE
+ * data[0] = queue index (assumed 0 for single queue)
+ * data[1] = 0
+ * data[2] = 0
+ *
+ * Response:
+ *
+ * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not
+ * supported
+ * XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER - The queue index is
+ * out of range
+ * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful
+ * data = maximum number of entries allowed in the gref mapping table
+ * (if operation was successful) or zero if it is not supported.
+ *
+ * XEN_NETIF_CTRL_TYPE_ADD_GREF_MAPPING
+ * ------------------------------------
+ *
+ * This is sent by the frontend for backend to map a list of grant
+ * references.
+ *
+ * Request:
+ *
+ * type = XEN_NETIF_CTRL_TYPE_ADD_GREF_MAPPING
+ * data[0] = queue index
+ * data[1] = grant reference of page containing the mapping list
+ * (r/w and assumed to start at beginning of page)
+ * data[2] = size of list in entries
+ *
+ * Response:
+ *
+ * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not
+ * supported
+ * XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER - Operation failed
+ * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful
+ *
+ * NOTE: Each entry in the input table has the format outlined
+ * in struct xen_netif_gref.
+ * Contrary to XEN_NETIF_CTRL_TYPE_DEL_GREF_MAPPING, the struct
+ * xen_netif_gref 'status' field is not used and therefore the response
+ * 'status' determines the success of this operation. In case of
+ * failure none of grants mappings get added in the backend.
+ *
+ * XEN_NETIF_CTRL_TYPE_DEL_GREF_MAPPING
+ * ------------------------------------
+ *
+ * This is sent by the frontend for backend to unmap a list of grant
+ * references.
+ *
+ * Request:
+ *
+ * type = XEN_NETIF_CTRL_TYPE_DEL_GREF_MAPPING
+ * data[0] = queue index
+ * data[1] = grant reference of page containing the mapping list
+ * (r/w and assumed to start at beginning of page)
+ * data[2] = size of list in entries
+ *
+ * Response:
+ *
+ * status = XEN_NETIF_CTRL_STATUS_NOT_SUPPORTED - Operation not
+ * supported
+ * XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER - Operation failed
+ * XEN_NETIF_CTRL_STATUS_SUCCESS - Operation successful
+ * data = number of entries that were unmapped
+ *
+ * NOTE: Each entry in the input table has the format outlined in struct
+ * xen_netif_gref.
+ * The struct xen_netif_gref 'status' field determines if the entry
+ * was successfully removed.
+ * The entries used are only the ones representing grant references that
+ * were previously the subject of a XEN_NETIF_CTRL_TYPE_ADD_GREF_MAPPING
+ * operation. Any other entries will have their status set to
+ * XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER upon completion.
+ */
+
+DEFINE_RING_TYPES(xen_netif_ctrl,
+ struct xen_netif_ctrl_request,
+ struct xen_netif_ctrl_response);
+
+/*
+ * Guest transmit
+ * ==============
+ *
+ * This is the 'wire' format for transmit (frontend -> backend) packets:
+ *
+ * Fragment 1: netif_tx_request_t - flags = NETTXF_*
+ * size = total packet size
+ * [Extra 1: netif_extra_info_t] - (only if fragment 1 flags include
+ * NETTXF_extra_info)
+ * ...
+ * [Extra N: netif_extra_info_t] - (only if extra N-1 flags include
+ * XEN_NETIF_EXTRA_MORE)
+ * ...
+ * Fragment N: netif_tx_request_t - (only if fragment N-1 flags include
+ * NETTXF_more_data - flags on preceding
+ * extras are not relevant here)
+ * flags = 0
+ * size = fragment size
+ *
+ * NOTE:
+ *
+ * This format slightly is different from that used for receive
+ * (backend -> frontend) packets. Specifically, in a multi-fragment
+ * packet the actual size of fragment 1 can only be determined by
+ * subtracting the sizes of fragments 2..N from the total packet size.
+ *
+ * Ring slot size is 12 octets, however not all request/response
+ * structs use the full size.
+ *
+ * tx request data (netif_tx_request_t)
+ * ------------------------------------
+ *
+ * 0 1 2 3 4 5 6 7 octet
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | grant ref | offset | flags |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | id | size |
+ * +-----+-----+-----+-----+
+ *
+ * grant ref: Reference to buffer page.
+ * offset: Offset within buffer page.
+ * flags: NETTXF_*.
+ * id: request identifier, echoed in response.
+ * size: packet size in bytes.
+ *
+ * tx response (netif_tx_response_t)
+ * ---------------------------------
+ *
+ * 0 1 2 3 4 5 6 7 octet
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | id | status | unused |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | unused |
+ * +-----+-----+-----+-----+
+ *
+ * id: reflects id in transmit request
+ * status: NETIF_RSP_*
+ *
+ * Guest receive
+ * =============
+ *
+ * This is the 'wire' format for receive (backend -> frontend) packets:
+ *
+ * Fragment 1: netif_rx_request_t - flags = NETRXF_*
+ * size = fragment size
+ * [Extra 1: netif_extra_info_t] - (only if fragment 1 flags include
+ * NETRXF_extra_info)
+ * ...
+ * [Extra N: netif_extra_info_t] - (only if extra N-1 flags include
+ * XEN_NETIF_EXTRA_MORE)
+ * ...
+ * Fragment N: netif_rx_request_t - (only if fragment N-1 flags include
+ * NETRXF_more_data - flags on preceding
+ * extras are not relevant here)
+ * flags = 0
+ * size = fragment size
+ *
+ * NOTE:
+ *
+ * This format slightly is different from that used for transmit
+ * (frontend -> backend) packets. Specifically, in a multi-fragment
+ * packet the size of the packet can only be determined by summing the
+ * sizes of fragments 1..N.
+ *
+ * Ring slot size is 8 octets.
+ *
+ * rx request (netif_rx_request_t)
+ * -------------------------------
+ *
+ * 0 1 2 3 4 5 6 7 octet
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | id | pad | gref |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ *
+ * id: request identifier, echoed in response.
+ * gref: reference to incoming granted frame.
+ *
+ * rx response (netif_rx_response_t)
+ * ---------------------------------
+ *
+ * 0 1 2 3 4 5 6 7 octet
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | id | offset | flags | status |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ *
+ * id: reflects id in receive request
+ * offset: offset in page of start of received packet
+ * flags: NETRXF_*
+ * status: -ve: NETIF_RSP_*; +ve: Rx'ed pkt size.
+ *
+ * NOTE: Historically, to support GSO on the frontend receive side, Linux
+ * netfront does not make use of the rx response id (because, as
+ * described below, extra info structures overlay the id field).
+ * Instead it assumes that responses always appear in the same ring
+ * slot as their corresponding request. Thus, to maintain
+ * compatibility, backends must make sure this is the case.
+ *
+ * Extra Info
+ * ==========
+ *
+ * Can be present if initial request or response has NET{T,R}XF_extra_info,
+ * or previous extra request has XEN_NETIF_EXTRA_MORE.
+ *
+ * The struct therefore needs to fit into either a tx or rx slot and
+ * is therefore limited to 8 octets.
+ *
+ * NOTE: Because extra info data overlays the usual request/response
+ * structures, there is no id information in the opposite direction.
+ * So, if an extra info overlays an rx response the frontend can
+ * assume that it is in the same ring slot as the request that was
+ * consumed to make the slot available, and the backend must ensure
+ * this assumption is true.
+ *
+ * extra info (netif_extra_info_t)
+ * -------------------------------
+ *
+ * General format:
+ *
+ * 0 1 2 3 4 5 6 7 octet
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * |type |flags| type specific data |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | padding for tx |
+ * +-----+-----+-----+-----+
+ *
+ * type: XEN_NETIF_EXTRA_TYPE_*
+ * flags: XEN_NETIF_EXTRA_FLAG_*
+ * padding for tx: present only in the tx case due to 8 octet limit
+ * from rx case. Not shown in type specific entries
+ * below.
+ *
+ * XEN_NETIF_EXTRA_TYPE_GSO:
+ *
+ * 0 1 2 3 4 5 6 7 octet
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * |type |flags| size |type | pad | features |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ *
+ * type: Must be XEN_NETIF_EXTRA_TYPE_GSO
+ * flags: XEN_NETIF_EXTRA_FLAG_*
+ * size: Maximum payload size of each segment. For example,
+ * for TCP this is just the path MSS.
+ * type: XEN_NETIF_GSO_TYPE_*: This determines the protocol of
+ * the packet and any extra features required to segment the
+ * packet properly.
+ * features: EN_NETIF_GSO_FEAT_*: This specifies any extra GSO
+ * features required to process this packet, such as ECN
+ * support for TCPv4.
+ *
+ * XEN_NETIF_EXTRA_TYPE_MCAST_{ADD,DEL}:
+ *
+ * 0 1 2 3 4 5 6 7 octet
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * |type |flags| addr |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ *
+ * type: Must be XEN_NETIF_EXTRA_TYPE_MCAST_{ADD,DEL}
+ * flags: XEN_NETIF_EXTRA_FLAG_*
+ * addr: address to add/remove
+ *
+ * XEN_NETIF_EXTRA_TYPE_HASH:
+ *
+ * A backend that supports teoplitz hashing is assumed to accept
+ * this type of extra info in transmit packets.
+ * A frontend that enables hashing is assumed to accept
+ * this type of extra info in receive packets.
+ *
+ * 0 1 2 3 4 5 6 7 octet
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * |type |flags|htype| alg |LSB ---- value ---- MSB|
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ *
+ * type: Must be XEN_NETIF_EXTRA_TYPE_HASH
+ * flags: XEN_NETIF_EXTRA_FLAG_*
+ * htype: Hash type (one of _XEN_NETIF_CTRL_HASH_TYPE_* - see above)
+ * alg: The algorithm used to calculate the hash (one of
+ * XEN_NETIF_CTRL_HASH_TYPE_ALGORITHM_* - see above)
+ * value: Hash value
+ */
+
+/* Protocol checksum field is blank in the packet (hardware offload)? */
+#define _NETTXF_csum_blank (0)
+#define NETTXF_csum_blank (1U<<_NETTXF_csum_blank)
+
+/* Packet data has been validated against protocol checksum. */
+#define _NETTXF_data_validated (1)
+#define NETTXF_data_validated (1U<<_NETTXF_data_validated)
+
+/* Packet continues in the next request descriptor. */
+#define _NETTXF_more_data (2)
+#define NETTXF_more_data (1U<<_NETTXF_more_data)
+
+/* Packet to be followed by extra descriptor(s). */
+#define _NETTXF_extra_info (3)
+#define NETTXF_extra_info (1U<<_NETTXF_extra_info)
+
+#define XEN_NETIF_MAX_TX_SIZE 0xFFFF
+struct netif_tx_request {
+ grant_ref_t gref;
+ uint16_t offset;
+ uint16_t flags;
+ uint16_t id;
+ uint16_t size;
+};
+typedef struct netif_tx_request netif_tx_request_t;
+
+/* Types of netif_extra_info descriptors. */
+#define XEN_NETIF_EXTRA_TYPE_NONE (0) /* Never used - invalid */
+#define XEN_NETIF_EXTRA_TYPE_GSO (1) /* u.gso */
+#define XEN_NETIF_EXTRA_TYPE_MCAST_ADD (2) /* u.mcast */
+#define XEN_NETIF_EXTRA_TYPE_MCAST_DEL (3) /* u.mcast */
+#define XEN_NETIF_EXTRA_TYPE_HASH (4) /* u.hash */
+#define XEN_NETIF_EXTRA_TYPE_MAX (5)
+
+/* netif_extra_info_t flags. */
+#define _XEN_NETIF_EXTRA_FLAG_MORE (0)
+#define XEN_NETIF_EXTRA_FLAG_MORE (1U<<_XEN_NETIF_EXTRA_FLAG_MORE)
+
+/* GSO types */
+#define XEN_NETIF_GSO_TYPE_NONE (0)
+#define XEN_NETIF_GSO_TYPE_TCPV4 (1)
+#define XEN_NETIF_GSO_TYPE_TCPV6 (2)
+
+/*
+ * This structure needs to fit within both netif_tx_request_t and
+ * netif_rx_response_t for compatibility.
+ */
+struct netif_extra_info {
+ uint8_t type;
+ uint8_t flags;
+ union {
+ struct {
+ uint16_t size;
+ uint8_t type;
+ uint8_t pad;
+ uint16_t features;
+ } gso;
+ struct {
+ uint8_t addr[6];
+ } mcast;
+ struct {
+ uint8_t type;
+ uint8_t algorithm;
+ uint8_t value[4];
+ } hash;
+ uint16_t pad[3];
+ } u;
+};
+typedef struct netif_extra_info netif_extra_info_t;
+
+struct netif_tx_response {
+ uint16_t id;
+ int16_t status;
+};
+typedef struct netif_tx_response netif_tx_response_t;
+
+struct netif_rx_request {
+ uint16_t id; /* Echoed in response message. */
+ uint16_t pad;
+ grant_ref_t gref;
+};
+typedef struct netif_rx_request netif_rx_request_t;
+
+/* Packet data has been validated against protocol checksum. */
+#define _NETRXF_data_validated (0)
+#define NETRXF_data_validated (1U<<_NETRXF_data_validated)
+
+/* Protocol checksum field is blank in the packet (hardware offload)? */
+#define _NETRXF_csum_blank (1)
+#define NETRXF_csum_blank (1U<<_NETRXF_csum_blank)
+
+/* Packet continues in the next request descriptor. */
+#define _NETRXF_more_data (2)
+#define NETRXF_more_data (1U<<_NETRXF_more_data)
+
+/* Packet to be followed by extra descriptor(s). */
+#define _NETRXF_extra_info (3)
+#define NETRXF_extra_info (1U<<_NETRXF_extra_info)
+
+/* Packet has GSO prefix. Deprecated but included for compatibility */
+#define _NETRXF_gso_prefix (4)
+#define NETRXF_gso_prefix (1U<<_NETRXF_gso_prefix)
+
+struct netif_rx_response {
+ uint16_t id;
+ uint16_t offset;
+ uint16_t flags;
+ int16_t status;
+};
+typedef struct netif_rx_response netif_rx_response_t;
+
+/*
+ * Generate netif ring structures and types.
+ */
+
+DEFINE_RING_TYPES(netif_tx, struct netif_tx_request, struct netif_tx_response);
+DEFINE_RING_TYPES(netif_rx, struct netif_rx_request, struct netif_rx_response);
+
+#define NETIF_RSP_DROPPED -2
+#define NETIF_RSP_ERROR -1
+#define NETIF_RSP_OKAY 0
+/* No response: used for auxiliary requests (e.g., netif_extra_info_t). */
+#define NETIF_RSP_NULL 1
+
+#endif
--- /dev/null
+/******************************************************************************
+ * protocols.h
+ *
+ * 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.
+ *
+ * Copyright (c) 2008, Keir Fraser
+ */
+
+#ifndef __XEN_PROTOCOLS_H__
+#define __XEN_PROTOCOLS_H__
+
+#define XEN_IO_PROTO_ABI_X86_32 "x86_32-abi"
+#define XEN_IO_PROTO_ABI_X86_64 "x86_64-abi"
+#define XEN_IO_PROTO_ABI_ARM "arm-abi"
+
+#if defined(__i386__)
+# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32
+#elif defined(__x86_64__)
+# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_64
+#elif defined(__arm__) || defined(__aarch64__)
+# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_ARM
+#else
+# error arch fixup needed here
+#endif
+
+#endif
--- /dev/null
+/******************************************************************************
+ * ring.h
+ *
+ * Shared producer-consumer ring macros.
+ *
+ * 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.
+ *
+ * Tim Deegan and Andrew Warfield November 2004.
+ */
+
+#ifndef __XEN_PUBLIC_IO_RING_H__
+#define __XEN_PUBLIC_IO_RING_H__
+
+/*
+ * When #include'ing this header, you need to provide the following
+ * declaration upfront:
+ * - standard integers types (uint8_t, uint16_t, etc)
+ * They are provided by stdint.h of the standard headers.
+ *
+ * In addition, if you intend to use the FLEX macros, you also need to
+ * provide the following, before invoking the FLEX macros:
+ * - size_t
+ * - memcpy
+ * - grant_ref_t
+ * These declarations are provided by string.h of the standard headers,
+ * and grant_table.h from the Xen public headers.
+ */
+
+#if __XEN_INTERFACE_VERSION__ < 0x00030208
+#define xen_mb() mb()
+#define xen_rmb() rmb()
+#define xen_wmb() wmb()
+#endif
+
+typedef unsigned int RING_IDX;
+
+/* Round a 32-bit unsigned constant down to the nearest power of two. */
+#define __RD2(_x) (((_x) & 0x00000002) ? 0x2 : ((_x) & 0x1))
+#define __RD4(_x) (((_x) & 0x0000000c) ? __RD2((_x)>>2)<<2 : __RD2(_x))
+#define __RD8(_x) (((_x) & 0x000000f0) ? __RD4((_x)>>4)<<4 : __RD4(_x))
+#define __RD16(_x) (((_x) & 0x0000ff00) ? __RD8((_x)>>8)<<8 : __RD8(_x))
+#define __RD32(_x) (((_x) & 0xffff0000) ? __RD16((_x)>>16)<<16 : __RD16(_x))
+
+/*
+ * Calculate size of a shared ring, given the total available space for the
+ * ring and indexes (_sz), and the name tag of the request/response structure.
+ * A ring contains as many entries as will fit, rounded down to the nearest
+ * power of two (so we can mask with (size-1) to loop around).
+ */
+#define __CONST_RING_SIZE(_s, _sz) \
+ (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \
+ sizeof_field(struct _s##_sring, ring[0])))
+/*
+ * The same for passing in an actual pointer instead of a name tag.
+ */
+#define __RING_SIZE(_s, _sz) \
+ (__RD32(((_sz) - (long)(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
+
+/*
+ * Macros to make the correct C datatypes for a new kind of ring.
+ *
+ * To make a new ring datatype, you need to have two message structures,
+ * let's say request_t, and response_t already defined.
+ *
+ * In a header where you want the ring datatype declared, you then do:
+ *
+ * DEFINE_RING_TYPES(mytag, request_t, response_t);
+ *
+ * These expand out to give you a set of types, as you can see below.
+ * The most important of these are:
+ *
+ * mytag_sring_t - The shared ring.
+ * mytag_front_ring_t - The 'front' half of the ring.
+ * mytag_back_ring_t - The 'back' half of the ring.
+ *
+ * To initialize a ring in your code you need to know the location and size
+ * of the shared memory area (PAGE_SIZE, for instance). To initialise
+ * the front half:
+ *
+ * mytag_front_ring_t front_ring;
+ * SHARED_RING_INIT((mytag_sring_t *)shared_page);
+ * FRONT_RING_INIT(&front_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
+ *
+ * Initializing the back follows similarly (note that only the front
+ * initializes the shared ring):
+ *
+ * mytag_back_ring_t back_ring;
+ * BACK_RING_INIT(&back_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
+ */
+
+#define DEFINE_RING_TYPES(__name, __req_t, __rsp_t) \
+ \
+/* Shared ring entry */ \
+union __name##_sring_entry { \
+ __req_t req; \
+ __rsp_t rsp; \
+}; \
+ \
+/* Shared ring page */ \
+struct __name##_sring { \
+ RING_IDX req_prod, req_event; \
+ RING_IDX rsp_prod, rsp_event; \
+ union { \
+ struct { \
+ uint8_t smartpoll_active; \
+ } netif; \
+ struct { \
+ uint8_t msg; \
+ } tapif_user; \
+ uint8_t pvt_pad[4]; \
+ } pvt; \
+ uint8_t __pad[44]; \
+ union __name##_sring_entry ring[1]; /* variable-length */ \
+}; \
+ \
+/* "Front" end's private variables */ \
+struct __name##_front_ring { \
+ RING_IDX req_prod_pvt; \
+ RING_IDX rsp_cons; \
+ unsigned int nr_ents; \
+ struct __name##_sring *sring; \
+}; \
+ \
+/* "Back" end's private variables */ \
+struct __name##_back_ring { \
+ RING_IDX rsp_prod_pvt; \
+ RING_IDX req_cons; \
+ unsigned int nr_ents; \
+ struct __name##_sring *sring; \
+}; \
+ \
+/* Syntactic sugar */ \
+typedef struct __name##_sring __name##_sring_t; \
+typedef struct __name##_front_ring __name##_front_ring_t; \
+typedef struct __name##_back_ring __name##_back_ring_t
+
+/*
+ * Macros for manipulating rings.
+ *
+ * FRONT_RING_whatever works on the "front end" of a ring: here
+ * requests are pushed on to the ring and responses taken off it.
+ *
+ * BACK_RING_whatever works on the "back end" of a ring: here
+ * requests are taken off the ring and responses put on.
+ *
+ * N.B. these macros do NO INTERLOCKS OR FLOW CONTROL.
+ * This is OK in 1-for-1 request-response situations where the
+ * requestor (front end) never has more than RING_SIZE()-1
+ * outstanding requests.
+ */
+
+/* Initialising empty rings */
+#define SHARED_RING_INIT(_s) do { \
+ (_s)->req_prod = (_s)->rsp_prod = 0; \
+ (_s)->req_event = (_s)->rsp_event = 1; \
+ (void)memset((_s)->pvt.pvt_pad, 0, sizeof((_s)->pvt.pvt_pad)); \
+ (void)memset((_s)->__pad, 0, sizeof((_s)->__pad)); \
+} while(0)
+
+#define FRONT_RING_INIT(_r, _s, __size) do { \
+ (_r)->req_prod_pvt = 0; \
+ (_r)->rsp_cons = 0; \
+ (_r)->nr_ents = __RING_SIZE(_s, __size); \
+ (_r)->sring = (_s); \
+} while (0)
+
+#define BACK_RING_INIT(_r, _s, __size) do { \
+ (_r)->rsp_prod_pvt = 0; \
+ (_r)->req_cons = 0; \
+ (_r)->nr_ents = __RING_SIZE(_s, __size); \
+ (_r)->sring = (_s); \
+} while (0)
+
+/* How big is this ring? */
+#define RING_SIZE(_r) \
+ ((_r)->nr_ents)
+
+/* Number of free requests (for use on front side only). */
+#define RING_FREE_REQUESTS(_r) \
+ (RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons))
+
+/* Test if there is an empty slot available on the front ring.
+ * (This is only meaningful from the front. )
+ */
+#define RING_FULL(_r) \
+ (RING_FREE_REQUESTS(_r) == 0)
+
+/* Test if there are outstanding messages to be processed on a ring. */
+#define RING_HAS_UNCONSUMED_RESPONSES(_r) \
+ ((_r)->sring->rsp_prod - (_r)->rsp_cons)
+
+#ifdef __GNUC__
+#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({ \
+ unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \
+ unsigned int rsp = RING_SIZE(_r) - \
+ ((_r)->req_cons - (_r)->rsp_prod_pvt); \
+ req < rsp ? req : rsp; \
+})
+#else
+/* Same as above, but without the nice GCC ({ ... }) syntax. */
+#define RING_HAS_UNCONSUMED_REQUESTS(_r) \
+ ((((_r)->sring->req_prod - (_r)->req_cons) < \
+ (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) ? \
+ ((_r)->sring->req_prod - (_r)->req_cons) : \
+ (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt)))
+#endif
+
+/* Direct access to individual ring elements, by index. */
+#define RING_GET_REQUEST(_r, _idx) \
+ (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
+
+/*
+ * Get a local copy of a request.
+ *
+ * Use this in preference to RING_GET_REQUEST() so all processing is
+ * done on a local copy that cannot be modified by the other end.
+ *
+ * Note that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 may cause this
+ * to be ineffective where _req is a struct which consists of only bitfields.
+ */
+#define RING_COPY_REQUEST(_r, _idx, _req) do { \
+ /* Use volatile to force the copy into _req. */ \
+ *(_req) = *(volatile typeof(_req))RING_GET_REQUEST(_r, _idx); \
+} while (0)
+
+#define RING_GET_RESPONSE(_r, _idx) \
+ (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
+
+/* Loop termination condition: Would the specified index overflow the ring? */
+#define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \
+ (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
+
+/* Ill-behaved frontend determination: Can there be this many requests? */
+#define RING_REQUEST_PROD_OVERFLOW(_r, _prod) \
+ (((_prod) - (_r)->rsp_prod_pvt) > RING_SIZE(_r))
+
+#define RING_PUSH_REQUESTS(_r) do { \
+ xen_wmb(); /* back sees requests /before/ updated producer index */ \
+ (_r)->sring->req_prod = (_r)->req_prod_pvt; \
+} while (0)
+
+#define RING_PUSH_RESPONSES(_r) do { \
+ xen_wmb(); /* front sees resps /before/ updated producer index */ \
+ (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt; \
+} while (0)
+
+/*
+ * Notification hold-off (req_event and rsp_event):
+ *
+ * When queueing requests or responses on a shared ring, it may not always be
+ * necessary to notify the remote end. For example, if requests are in flight
+ * in a backend, the front may be able to queue further requests without
+ * notifying the back (if the back checks for new requests when it queues
+ * responses).
+ *
+ * When enqueuing requests or responses:
+ *
+ * Use RING_PUSH_{REQUESTS,RESPONSES}_AND_CHECK_NOTIFY(). The second argument
+ * is a boolean return value. True indicates that the receiver requires an
+ * asynchronous notification.
+ *
+ * After dequeuing requests or responses (before sleeping the connection):
+ *
+ * Use RING_FINAL_CHECK_FOR_REQUESTS() or RING_FINAL_CHECK_FOR_RESPONSES().
+ * The second argument is a boolean return value. True indicates that there
+ * are pending messages on the ring (i.e., the connection should not be put
+ * to sleep).
+ *
+ * These macros will set the req_event/rsp_event field to trigger a
+ * notification on the very next message that is enqueued. If you want to
+ * create batches of work (i.e., only receive a notification after several
+ * messages have been enqueued) then you will need to create a customised
+ * version of the FINAL_CHECK macro in your own code, which sets the event
+ * field appropriately.
+ */
+
+#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify) do { \
+ RING_IDX __old = (_r)->sring->req_prod; \
+ RING_IDX __new = (_r)->req_prod_pvt; \
+ xen_wmb(); /* back sees requests /before/ updated producer index */ \
+ (_r)->sring->req_prod = __new; \
+ xen_mb(); /* back sees new requests /before/ we check req_event */ \
+ (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) < \
+ (RING_IDX)(__new - __old)); \
+} while (0)
+
+#define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify) do { \
+ RING_IDX __old = (_r)->sring->rsp_prod; \
+ RING_IDX __new = (_r)->rsp_prod_pvt; \
+ xen_wmb(); /* front sees resps /before/ updated producer index */ \
+ (_r)->sring->rsp_prod = __new; \
+ xen_mb(); /* front sees new resps /before/ we check rsp_event */ \
+ (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) < \
+ (RING_IDX)(__new - __old)); \
+} while (0)
+
+#define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do) do { \
+ (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
+ if (_work_to_do) break; \
+ (_r)->sring->req_event = (_r)->req_cons + 1; \
+ xen_mb(); \
+ (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
+} while (0)
+
+#define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do) do { \
+ (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
+ if (_work_to_do) break; \
+ (_r)->sring->rsp_event = (_r)->rsp_cons + 1; \
+ xen_mb(); \
+ (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
+} while (0)
+
+
+/*
+ * DEFINE_XEN_FLEX_RING_AND_INTF defines two monodirectional rings and
+ * functions to check if there is data on the ring, and to read and
+ * write to them.
+ *
+ * DEFINE_XEN_FLEX_RING is similar to DEFINE_XEN_FLEX_RING_AND_INTF, but
+ * does not define the indexes page. As different protocols can have
+ * extensions to the basic format, this macro allow them to define their
+ * own struct.
+ *
+ * XEN_FLEX_RING_SIZE
+ * Convenience macro to calculate the size of one of the two rings
+ * from the overall order.
+ *
+ * $NAME_mask
+ * Function to apply the size mask to an index, to reduce the index
+ * within the range [0-size].
+ *
+ * $NAME_read_packet
+ * Function to read data from the ring. The amount of data to read is
+ * specified by the "size" argument.
+ *
+ * $NAME_write_packet
+ * Function to write data to the ring. The amount of data to write is
+ * specified by the "size" argument.
+ *
+ * $NAME_get_ring_ptr
+ * Convenience function that returns a pointer to read/write to the
+ * ring at the right location.
+ *
+ * $NAME_data_intf
+ * Indexes page, shared between frontend and backend. It also
+ * contains the array of grant refs.
+ *
+ * $NAME_queued
+ * Function to calculate how many bytes are currently on the ring,
+ * ready to be read. It can also be used to calculate how much free
+ * space is currently on the ring (XEN_FLEX_RING_SIZE() -
+ * $NAME_queued()).
+ */
+
+#ifndef XEN_PAGE_SHIFT
+/* The PAGE_SIZE for ring protocols and hypercall interfaces is always
+ * 4K, regardless of the architecture, and page granularity chosen by
+ * operating systems.
+ */
+#define XEN_PAGE_SHIFT 12
+#endif
+#define XEN_FLEX_RING_SIZE(order) \
+ (1UL << ((order) + XEN_PAGE_SHIFT - 1))
+
+#define DEFINE_XEN_FLEX_RING(name) \
+static inline RING_IDX name##_mask(RING_IDX idx, RING_IDX ring_size) \
+{ \
+ return idx & (ring_size - 1); \
+} \
+ \
+static inline unsigned char *name##_get_ring_ptr(unsigned char *buf, \
+ RING_IDX idx, \
+ RING_IDX ring_size) \
+{ \
+ return buf + name##_mask(idx, ring_size); \
+} \
+ \
+static inline void name##_read_packet(void *opaque, \
+ const unsigned char *buf, \
+ size_t size, \
+ RING_IDX masked_prod, \
+ RING_IDX *masked_cons, \
+ RING_IDX ring_size) \
+{ \
+ if (*masked_cons < masked_prod || \
+ size <= ring_size - *masked_cons) { \
+ memcpy(opaque, buf + *masked_cons, size); \
+ } else { \
+ memcpy(opaque, buf + *masked_cons, ring_size - *masked_cons); \
+ memcpy((unsigned char *)opaque + ring_size - *masked_cons, buf, \
+ size - (ring_size - *masked_cons)); \
+ } \
+ *masked_cons = name##_mask(*masked_cons + size, ring_size); \
+} \
+ \
+static inline void name##_write_packet(unsigned char *buf, \
+ const void *opaque, \
+ size_t size, \
+ RING_IDX *masked_prod, \
+ RING_IDX masked_cons, \
+ RING_IDX ring_size) \
+{ \
+ if (*masked_prod < masked_cons || \
+ size <= ring_size - *masked_prod) { \
+ memcpy(buf + *masked_prod, opaque, size); \
+ } else { \
+ memcpy(buf + *masked_prod, opaque, ring_size - *masked_prod); \
+ memcpy(buf, (unsigned char *)opaque + (ring_size - *masked_prod), \
+ size - (ring_size - *masked_prod)); \
+ } \
+ *masked_prod = name##_mask(*masked_prod + size, ring_size); \
+} \
+ \
+static inline RING_IDX name##_queued(RING_IDX prod, \
+ RING_IDX cons, \
+ RING_IDX ring_size) \
+{ \
+ RING_IDX size; \
+ \
+ if (prod == cons) \
+ return 0; \
+ \
+ prod = name##_mask(prod, ring_size); \
+ cons = name##_mask(cons, ring_size); \
+ \
+ if (prod == cons) \
+ return ring_size; \
+ \
+ if (prod > cons) \
+ size = prod - cons; \
+ else \
+ size = ring_size - (cons - prod); \
+ return size; \
+} \
+ \
+struct name##_data { \
+ unsigned char *in; /* half of the allocation */ \
+ unsigned char *out; /* half of the allocation */ \
+}
+
+#define DEFINE_XEN_FLEX_RING_AND_INTF(name) \
+struct name##_data_intf { \
+ RING_IDX in_cons, in_prod; \
+ \
+ uint8_t pad1[56]; \
+ \
+ RING_IDX out_cons, out_prod; \
+ \
+ uint8_t pad2[56]; \
+ \
+ RING_IDX ring_order; \
+ grant_ref_t ref[]; \
+}; \
+DEFINE_XEN_FLEX_RING(name)
+
+#endif /* __XEN_PUBLIC_IO_RING_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+/*
+ * usbif.h
+ *
+ * USB I/O interface for Xen guest OSes.
+ *
+ * Copyright (C) 2009, FUJITSU LABORATORIES LTD.
+ * Author: Noboru Iwamatsu <n_iwamatsu@jp.fujitsu.com>
+ *
+ * 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.
+ */
+
+#ifndef __XEN_PUBLIC_IO_USBIF_H__
+#define __XEN_PUBLIC_IO_USBIF_H__
+
+#include "ring.h"
+#include "../grant_table.h"
+
+/*
+ * Feature and Parameter Negotiation
+ * =================================
+ * The two halves of a Xen pvUSB driver utilize nodes within the XenStore to
+ * communicate capabilities and to negotiate operating parameters. This
+ * section enumerates these nodes which reside in the respective front and
+ * backend portions of the XenStore, following the XenBus convention.
+ *
+ * Any specified default value is in effect if the corresponding XenBus node
+ * is not present in the XenStore.
+ *
+ * XenStore nodes in sections marked "PRIVATE" are solely for use by the
+ * driver side whose XenBus tree contains them.
+ *
+ *****************************************************************************
+ * Backend XenBus Nodes
+ *****************************************************************************
+ *
+ *------------------ Backend Device Identification (PRIVATE) ------------------
+ *
+ * num-ports
+ * Values: unsigned [1...31]
+ *
+ * Number of ports for this (virtual) USB host connector.
+ *
+ * usb-ver
+ * Values: unsigned [1...2]
+ *
+ * USB version of this host connector: 1 = USB 1.1, 2 = USB 2.0.
+ *
+ * port/[1...31]
+ * Values: string
+ *
+ * Physical USB device connected to the given port, e.g. "3-1.5".
+ *
+ *****************************************************************************
+ * Frontend XenBus Nodes
+ *****************************************************************************
+ *
+ *----------------------- Request Transport Parameters -----------------------
+ *
+ * event-channel
+ * Values: unsigned
+ *
+ * The identifier of the Xen event channel used to signal activity
+ * in the ring buffer.
+ *
+ * urb-ring-ref
+ * Values: unsigned
+ *
+ * The Xen grant reference granting permission for the backend to map
+ * the sole page in a single page sized ring buffer. This is the ring
+ * buffer for urb requests.
+ *
+ * conn-ring-ref
+ * Values: unsigned
+ *
+ * The Xen grant reference granting permission for the backend to map
+ * the sole page in a single page sized ring buffer. This is the ring
+ * buffer for connection/disconnection requests.
+ *
+ * protocol
+ * Values: string (XEN_IO_PROTO_ABI_*)
+ * Default Value: XEN_IO_PROTO_ABI_NATIVE
+ *
+ * The machine ABI rules governing the format of all ring request and
+ * response structures.
+ *
+ */
+
+enum usb_spec_version {
+ USB_VER_UNKNOWN = 0,
+ USB_VER_USB11,
+ USB_VER_USB20,
+ USB_VER_USB30, /* not supported yet */
+};
+
+/*
+ * USB pipe in usbif_request
+ *
+ * - port number: bits 0-4
+ * (USB_MAXCHILDREN is 31)
+ *
+ * - operation flag: bit 5
+ * (0 = submit urb,
+ * 1 = unlink urb)
+ *
+ * - direction: bit 7
+ * (0 = Host-to-Device [Out]
+ * 1 = Device-to-Host [In])
+ *
+ * - device address: bits 8-14
+ *
+ * - endpoint: bits 15-18
+ *
+ * - pipe type: bits 30-31
+ * (00 = isochronous, 01 = interrupt,
+ * 10 = control, 11 = bulk)
+ */
+
+#define USBIF_PIPE_PORT_MASK 0x0000001f
+#define USBIF_PIPE_UNLINK 0x00000020
+#define USBIF_PIPE_DIR 0x00000080
+#define USBIF_PIPE_DEV_MASK 0x0000007f
+#define USBIF_PIPE_DEV_SHIFT 8
+#define USBIF_PIPE_EP_MASK 0x0000000f
+#define USBIF_PIPE_EP_SHIFT 15
+#define USBIF_PIPE_TYPE_MASK 0x00000003
+#define USBIF_PIPE_TYPE_SHIFT 30
+#define USBIF_PIPE_TYPE_ISOC 0
+#define USBIF_PIPE_TYPE_INT 1
+#define USBIF_PIPE_TYPE_CTRL 2
+#define USBIF_PIPE_TYPE_BULK 3
+
+#define usbif_pipeportnum(pipe) ((pipe) & USBIF_PIPE_PORT_MASK)
+#define usbif_setportnum_pipe(pipe, portnum) ((pipe) | (portnum))
+
+#define usbif_pipeunlink(pipe) ((pipe) & USBIF_PIPE_UNLINK)
+#define usbif_pipesubmit(pipe) (!usbif_pipeunlink(pipe))
+#define usbif_setunlink_pipe(pipe) ((pipe) | USBIF_PIPE_UNLINK)
+
+#define usbif_pipein(pipe) ((pipe) & USBIF_PIPE_DIR)
+#define usbif_pipeout(pipe) (!usbif_pipein(pipe))
+
+#define usbif_pipedevice(pipe) \
+ (((pipe) >> USBIF_PIPE_DEV_SHIFT) & USBIF_PIPE_DEV_MASK)
+
+#define usbif_pipeendpoint(pipe) \
+ (((pipe) >> USBIF_PIPE_EP_SHIFT) & USBIF_PIPE_EP_MASK)
+
+#define usbif_pipetype(pipe) \
+ (((pipe) >> USBIF_PIPE_TYPE_SHIFT) & USBIF_PIPE_TYPE_MASK)
+#define usbif_pipeisoc(pipe) (usbif_pipetype(pipe) == USBIF_PIPE_TYPE_ISOC)
+#define usbif_pipeint(pipe) (usbif_pipetype(pipe) == USBIF_PIPE_TYPE_INT)
+#define usbif_pipectrl(pipe) (usbif_pipetype(pipe) == USBIF_PIPE_TYPE_CTRL)
+#define usbif_pipebulk(pipe) (usbif_pipetype(pipe) == USBIF_PIPE_TYPE_BULK)
+
+#define USBIF_MAX_SEGMENTS_PER_REQUEST (16)
+#define USBIF_MAX_PORTNR 31
+#define USBIF_RING_SIZE 4096
+
+/*
+ * RING for transferring urbs.
+ */
+struct usbif_request_segment {
+ grant_ref_t gref;
+ uint16_t offset;
+ uint16_t length;
+};
+
+struct usbif_urb_request {
+ uint16_t id; /* request id */
+ uint16_t nr_buffer_segs; /* number of urb->transfer_buffer segments */
+
+ /* basic urb parameter */
+ uint32_t pipe;
+ uint16_t transfer_flags;
+#define USBIF_SHORT_NOT_OK 0x0001
+ uint16_t buffer_length;
+ union {
+ uint8_t ctrl[8]; /* setup_packet (Ctrl) */
+
+ struct {
+ uint16_t interval; /* maximum (1024*8) in usb core */
+ uint16_t start_frame; /* start frame */
+ uint16_t number_of_packets; /* number of ISO packet */
+ uint16_t nr_frame_desc_segs; /* number of iso_frame_desc segments */
+ } isoc;
+
+ struct {
+ uint16_t interval; /* maximum (1024*8) in usb core */
+ uint16_t pad[3];
+ } intr;
+
+ struct {
+ uint16_t unlink_id; /* unlink request id */
+ uint16_t pad[3];
+ } unlink;
+
+ } u;
+
+ /* urb data segments */
+ struct usbif_request_segment seg[USBIF_MAX_SEGMENTS_PER_REQUEST];
+};
+typedef struct usbif_urb_request usbif_urb_request_t;
+
+struct usbif_urb_response {
+ uint16_t id; /* request id */
+ uint16_t start_frame; /* start frame (ISO) */
+ int32_t status; /* status (non-ISO) */
+ int32_t actual_length; /* actual transfer length */
+ int32_t error_count; /* number of ISO errors */
+};
+typedef struct usbif_urb_response usbif_urb_response_t;
+
+DEFINE_RING_TYPES(usbif_urb, struct usbif_urb_request, struct usbif_urb_response);
+#define USB_URB_RING_SIZE __CONST_RING_SIZE(usbif_urb, USBIF_RING_SIZE)
+
+/*
+ * RING for notifying connect/disconnect events to frontend
+ */
+struct usbif_conn_request {
+ uint16_t id;
+};
+typedef struct usbif_conn_request usbif_conn_request_t;
+
+struct usbif_conn_response {
+ uint16_t id; /* request id */
+ uint8_t portnum; /* port number */
+ uint8_t speed; /* usb_device_speed */
+#define USBIF_SPEED_NONE 0
+#define USBIF_SPEED_LOW 1
+#define USBIF_SPEED_FULL 2
+#define USBIF_SPEED_HIGH 3
+};
+typedef struct usbif_conn_response usbif_conn_response_t;
+
+DEFINE_RING_TYPES(usbif_conn, struct usbif_conn_request, struct usbif_conn_response);
+#define USB_CONN_RING_SIZE __CONST_RING_SIZE(usbif_conn, USBIF_RING_SIZE)
+
+#endif /* __XEN_PUBLIC_IO_USBIF_H__ */
--- /dev/null
+/*****************************************************************************
+ * xenbus.h
+ *
+ * Xenbus protocol details.
+ *
+ * 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.
+ *
+ * Copyright (C) 2005 XenSource Ltd.
+ */
+
+#ifndef _XEN_PUBLIC_IO_XENBUS_H
+#define _XEN_PUBLIC_IO_XENBUS_H
+
+/*
+ * The state of either end of the Xenbus, i.e. the current communication
+ * status of initialisation across the bus. States here imply nothing about
+ * the state of the connection between the driver and the kernel's device
+ * layers.
+ */
+enum xenbus_state {
+ XenbusStateUnknown = 0,
+
+ XenbusStateInitialising = 1,
+
+ /*
+ * InitWait: Finished early initialisation but waiting for information
+ * from the peer or hotplug scripts.
+ */
+ XenbusStateInitWait = 2,
+
+ /*
+ * Initialised: Waiting for a connection from the peer.
+ */
+ XenbusStateInitialised = 3,
+
+ XenbusStateConnected = 4,
+
+ /*
+ * Closing: The device is being closed due to an error or an unplug event.
+ */
+ XenbusStateClosing = 5,
+
+ XenbusStateClosed = 6,
+
+ /*
+ * Reconfiguring: The device is being reconfigured.
+ */
+ XenbusStateReconfiguring = 7,
+
+ XenbusStateReconfigured = 8
+};
+typedef enum xenbus_state XenbusState;
+
+#endif /* _XEN_PUBLIC_IO_XENBUS_H */
+++ /dev/null
-/******************************************************************************
- * ring.h
- *
- * Shared producer-consumer ring macros.
- *
- * 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.
- *
- * Tim Deegan and Andrew Warfield November 2004.
- */
-
-#ifndef XEN_PUBLIC_IO_RING_H
-#define XEN_PUBLIC_IO_RING_H
-
-/*
- * When #include'ing this header, you need to provide the following
- * declaration upfront:
- * - standard integers types (uint8_t, uint16_t, etc)
- * They are provided by stdint.h of the standard headers.
- *
- * In addition, if you intend to use the FLEX macros, you also need to
- * provide the following, before invoking the FLEX macros:
- * - size_t
- * - memcpy
- * - grant_ref_t
- * These declarations are provided by string.h of the standard headers,
- * and grant_table.h from the Xen public headers.
- */
-
-#if __XEN_INTERFACE_VERSION__ < 0x00030208
-#define xen_mb() mb()
-#define xen_rmb() rmb()
-#define xen_wmb() wmb()
-#endif
-
-typedef unsigned int RING_IDX;
-
-/* Round a 32-bit unsigned constant down to the nearest power of two. */
-#define __RD2(_x) (((_x) & 0x00000002) ? 0x2 : ((_x) & 0x1))
-#define __RD4(_x) (((_x) & 0x0000000c) ? __RD2((_x)>>2)<<2 : __RD2(_x))
-#define __RD8(_x) (((_x) & 0x000000f0) ? __RD4((_x)>>4)<<4 : __RD4(_x))
-#define __RD16(_x) (((_x) & 0x0000ff00) ? __RD8((_x)>>8)<<8 : __RD8(_x))
-#define __RD32(_x) (((_x) & 0xffff0000) ? __RD16((_x)>>16)<<16 : __RD16(_x))
-
-/*
- * Calculate size of a shared ring, given the total available space for the
- * ring and indexes (_sz), and the name tag of the request/response structure.
- * A ring contains as many entries as will fit, rounded down to the nearest
- * power of two (so we can mask with (size-1) to loop around).
- */
-#define __CONST_RING_SIZE(_s, _sz) \
- (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \
- sizeof_field(struct _s##_sring, ring[0])))
-/*
- * The same for passing in an actual pointer instead of a name tag.
- */
-#define __RING_SIZE(_s, _sz) \
- (__RD32(((_sz) - (long)(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
-
-/*
- * Macros to make the correct C datatypes for a new kind of ring.
- *
- * To make a new ring datatype, you need to have two message structures,
- * let's say request_t, and response_t already defined.
- *
- * In a header where you want the ring datatype declared, you then do:
- *
- * DEFINE_RING_TYPES(mytag, request_t, response_t);
- *
- * These expand out to give you a set of types, as you can see below.
- * The most important of these are:
- *
- * mytag_sring_t - The shared ring.
- * mytag_front_ring_t - The 'front' half of the ring.
- * mytag_back_ring_t - The 'back' half of the ring.
- *
- * To initialize a ring in your code you need to know the location and size
- * of the shared memory area (PAGE_SIZE, for instance). To initialise
- * the front half:
- *
- * mytag_front_ring_t front_ring;
- * SHARED_RING_INIT((mytag_sring_t *)shared_page);
- * FRONT_RING_INIT(&front_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
- *
- * Initializing the back follows similarly (note that only the front
- * initializes the shared ring):
- *
- * mytag_back_ring_t back_ring;
- * BACK_RING_INIT(&back_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
- */
-
-#define DEFINE_RING_TYPES(__name, __req_t, __rsp_t) \
- \
-/* Shared ring entry */ \
-union __name##_sring_entry { \
- __req_t req; \
- __rsp_t rsp; \
-}; \
- \
-/* Shared ring page */ \
-struct __name##_sring { \
- RING_IDX req_prod, req_event; \
- RING_IDX rsp_prod, rsp_event; \
- union { \
- struct { \
- uint8_t smartpoll_active; \
- } netif; \
- struct { \
- uint8_t msg; \
- } tapif_user; \
- uint8_t pvt_pad[4]; \
- } pvt; \
- uint8_t __pad[44]; \
- union __name##_sring_entry ring[1]; /* variable-length */ \
-}; \
- \
-/* "Front" end's private variables */ \
-struct __name##_front_ring { \
- RING_IDX req_prod_pvt; \
- RING_IDX rsp_cons; \
- unsigned int nr_ents; \
- struct __name##_sring *sring; \
-}; \
- \
-/* "Back" end's private variables */ \
-struct __name##_back_ring { \
- RING_IDX rsp_prod_pvt; \
- RING_IDX req_cons; \
- unsigned int nr_ents; \
- struct __name##_sring *sring; \
-}; \
- \
-/* Syntactic sugar */ \
-typedef struct __name##_sring __name##_sring_t; \
-typedef struct __name##_front_ring __name##_front_ring_t; \
-typedef struct __name##_back_ring __name##_back_ring_t
-
-/*
- * Macros for manipulating rings.
- *
- * FRONT_RING_whatever works on the "front end" of a ring: here
- * requests are pushed on to the ring and responses taken off it.
- *
- * BACK_RING_whatever works on the "back end" of a ring: here
- * requests are taken off the ring and responses put on.
- *
- * N.B. these macros do NO INTERLOCKS OR FLOW CONTROL.
- * This is OK in 1-for-1 request-response situations where the
- * requestor (front end) never has more than RING_SIZE()-1
- * outstanding requests.
- */
-
-/* Initialising empty rings */
-#define SHARED_RING_INIT(_s) do { \
- (_s)->req_prod = (_s)->rsp_prod = 0; \
- (_s)->req_event = (_s)->rsp_event = 1; \
- (void)memset((_s)->pvt.pvt_pad, 0, sizeof((_s)->pvt.pvt_pad)); \
- (void)memset((_s)->__pad, 0, sizeof((_s)->__pad)); \
-} while(0)
-
-#define FRONT_RING_INIT(_r, _s, __size) do { \
- (_r)->req_prod_pvt = 0; \
- (_r)->rsp_cons = 0; \
- (_r)->nr_ents = __RING_SIZE(_s, __size); \
- (_r)->sring = (_s); \
-} while (0)
-
-#define BACK_RING_INIT(_r, _s, __size) do { \
- (_r)->rsp_prod_pvt = 0; \
- (_r)->req_cons = 0; \
- (_r)->nr_ents = __RING_SIZE(_s, __size); \
- (_r)->sring = (_s); \
-} while (0)
-
-/* How big is this ring? */
-#define RING_SIZE(_r) \
- ((_r)->nr_ents)
-
-/* Number of free requests (for use on front side only). */
-#define RING_FREE_REQUESTS(_r) \
- (RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons))
-
-/* Test if there is an empty slot available on the front ring.
- * (This is only meaningful from the front. )
- */
-#define RING_FULL(_r) \
- (RING_FREE_REQUESTS(_r) == 0)
-
-/* Test if there are outstanding messages to be processed on a ring. */
-#define RING_HAS_UNCONSUMED_RESPONSES(_r) \
- ((_r)->sring->rsp_prod - (_r)->rsp_cons)
-
-#ifdef __GNUC__
-#define RING_HAS_UNCONSUMED_REQUESTS(_r) ({ \
- unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \
- unsigned int rsp = RING_SIZE(_r) - \
- ((_r)->req_cons - (_r)->rsp_prod_pvt); \
- req < rsp ? req : rsp; \
-})
-#else
-/* Same as above, but without the nice GCC ({ ... }) syntax. */
-#define RING_HAS_UNCONSUMED_REQUESTS(_r) \
- ((((_r)->sring->req_prod - (_r)->req_cons) < \
- (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) ? \
- ((_r)->sring->req_prod - (_r)->req_cons) : \
- (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt)))
-#endif
-
-/* Direct access to individual ring elements, by index. */
-#define RING_GET_REQUEST(_r, _idx) \
- (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
-
-/*
- * Get a local copy of a request.
- *
- * Use this in preference to RING_GET_REQUEST() so all processing is
- * done on a local copy that cannot be modified by the other end.
- *
- * Note that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 may cause this
- * to be ineffective where _req is a struct which consists of only bitfields.
- */
-#define RING_COPY_REQUEST(_r, _idx, _req) do { \
- /* Use volatile to force the copy into _req. */ \
- *(_req) = *(volatile typeof(_req))RING_GET_REQUEST(_r, _idx); \
-} while (0)
-
-#define RING_GET_RESPONSE(_r, _idx) \
- (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
-
-/* Loop termination condition: Would the specified index overflow the ring? */
-#define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \
- (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
-
-/* Ill-behaved frontend determination: Can there be this many requests? */
-#define RING_REQUEST_PROD_OVERFLOW(_r, _prod) \
- (((_prod) - (_r)->rsp_prod_pvt) > RING_SIZE(_r))
-
-#define RING_PUSH_REQUESTS(_r) do { \
- xen_wmb(); /* back sees requests /before/ updated producer index */ \
- (_r)->sring->req_prod = (_r)->req_prod_pvt; \
-} while (0)
-
-#define RING_PUSH_RESPONSES(_r) do { \
- xen_wmb(); /* front sees resps /before/ updated producer index */ \
- (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt; \
-} while (0)
-
-/*
- * Notification hold-off (req_event and rsp_event):
- *
- * When queueing requests or responses on a shared ring, it may not always be
- * necessary to notify the remote end. For example, if requests are in flight
- * in a backend, the front may be able to queue further requests without
- * notifying the back (if the back checks for new requests when it queues
- * responses).
- *
- * When enqueuing requests or responses:
- *
- * Use RING_PUSH_{REQUESTS,RESPONSES}_AND_CHECK_NOTIFY(). The second argument
- * is a boolean return value. True indicates that the receiver requires an
- * asynchronous notification.
- *
- * After dequeuing requests or responses (before sleeping the connection):
- *
- * Use RING_FINAL_CHECK_FOR_REQUESTS() or RING_FINAL_CHECK_FOR_RESPONSES().
- * The second argument is a boolean return value. True indicates that there
- * are pending messages on the ring (i.e., the connection should not be put
- * to sleep).
- *
- * These macros will set the req_event/rsp_event field to trigger a
- * notification on the very next message that is enqueued. If you want to
- * create batches of work (i.e., only receive a notification after several
- * messages have been enqueued) then you will need to create a customised
- * version of the FINAL_CHECK macro in your own code, which sets the event
- * field appropriately.
- */
-
-#define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify) do { \
- RING_IDX __old = (_r)->sring->req_prod; \
- RING_IDX __new = (_r)->req_prod_pvt; \
- xen_wmb(); /* back sees requests /before/ updated producer index */ \
- (_r)->sring->req_prod = __new; \
- xen_mb(); /* back sees new requests /before/ we check req_event */ \
- (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) < \
- (RING_IDX)(__new - __old)); \
-} while (0)
-
-#define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify) do { \
- RING_IDX __old = (_r)->sring->rsp_prod; \
- RING_IDX __new = (_r)->rsp_prod_pvt; \
- xen_wmb(); /* front sees resps /before/ updated producer index */ \
- (_r)->sring->rsp_prod = __new; \
- xen_mb(); /* front sees new resps /before/ we check rsp_event */ \
- (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) < \
- (RING_IDX)(__new - __old)); \
-} while (0)
-
-#define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do) do { \
- (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
- if (_work_to_do) break; \
- (_r)->sring->req_event = (_r)->req_cons + 1; \
- xen_mb(); \
- (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
-} while (0)
-
-#define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do) do { \
- (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
- if (_work_to_do) break; \
- (_r)->sring->rsp_event = (_r)->rsp_cons + 1; \
- xen_mb(); \
- (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
-} while (0)
-
-
-/*
- * DEFINE_XEN_FLEX_RING_AND_INTF defines two monodirectional rings and
- * functions to check if there is data on the ring, and to read and
- * write to them.
- *
- * DEFINE_XEN_FLEX_RING is similar to DEFINE_XEN_FLEX_RING_AND_INTF, but
- * does not define the indexes page. As different protocols can have
- * extensions to the basic format, this macro allow them to define their
- * own struct.
- *
- * XEN_FLEX_RING_SIZE
- * Convenience macro to calculate the size of one of the two rings
- * from the overall order.
- *
- * $NAME_mask
- * Function to apply the size mask to an index, to reduce the index
- * within the range [0-size].
- *
- * $NAME_read_packet
- * Function to read data from the ring. The amount of data to read is
- * specified by the "size" argument.
- *
- * $NAME_write_packet
- * Function to write data to the ring. The amount of data to write is
- * specified by the "size" argument.
- *
- * $NAME_get_ring_ptr
- * Convenience function that returns a pointer to read/write to the
- * ring at the right location.
- *
- * $NAME_data_intf
- * Indexes page, shared between frontend and backend. It also
- * contains the array of grant refs.
- *
- * $NAME_queued
- * Function to calculate how many bytes are currently on the ring,
- * ready to be read. It can also be used to calculate how much free
- * space is currently on the ring (XEN_FLEX_RING_SIZE() -
- * $NAME_queued()).
- */
-
-#ifndef XEN_PAGE_SHIFT
-/* The PAGE_SIZE for ring protocols and hypercall interfaces is always
- * 4K, regardless of the architecture, and page granularity chosen by
- * operating systems.
- */
-#define XEN_PAGE_SHIFT 12
-#endif
-#define XEN_FLEX_RING_SIZE(order) \
- (1UL << ((order) + XEN_PAGE_SHIFT - 1))
-
-#define DEFINE_XEN_FLEX_RING(name) \
-static inline RING_IDX name##_mask(RING_IDX idx, RING_IDX ring_size) \
-{ \
- return idx & (ring_size - 1); \
-} \
- \
-static inline unsigned char *name##_get_ring_ptr(unsigned char *buf, \
- RING_IDX idx, \
- RING_IDX ring_size) \
-{ \
- return buf + name##_mask(idx, ring_size); \
-} \
- \
-static inline void name##_read_packet(void *opaque, \
- const unsigned char *buf, \
- size_t size, \
- RING_IDX masked_prod, \
- RING_IDX *masked_cons, \
- RING_IDX ring_size) \
-{ \
- if (*masked_cons < masked_prod || \
- size <= ring_size - *masked_cons) { \
- memcpy(opaque, buf + *masked_cons, size); \
- } else { \
- memcpy(opaque, buf + *masked_cons, ring_size - *masked_cons); \
- memcpy((unsigned char *)opaque + ring_size - *masked_cons, buf, \
- size - (ring_size - *masked_cons)); \
- } \
- *masked_cons = name##_mask(*masked_cons + size, ring_size); \
-} \
- \
-static inline void name##_write_packet(unsigned char *buf, \
- const void *opaque, \
- size_t size, \
- RING_IDX *masked_prod, \
- RING_IDX masked_cons, \
- RING_IDX ring_size) \
-{ \
- if (*masked_prod < masked_cons || \
- size <= ring_size - *masked_prod) { \
- memcpy(buf + *masked_prod, opaque, size); \
- } else { \
- memcpy(buf + *masked_prod, opaque, ring_size - *masked_prod); \
- memcpy(buf, (unsigned char *)opaque + (ring_size - *masked_prod), \
- size - (ring_size - *masked_prod)); \
- } \
- *masked_prod = name##_mask(*masked_prod + size, ring_size); \
-} \
- \
-static inline RING_IDX name##_queued(RING_IDX prod, \
- RING_IDX cons, \
- RING_IDX ring_size) \
-{ \
- RING_IDX size; \
- \
- if (prod == cons) \
- return 0; \
- \
- prod = name##_mask(prod, ring_size); \
- cons = name##_mask(cons, ring_size); \
- \
- if (prod == cons) \
- return ring_size; \
- \
- if (prod > cons) \
- size = prod - cons; \
- else \
- size = ring_size - (cons - prod); \
- return size; \
-} \
- \
-struct name##_data { \
- unsigned char *in; /* half of the allocation */ \
- unsigned char *out; /* half of the allocation */ \
-}
-
-#define DEFINE_XEN_FLEX_RING_AND_INTF(name) \
-struct name##_data_intf { \
- RING_IDX in_cons, in_prod; \
- \
- uint8_t pad1[56]; \
- \
- RING_IDX out_cons, out_prod; \
- \
- uint8_t pad2[56]; \
- \
- RING_IDX ring_order; \
- grant_ref_t ref[]; \
-}; \
-DEFINE_XEN_FLEX_RING(name)
-
-#endif /* XEN_PUBLIC_IO_RING_H */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
typedef void (*XenWatchHandler)(void *opaque);
typedef struct XenWatch XenWatch;
+typedef struct XenEventChannel XenEventChannel;
typedef struct XenDevice {
DeviceState qdev;
XenWatch *backend_online_watch;
xengnttab_handle *xgth;
bool feature_grant_copy;
- xenevtchn_handle *xeh;
- NotifierList event_notifiers;
+ QLIST_HEAD(, XenEventChannel) event_channels;
} XenDevice;
typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp);
XenDeviceGrantCopySegment segs[],
unsigned int nr_segs, Error **errp);
-typedef struct XenEventChannel XenEventChannel;
-
-typedef void (*XenEventHandler)(void *opaque);
+typedef bool (*XenEventHandler)(void *opaque);
XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
+ AioContext *ctx,
unsigned int port,
XenEventHandler handler,
void *opaque, Error **errp);
#include <xenctrl.h>
#include <xenstore.h>
-#include <xen/io/xenbus.h>
+#include "hw/xen/interface/io/xenbus.h"
#include "hw/hw.h"
#include "hw/xen/xen.h"
--- /dev/null
+/*
+ * Human Monitor Interface
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef HMP_H
+#define HMP_H
+
+#include "qemu/readline.h"
+
+void hmp_handle_error(Monitor *mon, Error **errp);
+
+void hmp_info_name(Monitor *mon, const QDict *qdict);
+void hmp_info_version(Monitor *mon, const QDict *qdict);
+void hmp_info_kvm(Monitor *mon, const QDict *qdict);
+void hmp_info_status(Monitor *mon, const QDict *qdict);
+void hmp_info_uuid(Monitor *mon, const QDict *qdict);
+void hmp_info_chardev(Monitor *mon, const QDict *qdict);
+void hmp_info_mice(Monitor *mon, const QDict *qdict);
+void hmp_info_migrate(Monitor *mon, const QDict *qdict);
+void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict);
+void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict);
+void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict);
+void hmp_info_cpus(Monitor *mon, const QDict *qdict);
+void hmp_info_block(Monitor *mon, const QDict *qdict);
+void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
+void hmp_info_vnc(Monitor *mon, const QDict *qdict);
+void hmp_info_spice(Monitor *mon, const QDict *qdict);
+void hmp_info_balloon(Monitor *mon, const QDict *qdict);
+void hmp_info_irq(Monitor *mon, const QDict *qdict);
+void hmp_info_pic(Monitor *mon, const QDict *qdict);
+void hmp_info_rdma(Monitor *mon, const QDict *qdict);
+void hmp_info_pci(Monitor *mon, const QDict *qdict);
+void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
+void hmp_info_tpm(Monitor *mon, const QDict *qdict);
+void hmp_info_iothreads(Monitor *mon, const QDict *qdict);
+void hmp_quit(Monitor *mon, const QDict *qdict);
+void hmp_stop(Monitor *mon, const QDict *qdict);
+void hmp_sync_profile(Monitor *mon, const QDict *qdict);
+void hmp_system_reset(Monitor *mon, const QDict *qdict);
+void hmp_system_powerdown(Monitor *mon, const QDict *qdict);
+void hmp_exit_preconfig(Monitor *mon, const QDict *qdict);
+void hmp_announce_self(Monitor *mon, const QDict *qdict);
+void hmp_cpu(Monitor *mon, const QDict *qdict);
+void hmp_memsave(Monitor *mon, const QDict *qdict);
+void hmp_pmemsave(Monitor *mon, const QDict *qdict);
+void hmp_ringbuf_write(Monitor *mon, const QDict *qdict);
+void hmp_ringbuf_read(Monitor *mon, const QDict *qdict);
+void hmp_cont(Monitor *mon, const QDict *qdict);
+void hmp_system_wakeup(Monitor *mon, const QDict *qdict);
+void hmp_nmi(Monitor *mon, const QDict *qdict);
+void hmp_set_link(Monitor *mon, const QDict *qdict);
+void hmp_block_passwd(Monitor *mon, const QDict *qdict);
+void hmp_balloon(Monitor *mon, const QDict *qdict);
+void hmp_block_resize(Monitor *mon, const QDict *qdict);
+void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict);
+void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict);
+void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict);
+void hmp_drive_mirror(Monitor *mon, const QDict *qdict);
+void hmp_drive_backup(Monitor *mon, const QDict *qdict);
+void hmp_loadvm(Monitor *mon, const QDict *qdict);
+void hmp_savevm(Monitor *mon, const QDict *qdict);
+void hmp_delvm(Monitor *mon, const QDict *qdict);
+void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
+void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
+void hmp_migrate_continue(Monitor *mon, const QDict *qdict);
+void hmp_migrate_incoming(Monitor *mon, const QDict *qdict);
+void hmp_migrate_recover(Monitor *mon, const QDict *qdict);
+void hmp_migrate_pause(Monitor *mon, const QDict *qdict);
+void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict);
+void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict);
+void hmp_migrate_set_capability(Monitor *mon, const QDict *qdict);
+void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict);
+void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict);
+void hmp_client_migrate_info(Monitor *mon, const QDict *qdict);
+void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict);
+void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict);
+void hmp_set_password(Monitor *mon, const QDict *qdict);
+void hmp_expire_password(Monitor *mon, const QDict *qdict);
+void hmp_eject(Monitor *mon, const QDict *qdict);
+void hmp_change(Monitor *mon, const QDict *qdict);
+void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict);
+void hmp_block_stream(Monitor *mon, const QDict *qdict);
+void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
+void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
+void hmp_block_job_pause(Monitor *mon, const QDict *qdict);
+void hmp_block_job_resume(Monitor *mon, const QDict *qdict);
+void hmp_block_job_complete(Monitor *mon, const QDict *qdict);
+void hmp_migrate(Monitor *mon, const QDict *qdict);
+void hmp_device_add(Monitor *mon, const QDict *qdict);
+void hmp_device_del(Monitor *mon, const QDict *qdict);
+void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict);
+void hmp_netdev_add(Monitor *mon, const QDict *qdict);
+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 hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
+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_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);
+void hmp_chardev_send_break(Monitor *mon, const QDict *qdict);
+void hmp_qemu_io(Monitor *mon, const QDict *qdict);
+void hmp_cpu_add(Monitor *mon, const QDict *qdict);
+void hmp_object_add(Monitor *mon, const QDict *qdict);
+void hmp_object_del(Monitor *mon, const QDict *qdict);
+void hmp_info_memdev(Monitor *mon, const QDict *qdict);
+void hmp_info_numa(Monitor *mon, const QDict *qdict);
+void hmp_info_memory_devices(Monitor *mon, const QDict *qdict);
+void hmp_qom_list(Monitor *mon, const QDict *qdict);
+void hmp_qom_set(Monitor *mon, const QDict *qdict);
+void hmp_info_qom_tree(Monitor *mon, const QDict *dict);
+void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
+void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void device_del_completion(ReadLineState *rs, int nb_args, const char *str);
+void sendkey_completion(ReadLineState *rs, int nb_args, const char *str);
+void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str);
+void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
+void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
+void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str);
+void info_trace_events_completion(ReadLineState *rs, int nb_args, const char *str);
+void trace_event_completion(ReadLineState *rs, int nb_args, const char *str);
+void watchdog_action_completion(ReadLineState *rs, int nb_args,
+ const char *str);
+void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
+ const char *str);
+void migrate_set_parameter_completion(ReadLineState *rs, int nb_args,
+ const char *str);
+void delvm_completion(ReadLineState *rs, int nb_args, const char *str);
+void loadvm_completion(ReadLineState *rs, int nb_args, const char *str);
+void hmp_rocker(Monitor *mon, const QDict *qdict);
+void hmp_rocker_ports(Monitor *mon, const QDict *qdict);
+void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict);
+void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict);
+void hmp_info_dump(Monitor *mon, const QDict *qdict);
+void hmp_info_ramblock(Monitor *mon, const QDict *qdict);
+void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict);
+void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict);
+void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict);
+void hmp_info_sev(Monitor *mon, const QDict *qdict);
+
+#endif
void hmp_info_qtree(Monitor *mon, const QDict *qdict);
void hmp_info_qdm(Monitor *mon, const QDict *qdict);
-void hmp_info_qom_tree(Monitor *mon, const QDict *dict);
void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp);
int qdev_device_help(QemuOpts *opts);
/* Returns: update the timer to the next time point */
int64_t qemu_announce_timer_step(AnnounceTimer *timer);
-/* Delete the underlying timer */
-void qemu_announce_timer_del(AnnounceTimer *timer);
+/*
+ * Delete the underlying timer and other data
+ * If 'free_named' true and the timer is a named timer, then remove
+ * it from the list of named timers and free the AnnounceTimer itself.
+ */
+void qemu_announce_timer_del(AnnounceTimer *timer, bool free_named);
/*
* Under BQL/main thread
#ifndef DUMP_H
#define DUMP_H
-#include "qapi/qapi-types-misc.h"
+#include "qapi/qapi-types-dump.h"
#define MAKEDUMPFILE_SIGNATURE "makedumpfile"
#define MAX_SIZE_MDF_HEADER (4096) /* max size of makedumpfile_header */
#define SYSEMU_HOSTMEM_H
#include "sysemu/sysemu.h" /* for MAX_NODES */
-#include "qapi/qapi-types-misc.h"
+#include "qapi/qapi-types-machine.h"
#include "qom/object.h"
#include "exec/memory.h"
#include "qemu/bitmap.h"
};
extern NodeInfo numa_info[MAX_NODES];
+
+void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp);
void parse_numa_opts(MachineState *ms);
void numa_complete_configuration(MachineState *ms);
void query_numa_node_mem(NumaNodeMem node_mem[]);
obj-$(TARGET_ARM) += arm/nwfpe/
obj-$(TARGET_ARM) += arm/semihost.o
obj-$(TARGET_AARCH64) += arm/semihost.o
-obj-$(TARGET_M68K) += m68k-sim.o
QEMU_PPC_FEATURE2_HAS_EBB = 0x10000000, /* Event Base Branching */
QEMU_PPC_FEATURE2_HAS_ISEL = 0x08000000, /* Integer Select */
QEMU_PPC_FEATURE2_HAS_TAR = 0x04000000, /* Target Address Register */
+ QEMU_PPC_FEATURE2_VEC_CRYPTO = 0x02000000,
+ QEMU_PPC_FEATURE2_HTM_NOSC = 0x01000000,
QEMU_PPC_FEATURE2_ARCH_3_00 = 0x00800000, /* ISA 3.00 */
+ QEMU_PPC_FEATURE2_HAS_IEEE128 = 0x00400000, /* VSX IEEE Bin Float 128-bit */
+ QEMU_PPC_FEATURE2_DARN = 0x00200000, /* darn random number insn */
+ QEMU_PPC_FEATURE2_SCV = 0x00100000, /* scv syscall */
+ QEMU_PPC_FEATURE2_HTM_NO_SUSPEND = 0x00080000, /* TM w/o suspended state */
};
#define ELF_HWCAP get_elf_hwcap()
GET_FEATURE(PPC_ISEL, QEMU_PPC_FEATURE2_HAS_ISEL);
GET_FEATURE2(PPC2_BCTAR_ISA207, QEMU_PPC_FEATURE2_HAS_TAR);
GET_FEATURE2((PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
- PPC2_ISA207S), QEMU_PPC_FEATURE2_ARCH_2_07);
- GET_FEATURE2(PPC2_ISA300, QEMU_PPC_FEATURE2_ARCH_3_00);
+ PPC2_ISA207S), QEMU_PPC_FEATURE2_ARCH_2_07 |
+ QEMU_PPC_FEATURE2_VEC_CRYPTO);
+ GET_FEATURE2(PPC2_ISA300, QEMU_PPC_FEATURE2_ARCH_3_00 |
+ QEMU_PPC_FEATURE2_DARN);
#undef GET_FEATURE
#undef GET_FEATURE2
case QEMU_IFLA_BR_ROOT_ID:
case QEMU_IFLA_BR_BRIDGE_ID:
break;
+ /* br_boolopt_multi { uint32_t, uint32_t } */
+ case QEMU_IFLA_BR_MULTI_BOOLOPT:
+ u32 = NLA_DATA(nlattr);
+ u32[0] = tswap32(u32[0]); /* optval */
+ u32[1] = tswap32(u32[1]); /* optmask */
+ break;
default:
gemu_log("Unknown QEMU_IFLA_BR type %d\n", nlattr->nla_type);
break;
case QEMU_IFLA_BRPORT_ROOT_ID:
case QEMU_IFLA_BRPORT_BRIDGE_ID:
break;
- /* br_boolopt_multi { uint32_t, uint32_t } */
- case QEMU_IFLA_BR_MULTI_BOOLOPT:
- u32 = NLA_DATA(nlattr);
- u32[0] = tswap32(u32[0]); /* optval */
- u32[1] = tswap32(u32[1]); /* optmask */
- break;
default:
gemu_log("Unknown QEMU_IFLA_BRPORT type %d\n", nlattr->nla_type);
break;
#define TARGET_F_SHLCK 8
#endif
+#ifndef TARGET_HAVE_ARCH_STRUCT_FLOCK
#ifndef TARGET_ARCH_FLOCK_PAD
#define TARGET_ARCH_FLOCK_PAD
#endif
short l_whence;
abi_long l_start;
abi_long l_len;
-#if defined(TARGET_MIPS)
- abi_long l_sysid;
-#endif
int l_pid;
TARGET_ARCH_FLOCK_PAD
};
+#endif
+#ifndef TARGET_HAVE_ARCH_STRUCT_FLOCK64
#ifndef TARGET_ARCH_FLOCK64_PAD
#define TARGET_ARCH_FLOCK64_PAD
#endif
TARGET_ARCH_FLOCK64_PAD
};
#endif
+
+#endif
+++ /dev/null
-/*
- * m68k simulator syscall interface
- *
- * Copyright (c) 2005 CodeSourcery, LLC. Written by Paul Brook.
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-
-#include "qemu.h"
-
-#define SYS_EXIT 1
-#define SYS_READ 3
-#define SYS_WRITE 4
-#define SYS_OPEN 5
-#define SYS_CLOSE 6
-#define SYS_BRK 17
-#define SYS_FSTAT 28
-#define SYS_ISATTY 29
-#define SYS_LSEEK 199
-
-struct m68k_sim_stat {
- uint16_t sim_st_dev;
- uint16_t sim_st_ino;
- uint32_t sim_st_mode;
- uint16_t sim_st_nlink;
- uint16_t sim_st_uid;
- uint16_t sim_st_gid;
- uint16_t sim_st_rdev;
- uint32_t sim_st_size;
- uint32_t sim_st_atime;
- uint32_t sim_st_mtime;
- uint32_t sim_st_ctime;
- uint32_t sim_st_blksize;
- uint32_t sim_st_blocks;
-};
-
-static inline uint32_t check_err(CPUM68KState *env, uint32_t code)
-{
- env->dregs[0] = code;
- if (code == (uint32_t)-1) {
- env->dregs[1] = errno;
- } else {
- env->dregs[1] = 0;
- }
- return code;
-}
-
-#define SIM_O_APPEND 0x0008
-#define SIM_O_CREAT 0x0200
-#define SIM_O_TRUNC 0x0400
-#define SIM_O_EXCL 0x0800
-#define SIM_O_NONBLOCK 0x4000
-#define SIM_O_NOCTTY 0x8000
-#define SIM_O_SYNC 0x2000
-
-static int translate_openflags(int flags)
-{
- int hf;
-
- switch (flags & 3) {
- case 0: hf = O_RDONLY; break;
- case 1: hf = O_WRONLY; break;
- case 2: hf = O_RDWR; break;
- default: hf = O_RDWR; break;
- }
-
- if (flags & SIM_O_APPEND) hf |= O_APPEND;
- if (flags & SIM_O_CREAT) hf |= O_CREAT;
- if (flags & SIM_O_TRUNC) hf |= O_TRUNC;
- if (flags & SIM_O_EXCL) hf |= O_EXCL;
- if (flags & SIM_O_NONBLOCK) hf |= O_NONBLOCK;
- if (flags & SIM_O_NOCTTY) hf |= O_NOCTTY;
- if (flags & SIM_O_SYNC) hf |= O_SYNC;
-
- return hf;
-}
-
-#define ARG(x) tswap32(args[x])
-void do_m68k_simcall(CPUM68KState *env, int nr)
-{
- uint32_t *args;
-
- args = (uint32_t *)(unsigned long)(env->aregs[7] + 4);
- switch (nr) {
- case SYS_EXIT:
- exit(ARG(0));
- case SYS_READ:
- check_err(env, read(ARG(0), (void *)(unsigned long)ARG(1), ARG(2)));
- break;
- case SYS_WRITE:
- check_err(env, write(ARG(0), (void *)(unsigned long)ARG(1), ARG(2)));
- break;
- case SYS_OPEN:
- check_err(env, open((char *)(unsigned long)ARG(0),
- translate_openflags(ARG(1)), ARG(2)));
- break;
- case SYS_CLOSE:
- {
- /* Ignore attempts to close stdin/out/err. */
- int fd = ARG(0);
- if (fd > 2)
- check_err(env, close(fd));
- else
- check_err(env, 0);
- break;
- }
- case SYS_BRK:
- {
- int32_t ret;
-
- ret = do_brk((abi_ulong)ARG(0));
- if (ret == -ENOMEM)
- ret = -1;
- check_err(env, ret);
- }
- break;
- case SYS_FSTAT:
- {
- struct stat s;
- int rc;
- struct m68k_sim_stat *p;
- rc = check_err(env, fstat(ARG(0), &s));
- if (rc == 0) {
- p = (struct m68k_sim_stat *)(unsigned long)ARG(1);
- p->sim_st_dev = tswap16(s.st_dev);
- p->sim_st_ino = tswap16(s.st_ino);
- p->sim_st_mode = tswap32(s.st_mode);
- p->sim_st_nlink = tswap16(s.st_nlink);
- p->sim_st_uid = tswap16(s.st_uid);
- p->sim_st_gid = tswap16(s.st_gid);
- p->sim_st_rdev = tswap16(s.st_rdev);
- p->sim_st_size = tswap32(s.st_size);
- p->sim_st_atime = tswap32(s.st_atime);
- p->sim_st_mtime = tswap32(s.st_mtime);
- p->sim_st_ctime = tswap32(s.st_ctime);
- p->sim_st_blksize = tswap32(s.st_blksize);
- p->sim_st_blocks = tswap32(s.st_blocks);
- }
- }
- break;
- case SYS_ISATTY:
- check_err(env, isatty(ARG(0)));
- break;
- case SYS_LSEEK:
- check_err(env, lseek(ARG(0), (int32_t)ARG(1), ARG(2)));
- break;
- default:
- cpu_abort(env_cpu(env), "Unsupported m68k sim syscall %d\n", nr);
- }
-}
int trapnr;
unsigned int n;
target_siginfo_t info;
- TaskState *ts = cs->opaque;
for(;;) {
cpu_exec_start(cs);
process_queued_cpu_work(cs);
switch(trapnr) {
- case EXCP_ILLEGAL:
- {
- if (ts->sim_syscalls) {
- uint16_t nr;
- get_user_u16(nr, env->pc + 2);
- env->pc += 4;
- do_m68k_simcall(env, nr);
- } else {
- goto do_sigill;
- }
- }
- break;
case EXCP_HALT_INSN:
/* Semihosing syscall. */
env->pc += 4;
do_m68k_semihosting(env, env->dregs[0]);
break;
+ case EXCP_ILLEGAL:
case EXCP_LINEA:
case EXCP_LINEF:
- do_sigill:
info.si_signo = TARGET_SIGILL;
info.si_errno = 0;
info.si_code = TARGET_ILL_ILLOPN;
case EXCP_TRAP0:
{
abi_long ret;
- ts->sim_syscalls = 0;
n = env->dregs[0];
env->pc += 2;
ret = do_syscall(env,
env->aregs[7] = regs->usp;
env->sr = regs->sr;
- ts->sim_syscalls = 1;
ts->stack_base = info->start_stack;
ts->heap_base = info->brk;
/* This will be filled in on the first SYS_HEAPINFO call. */
#define TARGET_WANT_OLD_SYS_SELECT
-void do_m68k_simcall(CPUM68KState *, int);
-
#endif /* M68K_TARGET_SYSCALL_H */
info.si_code = TARGET_ILL_ILLOPC;
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
+ case EXCP_FPE:
+ info.si_signo = TARGET_SIGFPE;
+ info.si_errno = 0;
+ info.si_code = TARGET_FPE_FLTUNK;
+ if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INVALID) {
+ info.si_code = TARGET_FPE_FLTINV;
+ } else if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_DIV0) {
+ info.si_code = TARGET_FPE_FLTDIV;
+ } else if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_OVERFLOW) {
+ info.si_code = TARGET_FPE_FLTOVF;
+ } else if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_UNDERFLOW) {
+ info.si_code = TARGET_FPE_FLTUND;
+ } else if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INEXACT) {
+ info.si_code = TARGET_FPE_FLTRES;
+ }
+ queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
+ break;
/* The code below was inspired by the MIPS Linux kernel trap
* handling code in arch/mips/kernel/traps.c.
*/
#define TARGET_F_SETOWN 24 /* for sockets. */
#define TARGET_F_GETOWN 23 /* for sockets. */
-#define TARGET_ARCH_FLOCK_PAD abi_long pad[4];
-#define TARGET_ARCH_FLOCK64_PAD
+#if (TARGET_ABI_BITS == 32)
+
+struct target_flock {
+ short l_type;
+ short l_whence;
+ abi_long l_start;
+ abi_long l_len;
+ abi_long l_sysid;
+ int l_pid;
+ abi_long pad[4];
+};
+
+#define TARGET_HAVE_ARCH_STRUCT_FLOCK
+
+#endif
#define TARGET_F_GETLK64 33 /* using 'struct flock64' */
#define TARGET_F_SETLK64 34
static inline const char *cpu_get_model(uint32_t eflags)
{
#ifdef TARGET_PPC64
- return "POWER8";
+ return "POWER9";
#else
return "750";
#endif
#endif
abi_ulong child_tidptr;
#ifdef TARGET_M68K
- int sim_syscalls;
abi_ulong tp_value;
#endif
#if defined(TARGET_ARM) || defined(TARGET_M68K)
#define TARGET_NR_pipe2 59
#define TARGET_NR_quotactl 60
#define TARGET_NR_getdents64 61
+#ifdef TARGET_RISCV32
+#define TARGET_NR__llseek 62
+#else
#define TARGET_NR_lseek 62
+#endif
#define TARGET_NR_read 63
#define TARGET_NR_write 64
#define TARGET_NR_readv 65
#define TARGET_NR_membarrier 283
#define TARGET_NR_mlock2 284
#define TARGET_NR_copy_file_range 285
+#define TARGET_NR_preadv2 286
+#define TARGET_NR_pwritev2 287
+#define TARGET_NR_pkey_mprotect 288
+#define TARGET_NR_pkey_alloc 289
+#define TARGET_NR_pkey_free 290
+#define TARGET_NR_statx 291
+#define TARGET_NR_io_pgetevents 292
+#define TARGET_NR_rseq 293
+#define TARGET_NR_kexec_file_load 294
-#define TARGET_NR_syscalls (TARGET_NR_copy_file_range + 1)
+#define TARGET_NR_syscalls (TARGET_NR_kexec_file_load + 1)
#endif
FLAG_END,
};
+UNUSED static struct flags statx_flags[] = {
+#ifdef AT_EMPTY_PATH
+ FLAG_GENERIC(AT_EMPTY_PATH),
+#endif
+#ifdef AT_NO_AUTOMOUNT
+ FLAG_GENERIC(AT_NO_AUTOMOUNT),
+#endif
+#ifdef AT_SYMLINK_NOFOLLOW
+ FLAG_GENERIC(AT_SYMLINK_NOFOLLOW),
+#endif
+#ifdef AT_STATX_SYNC_AS_STAT
+ FLAG_GENERIC(AT_STATX_SYNC_AS_STAT),
+#endif
+#ifdef AT_STATX_FORCE_SYNC
+ FLAG_GENERIC(AT_STATX_FORCE_SYNC),
+#endif
+#ifdef AT_STATX_DONT_SYNC
+ FLAG_GENERIC(AT_STATX_DONT_SYNC),
+#endif
+ FLAG_END,
+};
+
+UNUSED static struct flags statx_mask[] = {
+/* This must come first, because it includes everything. */
+#ifdef STATX_ALL
+ FLAG_GENERIC(STATX_ALL),
+#endif
+/* This must come second; it includes everything except STATX_BTIME. */
+#ifdef STATX_BASIC_STATS
+ FLAG_GENERIC(STATX_BASIC_STATS),
+#endif
+#ifdef STATX_TYPE
+ FLAG_GENERIC(STATX_TYPE),
+#endif
+#ifdef STATX_MODE
+ FLAG_GENERIC(STATX_MODE),
+#endif
+#ifdef STATX_NLINK
+ FLAG_GENERIC(STATX_NLINK),
+#endif
+#ifdef STATX_UID
+ FLAG_GENERIC(STATX_UID),
+#endif
+#ifdef STATX_GID
+ FLAG_GENERIC(STATX_GID),
+#endif
+#ifdef STATX_ATIME
+ FLAG_GENERIC(STATX_ATIME),
+#endif
+#ifdef STATX_MTIME
+ FLAG_GENERIC(STATX_MTIME),
+#endif
+#ifdef STATX_CTIME
+ FLAG_GENERIC(STATX_CTIME),
+#endif
+#ifdef STATX_INO
+ FLAG_GENERIC(STATX_INO),
+#endif
+#ifdef STATX_SIZE
+ FLAG_GENERIC(STATX_SIZE),
+#endif
+#ifdef STATX_BLOCKS
+ FLAG_GENERIC(STATX_BLOCKS),
+#endif
+#ifdef STATX_BTIME
+ FLAG_GENERIC(STATX_BTIME),
+#endif
+ FLAG_END,
+};
+
/*
* print_xxx utility functions. These are used to print syscall
* parameters in certain format. All of these have parameter
}
#endif
+#ifdef TARGET_NR_statx
+static void
+print_statx(const struct syscallname *name,
+ abi_long arg0, abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4, abi_long arg5)
+{
+ print_syscall_prologue(name);
+ print_at_dirfd(arg0, 0);
+ print_string(arg1, 0);
+ print_flags(statx_flags, arg2, 0);
+ print_flags(statx_mask, arg3, 0);
+ print_pointer(arg4, 1);
+ print_syscall_epilogue(name);
+}
+#endif
+
/*
* An array of all of the syscalls we know about
*/
#ifdef TARGET_NR_atomic_barrier
{ TARGET_NR_atomic_barrier, "atomic_barrier", NULL, NULL, NULL },
#endif
+#ifdef TARGET_NR_statx
+{ TARGET_NR_statx, "statx", NULL, print_statx, NULL },
+#endif
#include <linux/blkpg.h>
#include <netpacket/packet.h>
#include <linux/netlink.h>
+#include <linux/if_alg.h>
#include "linux_loop.h"
#include "uname.h"
#define __NR_sys_inotify_init __NR_inotify_init
#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
+#define __NR_sys_statx __NR_statx
#if defined(__alpha__) || defined(__x86_64__) || defined(__s390x__)
#define __NR__llseek __NR_lseek
unsigned long, idx1, unsigned long, idx2)
#endif
+/*
+ * It is assumed that struct statx is architecture independent.
+ */
+#if defined(TARGET_NR_statx) && defined(__NR_statx)
+_syscall5(int, sys_statx, int, dirfd, const char *, pathname, int, flags,
+ unsigned int, mask, struct target_statx *, statxbuf)
+#endif
+
static bitmask_transtbl fcntl_flags_tbl[] = {
{ TARGET_O_ACCMODE, TARGET_O_WRONLY, O_ACCMODE, O_WRONLY, },
{ TARGET_O_ACCMODE, TARGET_O_RDWR, O_ACCMODE, O_RDWR, },
safe_syscall4(int, clock_nanosleep, const clockid_t, clock, int, flags,
const struct timespec *, req, struct timespec *, rem)
#endif
-#if !defined(__NR_msgsnd) || !defined(__NR_msgrcv) || !defined(__NR_semtimedop)
-/* This host kernel architecture uses a single ipc syscall; fake up
- * wrappers for the sub-operations to hide this implementation detail.
- * Annoyingly we can't include linux/ipc.h to get the constant definitions
- * for the call parameter because some structs in there conflict with the
- * sys/ipc.h ones. So we just define them here, and rely on them being
- * the same for all host architectures.
- */
-#define Q_SEMTIMEDOP 4
-#define Q_MSGSND 11
-#define Q_MSGRCV 12
-#define Q_IPCCALL(VERSION, OP) ((VERSION) << 16 | (OP))
-
+#ifdef __NR_ipc
safe_syscall6(int, ipc, int, call, long, first, long, second, long, third,
void *, ptr, long, fifth)
#endif
#ifdef __NR_msgsnd
safe_syscall4(int, msgsnd, int, msgid, const void *, msgp, size_t, sz,
int, flags)
-#else
-static int safe_msgsnd(int msgid, const void *msgp, size_t sz, int flags)
-{
- return safe_ipc(Q_IPCCALL(0, Q_MSGSND), msgid, sz, flags, (void *)msgp, 0);
-}
#endif
#ifdef __NR_msgrcv
safe_syscall5(int, msgrcv, int, msgid, void *, msgp, size_t, sz,
long, msgtype, int, flags)
-#else
-static int safe_msgrcv(int msgid, void *msgp, size_t sz, long type, int flags)
-{
- return safe_ipc(Q_IPCCALL(1, Q_MSGRCV), msgid, sz, flags, msgp, type);
-}
#endif
#ifdef __NR_semtimedop
safe_syscall4(int, semtimedop, int, semid, struct sembuf *, tsops,
unsigned, nsops, const struct timespec *, timeout)
-#else
-static int safe_semtimedop(int semid, struct sembuf *tsops, unsigned nsops,
- const struct timespec *timeout)
-{
- return safe_ipc(Q_IPCCALL(0, Q_SEMTIMEDOP), semid, nsops, 0, tsops,
- (long)timeout);
-}
#endif
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
safe_syscall5(int, mq_timedsend, int, mqdes, const char *, msg_ptr,
&pki, sizeof(pki)));
break;
}
+ case IPV6_ADD_MEMBERSHIP:
+ case IPV6_DROP_MEMBERSHIP:
+ {
+ struct ipv6_mreq ipv6mreq;
+
+ if (optlen < sizeof(ipv6mreq)) {
+ return -TARGET_EINVAL;
+ }
+
+ if (copy_from_user(&ipv6mreq, optval_addr, sizeof(ipv6mreq))) {
+ return -TARGET_EFAULT;
+ }
+
+ ipv6mreq.ipv6mr_interface = tswap32(ipv6mreq.ipv6mr_interface);
+
+ ret = get_errno(setsockopt(sockfd, level, optname,
+ &ipv6mreq, sizeof(ipv6mreq)));
+ break;
+ }
default:
goto unimplemented;
}
goto unimplemented;
}
break;
+#if defined(SOL_ALG) && defined(ALG_SET_KEY) && defined(ALG_SET_AEAD_AUTHSIZE)
+ case SOL_ALG:
+ switch (optname) {
+ case ALG_SET_KEY:
+ {
+ char *alg_key = g_malloc(optlen);
+
+ if (!alg_key) {
+ return -TARGET_ENOMEM;
+ }
+ if (copy_from_user(alg_key, optval_addr, optlen)) {
+ g_free(alg_key);
+ return -TARGET_EFAULT;
+ }
+ ret = get_errno(setsockopt(sockfd, level, optname,
+ alg_key, optlen));
+ g_free(alg_key);
+ break;
+ }
+ case ALG_SET_AEAD_AUTHSIZE:
+ {
+ ret = get_errno(setsockopt(sockfd, level, optname,
+ NULL, optlen));
+ break;
+ }
+ default:
+ goto unimplemented;
+ }
+ break;
+#endif
case TARGET_SOL_SOCKET:
switch (optname) {
case TARGET_SO_RCVTIMEO:
static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
{
struct sembuf sops[nsops];
+ abi_long ret;
if (target_to_host_sembuf(sops, ptr, nsops))
return -TARGET_EFAULT;
- return get_errno(safe_semtimedop(semid, sops, nsops, NULL));
+ ret = -TARGET_ENOSYS;
+#ifdef __NR_semtimedop
+ ret = get_errno(safe_semtimedop(semid, sops, nsops, NULL));
+#endif
+#ifdef __NR_ipc
+ if (ret == -TARGET_ENOSYS) {
+ ret = get_errno(safe_ipc(IPCOP_semtimedop, semid, nsops, 0, sops, 0));
+ }
+#endif
+ return ret;
}
struct target_msqid_ds
}
host_mb->mtype = (abi_long) tswapal(target_mb->mtype);
memcpy(host_mb->mtext, target_mb->mtext, msgsz);
+ ret = -TARGET_ENOSYS;
+#ifdef __NR_msgsnd
ret = get_errno(safe_msgsnd(msqid, host_mb, msgsz, msgflg));
+#endif
+#ifdef __NR_ipc
+ if (ret == -TARGET_ENOSYS) {
+ ret = get_errno(safe_ipc(IPCOP_msgsnd, msqid, msgsz, msgflg,
+ host_mb, 0));
+ }
+#endif
g_free(host_mb);
unlock_user_struct(target_mb, msgp, 0);
ret = -TARGET_ENOMEM;
goto end;
}
+ ret = -TARGET_ENOSYS;
+#ifdef __NR_msgrcv
ret = get_errno(safe_msgrcv(msqid, host_mb, msgsz, msgtyp, msgflg));
+#endif
+#ifdef __NR_ipc
+ if (ret == -TARGET_ENOSYS) {
+ ret = get_errno(safe_ipc(IPCOP_CALL(1, IPCOP_msgrcv), msqid, msgsz,
+ msgflg, host_mb, msgtyp));
+ }
+#endif
if (ret > 0) {
abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong);
}
#endif
+#if defined(TARGET_NR_statx) && defined(__NR_statx)
+static inline abi_long host_to_target_statx(struct target_statx *host_stx,
+ abi_ulong target_addr)
+{
+ struct target_statx *target_stx;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_stx, target_addr, 0)) {
+ return -TARGET_EFAULT;
+ }
+ memset(target_stx, 0, sizeof(*target_stx));
+
+ __put_user(host_stx->stx_mask, &target_stx->stx_mask);
+ __put_user(host_stx->stx_blksize, &target_stx->stx_blksize);
+ __put_user(host_stx->stx_attributes, &target_stx->stx_attributes);
+ __put_user(host_stx->stx_nlink, &target_stx->stx_nlink);
+ __put_user(host_stx->stx_uid, &target_stx->stx_uid);
+ __put_user(host_stx->stx_gid, &target_stx->stx_gid);
+ __put_user(host_stx->stx_mode, &target_stx->stx_mode);
+ __put_user(host_stx->stx_ino, &target_stx->stx_ino);
+ __put_user(host_stx->stx_size, &target_stx->stx_size);
+ __put_user(host_stx->stx_blocks, &target_stx->stx_blocks);
+ __put_user(host_stx->stx_attributes_mask, &target_stx->stx_attributes_mask);
+ __put_user(host_stx->stx_atime.tv_sec, &target_stx->stx_atime.tv_sec);
+ __put_user(host_stx->stx_atime.tv_nsec, &target_stx->stx_atime.tv_nsec);
+ __put_user(host_stx->stx_btime.tv_sec, &target_stx->stx_atime.tv_sec);
+ __put_user(host_stx->stx_btime.tv_nsec, &target_stx->stx_atime.tv_nsec);
+ __put_user(host_stx->stx_ctime.tv_sec, &target_stx->stx_atime.tv_sec);
+ __put_user(host_stx->stx_ctime.tv_nsec, &target_stx->stx_atime.tv_nsec);
+ __put_user(host_stx->stx_mtime.tv_sec, &target_stx->stx_atime.tv_sec);
+ __put_user(host_stx->stx_mtime.tv_nsec, &target_stx->stx_atime.tv_nsec);
+ __put_user(host_stx->stx_rdev_major, &target_stx->stx_rdev_major);
+ __put_user(host_stx->stx_rdev_minor, &target_stx->stx_rdev_minor);
+ __put_user(host_stx->stx_dev_major, &target_stx->stx_dev_major);
+ __put_user(host_stx->stx_dev_minor, &target_stx->stx_dev_minor);
+
+ unlock_user_struct(target_stx, target_addr, 1);
+
+ return 0;
+}
+#endif
+
+
/* ??? Using host futex calls even when target atomic operations
are not really atomic probably breaks things. However implementing
futexes locally would make futexes shared between multiple processes
abi_long ret;
#if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) \
|| defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64) \
- || defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64)
+ || defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64) \
+ || defined(TARGET_NR_statx)
struct stat st;
#endif
#if defined(TARGET_NR_statfs) || defined(TARGET_NR_statfs64) \
ret = host_to_target_stat64(cpu_env, arg3, &st);
return ret;
#endif
+#if defined(TARGET_NR_statx)
+ case TARGET_NR_statx:
+ {
+ struct target_statx *target_stx;
+ int dirfd = arg1;
+ int flags = arg3;
+
+ p = lock_user_string(arg2);
+ if (p == NULL) {
+ return -TARGET_EFAULT;
+ }
+#if defined(__NR_statx)
+ {
+ /*
+ * It is assumed that struct statx is architecture independent.
+ */
+ struct target_statx host_stx;
+ int mask = arg4;
+
+ ret = get_errno(sys_statx(dirfd, p, flags, mask, &host_stx));
+ if (!is_error(ret)) {
+ if (host_to_target_statx(&host_stx, arg5) != 0) {
+ unlock_user(p, arg2, 0);
+ return -TARGET_EFAULT;
+ }
+ }
+
+ if (ret != -TARGET_ENOSYS) {
+ unlock_user(p, arg2, 0);
+ return ret;
+ }
+ }
+#endif
+ ret = get_errno(fstatat(dirfd, path(p), &st, flags));
+ unlock_user(p, arg2, 0);
+
+ if (!is_error(ret)) {
+ if (!lock_user_struct(VERIFY_WRITE, target_stx, arg5, 0)) {
+ return -TARGET_EFAULT;
+ }
+ memset(target_stx, 0, sizeof(*target_stx));
+ __put_user(major(st.st_dev), &target_stx->stx_dev_major);
+ __put_user(minor(st.st_dev), &target_stx->stx_dev_minor);
+ __put_user(st.st_ino, &target_stx->stx_ino);
+ __put_user(st.st_mode, &target_stx->stx_mode);
+ __put_user(st.st_uid, &target_stx->stx_uid);
+ __put_user(st.st_gid, &target_stx->stx_gid);
+ __put_user(st.st_nlink, &target_stx->stx_nlink);
+ __put_user(major(st.st_rdev), &target_stx->stx_rdev_major);
+ __put_user(minor(st.st_rdev), &target_stx->stx_rdev_minor);
+ __put_user(st.st_size, &target_stx->stx_size);
+ __put_user(st.st_blksize, &target_stx->stx_blksize);
+ __put_user(st.st_blocks, &target_stx->stx_blocks);
+ __put_user(st.st_atime, &target_stx->stx_atime.tv_sec);
+ __put_user(st.st_mtime, &target_stx->stx_mtime.tv_sec);
+ __put_user(st.st_ctime, &target_stx->stx_ctime.tv_sec);
+ unlock_user_struct(target_stx, arg5, 1);
+ }
+ }
+ return ret;
+#endif
#ifdef TARGET_NR_lchown
case TARGET_NR_lchown:
if (!(p = lock_user_string(arg1)))
#define TARGET_SYS_RECVMMSG 19 /* recvmmsg() */
#define TARGET_SYS_SENDMMSG 20 /* sendmmsg() */
+#define IPCOP_CALL(VERSION, OP) ((VERSION) << 16 | (OP))
#define IPCOP_semop 1
#define IPCOP_semget 2
#define IPCOP_semctl 3
/* Return size of the log buffer */
#define TARGET_SYSLOG_ACTION_SIZE_BUFFER 10
+struct target_statx_timestamp {
+ int64_t tv_sec;
+ uint32_t tv_nsec;
+ int32_t __reserved;
+};
+
+struct target_statx {
+ /* 0x00 */
+ uint32_t stx_mask; /* What results were written [uncond] */
+ uint32_t stx_blksize; /* Preferred general I/O size [uncond] */
+ uint64_t stx_attributes; /* Flags conveying information about the file */
+ /* 0x10 */
+ uint32_t stx_nlink; /* Number of hard links */
+ uint32_t stx_uid; /* User ID of owner */
+ uint32_t stx_gid; /* Group ID of owner */
+ uint16_t stx_mode; /* File mode */
+ uint16_t __spare0[1];
+ /* 0x20 */
+ uint64_t stx_ino; /* Inode number */
+ uint64_t stx_size; /* File size */
+ uint64_t stx_blocks; /* Number of 512-byte blocks allocated */
+ uint64_t stx_attributes_mask; /* Mask to show what is supported */
+ /* 0x40 */
+ struct target_statx_timestamp stx_atime; /* Last access time */
+ struct target_statx_timestamp stx_btime; /* File creation time */
+ struct target_statx_timestamp stx_ctime; /* Last attribute change time */
+ struct target_statx_timestamp stx_mtime; /* Last data modification time */
+ /* 0x80 */
+ uint32_t stx_rdev_major; /* Device ID of special file [if bdev/cdev] */
+ uint32_t stx_rdev_minor;
+ uint32_t stx_dev_major; /* ID of device containing file [uncond] */
+ uint32_t stx_dev_minor;
+ /* 0x90 */
+ uint64_t __spare2[14]; /* Spare space for future expansion */
+ /* 0x100 */
+};
+
#endif
listener->address_space = NULL;
}
+void address_space_remove_listeners(AddressSpace *as)
+{
+ while (!QTAILQ_EMPTY(&as->listeners)) {
+ memory_listener_unregister(QTAILQ_FIRST(&as->listeners));
+ }
+}
+
void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
{
memory_region_ref(root);
void qmp_xen_colo_do_checkpoint(Error **errp)
{
replication_do_checkpoint_all(errp);
+ /* Notify all filters of all NIC to do checkpoint */
+ colo_notify_filters_event(COLO_EVENT_CHECKPOINT, errp);
}
#endif
*/
#include "qemu/osdep.h"
-#include "hmp.h"
+#include "monitor/hmp.h"
#include "net/net.h"
#include "net/eth.h"
#include "chardev/char.h"
#include "monitor/monitor-internal.h"
#include "monitor/qdev.h"
#include "qapi/error.h"
+#include "qapi/clone-visitor.h"
#include "qapi/opts-visitor.h"
#include "qapi/qapi-builtin-visit.h"
#include "qapi/qapi-commands-block.h"
#include "qapi/qapi-commands-migration.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/qapi-commands-net.h"
+#include "qapi/qapi-commands-qdev.h"
#include "qapi/qapi-commands-rocker.h"
#include "qapi/qapi-commands-run-state.h"
#include "qapi/qapi-commands-tpm.h"
#include "qapi/qapi-commands-ui.h"
+#include "qapi/qapi-visit-net.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
#include "qapi/string-input-visitor.h"
#include <spice/enums.h>
#endif
-static void hmp_handle_error(Monitor *mon, Error **errp)
+void hmp_handle_error(Monitor *mon, Error **errp)
{
assert(errp);
if (*errp) {
}
}
+/*
+ * Produce a strList from a comma separated list.
+ * A NULL or empty input string return NULL.
+ */
+static strList *strList_from_comma_list(const char *in)
+{
+ strList *res = NULL;
+ strList **hook = &res;
+
+ while (in && in[0]) {
+ char *comma = strchr(in, ',');
+ *hook = g_new0(strList, 1);
+
+ if (comma) {
+ (*hook)->value = g_strndup(in, comma - in);
+ in = comma + 1; /* skip the , */
+ } else {
+ (*hook)->value = g_strdup(in);
+ in = NULL;
+ }
+ hook = &(*hook)->next;
+ }
+
+ return res;
+}
+
void hmp_info_name(Monitor *mon, const QDict *qdict)
{
NameInfo *info;
qmp_query_migrate_cache_size(NULL) >> 10);
}
-void hmp_info_cpus(Monitor *mon, const QDict *qdict)
-{
- CpuInfoFastList *cpu_list, *cpu;
-
- cpu_list = qmp_query_cpus_fast(NULL);
-
- for (cpu = cpu_list; cpu; cpu = cpu->next) {
- int active = ' ';
-
- if (cpu->value->cpu_index == monitor_get_cpu_index()) {
- active = '*';
- }
-
- monitor_printf(mon, "%c CPU #%" PRId64 ":", active,
- cpu->value->cpu_index);
- monitor_printf(mon, " thread_id=%" PRId64 "\n", cpu->value->thread_id);
- }
-
- qapi_free_CpuInfoFastList(cpu_list);
-}
-
static void print_block_info(Monitor *mon, BlockInfo *info,
BlockDeviceInfo *inserted, bool verbose)
{
void hmp_announce_self(Monitor *mon, const QDict *qdict)
{
- qmp_announce_self(migrate_announce_params(), NULL);
+ const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
+ const char *id = qdict_get_try_str(qdict, "id");
+ AnnounceParameters *params = QAPI_CLONE(AnnounceParameters,
+ migrate_announce_params());
+
+ qapi_free_strList(params->interfaces);
+ params->interfaces = strList_from_comma_list(interfaces_str);
+ params->has_interfaces = params->interfaces != NULL;
+ params->id = g_strdup(id);
+ params->has_id = !!params->id;
+ qmp_announce_self(params, NULL);
+ qapi_free_AnnounceParameters(params);
}
void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
hmp_handle_error(mon, &err);
}
-void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
-{
- Error *err = NULL;
- bool win_dmp = qdict_get_try_bool(qdict, "windmp", false);
- bool paging = qdict_get_try_bool(qdict, "paging", false);
- bool zlib = qdict_get_try_bool(qdict, "zlib", false);
- bool lzo = qdict_get_try_bool(qdict, "lzo", false);
- bool snappy = qdict_get_try_bool(qdict, "snappy", false);
- const char *file = qdict_get_str(qdict, "filename");
- bool has_begin = qdict_haskey(qdict, "begin");
- bool has_length = qdict_haskey(qdict, "length");
- bool has_detach = qdict_haskey(qdict, "detach");
- int64_t begin = 0;
- int64_t length = 0;
- bool detach = false;
- enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF;
- char *prot;
-
- if (zlib + lzo + snappy + win_dmp > 1) {
- error_setg(&err, "only one of '-z|-l|-s|-w' can be set");
- hmp_handle_error(mon, &err);
- return;
- }
-
- if (win_dmp) {
- dump_format = DUMP_GUEST_MEMORY_FORMAT_WIN_DMP;
- }
-
- if (zlib) {
- dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB;
- }
-
- if (lzo) {
- dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO;
- }
-
- if (snappy) {
- dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY;
- }
-
- if (has_begin) {
- begin = qdict_get_int(qdict, "begin");
- }
- if (has_length) {
- length = qdict_get_int(qdict, "length");
- }
- if (has_detach) {
- detach = qdict_get_bool(qdict, "detach");
- }
-
- prot = g_strconcat("file:", file, NULL);
-
- qmp_dump_guest_memory(paging, prot, true, detach, has_begin, begin,
- has_length, length, true, dump_format, &err);
- hmp_handle_error(mon, &err);
- g_free(prot);
-}
-
void hmp_netdev_add(Monitor *mon, const QDict *qdict)
{
Error *err = NULL;
hmp_handle_error(mon, &err);
}
-void hmp_cpu_add(Monitor *mon, const QDict *qdict)
-{
- int cpuid;
- Error *err = NULL;
-
- error_report("cpu_add is deprecated, please use device_add instead");
-
- cpuid = qdict_get_int(qdict, "id");
- qmp_cpu_add(cpuid, &err);
- hmp_handle_error(mon, &err);
-}
-
void hmp_chardev_add(Monitor *mon, const QDict *qdict)
{
const char *args = qdict_get_str(qdict, "args");
hmp_handle_error(mon, &err);
}
-void hmp_info_memdev(Monitor *mon, const QDict *qdict)
-{
- Error *err = NULL;
- MemdevList *memdev_list = qmp_query_memdev(&err);
- MemdevList *m = memdev_list;
- Visitor *v;
- char *str;
-
- while (m) {
- v = string_output_visitor_new(false, &str);
- visit_type_uint16List(v, NULL, &m->value->host_nodes, NULL);
- monitor_printf(mon, "memory backend: %s\n", m->value->id);
- monitor_printf(mon, " size: %" PRId64 "\n", m->value->size);
- monitor_printf(mon, " merge: %s\n",
- m->value->merge ? "true" : "false");
- monitor_printf(mon, " dump: %s\n",
- m->value->dump ? "true" : "false");
- monitor_printf(mon, " prealloc: %s\n",
- m->value->prealloc ? "true" : "false");
- monitor_printf(mon, " policy: %s\n",
- HostMemPolicy_str(m->value->policy));
- visit_complete(v, &str);
- monitor_printf(mon, " host nodes: %s\n", str);
-
- g_free(str);
- visit_free(v);
- m = m->next;
- }
-
- monitor_printf(mon, "\n");
-
- qapi_free_MemdevList(memdev_list);
- hmp_handle_error(mon, &err);
-}
-
void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
{
Error *err = NULL;
qapi_free_IOThreadInfoList(info_list);
}
-void hmp_qom_list(Monitor *mon, const QDict *qdict)
-{
- const char *path = qdict_get_try_str(qdict, "path");
- ObjectPropertyInfoList *list;
- Error *err = NULL;
-
- if (path == NULL) {
- monitor_printf(mon, "/\n");
- return;
- }
-
- list = qmp_qom_list(path, &err);
- if (err == NULL) {
- ObjectPropertyInfoList *start = list;
- while (list != NULL) {
- ObjectPropertyInfo *value = list->value;
-
- monitor_printf(mon, "%s (%s)\n",
- value->name, value->type);
- list = list->next;
- }
- qapi_free_ObjectPropertyInfoList(start);
- }
- hmp_handle_error(mon, &err);
-}
-
-void hmp_qom_set(Monitor *mon, const QDict *qdict)
-{
- const char *path = qdict_get_str(qdict, "path");
- const char *property = qdict_get_str(qdict, "property");
- const char *value = qdict_get_str(qdict, "value");
- Error *err = NULL;
- bool ambiguous = false;
- Object *obj;
-
- obj = object_resolve_path(path, &ambiguous);
- if (obj == NULL) {
- error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
- "Device '%s' not found", path);
- } else {
- if (ambiguous) {
- monitor_printf(mon, "Warning: Path '%s' is ambiguous\n", path);
- }
- object_property_parse(obj, value, property, &err);
- }
- hmp_handle_error(mon, &err);
-}
-
void hmp_rocker(Monitor *mon, const QDict *qdict)
{
const char *name = qdict_get_str(qdict, "name");
qapi_free_RockerOfDpaGroupList(list);
}
-void hmp_info_dump(Monitor *mon, const QDict *qdict)
-{
- DumpQueryResult *result = qmp_query_dump(NULL);
-
- assert(result && result->status < DUMP_STATUS__MAX);
- monitor_printf(mon, "Status: %s\n", DumpStatus_str(result->status));
-
- if (result->status == DUMP_STATUS_ACTIVE) {
- float percent = 0;
- assert(result->total != 0);
- percent = 100.0 * result->completed / result->total;
- monitor_printf(mon, "Finished: %.2f %%\n", percent);
- }
-
- qapi_free_DumpQueryResult(result);
-}
-
void hmp_info_ramblock(Monitor *mon, const QDict *qdict)
{
ram_block_dump(mon);
}
-void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
-{
- Error *err = NULL;
- HotpluggableCPUList *l = qmp_query_hotpluggable_cpus(&err);
- HotpluggableCPUList *saved = l;
- CpuInstanceProperties *c;
-
- if (err != NULL) {
- hmp_handle_error(mon, &err);
- return;
- }
-
- monitor_printf(mon, "Hotpluggable CPUs:\n");
- while (l) {
- monitor_printf(mon, " type: \"%s\"\n", l->value->type);
- monitor_printf(mon, " vcpus_count: \"%" PRIu64 "\"\n",
- l->value->vcpus_count);
- if (l->value->has_qom_path) {
- monitor_printf(mon, " qom_path: \"%s\"\n", l->value->qom_path);
- }
-
- c = l->value->props;
- monitor_printf(mon, " CPUInstance Properties:\n");
- if (c->has_node_id) {
- monitor_printf(mon, " node-id: \"%" PRIu64 "\"\n", c->node_id);
- }
- if (c->has_socket_id) {
- monitor_printf(mon, " socket-id: \"%" PRIu64 "\"\n", c->socket_id);
- }
- if (c->has_core_id) {
- monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id);
- }
- if (c->has_thread_id) {
- monitor_printf(mon, " thread-id: \"%" PRIu64 "\"\n", c->thread_id);
- }
-
- l = l->next;
- }
-
- qapi_free_HotpluggableCPUList(saved);
-}
-
void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict)
{
Error *err = NULL;
#include "net/slirp.h"
#include "chardev/char-mux.h"
#include "ui/qemu-spice.h"
-#include "sysemu/numa.h"
#include "qemu/config-file.h"
#include "qemu/ctype.h"
#include "ui/console.h"
#include "sysemu/hw_accel.h"
#include "authz/list.h"
#include "qapi/util.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/sysemu.h"
#include "sysemu/tcg.h"
#include "sysemu/tpm.h"
#include "qapi/qmp/qdict.h"
#include "qom/object_interfaces.h"
#include "trace/control.h"
#include "monitor/hmp-target.h"
+#include "monitor/hmp.h"
#ifdef CONFIG_TRACE_SIMPLE
#include "trace/simple.h"
#endif
#include "exec/memory.h"
#include "exec/exec-all.h"
#include "qemu/option.h"
-#include "hmp.h"
#include "qemu/thread.h"
#include "block/qapi.h"
#include "qapi/qapi-commands.h"
mtree_info(flatview, dispatch_tree, owner);
}
-static void hmp_info_numa(Monitor *mon, const QDict *qdict)
-{
- int i;
- NumaNodeMem *node_mem;
- CpuInfoList *cpu_list, *cpu;
-
- cpu_list = qmp_query_cpus(&error_abort);
- node_mem = g_new0(NumaNodeMem, nb_numa_nodes);
-
- query_numa_node_mem(node_mem);
- monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
- for (i = 0; i < nb_numa_nodes; i++) {
- monitor_printf(mon, "node %d cpus:", i);
- for (cpu = cpu_list; cpu; cpu = cpu->next) {
- if (cpu->value->has_props && cpu->value->props->has_node_id &&
- cpu->value->props->node_id == i) {
- monitor_printf(mon, " %" PRIi64, cpu->value->CPU);
- }
- }
- monitor_printf(mon, "\n");
- monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i,
- node_mem[i].node_mem >> 20);
- monitor_printf(mon, "node %d plugged: %" PRId64 " MB\n", i,
- node_mem[i].node_plugged_mem >> 20);
- }
- qapi_free_CpuInfoList(cpu_list);
- g_free(node_mem);
-}
-
#ifdef CONFIG_PROFILER
int64_t dev_time;
sortcmdlist();
qemu_mutex_init(&mon_fdsets_lock);
}
-
-HotpluggableCPUList *qmp_query_hotpluggable_cpus(Error **errp)
-{
- MachineState *ms = MACHINE(qdev_get_machine());
- MachineClass *mc = MACHINE_GET_CLASS(ms);
-
- if (!mc->has_hotpluggable_cpus) {
- error_setg(errp, QERR_FEATURE_DISABLED, "query-hotpluggable-cpus");
- return NULL;
- }
-
- return machine_query_hotpluggable_cpus(ms);
-}
#include "ui/vnc.h"
#include "sysemu/kvm.h"
#include "sysemu/arch_init.h"
-#include "hw/qdev.h"
#include "sysemu/blockdev.h"
#include "sysemu/block-backend.h"
-#include "qom/qom-qobject.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-block-core.h"
+#include "qapi/qapi-commands-machine.h"
#include "qapi/qapi-commands-misc.h"
#include "qapi/qapi-commands-ui.h"
-#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
-#include "qapi/qobject-input-visitor.h"
#include "hw/boards.h"
-#include "qom/object_interfaces.h"
#include "hw/mem/memory-device.h"
#include "hw/acpi/acpi_dev_interface.h"
qemu_system_powerdown_request();
}
-void qmp_cpu_add(int64_t id, Error **errp)
-{
- MachineClass *mc;
-
- mc = MACHINE_GET_CLASS(current_machine);
- if (mc->hot_add_cpu) {
- mc->hot_add_cpu(id, errp);
- } else {
- error_setg(errp, "Not supported");
- }
-}
-
void qmp_x_exit_preconfig(Error **errp)
{
if (!runstate_check(RUN_STATE_PRECONFIG)) {
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, errp);
}
-ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
-{
- Object *obj;
- bool ambiguous = false;
- ObjectPropertyInfoList *props = NULL;
- ObjectProperty *prop;
- ObjectPropertyIterator iter;
-
- obj = object_resolve_path(path, &ambiguous);
- if (obj == NULL) {
- if (ambiguous) {
- error_setg(errp, "Path '%s' is ambiguous", path);
- } else {
- error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
- "Device '%s' not found", path);
- }
- return NULL;
- }
-
- object_property_iter_init(&iter, obj);
- while ((prop = object_property_iter_next(&iter))) {
- ObjectPropertyInfoList *entry = g_malloc0(sizeof(*entry));
-
- entry->value = g_malloc0(sizeof(ObjectPropertyInfo));
- entry->next = props;
- props = entry;
-
- entry->value->name = g_strdup(prop->name);
- entry->value->type = g_strdup(prop->type);
- }
-
- return props;
-}
-
-void qmp_qom_set(const char *path, const char *property, QObject *value,
- Error **errp)
-{
- Object *obj;
-
- obj = object_resolve_path(path, NULL);
- if (!obj) {
- error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
- "Device '%s' not found", path);
- return;
- }
-
- object_property_set_qobject(obj, value, property, errp);
-}
-
-QObject *qmp_qom_get(const char *path, const char *property, Error **errp)
-{
- Object *obj;
-
- obj = object_resolve_path(path, NULL);
- if (!obj) {
- error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
- "Device '%s' not found", path);
- return NULL;
- }
-
- return object_property_get_qobject(obj, property, errp);
-}
-
void qmp_set_password(const char *protocol, const char *password,
bool has_connected, const char *connected, Error **errp)
{
}
}
-static void qom_list_types_tramp(ObjectClass *klass, void *data)
-{
- ObjectTypeInfoList *e, **pret = data;
- ObjectTypeInfo *info;
- ObjectClass *parent = object_class_get_parent(klass);
-
- info = g_malloc0(sizeof(*info));
- info->name = g_strdup(object_class_get_name(klass));
- info->has_abstract = info->abstract = object_class_is_abstract(klass);
- if (parent) {
- info->has_parent = true;
- info->parent = g_strdup(object_class_get_name(parent));
- }
-
- e = g_malloc0(sizeof(*e));
- e->value = info;
- e->next = *pret;
- *pret = e;
-}
-
-ObjectTypeInfoList *qmp_qom_list_types(bool has_implements,
- const char *implements,
- bool has_abstract,
- bool abstract,
- Error **errp)
-{
- ObjectTypeInfoList *ret = NULL;
-
- object_class_foreach(qom_list_types_tramp, implements, abstract, &ret);
-
- return ret;
-}
-
-/* Return a DevicePropertyInfo for a qdev property.
- *
- * If a qdev property with the given name does not exist, use the given default
- * type. If the qdev property info should not be shown, return NULL.
- *
- * The caller must free the return value.
- */
-static ObjectPropertyInfo *make_device_property_info(ObjectClass *klass,
- const char *name,
- const char *default_type,
- const char *description)
-{
- ObjectPropertyInfo *info;
- Property *prop;
-
- do {
- for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) {
- if (strcmp(name, prop->name) != 0) {
- continue;
- }
-
- /*
- * TODO Properties without a parser are just for dirty hacks.
- * qdev_prop_ptr is the only such PropertyInfo. It's marked
- * for removal. This conditional should be removed along with
- * it.
- */
- if (!prop->info->set && !prop->info->create) {
- return NULL; /* no way to set it, don't show */
- }
-
- info = g_malloc0(sizeof(*info));
- info->name = g_strdup(prop->name);
- info->type = default_type ? g_strdup(default_type)
- : g_strdup(prop->info->name);
- info->has_description = !!prop->info->description;
- info->description = g_strdup(prop->info->description);
- return info;
- }
- klass = object_class_get_parent(klass);
- } while (klass != object_class_by_name(TYPE_DEVICE));
-
- /* Not a qdev property, use the default type */
- info = g_malloc0(sizeof(*info));
- info->name = g_strdup(name);
- info->type = g_strdup(default_type);
- info->has_description = !!description;
- info->description = g_strdup(description);
-
- return info;
-}
-
-ObjectPropertyInfoList *qmp_device_list_properties(const char *typename,
- Error **errp)
-{
- ObjectClass *klass;
- Object *obj;
- ObjectProperty *prop;
- ObjectPropertyIterator iter;
- ObjectPropertyInfoList *prop_list = NULL;
-
- klass = object_class_by_name(typename);
- if (klass == NULL) {
- error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
- "Device '%s' not found", typename);
- return NULL;
- }
-
- klass = object_class_dynamic_cast(klass, TYPE_DEVICE);
- if (klass == NULL) {
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename", TYPE_DEVICE);
- return NULL;
- }
-
- if (object_class_is_abstract(klass)) {
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename",
- "non-abstract device type");
- return NULL;
- }
-
- obj = object_new(typename);
-
- object_property_iter_init(&iter, obj);
- while ((prop = object_property_iter_next(&iter))) {
- ObjectPropertyInfo *info;
- ObjectPropertyInfoList *entry;
-
- /* Skip Object and DeviceState properties */
- if (strcmp(prop->name, "type") == 0 ||
- strcmp(prop->name, "realized") == 0 ||
- strcmp(prop->name, "hotpluggable") == 0 ||
- strcmp(prop->name, "hotplugged") == 0 ||
- strcmp(prop->name, "parent_bus") == 0) {
- continue;
- }
-
- /* Skip legacy properties since they are just string versions of
- * properties that we already list.
- */
- if (strstart(prop->name, "legacy-", NULL)) {
- continue;
- }
-
- info = make_device_property_info(klass, prop->name, prop->type,
- prop->description);
- if (!info) {
- continue;
- }
-
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = prop_list;
- prop_list = entry;
- }
-
- object_unref(obj);
-
- return prop_list;
-}
-
-ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename,
- Error **errp)
-{
- ObjectClass *klass;
- Object *obj = NULL;
- ObjectProperty *prop;
- ObjectPropertyIterator iter;
- ObjectPropertyInfoList *prop_list = NULL;
-
- klass = object_class_by_name(typename);
- if (klass == NULL) {
- error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
- "Class '%s' not found", typename);
- return NULL;
- }
-
- klass = object_class_dynamic_cast(klass, TYPE_OBJECT);
- if (klass == NULL) {
- error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename", TYPE_OBJECT);
- return NULL;
- }
-
- if (object_class_is_abstract(klass)) {
- object_class_property_iter_init(&iter, klass);
- } else {
- obj = object_new(typename);
- object_property_iter_init(&iter, obj);
- }
- while ((prop = object_property_iter_next(&iter))) {
- ObjectPropertyInfo *info;
- ObjectPropertyInfoList *entry;
-
- info = g_malloc0(sizeof(*info));
- info->name = g_strdup(prop->name);
- info->type = g_strdup(prop->type);
- info->has_description = !!prop->description;
- info->description = g_strdup(prop->description);
-
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = prop_list;
- prop_list = entry;
- }
-
- object_unref(obj);
-
- return prop_list;
-}
-
void qmp_add_client(const char *protocol, const char *fdname,
bool has_skipauth, bool skipauth, bool has_tls, bool tls,
Error **errp)
}
-void qmp_object_add(const char *type, const char *id,
- bool has_props, QObject *props, Error **errp)
-{
- QDict *pdict;
- Visitor *v;
- Object *obj;
-
- if (props) {
- pdict = qobject_to(QDict, props);
- if (!pdict) {
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
- return;
- }
- qobject_ref(pdict);
- } else {
- pdict = qdict_new();
- }
-
- v = qobject_input_visitor_new(QOBJECT(pdict));
- obj = user_creatable_add_type(type, id, pdict, v, errp);
- visit_free(v);
- if (obj) {
- object_unref(obj);
- }
- qobject_unref(pdict);
-}
-
-void qmp_object_del(const char *id, Error **errp)
-{
- user_creatable_del(id, errp);
-}
-
MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp)
{
return qmp_memory_device_list();
#include "qapi/qapi-commands-net.h"
#include "trace.h"
+static GData *named_timers;
+
int64_t qemu_announce_timer_step(AnnounceTimer *timer)
{
int64_t step;
return step;
}
-void qemu_announce_timer_del(AnnounceTimer *timer)
+/*
+ * If 'free_named' is true, then remove the timer from the list
+ * and free the timer itself.
+ */
+void qemu_announce_timer_del(AnnounceTimer *timer, bool free_named)
{
+ bool free_timer = false;
if (timer->tm) {
timer_del(timer->tm);
timer_free(timer->tm);
timer->tm = NULL;
}
+ qapi_free_strList(timer->params.interfaces);
+ timer->params.interfaces = NULL;
+ if (free_named && timer->params.has_id) {
+ AnnounceTimer *list_timer;
+ /*
+ * Sanity check: There should only be one timer on the list with
+ * the id.
+ */
+ list_timer = g_datalist_get_data(&named_timers, timer->params.id);
+ assert(timer == list_timer);
+ free_timer = true;
+ g_datalist_remove_data(&named_timers, timer->params.id);
+ }
+ trace_qemu_announce_timer_del(free_named, free_timer, timer->params.id);
+ g_free(timer->params.id);
+ timer->params.id = NULL;
+
+ if (free_timer) {
+ g_free(timer);
+ }
}
/*
* We're under the BQL, so the current timer can't
* be firing, so we should be able to delete it.
*/
- qemu_announce_timer_del(timer);
+ qemu_announce_timer_del(timer, false);
QAPI_CLONE_MEMBERS(AnnounceParameters, &timer->params, params);
timer->round = params->rounds;
static void qemu_announce_self_iter(NICState *nic, void *opaque)
{
+ AnnounceTimer *timer = opaque;
uint8_t buf[60];
int len;
+ bool skip;
+
+ if (timer->params.has_interfaces) {
+ strList *entry = timer->params.interfaces;
+ /* Skip unless we find our name in the requested list */
+ skip = true;
+
+ while (entry) {
+ if (!strcmp(entry->value, nic->ncs->name)) {
+ /* Found us */
+ skip = false;
+ break;
+ }
+ entry = entry->next;
+ }
+ } else {
+ skip = false;
+ }
+
+ trace_qemu_announce_self_iter(timer->params.has_id ? timer->params.id : "_",
+ nic->ncs->name,
+ qemu_ether_ntoa(&nic->conf->macaddr), skip);
- trace_qemu_announce_self_iter(qemu_ether_ntoa(&nic->conf->macaddr));
- len = announce_self_create(buf, nic->conf->macaddr.a);
+ if (!skip) {
+ len = announce_self_create(buf, nic->conf->macaddr.a);
- qemu_send_packet_raw(qemu_get_queue(nic), buf, len);
+ qemu_send_packet_raw(qemu_get_queue(nic), buf, len);
- /* if the NIC provides it's own announcement support, use it as well */
- if (nic->ncs->info->announce) {
- nic->ncs->info->announce(nic->ncs);
+ /* if the NIC provides it's own announcement support, use it as well */
+ if (nic->ncs->info->announce) {
+ nic->ncs->info->announce(nic->ncs);
+ }
}
}
static void qemu_announce_self_once(void *opaque)
{
AnnounceTimer *timer = (AnnounceTimer *)opaque;
- qemu_foreach_nic(qemu_announce_self_iter, NULL);
+ qemu_foreach_nic(qemu_announce_self_iter, timer);
if (--timer->round) {
qemu_announce_timer_step(timer);
} else {
- qemu_announce_timer_del(timer);
+ qemu_announce_timer_del(timer, true);
}
}
if (params->rounds) {
qemu_announce_self_once(timer);
} else {
- qemu_announce_timer_del(timer);
+ qemu_announce_timer_del(timer, true);
}
}
void qmp_announce_self(AnnounceParameters *params, Error **errp)
{
- static AnnounceTimer announce_timer;
- qemu_announce_self(&announce_timer, params);
+ AnnounceTimer *named_timer;
+ if (!params->has_id) {
+ params->id = g_strdup("");
+ params->has_id = true;
+ }
+
+ named_timer = g_datalist_get_data(&named_timers, params->id);
+
+ if (!named_timer) {
+ named_timer = g_new0(AnnounceTimer, 1);
+ g_datalist_set_data(&named_timers, params->id, named_timer);
+ }
+
+ qemu_announce_self(named_timer, params);
}
char *pri_indev;
char *sec_indev;
char *outdev;
+ char *notify_dev;
CharBackend chr_pri_in;
CharBackend chr_sec_in;
CharBackend chr_out;
+ CharBackend chr_notify_dev;
SocketReadState pri_rs;
SocketReadState sec_rs;
+ SocketReadState notify_rs;
bool vnet_hdr;
/*
SECONDARY_IN,
};
-static void colo_compare_inconsistency_notify(void)
-{
- notifier_list_notify(&colo_compare_notifiers,
- migrate_get_current());
-}
static int compare_chr_send(CompareState *s,
const uint8_t *buf,
uint32_t size,
- uint32_t vnet_hdr_len);
+ uint32_t vnet_hdr_len,
+ bool notify_remote_frame);
+
+static void notify_remote_frame(CompareState *s)
+{
+ char msg[] = "DO_CHECKPOINT";
+ int ret = 0;
+
+ ret = compare_chr_send(s, (uint8_t *)msg, strlen(msg), 0, true);
+ if (ret < 0) {
+ error_report("Notify Xen COLO-frame failed");
+ }
+}
+
+static void colo_compare_inconsistency_notify(CompareState *s)
+{
+ if (s->notify_dev) {
+ notify_remote_frame(s);
+ } else {
+ notifier_list_notify(&colo_compare_notifiers,
+ migrate_get_current());
+ }
+}
static gint seq_sorter(Packet *a, Packet *b, gpointer data)
{
ret = compare_chr_send(s,
pkt->data,
pkt->size,
- pkt->vnet_hdr_len);
+ pkt->vnet_hdr_len,
+ false);
if (ret < 0) {
error_report("colo send primary packet failed");
}
qemu_hexdump((char *)spkt->data, stderr,
"colo-compare spkt", spkt->size);
- colo_compare_inconsistency_notify();
+ colo_compare_inconsistency_notify(s);
}
}
}
static int colo_old_packet_check_one_conn(Connection *conn,
- void *user_data)
+ CompareState *s)
{
GList *result = NULL;
int64_t check_time = REGULAR_PACKET_CHECK_MS;
if (result) {
/* Do checkpoint will flush old packet */
- colo_compare_inconsistency_notify();
+ colo_compare_inconsistency_notify(s);
return 0;
}
* If we find one old packet, stop finding job and notify
* COLO frame do checkpoint.
*/
- g_queue_find_custom(&s->conn_list, NULL,
+ g_queue_find_custom(&s->conn_list, s,
(GCompareFunc)colo_old_packet_check_one_conn);
}
*/
trace_colo_compare_main("packet different");
g_queue_push_head(&conn->primary_list, pkt);
- colo_compare_inconsistency_notify();
+
+ colo_compare_inconsistency_notify(s);
break;
}
}
static int compare_chr_send(CompareState *s,
const uint8_t *buf,
uint32_t size,
- uint32_t vnet_hdr_len)
+ uint32_t vnet_hdr_len,
+ bool notify_remote_frame)
{
int ret = 0;
uint32_t len = htonl(size);
return 0;
}
- ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
+ if (notify_remote_frame) {
+ ret = qemu_chr_fe_write_all(&s->chr_notify_dev,
+ (uint8_t *)&len,
+ sizeof(len));
+ } else {
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
+ }
+
if (ret != sizeof(len)) {
goto err;
}
* know how to parse net packet correctly.
*/
len = htonl(vnet_hdr_len);
- ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
+
+ if (!notify_remote_frame) {
+ ret = qemu_chr_fe_write_all(&s->chr_out,
+ (uint8_t *)&len,
+ sizeof(len));
+ }
+
if (ret != sizeof(len)) {
goto err;
}
}
- ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
+ if (notify_remote_frame) {
+ ret = qemu_chr_fe_write_all(&s->chr_notify_dev,
+ (uint8_t *)buf,
+ size);
+ } else {
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
+ }
+
if (ret != size) {
goto err;
}
}
}
+static void compare_notify_chr(void *opaque, const uint8_t *buf, int size)
+{
+ CompareState *s = COLO_COMPARE(opaque);
+ int ret;
+
+ ret = net_fill_rstate(&s->notify_rs, buf, size);
+ if (ret == -1) {
+ qemu_chr_fe_set_handlers(&s->chr_notify_dev, NULL, NULL, NULL, NULL,
+ NULL, NULL, true);
+ error_report("colo-compare notify_dev error");
+ }
+}
+
/*
* Check old packet regularly so it can watch for any packets
* that the secondary hasn't produced equivalents of.
qemu_chr_fe_set_handlers(&s->chr_sec_in, compare_chr_can_read,
compare_sec_chr_in, NULL, NULL,
s, s->worker_context, true);
+ if (s->notify_dev) {
+ qemu_chr_fe_set_handlers(&s->chr_notify_dev, compare_chr_can_read,
+ compare_notify_chr, NULL, NULL,
+ s, s->worker_context, true);
+ }
colo_compare_timer_init(s);
s->event_bh = qemu_bh_new(colo_compare_handle_event, s);
s->vnet_hdr = value;
}
+static char *compare_get_notify_dev(Object *obj, Error **errp)
+{
+ CompareState *s = COLO_COMPARE(obj);
+
+ return g_strdup(s->notify_dev);
+}
+
+static void compare_set_notify_dev(Object *obj, const char *value, Error **errp)
+{
+ CompareState *s = COLO_COMPARE(obj);
+
+ g_free(s->notify_dev);
+ s->notify_dev = g_strdup(value);
+}
+
static void compare_pri_rs_finalize(SocketReadState *pri_rs)
{
CompareState *s = container_of(pri_rs, CompareState, pri_rs);
compare_chr_send(s,
pri_rs->buf,
pri_rs->packet_len,
- pri_rs->vnet_hdr_len);
+ pri_rs->vnet_hdr_len,
+ false);
} else {
/* compare packet in the specified connection */
colo_compare_connection(conn, s);
}
}
+static void compare_notify_rs_finalize(SocketReadState *notify_rs)
+{
+ CompareState *s = container_of(notify_rs, CompareState, notify_rs);
+
+ /* Get Xen colo-frame's notify and handle the message */
+ char *data = g_memdup(notify_rs->buf, notify_rs->packet_len);
+ char msg[] = "COLO_COMPARE_GET_XEN_INIT";
+ int ret;
+
+ if (!strcmp(data, "COLO_USERSPACE_PROXY_INIT")) {
+ ret = compare_chr_send(s, (uint8_t *)msg, strlen(msg), 0, true);
+ if (ret < 0) {
+ error_report("Notify Xen COLO-frame INIT failed");
+ }
+ }
+
+ if (!strcmp(data, "COLO_CHECKPOINT")) {
+ /* colo-compare do checkpoint, flush pri packet and remove sec packet */
+ g_queue_foreach(&s->conn_list, colo_flush_packets, s);
+ }
+}
/*
* Return 0 is success.
net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, s->vnet_hdr);
net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, s->vnet_hdr);
+ /* Try to enable remote notify chardev, currently just for Xen COLO */
+ if (s->notify_dev) {
+ if (find_and_check_chardev(&chr, s->notify_dev, errp) ||
+ !qemu_chr_fe_init(&s->chr_notify_dev, chr, errp)) {
+ return;
+ }
+
+ net_socket_rs_init(&s->notify_rs, compare_notify_rs_finalize,
+ s->vnet_hdr);
+ }
+
QTAILQ_INSERT_TAIL(&net_compares, s, next);
g_queue_init(&s->conn_list);
compare_chr_send(s,
pkt->data,
pkt->size,
- pkt->vnet_hdr_len);
+ pkt->vnet_hdr_len,
+ false);
packet_destroy(pkt, NULL);
}
while (!g_queue_is_empty(&conn->secondary_list)) {
(Object **)&s->iothread,
object_property_allow_set_link,
OBJ_PROP_LINK_STRONG, NULL);
+ /* This parameter just for Xen COLO */
+ object_property_add_str(obj, "notify_dev",
+ compare_get_notify_dev, compare_set_notify_dev,
+ NULL);
s->vnet_hdr = false;
object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
qemu_chr_fe_deinit(&s->chr_pri_in, false);
qemu_chr_fe_deinit(&s->chr_sec_in, false);
qemu_chr_fe_deinit(&s->chr_out, false);
+ if (s->notify_dev) {
+ qemu_chr_fe_deinit(&s->chr_notify_dev, false);
+ }
+
if (s->iothread) {
colo_compare_timer_del(s);
}
g_free(s->pri_indev);
g_free(s->sec_indev);
g_free(s->outdev);
+ g_free(s->notify_dev);
}
static const TypeInfo colo_compare_info = {
/***********************************************************/
/* network device redirectors */
-static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
-{
- const char *p, *p1;
- int len;
- p = *pp;
- p1 = strchr(p, sep);
- if (!p1)
- return -1;
- len = p1 - p;
- p1++;
- if (buf_size > 0) {
- if (len > buf_size - 1)
- len = buf_size - 1;
- memcpy(buf, p, len);
- buf[len] = '\0';
- }
- *pp = p1;
- return 0;
-}
-
int parse_host_port(struct sockaddr_in *saddr, const char *str,
Error **errp)
{
- char buf[512];
+ gchar **substrings;
struct hostent *he;
- const char *p, *r;
- int port;
+ const char *addr, *p, *r;
+ int port, ret = 0;
- p = str;
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
+ 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);
- return -1;
+ ret = -1;
+ goto out;
}
+
+ addr = substrings[0];
+ p = substrings[1];
+
saddr->sin_family = AF_INET;
- if (buf[0] == '\0') {
+ if (addr[0] == '\0') {
saddr->sin_addr.s_addr = 0;
} else {
- if (qemu_isdigit(buf[0])) {
- if (!inet_aton(buf, &saddr->sin_addr)) {
+ if (qemu_isdigit(addr[0])) {
+ if (!inet_aton(addr, &saddr->sin_addr)) {
error_setg(errp, "host address '%s' is not a valid "
- "IPv4 address", buf);
- return -1;
+ "IPv4 address", addr);
+ ret = -1;
+ goto out;
}
} else {
- he = gethostbyname(buf);
+ he = gethostbyname(addr);
if (he == NULL) {
- error_setg(errp, "can't resolve host address '%s'", buf);
- return - 1;
+ error_setg(errp, "can't resolve host address '%s'", addr);
+ ret = -1;
+ goto out;
}
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);
- return -1;
+ ret = -1;
+ goto out;
}
saddr->sin_port = htons(port);
- return 0;
+
+out:
+ g_strfreev(substrings);
+ return ret;
}
char *qemu_mac_strdup_printf(const uint8_t *macaddr)
static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
{
+ gchar **substrings = NULL;
void *object = NULL;
Error *err = NULL;
int ret = -1;
const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
if (ip6_net) {
- char buf[strlen(ip6_net) + 1];
+ char *prefix_addr;
+ unsigned long prefix_len = 64; /* Default 64bit prefix length. */
+
+ substrings = g_strsplit(ip6_net, "/", 2);
+ if (!substrings || !substrings[0]) {
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net",
+ "a valid IPv6 prefix");
+ goto out;
+ }
- if (get_str_sep(buf, sizeof(buf), &ip6_net, '/') < 0) {
- /* Default 64bit prefix length. */
- qemu_opt_set(opts, "ipv6-prefix", ip6_net, &error_abort);
- qemu_opt_set_number(opts, "ipv6-prefixlen", 64, &error_abort);
- } else {
+ prefix_addr = substrings[0];
+
+ if (substrings[1]) {
/* User-specified prefix length. */
- unsigned long len;
int err;
- qemu_opt_set(opts, "ipv6-prefix", buf, &error_abort);
- err = qemu_strtoul(ip6_net, NULL, 10, &len);
-
+ err = qemu_strtoul(substrings[1], NULL, 10, &prefix_len);
if (err) {
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
- "ipv6-prefix", "a number");
- } else {
- qemu_opt_set_number(opts, "ipv6-prefixlen", len,
- &error_abort);
+ "ipv6-prefixlen", "a number");
+ goto out;
}
}
+
+ qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort);
+ qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len,
+ &error_abort);
qemu_opt_unset(opts, "ipv6-net");
}
}
qapi_free_NetLegacy(object);
}
+out:
error_propagate(errp, err);
+ g_strfreev(substrings);
visit_free(v);
return ret;
}
# See docs/devel/tracing.txt for syntax documentation.
# announce.c
-qemu_announce_self_iter(const char *mac) "%s"
+qemu_announce_self_iter(const char *id, const char *name, const char *mac, int skip) "%s:%s:%s skip: %d"
+qemu_announce_timer_del(bool free_named, bool free_timer, char *id) "free named: %d free timer: %d id: %s"
# vhost-user.c
vhost_user_event(const char *chr, int event) "chr: %s got event: %d"
+++ /dev/null
-/*
- * NUMA parameter parsing routines
- *
- * Copyright (c) 2014 Fujitsu Ltd.
- *
- * 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 "sysemu/numa.h"
-#include "exec/cpu-common.h"
-#include "exec/ramlist.h"
-#include "qemu/bitmap.h"
-#include "qom/cpu.h"
-#include "qemu/error-report.h"
-#include "qapi/error.h"
-#include "qapi/opts-visitor.h"
-#include "qapi/qapi-commands-misc.h"
-#include "qapi/qapi-visit-misc.h"
-#include "hw/boards.h"
-#include "sysemu/hostmem.h"
-#include "hw/mem/pc-dimm.h"
-#include "hw/mem/memory-device.h"
-#include "qemu/option.h"
-#include "qemu/config-file.h"
-#include "qemu/cutils.h"
-
-QemuOptsList qemu_numa_opts = {
- .name = "numa",
- .implied_opt_name = "type",
- .head = QTAILQ_HEAD_INITIALIZER(qemu_numa_opts.head),
- .desc = { { 0 } } /* validated with OptsVisitor */
-};
-
-static int have_memdevs = -1;
-static int max_numa_nodeid; /* Highest specified NUMA node ID, plus one.
- * For all nodes, nodeid < max_numa_nodeid
- */
-int nb_numa_nodes;
-bool have_numa_distance;
-NodeInfo numa_info[MAX_NODES];
-
-
-static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
- Error **errp)
-{
- Error *err = NULL;
- uint16_t nodenr;
- uint16List *cpus = NULL;
- MachineClass *mc = MACHINE_GET_CLASS(ms);
-
- if (node->has_nodeid) {
- nodenr = node->nodeid;
- } else {
- nodenr = nb_numa_nodes;
- }
-
- if (nodenr >= MAX_NODES) {
- error_setg(errp, "Max number of NUMA nodes reached: %"
- PRIu16 "", nodenr);
- return;
- }
-
- if (numa_info[nodenr].present) {
- error_setg(errp, "Duplicate NUMA nodeid: %" PRIu16, nodenr);
- return;
- }
-
- if (!mc->cpu_index_to_instance_props || !mc->get_default_cpu_node_id) {
- error_setg(errp, "NUMA is not supported by this machine-type");
- return;
- }
- for (cpus = node->cpus; cpus; cpus = cpus->next) {
- CpuInstanceProperties props;
- if (cpus->value >= max_cpus) {
- error_setg(errp,
- "CPU index (%" PRIu16 ")"
- " should be smaller than maxcpus (%d)",
- cpus->value, max_cpus);
- return;
- }
- props = mc->cpu_index_to_instance_props(ms, cpus->value);
- props.node_id = nodenr;
- props.has_node_id = true;
- machine_set_cpu_numa_node(ms, &props, &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- }
-
- if (node->has_mem && node->has_memdev) {
- error_setg(errp, "cannot specify both mem= and memdev=");
- return;
- }
-
- if (have_memdevs == -1) {
- have_memdevs = node->has_memdev;
- }
- if (node->has_memdev != have_memdevs) {
- error_setg(errp, "memdev option must be specified for either "
- "all or no nodes");
- return;
- }
-
- if (node->has_mem) {
- numa_info[nodenr].node_mem = node->mem;
- }
- if (node->has_memdev) {
- Object *o;
- o = object_resolve_path_type(node->memdev, TYPE_MEMORY_BACKEND, NULL);
- if (!o) {
- error_setg(errp, "memdev=%s is ambiguous", node->memdev);
- return;
- }
-
- object_ref(o);
- numa_info[nodenr].node_mem = object_property_get_uint(o, "size", NULL);
- numa_info[nodenr].node_memdev = MEMORY_BACKEND(o);
- }
- numa_info[nodenr].present = true;
- max_numa_nodeid = MAX(max_numa_nodeid, nodenr + 1);
- nb_numa_nodes++;
-}
-
-static void parse_numa_distance(NumaDistOptions *dist, Error **errp)
-{
- uint16_t src = dist->src;
- uint16_t dst = dist->dst;
- uint8_t val = dist->val;
-
- if (src >= MAX_NODES || dst >= MAX_NODES) {
- error_setg(errp, "Parameter '%s' expects an integer between 0 and %d",
- src >= MAX_NODES ? "src" : "dst", MAX_NODES - 1);
- return;
- }
-
- if (!numa_info[src].present || !numa_info[dst].present) {
- error_setg(errp, "Source/Destination NUMA node is missing. "
- "Please use '-numa node' option to declare it first.");
- return;
- }
-
- if (val < NUMA_DISTANCE_MIN) {
- error_setg(errp, "NUMA distance (%" PRIu8 ") is invalid, "
- "it shouldn't be less than %d.",
- val, NUMA_DISTANCE_MIN);
- return;
- }
-
- if (src == dst && val != NUMA_DISTANCE_MIN) {
- error_setg(errp, "Local distance of node %d should be %d.",
- src, NUMA_DISTANCE_MIN);
- return;
- }
-
- numa_info[src].distance[dst] = val;
- have_numa_distance = true;
-}
-
-static
-void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp)
-{
- Error *err = NULL;
-
- switch (object->type) {
- case NUMA_OPTIONS_TYPE_NODE:
- parse_numa_node(ms, &object->u.node, &err);
- if (err) {
- goto end;
- }
- break;
- case NUMA_OPTIONS_TYPE_DIST:
- parse_numa_distance(&object->u.dist, &err);
- if (err) {
- goto end;
- }
- break;
- case NUMA_OPTIONS_TYPE_CPU:
- if (!object->u.cpu.has_node_id) {
- error_setg(&err, "Missing mandatory node-id property");
- goto end;
- }
- if (!numa_info[object->u.cpu.node_id].present) {
- error_setg(&err, "Invalid node-id=%" PRId64 ", NUMA node must be "
- "defined with -numa node,nodeid=ID before it's used with "
- "-numa cpu,node-id=ID", object->u.cpu.node_id);
- goto end;
- }
-
- machine_set_cpu_numa_node(ms, qapi_NumaCpuOptions_base(&object->u.cpu),
- &err);
- break;
- default:
- abort();
- }
-
-end:
- error_propagate(errp, err);
-}
-
-static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
-{
- NumaOptions *object = NULL;
- MachineState *ms = MACHINE(opaque);
- Error *err = NULL;
- Visitor *v = opts_visitor_new(opts);
-
- visit_type_NumaOptions(v, NULL, &object, &err);
- visit_free(v);
- if (err) {
- goto end;
- }
-
- /* Fix up legacy suffix-less format */
- if ((object->type == NUMA_OPTIONS_TYPE_NODE) && object->u.node.has_mem) {
- const char *mem_str = qemu_opt_get(opts, "mem");
- qemu_strtosz_MiB(mem_str, NULL, &object->u.node.mem);
- }
-
- set_numa_options(ms, object, &err);
-
-end:
- qapi_free_NumaOptions(object);
- if (err) {
- error_propagate(errp, err);
- return -1;
- }
-
- return 0;
-}
-
-/* If all node pair distances are symmetric, then only distances
- * in one direction are enough. If there is even one asymmetric
- * pair, though, then all distances must be provided. The
- * distance from a node to itself is always NUMA_DISTANCE_MIN,
- * so providing it is never necessary.
- */
-static void validate_numa_distance(void)
-{
- int src, dst;
- bool is_asymmetrical = false;
-
- for (src = 0; src < nb_numa_nodes; src++) {
- for (dst = src; dst < nb_numa_nodes; dst++) {
- if (numa_info[src].distance[dst] == 0 &&
- numa_info[dst].distance[src] == 0) {
- if (src != dst) {
- error_report("The distance between node %d and %d is "
- "missing, at least one distance value "
- "between each nodes should be provided.",
- src, dst);
- exit(EXIT_FAILURE);
- }
- }
-
- if (numa_info[src].distance[dst] != 0 &&
- numa_info[dst].distance[src] != 0 &&
- numa_info[src].distance[dst] !=
- numa_info[dst].distance[src]) {
- is_asymmetrical = true;
- }
- }
- }
-
- if (is_asymmetrical) {
- for (src = 0; src < nb_numa_nodes; src++) {
- for (dst = 0; dst < nb_numa_nodes; dst++) {
- if (src != dst && numa_info[src].distance[dst] == 0) {
- error_report("At least one asymmetrical pair of "
- "distances is given, please provide distances "
- "for both directions of all node pairs.");
- exit(EXIT_FAILURE);
- }
- }
- }
- }
-}
-
-static void complete_init_numa_distance(void)
-{
- int src, dst;
-
- /* Fixup NUMA distance by symmetric policy because if it is an
- * asymmetric distance table, it should be a complete table and
- * there would not be any missing distance except local node, which
- * is verified by validate_numa_distance above.
- */
- for (src = 0; src < nb_numa_nodes; src++) {
- for (dst = 0; dst < nb_numa_nodes; dst++) {
- if (numa_info[src].distance[dst] == 0) {
- if (src == dst) {
- numa_info[src].distance[dst] = NUMA_DISTANCE_MIN;
- } else {
- numa_info[src].distance[dst] = numa_info[dst].distance[src];
- }
- }
- }
- }
-}
-
-void numa_legacy_auto_assign_ram(MachineClass *mc, NodeInfo *nodes,
- int nb_nodes, ram_addr_t size)
-{
- int i;
- uint64_t usedmem = 0;
-
- /* Align each node according to the alignment
- * requirements of the machine class
- */
-
- for (i = 0; i < nb_nodes - 1; i++) {
- nodes[i].node_mem = (size / nb_nodes) &
- ~((1 << mc->numa_mem_align_shift) - 1);
- usedmem += nodes[i].node_mem;
- }
- nodes[i].node_mem = size - usedmem;
-}
-
-void numa_default_auto_assign_ram(MachineClass *mc, NodeInfo *nodes,
- int nb_nodes, ram_addr_t size)
-{
- int i;
- uint64_t usedmem = 0, node_mem;
- uint64_t granularity = size / nb_nodes;
- uint64_t propagate = 0;
-
- for (i = 0; i < nb_nodes - 1; i++) {
- node_mem = (granularity + propagate) &
- ~((1 << mc->numa_mem_align_shift) - 1);
- propagate = granularity + propagate - node_mem;
- nodes[i].node_mem = node_mem;
- usedmem += node_mem;
- }
- nodes[i].node_mem = size - usedmem;
-}
-
-void numa_complete_configuration(MachineState *ms)
-{
- int i;
- MachineClass *mc = MACHINE_GET_CLASS(ms);
-
- /*
- * If memory hotplug is enabled (slots > 0) but without '-numa'
- * options explicitly on CLI, guestes will break.
- *
- * Windows: won't enable memory hotplug without SRAT table at all
- *
- * Linux: if QEMU is started with initial memory all below 4Gb
- * and no SRAT table present, guest kernel will use nommu DMA ops,
- * which breaks 32bit hw drivers when memory is hotplugged and
- * guest tries to use it with that drivers.
- *
- * Enable NUMA implicitly by adding a new NUMA node automatically.
- */
- if (ms->ram_slots > 0 && nb_numa_nodes == 0 &&
- mc->auto_enable_numa_with_memhp) {
- NumaNodeOptions node = { };
- parse_numa_node(ms, &node, &error_abort);
- }
-
- assert(max_numa_nodeid <= MAX_NODES);
-
- /* No support for sparse NUMA node IDs yet: */
- for (i = max_numa_nodeid - 1; i >= 0; i--) {
- /* Report large node IDs first, to make mistakes easier to spot */
- if (!numa_info[i].present) {
- error_report("numa: Node ID missing: %d", i);
- exit(1);
- }
- }
-
- /* This must be always true if all nodes are present: */
- assert(nb_numa_nodes == max_numa_nodeid);
-
- if (nb_numa_nodes > 0) {
- uint64_t numa_total;
-
- if (nb_numa_nodes > MAX_NODES) {
- nb_numa_nodes = MAX_NODES;
- }
-
- /* If no memory size is given for any node, assume the default case
- * and distribute the available memory equally across all nodes
- */
- for (i = 0; i < nb_numa_nodes; i++) {
- if (numa_info[i].node_mem != 0) {
- break;
- }
- }
- if (i == nb_numa_nodes) {
- assert(mc->numa_auto_assign_ram);
- mc->numa_auto_assign_ram(mc, numa_info, nb_numa_nodes, ram_size);
- }
-
- numa_total = 0;
- for (i = 0; i < nb_numa_nodes; i++) {
- numa_total += numa_info[i].node_mem;
- }
- if (numa_total != ram_size) {
- error_report("total memory for NUMA nodes (0x%" PRIx64 ")"
- " should equal RAM size (0x" RAM_ADDR_FMT ")",
- numa_total, ram_size);
- exit(1);
- }
-
- /* QEMU needs at least all unique node pair distances to build
- * the whole NUMA distance table. QEMU treats the distance table
- * as symmetric by default, i.e. distance A->B == distance B->A.
- * Thus, QEMU is able to complete the distance table
- * initialization even though only distance A->B is provided and
- * distance B->A is not. QEMU knows the distance of a node to
- * itself is always 10, so A->A distances may be omitted. When
- * the distances of two nodes of a pair differ, i.e. distance
- * A->B != distance B->A, then that means the distance table is
- * asymmetric. In this case, the distances for both directions
- * of all node pairs are required.
- */
- if (have_numa_distance) {
- /* Validate enough NUMA distance information was provided. */
- validate_numa_distance();
-
- /* Validation succeeded, now fill in any missing distances. */
- complete_init_numa_distance();
- }
- }
-}
-
-void parse_numa_opts(MachineState *ms)
-{
- qemu_opts_foreach(qemu_find_opts("numa"), parse_numa, ms, &error_fatal);
-}
-
-void qmp_set_numa_node(NumaOptions *cmd, Error **errp)
-{
- if (!runstate_check(RUN_STATE_PRECONFIG)) {
- error_setg(errp, "The command is permitted only in '%s' state",
- RunState_str(RUN_STATE_PRECONFIG));
- return;
- }
-
- set_numa_options(MACHINE(qdev_get_machine()), cmd, errp);
-}
-
-void numa_cpu_pre_plug(const CPUArchId *slot, DeviceState *dev, Error **errp)
-{
- int node_id = object_property_get_int(OBJECT(dev), "node-id", &error_abort);
-
- if (node_id == CPU_UNSET_NUMA_NODE_ID) {
- /* due to bug in libvirt, it doesn't pass node-id from props on
- * device_add as expected, so we have to fix it up here */
- if (slot->props.has_node_id) {
- object_property_set_int(OBJECT(dev), slot->props.node_id,
- "node-id", errp);
- }
- } else if (node_id != slot->props.node_id) {
- error_setg(errp, "invalid node-id, must be %"PRId64,
- slot->props.node_id);
- }
-}
-
-static void allocate_system_memory_nonnuma(MemoryRegion *mr, Object *owner,
- const char *name,
- uint64_t ram_size)
-{
- if (mem_path) {
-#ifdef __linux__
- Error *err = NULL;
- memory_region_init_ram_from_file(mr, owner, name, ram_size, 0, 0,
- mem_path, &err);
- if (err) {
- error_report_err(err);
- if (mem_prealloc) {
- exit(1);
- }
- error_report("falling back to regular RAM allocation.");
-
- /* Legacy behavior: if allocation failed, fall back to
- * regular RAM allocation.
- */
- mem_path = NULL;
- memory_region_init_ram_nomigrate(mr, owner, name, ram_size, &error_fatal);
- }
-#else
- fprintf(stderr, "-mem-path not supported on this host\n");
- exit(1);
-#endif
- } else {
- memory_region_init_ram_nomigrate(mr, owner, name, ram_size, &error_fatal);
- }
- vmstate_register_ram_global(mr);
-}
-
-void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner,
- const char *name,
- uint64_t ram_size)
-{
- uint64_t addr = 0;
- int i;
-
- if (nb_numa_nodes == 0 || !have_memdevs) {
- allocate_system_memory_nonnuma(mr, owner, name, ram_size);
- return;
- }
-
- memory_region_init(mr, owner, name, ram_size);
- for (i = 0; i < nb_numa_nodes; i++) {
- uint64_t size = numa_info[i].node_mem;
- HostMemoryBackend *backend = numa_info[i].node_memdev;
- if (!backend) {
- continue;
- }
- MemoryRegion *seg = host_memory_backend_get_memory(backend);
-
- if (memory_region_is_mapped(seg)) {
- char *path = object_get_canonical_path_component(OBJECT(backend));
- error_report("memory backend %s is used multiple times. Each "
- "-numa option must use a different memdev value.",
- path);
- g_free(path);
- exit(1);
- }
-
- host_memory_backend_set_mapped(backend, true);
- memory_region_add_subregion(mr, addr, seg);
- vmstate_register_ram_global(seg);
- addr += size;
- }
-}
-
-static void numa_stat_memory_devices(NumaNodeMem node_mem[])
-{
- MemoryDeviceInfoList *info_list = qmp_memory_device_list();
- MemoryDeviceInfoList *info;
- PCDIMMDeviceInfo *pcdimm_info;
-
- for (info = info_list; info; info = info->next) {
- MemoryDeviceInfo *value = info->value;
-
- if (value) {
- switch (value->type) {
- case MEMORY_DEVICE_INFO_KIND_DIMM:
- pcdimm_info = value->u.dimm.data;
- break;
-
- case MEMORY_DEVICE_INFO_KIND_NVDIMM:
- pcdimm_info = value->u.nvdimm.data;
- break;
-
- default:
- pcdimm_info = NULL;
- break;
- }
-
- if (pcdimm_info) {
- node_mem[pcdimm_info->node].node_mem += pcdimm_info->size;
- node_mem[pcdimm_info->node].node_plugged_mem +=
- pcdimm_info->size;
- }
- }
- }
- qapi_free_MemoryDeviceInfoList(info_list);
-}
-
-void query_numa_node_mem(NumaNodeMem node_mem[])
-{
- int i;
-
- if (nb_numa_nodes <= 0) {
- return;
- }
-
- numa_stat_memory_devices(node_mem);
- for (i = 0; i < nb_numa_nodes; i++) {
- node_mem[i].node_mem += numa_info[i].node_mem;
- }
-}
-
-static int query_memdev(Object *obj, void *opaque)
-{
- MemdevList **list = opaque;
- MemdevList *m = NULL;
-
- if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) {
- m = g_malloc0(sizeof(*m));
-
- m->value = g_malloc0(sizeof(*m->value));
-
- m->value->id = object_get_canonical_path_component(obj);
- m->value->has_id = !!m->value->id;
-
- m->value->size = object_property_get_uint(obj, "size",
- &error_abort);
- m->value->merge = object_property_get_bool(obj, "merge",
- &error_abort);
- m->value->dump = object_property_get_bool(obj, "dump",
- &error_abort);
- m->value->prealloc = object_property_get_bool(obj,
- "prealloc",
- &error_abort);
- m->value->policy = object_property_get_enum(obj,
- "policy",
- "HostMemPolicy",
- &error_abort);
- object_property_get_uint16List(obj, "host-nodes",
- &m->value->host_nodes,
- &error_abort);
-
- m->next = *list;
- *list = m;
- }
-
- return 0;
-}
-
-MemdevList *qmp_query_memdev(Error **errp)
-{
- Object *obj = object_get_objects_root();
- MemdevList *list = NULL;
-
- object_child_foreach(obj, query_memdev, &list);
- return list;
-}
-
-void ram_block_notifier_add(RAMBlockNotifier *n)
-{
- QLIST_INSERT_HEAD(&ram_list.ramblock_notifiers, n, next);
-}
-
-void ram_block_notifier_remove(RAMBlockNotifier *n)
-{
- QLIST_REMOVE(n, next);
-}
-
-void ram_block_notify_add(void *host, size_t size)
-{
- RAMBlockNotifier *notifier;
-
- QLIST_FOREACH(notifier, &ram_list.ramblock_notifiers, next) {
- notifier->ram_block_added(notifier, host, size);
- }
-}
-
-void ram_block_notify_remove(void *host, size_t size)
-{
- RAMBlockNotifier *notifier;
-
- QLIST_FOREACH(notifier, &ram_list.ramblock_notifiers, next) {
- notifier->ram_block_removed(notifier, host, size);
- }
-}
build-all: spapr-rtas.bin
+%.o: %.S
+ $(call quiet-command,$(CCAS) -mbig -c -o $@ $<,"CCAS","$(TARGET_DIR)$@")
+
%.img: %.o
- $(call quiet-command,$(CC) -nostdlib -o $@ $<,"Building","$(TARGET_DIR)$@")
+ $(call quiet-command,$(CC) -nostdlib -mbig -o $@ $<,"Building","$(TARGET_DIR)$@")
%.bin: %.img
$(call quiet-command,$(OBJCOPY) -O binary -j .text $< $@,"Building","$(TARGET_DIR)$@")
# Based on qmp.py.
#
-import errno
import logging
import os
-import subprocess
-import re
-import shutil
-import socket
-import tempfile
from . import qmp
-
+from . import machine
LOG = logging.getLogger(__name__)
if target_arch != ADDITIONAL_ARCHES.get(host_arch):
return False
return os.access("/dev/kvm", os.R_OK | os.W_OK)
-
-
-class QEMUMachineError(Exception):
- """
- Exception called when an error in QEMUMachine happens.
- """
-
-
-class QEMUMachineAddDeviceError(QEMUMachineError):
- """
- Exception raised when a request to add a device can not be fulfilled
-
- The failures are caused by limitations, lack of information or conflicting
- requests on the QEMUMachine methods. This exception does not represent
- failures reported by the QEMU binary itself.
- """
-
-class MonitorResponseError(qmp.QMPError):
- """
- Represents erroneous QMP monitor reply
- """
- def __init__(self, reply):
- try:
- desc = reply["error"]["desc"]
- except KeyError:
- desc = reply
- super(MonitorResponseError, self).__init__(desc)
- self.reply = reply
-
-
-class QEMUMachine(object):
- """
- A QEMU VM
-
- Use this object as a context manager to ensure the QEMU process terminates::
-
- with VM(binary) as vm:
- ...
- # vm is guaranteed to be shut down here
- """
-
- def __init__(self, binary, args=None, wrapper=None, name=None,
- test_dir="/var/tmp", monitor_address=None,
- socket_scm_helper=None):
- '''
- Initialize a QEMUMachine
-
- @param binary: path to the qemu binary
- @param args: list of extra arguments
- @param wrapper: list of arguments used as prefix to qemu binary
- @param name: prefix for socket and log file names (default: qemu-PID)
- @param test_dir: where to create socket and log file
- @param monitor_address: address for QMP monitor
- @param socket_scm_helper: helper program, required for send_fd_scm()
- @note: Qemu process is not started until launch() is used.
- '''
- if args is None:
- args = []
- if wrapper is None:
- wrapper = []
- if name is None:
- name = "qemu-%d" % os.getpid()
- self._name = name
- self._monitor_address = monitor_address
- self._vm_monitor = None
- self._qemu_log_path = None
- self._qemu_log_file = None
- self._popen = None
- self._binary = binary
- self._args = list(args) # Force copy args in case we modify them
- self._wrapper = wrapper
- self._events = []
- self._iolog = None
- self._socket_scm_helper = socket_scm_helper
- self._qmp = None
- self._qemu_full_args = None
- self._test_dir = test_dir
- self._temp_dir = None
- self._launched = False
- self._machine = None
- self._console_set = False
- self._console_device_type = None
- self._console_address = None
- self._console_socket = None
-
- # just in case logging wasn't configured by the main script:
- logging.basicConfig()
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self.shutdown()
- return False
-
- # This can be used to add an unused monitor instance.
- def add_monitor_null(self):
- self._args.append('-monitor')
- self._args.append('null')
-
- def add_fd(self, fd, fdset, opaque, opts=''):
- """
- Pass a file descriptor to the VM
- """
- options = ['fd=%d' % fd,
- 'set=%d' % fdset,
- 'opaque=%s' % opaque]
- if opts:
- options.append(opts)
-
- # This did not exist before 3.4, but since then it is
- # mandatory for our purpose
- if hasattr(os, 'set_inheritable'):
- os.set_inheritable(fd, True)
-
- self._args.append('-add-fd')
- self._args.append(','.join(options))
- return self
-
- # Exactly one of fd and file_path must be given.
- # (If it is file_path, the helper will open that file and pass its
- # own fd)
- def send_fd_scm(self, fd=None, file_path=None):
- # In iotest.py, the qmp should always use unix socket.
- assert self._qmp.is_scm_available()
- if self._socket_scm_helper is None:
- raise QEMUMachineError("No path to socket_scm_helper set")
- if not os.path.exists(self._socket_scm_helper):
- raise QEMUMachineError("%s does not exist" %
- self._socket_scm_helper)
-
- # This did not exist before 3.4, but since then it is
- # mandatory for our purpose
- if hasattr(os, 'set_inheritable'):
- os.set_inheritable(self._qmp.get_sock_fd(), True)
- if fd is not None:
- os.set_inheritable(fd, True)
-
- fd_param = ["%s" % self._socket_scm_helper,
- "%d" % self._qmp.get_sock_fd()]
-
- if file_path is not None:
- assert fd is None
- fd_param.append(file_path)
- else:
- assert fd is not None
- fd_param.append(str(fd))
-
- devnull = open(os.path.devnull, 'rb')
- proc = subprocess.Popen(fd_param, stdin=devnull, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT, close_fds=False)
- output = proc.communicate()[0]
- if output:
- LOG.debug(output)
-
- return proc.returncode
-
- @staticmethod
- def _remove_if_exists(path):
- """
- Remove file object at path if it exists
- """
- try:
- os.remove(path)
- except OSError as exception:
- if exception.errno == errno.ENOENT:
- return
- raise
-
- def is_running(self):
- return self._popen is not None and self._popen.poll() is None
-
- def exitcode(self):
- if self._popen is None:
- return None
- return self._popen.poll()
-
- def get_pid(self):
- if not self.is_running():
- return None
- return self._popen.pid
-
- def _load_io_log(self):
- if self._qemu_log_path is not None:
- with open(self._qemu_log_path, "r") as iolog:
- self._iolog = iolog.read()
-
- def _base_args(self):
- if isinstance(self._monitor_address, tuple):
- moncdev = "socket,id=mon,host=%s,port=%s" % (
- self._monitor_address[0],
- self._monitor_address[1])
- else:
- moncdev = 'socket,id=mon,path=%s' % self._vm_monitor
- args = ['-chardev', moncdev,
- '-mon', 'chardev=mon,mode=control',
- '-display', 'none', '-vga', 'none']
- if self._machine is not None:
- args.extend(['-machine', self._machine])
- if self._console_set:
- self._console_address = os.path.join(self._temp_dir,
- self._name + "-console.sock")
- chardev = ('socket,id=console,path=%s,server,nowait' %
- self._console_address)
- args.extend(['-chardev', chardev])
- if self._console_device_type is None:
- args.extend(['-serial', 'chardev:console'])
- else:
- device = '%s,chardev=console' % self._console_device_type
- args.extend(['-device', device])
- return args
-
- def _pre_launch(self):
- self._temp_dir = tempfile.mkdtemp(dir=self._test_dir)
- if self._monitor_address is not None:
- self._vm_monitor = self._monitor_address
- else:
- self._vm_monitor = os.path.join(self._temp_dir,
- self._name + "-monitor.sock")
- self._qemu_log_path = os.path.join(self._temp_dir, self._name + ".log")
- self._qemu_log_file = open(self._qemu_log_path, 'wb')
-
- self._qmp = qmp.QEMUMonitorProtocol(self._vm_monitor,
- server=True)
-
- def _post_launch(self):
- self._qmp.accept()
-
- def _post_shutdown(self):
- if self._qemu_log_file is not None:
- self._qemu_log_file.close()
- self._qemu_log_file = None
-
- self._qemu_log_path = None
-
- if self._console_socket is not None:
- self._console_socket.close()
- self._console_socket = None
-
- if self._temp_dir is not None:
- shutil.rmtree(self._temp_dir)
- self._temp_dir = None
-
- def launch(self):
- """
- Launch the VM and make sure we cleanup and expose the
- command line/output in case of exception
- """
-
- if self._launched:
- raise QEMUMachineError('VM already launched')
-
- self._iolog = None
- self._qemu_full_args = None
- try:
- self._launch()
- self._launched = True
- except:
- self.shutdown()
-
- LOG.debug('Error launching VM')
- if self._qemu_full_args:
- LOG.debug('Command: %r', ' '.join(self._qemu_full_args))
- if self._iolog:
- LOG.debug('Output: %r', self._iolog)
- raise
-
- def _launch(self):
- """
- Launch the VM and establish a QMP connection
- """
- devnull = open(os.path.devnull, 'rb')
- self._pre_launch()
- self._qemu_full_args = (self._wrapper + [self._binary] +
- self._base_args() + self._args)
- LOG.debug('VM launch command: %r', ' '.join(self._qemu_full_args))
- self._popen = subprocess.Popen(self._qemu_full_args,
- stdin=devnull,
- stdout=self._qemu_log_file,
- stderr=subprocess.STDOUT,
- shell=False,
- close_fds=False)
- self._post_launch()
-
- def wait(self):
- """
- Wait for the VM to power off
- """
- self._popen.wait()
- self._qmp.close()
- self._load_io_log()
- self._post_shutdown()
-
- def shutdown(self):
- """
- Terminate the VM and clean up
- """
- if self.is_running():
- try:
- self._qmp.cmd('quit')
- self._qmp.close()
- except:
- self._popen.kill()
- self._popen.wait()
-
- self._load_io_log()
- self._post_shutdown()
-
- exitcode = self.exitcode()
- if exitcode is not None and exitcode < 0:
- msg = 'qemu received signal %i: %s'
- if self._qemu_full_args:
- command = ' '.join(self._qemu_full_args)
- else:
- command = ''
- LOG.warn(msg, -exitcode, command)
-
- self._launched = False
-
- def qmp(self, cmd, conv_keys=True, **args):
- """
- Invoke a QMP command and return the response dict
- """
- qmp_args = dict()
- for key, value in args.items():
- if conv_keys:
- qmp_args[key.replace('_', '-')] = value
- else:
- qmp_args[key] = value
-
- return self._qmp.cmd(cmd, args=qmp_args)
-
- def command(self, cmd, conv_keys=True, **args):
- """
- Invoke a QMP command.
- On success return the response dict.
- On failure raise an exception.
- """
- reply = self.qmp(cmd, conv_keys, **args)
- if reply is None:
- raise qmp.QMPError("Monitor is closed")
- if "error" in reply:
- raise MonitorResponseError(reply)
- return reply["return"]
-
- def get_qmp_event(self, wait=False):
- """
- Poll for one queued QMP events and return it
- """
- if len(self._events) > 0:
- return self._events.pop(0)
- return self._qmp.pull_event(wait=wait)
-
- def get_qmp_events(self, wait=False):
- """
- Poll for queued QMP events and return a list of dicts
- """
- events = self._qmp.get_events(wait=wait)
- events.extend(self._events)
- del self._events[:]
- self._qmp.clear_events()
- return events
-
- @staticmethod
- def event_match(event, match=None):
- """
- Check if an event matches optional match criteria.
-
- The match criteria takes the form of a matching subdict. The event is
- checked to be a superset of the subdict, recursively, with matching
- values whenever the subdict values are not None.
-
- This has a limitation that you cannot explicitly check for None values.
-
- Examples, with the subdict queries on the left:
- - None matches any object.
- - {"foo": None} matches {"foo": {"bar": 1}}
- - {"foo": None} matches {"foo": 5}
- - {"foo": {"abc": None}} does not match {"foo": {"bar": 1}}
- - {"foo": {"rab": 2}} matches {"foo": {"bar": 1, "rab": 2}}
- """
- if match is None:
- return True
-
- try:
- for key in match:
- if key in event:
- if not QEMUMachine.event_match(event[key], match[key]):
- return False
- else:
- return False
- return True
- except TypeError:
- # either match or event wasn't iterable (not a dict)
- return match == event
-
- def event_wait(self, name, timeout=60.0, match=None):
- """
- event_wait waits for and returns a named event from QMP with a timeout.
-
- name: The event to wait for.
- timeout: QEMUMonitorProtocol.pull_event timeout parameter.
- match: Optional match criteria. See event_match for details.
- """
- return self.events_wait([(name, match)], timeout)
-
- def events_wait(self, events, timeout=60.0):
- """
- events_wait waits for and returns a named event from QMP with a timeout.
-
- events: a sequence of (name, match_criteria) tuples.
- The match criteria are optional and may be None.
- See event_match for details.
- timeout: QEMUMonitorProtocol.pull_event timeout parameter.
- """
- def _match(event):
- for name, match in events:
- if (event['event'] == name and
- self.event_match(event, match)):
- return True
- return False
-
- # Search cached events
- for event in self._events:
- if _match(event):
- self._events.remove(event)
- return event
-
- # Poll for new events
- while True:
- event = self._qmp.pull_event(wait=timeout)
- if _match(event):
- return event
- self._events.append(event)
-
- return None
-
- def get_log(self):
- """
- After self.shutdown or failed qemu execution, this returns the output
- of the qemu process.
- """
- return self._iolog
-
- def add_args(self, *args):
- """
- Adds to the list of extra arguments to be given to the QEMU binary
- """
- self._args.extend(args)
-
- def set_machine(self, machine_type):
- """
- Sets the machine type
-
- If set, the machine type will be added to the base arguments
- of the resulting QEMU command line.
- """
- self._machine = machine_type
-
- def set_console(self, device_type=None):
- """
- Sets the device type for a console device
-
- If set, the console device and a backing character device will
- be added to the base arguments of the resulting QEMU command
- line.
-
- This is a convenience method that will either use the provided
- device type, or default to a "-serial chardev:console" command
- line argument.
-
- The actual setting of command line arguments will be be done at
- machine launch time, as it depends on the temporary directory
- to be created.
-
- @param device_type: the device type, such as "isa-serial". If
- None is given (the default value) a "-serial
- chardev:console" command line argument will
- be used instead, resorting to the machine's
- default device type.
- """
- self._console_set = True
- self._console_device_type = device_type
-
- @property
- def console_socket(self):
- """
- Returns a socket connected to the console
- """
- if self._console_socket is None:
- self._console_socket = socket.socket(socket.AF_UNIX,
- socket.SOCK_STREAM)
- self._console_socket.connect(self._console_address)
- return self._console_socket
--- /dev/null
+"""
+QEMU machine module:
+
+The machine module primarily provides the QEMUMachine class,
+which provides facilities for managing the lifetime of a QEMU VM.
+"""
+
+# Copyright (C) 2015-2016 Red Hat Inc.
+# Copyright (C) 2012 IBM Corp.
+#
+# Authors:
+# Fam Zheng <famz@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2. See
+# the COPYING file in the top-level directory.
+#
+# Based on qmp.py.
+#
+
+import errno
+import logging
+import os
+import subprocess
+import shutil
+import socket
+import tempfile
+
+from . import qmp
+
+LOG = logging.getLogger(__name__)
+
+class QEMUMachineError(Exception):
+ """
+ Exception called when an error in QEMUMachine happens.
+ """
+
+
+class QEMUMachineAddDeviceError(QEMUMachineError):
+ """
+ Exception raised when a request to add a device can not be fulfilled
+
+ The failures are caused by limitations, lack of information or conflicting
+ requests on the QEMUMachine methods. This exception does not represent
+ failures reported by the QEMU binary itself.
+ """
+
+
+class MonitorResponseError(qmp.QMPError):
+ """
+ Represents erroneous QMP monitor reply
+ """
+ def __init__(self, reply):
+ try:
+ desc = reply["error"]["desc"]
+ except KeyError:
+ desc = reply
+ super(MonitorResponseError, self).__init__(desc)
+ self.reply = reply
+
+
+class QEMUMachine(object):
+ """
+ A QEMU VM
+
+ Use this object as a context manager to ensure the QEMU process terminates::
+
+ with VM(binary) as vm:
+ ...
+ # vm is guaranteed to be shut down here
+ """
+
+ def __init__(self, binary, args=None, wrapper=None, name=None,
+ test_dir="/var/tmp", monitor_address=None,
+ socket_scm_helper=None):
+ '''
+ Initialize a QEMUMachine
+
+ @param binary: path to the qemu binary
+ @param args: list of extra arguments
+ @param wrapper: list of arguments used as prefix to qemu binary
+ @param name: prefix for socket and log file names (default: qemu-PID)
+ @param test_dir: where to create socket and log file
+ @param monitor_address: address for QMP monitor
+ @param socket_scm_helper: helper program, required for send_fd_scm()
+ @note: Qemu process is not started until launch() is used.
+ '''
+ if args is None:
+ args = []
+ if wrapper is None:
+ wrapper = []
+ if name is None:
+ name = "qemu-%d" % os.getpid()
+ self._name = name
+ self._monitor_address = monitor_address
+ self._vm_monitor = None
+ self._qemu_log_path = None
+ self._qemu_log_file = None
+ self._popen = None
+ self._binary = binary
+ self._args = list(args) # Force copy args in case we modify them
+ self._wrapper = wrapper
+ self._events = []
+ self._iolog = None
+ self._socket_scm_helper = socket_scm_helper
+ self._qmp = None
+ self._qemu_full_args = None
+ self._test_dir = test_dir
+ self._temp_dir = None
+ self._launched = False
+ self._machine = None
+ self._console_set = False
+ self._console_device_type = None
+ self._console_address = None
+ self._console_socket = None
+
+ # just in case logging wasn't configured by the main script:
+ logging.basicConfig()
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.shutdown()
+ return False
+
+ def add_monitor_null(self):
+ """
+ This can be used to add an unused monitor instance.
+ """
+ self._args.append('-monitor')
+ self._args.append('null')
+
+ def add_fd(self, fd, fdset, opaque, opts=''):
+ """
+ Pass a file descriptor to the VM
+ """
+ options = ['fd=%d' % fd,
+ 'set=%d' % fdset,
+ 'opaque=%s' % opaque]
+ if opts:
+ options.append(opts)
+
+ # This did not exist before 3.4, but since then it is
+ # mandatory for our purpose
+ if hasattr(os, 'set_inheritable'):
+ os.set_inheritable(fd, True)
+
+ self._args.append('-add-fd')
+ self._args.append(','.join(options))
+ return self
+
+ def send_fd_scm(self, fd=None, file_path=None):
+ """
+ Send an fd or file_path to socket_scm_helper.
+
+ Exactly one of fd and file_path must be given.
+ If it is file_path, the helper will open that file and pass its own fd.
+ """
+ # In iotest.py, the qmp should always use unix socket.
+ assert self._qmp.is_scm_available()
+ if self._socket_scm_helper is None:
+ raise QEMUMachineError("No path to socket_scm_helper set")
+ if not os.path.exists(self._socket_scm_helper):
+ raise QEMUMachineError("%s does not exist" %
+ self._socket_scm_helper)
+
+ # This did not exist before 3.4, but since then it is
+ # mandatory for our purpose
+ if hasattr(os, 'set_inheritable'):
+ os.set_inheritable(self._qmp.get_sock_fd(), True)
+ if fd is not None:
+ os.set_inheritable(fd, True)
+
+ fd_param = ["%s" % self._socket_scm_helper,
+ "%d" % self._qmp.get_sock_fd()]
+
+ if file_path is not None:
+ assert fd is None
+ fd_param.append(file_path)
+ else:
+ assert fd is not None
+ fd_param.append(str(fd))
+
+ devnull = open(os.path.devnull, 'rb')
+ proc = subprocess.Popen(fd_param, stdin=devnull, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT, close_fds=False)
+ output = proc.communicate()[0]
+ if output:
+ LOG.debug(output)
+
+ return proc.returncode
+
+ @staticmethod
+ def _remove_if_exists(path):
+ """
+ Remove file object at path if it exists
+ """
+ try:
+ os.remove(path)
+ except OSError as exception:
+ if exception.errno == errno.ENOENT:
+ return
+ raise
+
+ def is_running(self):
+ """Returns true if the VM is running."""
+ return self._popen is not None and self._popen.poll() is None
+
+ def exitcode(self):
+ """Returns the exit code if possible, or None."""
+ if self._popen is None:
+ return None
+ return self._popen.poll()
+
+ def get_pid(self):
+ """Returns the PID of the running process, or None."""
+ if not self.is_running():
+ return None
+ return self._popen.pid
+
+ def _load_io_log(self):
+ if self._qemu_log_path is not None:
+ with open(self._qemu_log_path, "r") as iolog:
+ self._iolog = iolog.read()
+
+ def _base_args(self):
+ if isinstance(self._monitor_address, tuple):
+ moncdev = "socket,id=mon,host=%s,port=%s" % (
+ self._monitor_address[0],
+ self._monitor_address[1])
+ else:
+ moncdev = 'socket,id=mon,path=%s' % self._vm_monitor
+ args = ['-chardev', moncdev,
+ '-mon', 'chardev=mon,mode=control',
+ '-display', 'none', '-vga', 'none']
+ if self._machine is not None:
+ args.extend(['-machine', self._machine])
+ if self._console_set:
+ self._console_address = os.path.join(self._temp_dir,
+ self._name + "-console.sock")
+ chardev = ('socket,id=console,path=%s,server,nowait' %
+ self._console_address)
+ args.extend(['-chardev', chardev])
+ if self._console_device_type is None:
+ args.extend(['-serial', 'chardev:console'])
+ else:
+ device = '%s,chardev=console' % self._console_device_type
+ args.extend(['-device', device])
+ return args
+
+ def _pre_launch(self):
+ self._temp_dir = tempfile.mkdtemp(dir=self._test_dir)
+ if self._monitor_address is not None:
+ self._vm_monitor = self._monitor_address
+ else:
+ self._vm_monitor = os.path.join(self._temp_dir,
+ self._name + "-monitor.sock")
+ self._qemu_log_path = os.path.join(self._temp_dir, self._name + ".log")
+ self._qemu_log_file = open(self._qemu_log_path, 'wb')
+
+ self._qmp = qmp.QEMUMonitorProtocol(self._vm_monitor,
+ server=True)
+
+ def _post_launch(self):
+ self._qmp.accept()
+
+ def _post_shutdown(self):
+ if self._qemu_log_file is not None:
+ self._qemu_log_file.close()
+ self._qemu_log_file = None
+
+ self._qemu_log_path = None
+
+ if self._console_socket is not None:
+ self._console_socket.close()
+ self._console_socket = None
+
+ if self._temp_dir is not None:
+ shutil.rmtree(self._temp_dir)
+ self._temp_dir = None
+
+ def launch(self):
+ """
+ Launch the VM and make sure we cleanup and expose the
+ command line/output in case of exception
+ """
+
+ if self._launched:
+ raise QEMUMachineError('VM already launched')
+
+ self._iolog = None
+ self._qemu_full_args = None
+ try:
+ self._launch()
+ self._launched = True
+ except:
+ self.shutdown()
+
+ LOG.debug('Error launching VM')
+ if self._qemu_full_args:
+ LOG.debug('Command: %r', ' '.join(self._qemu_full_args))
+ if self._iolog:
+ LOG.debug('Output: %r', self._iolog)
+ raise
+
+ def _launch(self):
+ """
+ Launch the VM and establish a QMP connection
+ """
+ devnull = open(os.path.devnull, 'rb')
+ self._pre_launch()
+ self._qemu_full_args = (self._wrapper + [self._binary] +
+ self._base_args() + self._args)
+ LOG.debug('VM launch command: %r', ' '.join(self._qemu_full_args))
+ self._popen = subprocess.Popen(self._qemu_full_args,
+ stdin=devnull,
+ stdout=self._qemu_log_file,
+ stderr=subprocess.STDOUT,
+ shell=False,
+ close_fds=False)
+ self._post_launch()
+
+ def wait(self):
+ """
+ Wait for the VM to power off
+ """
+ self._popen.wait()
+ self._qmp.close()
+ self._load_io_log()
+ self._post_shutdown()
+
+ def shutdown(self):
+ """
+ Terminate the VM and clean up
+ """
+ if self.is_running():
+ try:
+ self._qmp.cmd('quit')
+ self._qmp.close()
+ except:
+ self._popen.kill()
+ self._popen.wait()
+
+ self._load_io_log()
+ self._post_shutdown()
+
+ exitcode = self.exitcode()
+ if exitcode is not None and exitcode < 0:
+ msg = 'qemu received signal %i: %s'
+ if self._qemu_full_args:
+ command = ' '.join(self._qemu_full_args)
+ else:
+ command = ''
+ LOG.warning(msg, -exitcode, command)
+
+ self._launched = False
+
+ def qmp(self, cmd, conv_keys=True, **args):
+ """
+ Invoke a QMP command and return the response dict
+ """
+ qmp_args = dict()
+ for key, value in args.items():
+ if conv_keys:
+ qmp_args[key.replace('_', '-')] = value
+ else:
+ qmp_args[key] = value
+
+ return self._qmp.cmd(cmd, args=qmp_args)
+
+ def command(self, cmd, conv_keys=True, **args):
+ """
+ Invoke a QMP command.
+ On success return the response dict.
+ On failure raise an exception.
+ """
+ reply = self.qmp(cmd, conv_keys, **args)
+ if reply is None:
+ raise qmp.QMPError("Monitor is closed")
+ if "error" in reply:
+ raise MonitorResponseError(reply)
+ return reply["return"]
+
+ def get_qmp_event(self, wait=False):
+ """
+ Poll for one queued QMP events and return it
+ """
+ if self._events:
+ return self._events.pop(0)
+ return self._qmp.pull_event(wait=wait)
+
+ def get_qmp_events(self, wait=False):
+ """
+ Poll for queued QMP events and return a list of dicts
+ """
+ events = self._qmp.get_events(wait=wait)
+ events.extend(self._events)
+ del self._events[:]
+ self._qmp.clear_events()
+ return events
+
+ @staticmethod
+ def event_match(event, match=None):
+ """
+ Check if an event matches optional match criteria.
+
+ The match criteria takes the form of a matching subdict. The event is
+ checked to be a superset of the subdict, recursively, with matching
+ values whenever the subdict values are not None.
+
+ This has a limitation that you cannot explicitly check for None values.
+
+ Examples, with the subdict queries on the left:
+ - None matches any object.
+ - {"foo": None} matches {"foo": {"bar": 1}}
+ - {"foo": None} matches {"foo": 5}
+ - {"foo": {"abc": None}} does not match {"foo": {"bar": 1}}
+ - {"foo": {"rab": 2}} matches {"foo": {"bar": 1, "rab": 2}}
+ """
+ if match is None:
+ return True
+
+ try:
+ for key in match:
+ if key in event:
+ if not QEMUMachine.event_match(event[key], match[key]):
+ return False
+ else:
+ return False
+ return True
+ except TypeError:
+ # either match or event wasn't iterable (not a dict)
+ return match == event
+
+ def event_wait(self, name, timeout=60.0, match=None):
+ """
+ event_wait waits for and returns a named event from QMP with a timeout.
+
+ name: The event to wait for.
+ timeout: QEMUMonitorProtocol.pull_event timeout parameter.
+ match: Optional match criteria. See event_match for details.
+ """
+ return self.events_wait([(name, match)], timeout)
+
+ def events_wait(self, events, timeout=60.0):
+ """
+ events_wait waits for and returns a named event from QMP with a timeout.
+
+ events: a sequence of (name, match_criteria) tuples.
+ The match criteria are optional and may be None.
+ See event_match for details.
+ timeout: QEMUMonitorProtocol.pull_event timeout parameter.
+ """
+ def _match(event):
+ for name, match in events:
+ if event['event'] == name and self.event_match(event, match):
+ return True
+ return False
+
+ # Search cached events
+ for event in self._events:
+ if _match(event):
+ self._events.remove(event)
+ return event
+
+ # Poll for new events
+ while True:
+ event = self._qmp.pull_event(wait=timeout)
+ if _match(event):
+ return event
+ self._events.append(event)
+
+ return None
+
+ def get_log(self):
+ """
+ After self.shutdown or failed qemu execution, this returns the output
+ of the qemu process.
+ """
+ return self._iolog
+
+ def add_args(self, *args):
+ """
+ Adds to the list of extra arguments to be given to the QEMU binary
+ """
+ self._args.extend(args)
+
+ def set_machine(self, machine_type):
+ """
+ Sets the machine type
+
+ If set, the machine type will be added to the base arguments
+ of the resulting QEMU command line.
+ """
+ self._machine = machine_type
+
+ def set_console(self, device_type=None):
+ """
+ Sets the device type for a console device
+
+ If set, the console device and a backing character device will
+ be added to the base arguments of the resulting QEMU command
+ line.
+
+ This is a convenience method that will either use the provided
+ device type, or default to a "-serial chardev:console" command
+ line argument.
+
+ The actual setting of command line arguments will be be done at
+ machine launch time, as it depends on the temporary directory
+ to be created.
+
+ @param device_type: the device type, such as "isa-serial". If
+ None is given (the default value) a "-serial
+ chardev:console" command line argument will
+ be used instead, resorting to the machine's
+ default device type.
+ """
+ self._console_set = True
+ self._console_device_type = device_type
+
+ @property
+ def console_socket(self):
+ """
+ Returns a socket connected to the console
+ """
+ if self._console_socket is None:
+ self._console_socket = socket.socket(socket.AF_UNIX,
+ socket.SOCK_STREAM)
+ self._console_socket.connect(self._console_address)
+ return self._console_socket
import socket
import os
-from . import QEMUMachine
+from .machine import QEMUMachine
class QEMUQtestProtocol(object):
util-obj-y += qapi-util.o
QAPI_COMMON_MODULES = audio authz block-core block char common crypto
-QAPI_COMMON_MODULES += introspect job migration misc net rdma rocker
-QAPI_COMMON_MODULES += run-state sockets tpm trace transaction ui
-QAPI_TARGET_MODULES = target
+QAPI_COMMON_MODULES += dump introspect job machine migration misc net
+QAPI_COMMON_MODULES += qdev qom rdma rocker run-state sockets tpm
+QAPI_COMMON_MODULES += trace transaction ui
+QAPI_TARGET_MODULES = machine-target misc-target
QAPI_MODULES = $(QAPI_COMMON_MODULES) $(QAPI_TARGET_MODULES)
util-obj-y += qapi-builtin-types.o
--- /dev/null
+# -*- Mode: Python -*-
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+##
+# = Dump guest memory
+##
+
+##
+# @DumpGuestMemoryFormat:
+#
+# An enumeration of guest-memory-dump's format.
+#
+# @elf: elf format
+#
+# @kdump-zlib: kdump-compressed format with zlib-compressed
+#
+# @kdump-lzo: kdump-compressed format with lzo-compressed
+#
+# @kdump-snappy: kdump-compressed format with snappy-compressed
+#
+# @win-dmp: Windows full crashdump format,
+# can be used instead of ELF converting (since 2.13)
+#
+# Since: 2.0
+##
+{ 'enum': 'DumpGuestMemoryFormat',
+ 'data': [ 'elf', 'kdump-zlib', 'kdump-lzo', 'kdump-snappy', 'win-dmp' ] }
+
+##
+# @dump-guest-memory:
+#
+# Dump guest's memory to vmcore. It is a synchronous operation that can take
+# very long depending on the amount of guest memory.
+#
+# @paging: if true, do paging to get guest's memory mapping. This allows
+# using gdb to process the core file.
+#
+# IMPORTANT: this option can make QEMU allocate several gigabytes
+# of RAM. This can happen for a large guest, or a
+# malicious guest pretending to be large.
+#
+# Also, paging=true has the following limitations:
+#
+# 1. The guest may be in a catastrophic state or can have corrupted
+# memory, which cannot be trusted
+# 2. The guest can be in real-mode even if paging is enabled. For
+# example, the guest uses ACPI to sleep, and ACPI sleep state
+# goes in real-mode
+# 3. Currently only supported on i386 and x86_64.
+#
+# @protocol: the filename or file descriptor of the vmcore. The supported
+# protocols are:
+#
+# 1. file: the protocol starts with "file:", and the following
+# string is the file's path.
+# 2. fd: the protocol starts with "fd:", and the following string
+# is the fd's name.
+#
+# @detach: if true, QMP will return immediately rather than
+# waiting for the dump to finish. The user can track progress
+# using "query-dump". (since 2.6).
+#
+# @begin: if specified, the starting physical address.
+#
+# @length: if specified, the memory size, in bytes. If you don't
+# want to dump all guest's memory, please specify the start @begin
+# and @length
+#
+# @format: if specified, the format of guest memory dump. But non-elf
+# format is conflict with paging and filter, ie. @paging, @begin and
+# @length is not allowed to be specified with non-elf @format at the
+# same time (since 2.0)
+#
+# Note: All boolean arguments default to false
+#
+# Returns: nothing on success
+#
+# Since: 1.2
+#
+# Example:
+#
+# -> { "execute": "dump-guest-memory",
+# "arguments": { "protocol": "fd:dump" } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'dump-guest-memory',
+ 'data': { 'paging': 'bool', 'protocol': 'str', '*detach': 'bool',
+ '*begin': 'int', '*length': 'int',
+ '*format': 'DumpGuestMemoryFormat'} }
+
+##
+# @DumpStatus:
+#
+# Describe the status of a long-running background guest memory dump.
+#
+# @none: no dump-guest-memory has started yet.
+#
+# @active: there is one dump running in background.
+#
+# @completed: the last dump has finished successfully.
+#
+# @failed: the last dump has failed.
+#
+# Since: 2.6
+##
+{ 'enum': 'DumpStatus',
+ 'data': [ 'none', 'active', 'completed', 'failed' ] }
+
+##
+# @DumpQueryResult:
+#
+# The result format for 'query-dump'.
+#
+# @status: enum of @DumpStatus, which shows current dump status
+#
+# @completed: bytes written in latest dump (uncompressed)
+#
+# @total: total bytes to be written in latest dump (uncompressed)
+#
+# Since: 2.6
+##
+{ 'struct': 'DumpQueryResult',
+ 'data': { 'status': 'DumpStatus',
+ 'completed': 'int',
+ 'total': 'int' } }
+
+##
+# @query-dump:
+#
+# Query latest dump status.
+#
+# Returns: A @DumpStatus object showing the dump status.
+#
+# Since: 2.6
+#
+# Example:
+#
+# -> { "execute": "query-dump" }
+# <- { "return": { "status": "active", "completed": 1024000,
+# "total": 2048000 } }
+#
+##
+{ 'command': 'query-dump', 'returns': 'DumpQueryResult' }
+
+##
+# @DUMP_COMPLETED:
+#
+# Emitted when background dump has completed
+#
+# @result: final dump status
+#
+# @error: human-readable error string that provides
+# hint on why dump failed. Only presents on failure. The
+# user should not try to interpret the error string.
+#
+# Since: 2.6
+#
+# Example:
+#
+# { "event": "DUMP_COMPLETED",
+# "data": {"result": {"total": 1090650112, "status": "completed",
+# "completed": 1090650112} } }
+#
+##
+{ 'event': 'DUMP_COMPLETED' ,
+ 'data': { 'result': 'DumpQueryResult', '*error': 'str' } }
+
+##
+# @DumpGuestMemoryCapability:
+#
+# A list of the available formats for dump-guest-memory
+#
+# Since: 2.0
+##
+{ 'struct': 'DumpGuestMemoryCapability',
+ 'data': {
+ 'formats': ['DumpGuestMemoryFormat'] } }
+
+##
+# @query-dump-guest-memory-capability:
+#
+# Returns the available formats for dump-guest-memory
+#
+# Returns: A @DumpGuestMemoryCapability object listing available formats for
+# dump-guest-memory
+#
+# Since: 2.0
+#
+# Example:
+#
+# -> { "execute": "query-dump-guest-memory-capability" }
+# <- { "return": { "formats":
+# ["elf", "kdump-zlib", "kdump-lzo", "kdump-snappy"] }
+#
+##
+{ 'command': 'query-dump-guest-memory-capability',
+ 'returns': 'DumpGuestMemoryCapability' }
--- /dev/null
+# -*- Mode: Python -*-
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+##
+# @CpuModelInfo:
+#
+# Virtual CPU model.
+#
+# A CPU model consists of the name of a CPU definition, to which
+# delta changes are applied (e.g. features added/removed). Most magic values
+# that an architecture might require should be hidden behind the name.
+# However, if required, architectures can expose relevant properties.
+#
+# @name: the name of the CPU definition the model is based on
+# @props: a dictionary of QOM properties to be applied
+#
+# Since: 2.8.0
+##
+{ 'struct': 'CpuModelInfo',
+ 'data': { 'name': 'str',
+ '*props': 'any' } }
+
+##
+# @CpuModelExpansionType:
+#
+# An enumeration of CPU model expansion types.
+#
+# @static: Expand to a static CPU model, a combination of a static base
+# model name and property delta changes. As the static base model will
+# never change, the expanded CPU model will be the same, independent of
+# QEMU version, machine type, machine options, and accelerator options.
+# Therefore, the resulting model can be used by tooling without having
+# to specify a compatibility machine - e.g. when displaying the "host"
+# model. The @static CPU models are migration-safe.
+
+# @full: Expand all properties. The produced model is not guaranteed to be
+# migration-safe, but allows tooling to get an insight and work with
+# model details.
+#
+# Note: When a non-migration-safe CPU model is expanded in static mode, some
+# features enabled by the CPU model may be omitted, because they can't be
+# implemented by a static CPU model definition (e.g. cache info passthrough and
+# PMU passthrough in x86). If you need an accurate representation of the
+# features enabled by a non-migration-safe CPU model, use @full. If you need a
+# static representation that will keep ABI compatibility even when changing QEMU
+# version or machine-type, use @static (but keep in mind that some features may
+# be omitted).
+#
+# Since: 2.8.0
+##
+{ 'enum': 'CpuModelExpansionType',
+ 'data': [ 'static', 'full' ] }
+
+
+##
+# @CpuModelCompareResult:
+#
+# An enumeration of CPU model comparison results. The result is usually
+# calculated using e.g. CPU features or CPU generations.
+#
+# @incompatible: If model A is incompatible to model B, model A is not
+# guaranteed to run where model B runs and the other way around.
+#
+# @identical: If model A is identical to model B, model A is guaranteed to run
+# where model B runs and the other way around.
+#
+# @superset: If model A is a superset of model B, model B is guaranteed to run
+# where model A runs. There are no guarantees about the other way.
+#
+# @subset: If model A is a subset of model B, model A is guaranteed to run
+# where model B runs. There are no guarantees about the other way.
+#
+# Since: 2.8.0
+##
+{ 'enum': 'CpuModelCompareResult',
+ 'data': [ 'incompatible', 'identical', 'superset', 'subset' ] }
+
+##
+# @CpuModelBaselineInfo:
+#
+# The result of a CPU model baseline.
+#
+# @model: the baselined CpuModelInfo.
+#
+# Since: 2.8.0
+##
+{ 'struct': 'CpuModelBaselineInfo',
+ 'data': { 'model': 'CpuModelInfo' },
+ 'if': 'defined(TARGET_S390X)' }
+
+##
+# @CpuModelCompareInfo:
+#
+# The result of a CPU model comparison.
+#
+# @result: The result of the compare operation.
+# @responsible-properties: List of properties that led to the comparison result
+# not being identical.
+#
+# @responsible-properties is a list of QOM property names that led to
+# both CPUs not being detected as identical. For identical models, this
+# list is empty.
+# If a QOM property is read-only, that means there's no known way to make the
+# CPU models identical. If the special property name "type" is included, the
+# models are by definition not identical and cannot be made identical.
+#
+# Since: 2.8.0
+##
+{ 'struct': 'CpuModelCompareInfo',
+ 'data': { 'result': 'CpuModelCompareResult',
+ 'responsible-properties': ['str'] },
+ 'if': 'defined(TARGET_S390X)' }
+
+##
+# @query-cpu-model-comparison:
+#
+# Compares two CPU models, returning how they compare in a specific
+# configuration. The results indicates how both models compare regarding
+# runnability. This result can be used by tooling to make decisions if a
+# certain CPU model will run in a certain configuration or if a compatible
+# CPU model has to be created by baselining.
+#
+# Usually, a CPU model is compared against the maximum possible CPU model
+# of a certain configuration (e.g. the "host" model for KVM). If that CPU
+# model is identical or a subset, it will run in that configuration.
+#
+# The result returned by this command may be affected by:
+#
+# * QEMU version: CPU models may look different depending on the QEMU version.
+# (Except for CPU models reported as "static" in query-cpu-definitions.)
+# * machine-type: CPU model may look different depending on the machine-type.
+# (Except for CPU models reported as "static" in query-cpu-definitions.)
+# * machine options (including accelerator): in some architectures, CPU models
+# may look different depending on machine and accelerator options. (Except for
+# CPU models reported as "static" in query-cpu-definitions.)
+# * "-cpu" arguments and global properties: arguments to the -cpu option and
+# global properties may affect expansion of CPU models. Using
+# query-cpu-model-expansion while using these is not advised.
+#
+# Some architectures may not support comparing CPU models. s390x supports
+# comparing CPU models.
+#
+# Returns: a CpuModelBaselineInfo. Returns an error if comparing CPU models is
+# not supported, if a model cannot be used, if a model contains
+# an unknown cpu definition name, unknown properties or properties
+# with wrong types.
+#
+# Note: this command isn't specific to s390x, but is only implemented
+# on this architecture currently.
+#
+# Since: 2.8.0
+##
+{ 'command': 'query-cpu-model-comparison',
+ 'data': { 'modela': 'CpuModelInfo', 'modelb': 'CpuModelInfo' },
+ 'returns': 'CpuModelCompareInfo',
+ 'if': 'defined(TARGET_S390X)' }
+
+##
+# @query-cpu-model-baseline:
+#
+# Baseline two CPU models, creating a compatible third model. The created
+# model will always be a static, migration-safe CPU model (see "static"
+# CPU model expansion for details).
+#
+# This interface can be used by tooling to create a compatible CPU model out
+# two CPU models. The created CPU model will be identical to or a subset of
+# both CPU models when comparing them. Therefore, the created CPU model is
+# guaranteed to run where the given CPU models run.
+#
+# The result returned by this command may be affected by:
+#
+# * QEMU version: CPU models may look different depending on the QEMU version.
+# (Except for CPU models reported as "static" in query-cpu-definitions.)
+# * machine-type: CPU model may look different depending on the machine-type.
+# (Except for CPU models reported as "static" in query-cpu-definitions.)
+# * machine options (including accelerator): in some architectures, CPU models
+# may look different depending on machine and accelerator options. (Except for
+# CPU models reported as "static" in query-cpu-definitions.)
+# * "-cpu" arguments and global properties: arguments to the -cpu option and
+# global properties may affect expansion of CPU models. Using
+# query-cpu-model-expansion while using these is not advised.
+#
+# Some architectures may not support baselining CPU models. s390x supports
+# baselining CPU models.
+#
+# Returns: a CpuModelBaselineInfo. Returns an error if baselining CPU models is
+# not supported, if a model cannot be used, if a model contains
+# an unknown cpu definition name, unknown properties or properties
+# with wrong types.
+#
+# Note: this command isn't specific to s390x, but is only implemented
+# on this architecture currently.
+#
+# Since: 2.8.0
+##
+{ 'command': 'query-cpu-model-baseline',
+ 'data': { 'modela': 'CpuModelInfo',
+ 'modelb': 'CpuModelInfo' },
+ 'returns': 'CpuModelBaselineInfo',
+ 'if': 'defined(TARGET_S390X)' }
+
+##
+# @CpuModelExpansionInfo:
+#
+# The result of a cpu model expansion.
+#
+# @model: the expanded CpuModelInfo.
+#
+# Since: 2.8.0
+##
+{ 'struct': 'CpuModelExpansionInfo',
+ 'data': { 'model': 'CpuModelInfo' },
+ 'if': 'defined(TARGET_S390X) || defined(TARGET_I386)' }
+
+##
+# @query-cpu-model-expansion:
+#
+# Expands a given CPU model (or a combination of CPU model + additional options)
+# to different granularities, allowing tooling to get an understanding what a
+# specific CPU model looks like in QEMU under a certain configuration.
+#
+# This interface can be used to query the "host" CPU model.
+#
+# The data returned by this command may be affected by:
+#
+# * QEMU version: CPU models may look different depending on the QEMU version.
+# (Except for CPU models reported as "static" in query-cpu-definitions.)
+# * machine-type: CPU model may look different depending on the machine-type.
+# (Except for CPU models reported as "static" in query-cpu-definitions.)
+# * machine options (including accelerator): in some architectures, CPU models
+# may look different depending on machine and accelerator options. (Except for
+# CPU models reported as "static" in query-cpu-definitions.)
+# * "-cpu" arguments and global properties: arguments to the -cpu option and
+# global properties may affect expansion of CPU models. Using
+# query-cpu-model-expansion while using these is not advised.
+#
+# Some architectures may not support all expansion types. s390x supports
+# "full" and "static".
+#
+# Returns: a CpuModelExpansionInfo. Returns an error if expanding CPU models is
+# not supported, if the model cannot be expanded, if the model contains
+# an unknown CPU definition name, unknown properties or properties
+# with a wrong type. Also returns an error if an expansion type is
+# not supported.
+#
+# Since: 2.8.0
+##
+{ 'command': 'query-cpu-model-expansion',
+ 'data': { 'type': 'CpuModelExpansionType',
+ 'model': 'CpuModelInfo' },
+ 'returns': 'CpuModelExpansionInfo',
+ 'if': 'defined(TARGET_S390X) || defined(TARGET_I386)' }
+
+##
+# @CpuDefinitionInfo:
+#
+# Virtual CPU definition.
+#
+# @name: the name of the CPU definition
+#
+# @migration-safe: whether a CPU definition can be safely used for
+# migration in combination with a QEMU compatibility machine
+# when migrating between different QEMU versions and between
+# hosts with different sets of (hardware or software)
+# capabilities. If not provided, information is not available
+# and callers should not assume the CPU definition to be
+# migration-safe. (since 2.8)
+#
+# @static: whether a CPU definition is static and will not change depending on
+# QEMU version, machine type, machine options and accelerator options.
+# A static model is always migration-safe. (since 2.8)
+#
+# @unavailable-features: List of properties that prevent
+# the CPU model from running in the current
+# host. (since 2.8)
+# @typename: Type name that can be used as argument to @device-list-properties,
+# to introspect properties configurable using -cpu or -global.
+# (since 2.9)
+#
+# @unavailable-features is a list of QOM property names that
+# represent CPU model attributes that prevent the CPU from running.
+# If the QOM property is read-only, that means there's no known
+# way to make the CPU model run in the current host. Implementations
+# that choose not to provide specific information return the
+# property name "type".
+# If the property is read-write, it means that it MAY be possible
+# to run the CPU model in the current host if that property is
+# changed. Management software can use it as hints to suggest or
+# choose an alternative for the user, or just to generate meaningful
+# error messages explaining why the CPU model can't be used.
+# If @unavailable-features is an empty list, the CPU model is
+# runnable using the current host and machine-type.
+# If @unavailable-features is not present, runnability
+# information for the CPU is not available.
+#
+# Since: 1.2.0
+##
+{ 'struct': 'CpuDefinitionInfo',
+ 'data': { 'name': 'str',
+ '*migration-safe': 'bool',
+ 'static': 'bool',
+ '*unavailable-features': [ 'str' ],
+ 'typename': 'str' },
+ 'if': 'defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_I386) || defined(TARGET_S390X) || defined(TARGET_MIPS)' }
+
+##
+# @query-cpu-definitions:
+#
+# Return a list of supported virtual CPU definitions
+#
+# Returns: a list of CpuDefInfo
+#
+# Since: 1.2.0
+##
+{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'],
+ 'if': 'defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_I386) || defined(TARGET_S390X) || defined(TARGET_MIPS)' }
--- /dev/null
+# -*- Mode: Python -*-
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+##
+# = Machines
+##
+
+{ 'include': 'common.json' }
+
+##
+# @CpuInfoArch:
+#
+# An enumeration of cpu types that enable additional information during
+# @query-cpus and @query-cpus-fast.
+#
+# @s390: since 2.12
+#
+# @riscv: since 2.12
+#
+# Since: 2.6
+##
+{ 'enum': 'CpuInfoArch',
+ 'data': ['x86', 'sparc', 'ppc', 'mips', 'tricore', 's390', 'riscv', 'other' ] }
+
+##
+# @CpuInfo:
+#
+# Information about a virtual CPU
+#
+# @CPU: the index of the virtual CPU
+#
+# @current: this only exists for backwards compatibility and should be ignored
+#
+# @halted: true if the virtual CPU is in the halt state. Halt usually refers
+# to a processor specific low power mode.
+#
+# @qom_path: path to the CPU object in the QOM tree (since 2.4)
+#
+# @thread_id: ID of the underlying host thread
+#
+# @props: properties describing to which node/socket/core/thread
+# virtual CPU belongs to, provided if supported by board (since 2.10)
+#
+# @arch: architecture of the cpu, which determines which additional fields
+# will be listed (since 2.6)
+#
+# Since: 0.14.0
+#
+# Notes: @halted is a transient state that changes frequently. By the time the
+# data is sent to the client, the guest may no longer be halted.
+##
+{ 'union': 'CpuInfo',
+ 'base': {'CPU': 'int', 'current': 'bool', 'halted': 'bool',
+ 'qom_path': 'str', 'thread_id': 'int',
+ '*props': 'CpuInstanceProperties', 'arch': 'CpuInfoArch' },
+ 'discriminator': 'arch',
+ 'data': { 'x86': 'CpuInfoX86',
+ 'sparc': 'CpuInfoSPARC',
+ 'ppc': 'CpuInfoPPC',
+ 'mips': 'CpuInfoMIPS',
+ 'tricore': 'CpuInfoTricore',
+ 's390': 'CpuInfoS390',
+ 'riscv': 'CpuInfoRISCV' } }
+
+##
+# @CpuInfoX86:
+#
+# Additional information about a virtual i386 or x86_64 CPU
+#
+# @pc: the 64-bit instruction pointer
+#
+# Since: 2.6
+##
+{ 'struct': 'CpuInfoX86', 'data': { 'pc': 'int' } }
+
+##
+# @CpuInfoSPARC:
+#
+# Additional information about a virtual SPARC CPU
+#
+# @pc: the PC component of the instruction pointer
+#
+# @npc: the NPC component of the instruction pointer
+#
+# Since: 2.6
+##
+{ 'struct': 'CpuInfoSPARC', 'data': { 'pc': 'int', 'npc': 'int' } }
+
+##
+# @CpuInfoPPC:
+#
+# Additional information about a virtual PPC CPU
+#
+# @nip: the instruction pointer
+#
+# Since: 2.6
+##
+{ 'struct': 'CpuInfoPPC', 'data': { 'nip': 'int' } }
+
+##
+# @CpuInfoMIPS:
+#
+# Additional information about a virtual MIPS CPU
+#
+# @PC: the instruction pointer
+#
+# Since: 2.6
+##
+{ 'struct': 'CpuInfoMIPS', 'data': { 'PC': 'int' } }
+
+##
+# @CpuInfoTricore:
+#
+# Additional information about a virtual Tricore CPU
+#
+# @PC: the instruction pointer
+#
+# Since: 2.6
+##
+{ 'struct': 'CpuInfoTricore', 'data': { 'PC': 'int' } }
+
+##
+# @CpuInfoRISCV:
+#
+# Additional information about a virtual RISCV CPU
+#
+# @pc: the instruction pointer
+#
+# Since 2.12
+##
+{ 'struct': 'CpuInfoRISCV', 'data': { 'pc': 'int' } }
+
+##
+# @CpuS390State:
+#
+# An enumeration of cpu states that can be assumed by a virtual
+# S390 CPU
+#
+# Since: 2.12
+##
+{ 'enum': 'CpuS390State',
+ 'prefix': 'S390_CPU_STATE',
+ 'data': [ 'uninitialized', 'stopped', 'check-stop', 'operating', 'load' ] }
+
+##
+# @CpuInfoS390:
+#
+# Additional information about a virtual S390 CPU
+#
+# @cpu-state: the virtual CPU's state
+#
+# Since: 2.12
+##
+{ 'struct': 'CpuInfoS390', 'data': { 'cpu-state': 'CpuS390State' } }
+
+##
+# @query-cpus:
+#
+# Returns a list of information about each virtual CPU.
+#
+# This command causes vCPU threads to exit to userspace, which causes
+# a small interruption to guest CPU execution. This will have a negative
+# impact on realtime guests and other latency sensitive guest workloads.
+# It is recommended to use @query-cpus-fast instead of this command to
+# avoid the vCPU interruption.
+#
+# Returns: a list of @CpuInfo for each virtual CPU
+#
+# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-cpus" }
+# <- { "return": [
+# {
+# "CPU":0,
+# "current":true,
+# "halted":false,
+# "qom_path":"/machine/unattached/device[0]",
+# "arch":"x86",
+# "pc":3227107138,
+# "thread_id":3134
+# },
+# {
+# "CPU":1,
+# "current":false,
+# "halted":true,
+# "qom_path":"/machine/unattached/device[2]",
+# "arch":"x86",
+# "pc":7108165,
+# "thread_id":3135
+# }
+# ]
+# }
+#
+# Notes: This interface is deprecated (since 2.12.0), and it is strongly
+# recommended that you avoid using it. Use @query-cpus-fast to
+# obtain information about virtual CPUs.
+#
+##
+{ 'command': 'query-cpus', 'returns': ['CpuInfo'] }
+
+##
+# @CpuInfoFast:
+#
+# Information about a virtual CPU
+#
+# @cpu-index: index of the virtual CPU
+#
+# @qom-path: path to the CPU object in the QOM tree
+#
+# @thread-id: ID of the underlying host thread
+#
+# @props: properties describing to which node/socket/core/thread
+# virtual CPU belongs to, provided if supported by board
+#
+# @arch: base architecture of the cpu; deprecated since 3.0.0 in favor
+# of @target
+#
+# @target: the QEMU system emulation target, which determines which
+# additional fields will be listed (since 3.0)
+#
+# Since: 2.12
+#
+##
+{ 'union' : 'CpuInfoFast',
+ 'base' : { 'cpu-index' : 'int',
+ 'qom-path' : 'str',
+ 'thread-id' : 'int',
+ '*props' : 'CpuInstanceProperties',
+ 'arch' : 'CpuInfoArch',
+ 'target' : 'SysEmuTarget' },
+ 'discriminator' : 'target',
+ 'data' : { 's390x' : 'CpuInfoS390' } }
+
+##
+# @query-cpus-fast:
+#
+# Returns information about all virtual CPUs. This command does not
+# incur a performance penalty and should be used in production
+# instead of query-cpus.
+#
+# Returns: list of @CpuInfoFast
+#
+# Since: 2.12
+#
+# Example:
+#
+# -> { "execute": "query-cpus-fast" }
+# <- { "return": [
+# {
+# "thread-id": 25627,
+# "props": {
+# "core-id": 0,
+# "thread-id": 0,
+# "socket-id": 0
+# },
+# "qom-path": "/machine/unattached/device[0]",
+# "arch":"x86",
+# "target":"x86_64",
+# "cpu-index": 0
+# },
+# {
+# "thread-id": 25628,
+# "props": {
+# "core-id": 0,
+# "thread-id": 0,
+# "socket-id": 1
+# },
+# "qom-path": "/machine/unattached/device[2]",
+# "arch":"x86",
+# "target":"x86_64",
+# "cpu-index": 1
+# }
+# ]
+# }
+##
+{ 'command': 'query-cpus-fast', 'returns': [ 'CpuInfoFast' ] }
+
+##
+# @cpu-add:
+#
+# Adds CPU with specified ID.
+#
+# @id: ID of CPU to be created, valid values [0..max_cpus)
+#
+# Returns: Nothing on success
+#
+# Since: 1.5
+#
+# Note: This command is deprecated. The `device_add` command should be
+# used instead. See the `query-hotpluggable-cpus` command for
+# details.
+#
+# Example:
+#
+# -> { "execute": "cpu-add", "arguments": { "id": 2 } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'cpu-add', 'data': {'id': 'int'} }
+
+##
+# @MachineInfo:
+#
+# Information describing a machine.
+#
+# @name: the name of the machine
+#
+# @alias: an alias for the machine name
+#
+# @is-default: whether the machine is default
+#
+# @cpu-max: maximum number of CPUs supported by the machine type
+# (since 1.5.0)
+#
+# @hotpluggable-cpus: cpu hotplug via -device is supported (since 2.7.0)
+#
+# Since: 1.2.0
+##
+{ 'struct': 'MachineInfo',
+ 'data': { 'name': 'str', '*alias': 'str',
+ '*is-default': 'bool', 'cpu-max': 'int',
+ 'hotpluggable-cpus': 'bool'} }
+
+##
+# @query-machines:
+#
+# Return a list of supported machines
+#
+# Returns: a list of MachineInfo
+#
+# Since: 1.2.0
+##
+{ 'command': 'query-machines', 'returns': ['MachineInfo'] }
+
+##
+# @CurrentMachineParams:
+#
+# Information describing the running machine parameters.
+#
+# @wakeup-suspend-support: true if the machine supports wake up from
+# suspend
+#
+# Since: 4.0
+##
+{ 'struct': 'CurrentMachineParams',
+ 'data': { 'wakeup-suspend-support': 'bool'} }
+
+##
+# @query-current-machine:
+#
+# Return information on the current virtual machine.
+#
+# Returns: CurrentMachineParams
+#
+# Since: 4.0
+##
+{ 'command': 'query-current-machine', 'returns': 'CurrentMachineParams' }
+
+##
+# @NumaOptionsType:
+#
+# @node: NUMA nodes configuration
+#
+# @dist: NUMA distance configuration (since 2.10)
+#
+# @cpu: property based CPU(s) to node mapping (Since: 2.10)
+#
+# Since: 2.1
+##
+{ 'enum': 'NumaOptionsType',
+ 'data': [ 'node', 'dist', 'cpu' ] }
+
+##
+# @NumaOptions:
+#
+# A discriminated record of NUMA options. (for OptsVisitor)
+#
+# Since: 2.1
+##
+{ 'union': 'NumaOptions',
+ 'base': { 'type': 'NumaOptionsType' },
+ 'discriminator': 'type',
+ 'data': {
+ 'node': 'NumaNodeOptions',
+ 'dist': 'NumaDistOptions',
+ 'cpu': 'NumaCpuOptions' }}
+
+##
+# @NumaNodeOptions:
+#
+# Create a guest NUMA node. (for OptsVisitor)
+#
+# @nodeid: NUMA node ID (increase by 1 from 0 if omitted)
+#
+# @cpus: VCPUs belonging to this node (assign VCPUS round-robin
+# if omitted)
+#
+# @mem: memory size of this node; mutually exclusive with @memdev.
+# Equally divide total memory among nodes if both @mem and @memdev are
+# omitted.
+#
+# @memdev: memory backend object. If specified for one node,
+# it must be specified for all nodes.
+#
+# Since: 2.1
+##
+{ 'struct': 'NumaNodeOptions',
+ 'data': {
+ '*nodeid': 'uint16',
+ '*cpus': ['uint16'],
+ '*mem': 'size',
+ '*memdev': 'str' }}
+
+##
+# @NumaDistOptions:
+#
+# Set the distance between 2 NUMA nodes.
+#
+# @src: source NUMA node.
+#
+# @dst: destination NUMA node.
+#
+# @val: NUMA distance from source node to destination node.
+# When a node is unreachable from another node, set the distance
+# between them to 255.
+#
+# Since: 2.10
+##
+{ 'struct': 'NumaDistOptions',
+ 'data': {
+ 'src': 'uint16',
+ 'dst': 'uint16',
+ 'val': 'uint8' }}
+
+##
+# @X86CPURegister32:
+#
+# A X86 32-bit register
+#
+# Since: 1.5
+##
+{ 'enum': 'X86CPURegister32',
+ 'data': [ 'EAX', 'EBX', 'ECX', 'EDX', 'ESP', 'EBP', 'ESI', 'EDI' ] }
+
+##
+# @X86CPUFeatureWordInfo:
+#
+# Information about a X86 CPU feature word
+#
+# @cpuid-input-eax: Input EAX value for CPUID instruction for that feature word
+#
+# @cpuid-input-ecx: Input ECX value for CPUID instruction for that
+# feature word
+#
+# @cpuid-register: Output register containing the feature bits
+#
+# @features: value of output register, containing the feature bits
+#
+# Since: 1.5
+##
+{ 'struct': 'X86CPUFeatureWordInfo',
+ 'data': { 'cpuid-input-eax': 'int',
+ '*cpuid-input-ecx': 'int',
+ 'cpuid-register': 'X86CPURegister32',
+ 'features': 'int' } }
+
+##
+# @DummyForceArrays:
+#
+# Not used by QMP; hack to let us use X86CPUFeatureWordInfoList internally
+#
+# Since: 2.5
+##
+{ 'struct': 'DummyForceArrays',
+ 'data': { 'unused': ['X86CPUFeatureWordInfo'] } }
+
+##
+# @NumaCpuOptions:
+#
+# Option "-numa cpu" overrides default cpu to node mapping.
+# It accepts the same set of cpu properties as returned by
+# query-hotpluggable-cpus[].props, where node-id could be used to
+# override default node mapping.
+#
+# Since: 2.10
+##
+{ 'struct': 'NumaCpuOptions',
+ 'base': 'CpuInstanceProperties',
+ 'data' : {} }
+
+##
+# @HostMemPolicy:
+#
+# Host memory policy types
+#
+# @default: restore default policy, remove any nondefault policy
+#
+# @preferred: set the preferred host nodes for allocation
+#
+# @bind: a strict policy that restricts memory allocation to the
+# host nodes specified
+#
+# @interleave: memory allocations are interleaved across the set
+# of host nodes specified
+#
+# Since: 2.1
+##
+{ 'enum': 'HostMemPolicy',
+ 'data': [ 'default', 'preferred', 'bind', 'interleave' ] }
+
+##
+# @Memdev:
+#
+# Information about memory backend
+#
+# @id: backend's ID if backend has 'id' property (since 2.9)
+#
+# @size: memory backend size
+#
+# @merge: enables or disables memory merge support
+#
+# @dump: includes memory backend's memory in a core dump or not
+#
+# @prealloc: enables or disables memory preallocation
+#
+# @host-nodes: host nodes for its memory policy
+#
+# @policy: memory policy of memory backend
+#
+# Since: 2.1
+##
+{ 'struct': 'Memdev',
+ 'data': {
+ '*id': 'str',
+ 'size': 'size',
+ 'merge': 'bool',
+ 'dump': 'bool',
+ 'prealloc': 'bool',
+ 'host-nodes': ['uint16'],
+ 'policy': 'HostMemPolicy' }}
+
+##
+# @query-memdev:
+#
+# Returns information for all memory backends.
+#
+# Returns: a list of @Memdev.
+#
+# Since: 2.1
+#
+# Example:
+#
+# -> { "execute": "query-memdev" }
+# <- { "return": [
+# {
+# "id": "mem1",
+# "size": 536870912,
+# "merge": false,
+# "dump": true,
+# "prealloc": false,
+# "host-nodes": [0, 1],
+# "policy": "bind"
+# },
+# {
+# "size": 536870912,
+# "merge": false,
+# "dump": true,
+# "prealloc": true,
+# "host-nodes": [2, 3],
+# "policy": "preferred"
+# }
+# ]
+# }
+#
+##
+{ 'command': 'query-memdev', 'returns': ['Memdev'], 'allow-preconfig': true }
+
+##
+# @CpuInstanceProperties:
+#
+# List of properties to be used for hotplugging a CPU instance,
+# it should be passed by management with device_add command when
+# a CPU is being hotplugged.
+#
+# @node-id: NUMA node ID the CPU belongs to
+# @socket-id: socket number within node/board the CPU belongs to
+# @core-id: core number within socket the CPU belongs to
+# @thread-id: thread number within core the CPU belongs to
+#
+# Note: currently there are 4 properties that could be present
+# but management should be prepared to pass through other
+# properties with device_add command to allow for future
+# interface extension. This also requires the filed names to be kept in
+# sync with the properties passed to -device/device_add.
+#
+# Since: 2.7
+##
+{ 'struct': 'CpuInstanceProperties',
+ 'data': { '*node-id': 'int',
+ '*socket-id': 'int',
+ '*core-id': 'int',
+ '*thread-id': 'int'
+ }
+}
+
+##
+# @HotpluggableCPU:
+#
+# @type: CPU object type for usage with device_add command
+# @props: list of properties to be used for hotplugging CPU
+# @vcpus-count: number of logical VCPU threads @HotpluggableCPU provides
+# @qom-path: link to existing CPU object if CPU is present or
+# omitted if CPU is not present.
+#
+# Since: 2.7
+##
+{ 'struct': 'HotpluggableCPU',
+ 'data': { 'type': 'str',
+ 'vcpus-count': 'int',
+ 'props': 'CpuInstanceProperties',
+ '*qom-path': 'str'
+ }
+}
+
+##
+# @query-hotpluggable-cpus:
+#
+# TODO: Better documentation; currently there is none.
+#
+# Returns: a list of HotpluggableCPU objects.
+#
+# Since: 2.7
+#
+# Example:
+#
+# For pseries machine type started with -smp 2,cores=2,maxcpus=4 -cpu POWER8:
+#
+# -> { "execute": "query-hotpluggable-cpus" }
+# <- {"return": [
+# { "props": { "core": 8 }, "type": "POWER8-spapr-cpu-core",
+# "vcpus-count": 1 },
+# { "props": { "core": 0 }, "type": "POWER8-spapr-cpu-core",
+# "vcpus-count": 1, "qom-path": "/machine/unattached/device[0]"}
+# ]}'
+#
+# For pc machine type started with -smp 1,maxcpus=2:
+#
+# -> { "execute": "query-hotpluggable-cpus" }
+# <- {"return": [
+# {
+# "type": "qemu64-x86_64-cpu", "vcpus-count": 1,
+# "props": {"core-id": 0, "socket-id": 1, "thread-id": 0}
+# },
+# {
+# "qom-path": "/machine/unattached/device[0]",
+# "type": "qemu64-x86_64-cpu", "vcpus-count": 1,
+# "props": {"core-id": 0, "socket-id": 0, "thread-id": 0}
+# }
+# ]}
+#
+# For s390x-virtio-ccw machine type started with -smp 1,maxcpus=2 -cpu qemu
+# (Since: 2.11):
+#
+# -> { "execute": "query-hotpluggable-cpus" }
+# <- {"return": [
+# {
+# "type": "qemu-s390x-cpu", "vcpus-count": 1,
+# "props": { "core-id": 1 }
+# },
+# {
+# "qom-path": "/machine/unattached/device[0]",
+# "type": "qemu-s390x-cpu", "vcpus-count": 1,
+# "props": { "core-id": 0 }
+# }
+# ]}
+#
+##
+{ 'command': 'query-hotpluggable-cpus', 'returns': ['HotpluggableCPU'],
+ 'allow-preconfig': true }
+
+##
+# @set-numa-node:
+#
+# Runtime equivalent of '-numa' CLI option, available at
+# preconfigure stage to configure numa mapping before initializing
+# machine.
+#
+# Since 3.0
+##
+{ 'command': 'set-numa-node', 'boxed': true,
+ 'data': 'NumaOptions',
+ 'allow-preconfig': true
+}
--- /dev/null
+# -*- Mode: Python -*-
+#
+
+##
+# @RTC_CHANGE:
+#
+# Emitted when the guest changes the RTC time.
+#
+# @offset: offset between base RTC clock (as specified by -rtc base), and
+# new RTC clock value
+#
+# Note: This event is rate-limited.
+#
+# Since: 0.13.0
+#
+# Example:
+#
+# <- { "event": "RTC_CHANGE",
+# "data": { "offset": 78 },
+# "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
+#
+##
+{ 'event': 'RTC_CHANGE',
+ 'data': { 'offset': 'int' },
+ 'if': 'defined(TARGET_ALPHA) || defined(TARGET_ARM) || defined(TARGET_HPPA) || defined(TARGET_I386) || defined(TARGET_MIPS) || defined(TARGET_MIPS64) || defined(TARGET_MOXIE) || defined(TARGET_PPC) || defined(TARGET_PPC64) || defined(TARGET_S390X) || defined(TARGET_SH4) || defined(TARGET_SPARC)' }
+
+##
+# @rtc-reset-reinjection:
+#
+# This command will reset the RTC interrupt reinjection backlog.
+# Can be used if another mechanism to synchronize guest time
+# is in effect, for example QEMU guest agent's guest-set-time
+# command.
+#
+# Since: 2.1
+#
+# Example:
+#
+# -> { "execute": "rtc-reset-reinjection" }
+# <- { "return": {} }
+#
+##
+{ 'command': 'rtc-reset-reinjection',
+ 'if': 'defined(TARGET_I386)' }
+
+
+##
+# @SevState:
+#
+# An enumeration of SEV state information used during @query-sev.
+#
+# @uninit: The guest is uninitialized.
+#
+# @launch-update: The guest is currently being launched; plaintext data and
+# register state is being imported.
+#
+# @launch-secret: The guest is currently being launched; ciphertext data
+# is being imported.
+#
+# @running: The guest is fully launched or migrated in.
+#
+# @send-update: The guest is currently being migrated out to another machine.
+#
+# @receive-update: The guest is currently being migrated from another machine.
+#
+# Since: 2.12
+##
+{ 'enum': 'SevState',
+ 'data': ['uninit', 'launch-update', 'launch-secret', 'running',
+ 'send-update', 'receive-update' ],
+ 'if': 'defined(TARGET_I386)' }
+
+##
+# @SevInfo:
+#
+# Information about Secure Encrypted Virtualization (SEV) support
+#
+# @enabled: true if SEV is active
+#
+# @api-major: SEV API major version
+#
+# @api-minor: SEV API minor version
+#
+# @build-id: SEV FW build id
+#
+# @policy: SEV policy value
+#
+# @state: SEV guest state
+#
+# @handle: SEV firmware handle
+#
+# Since: 2.12
+##
+{ 'struct': 'SevInfo',
+ 'data': { 'enabled': 'bool',
+ 'api-major': 'uint8',
+ 'api-minor' : 'uint8',
+ 'build-id' : 'uint8',
+ 'policy' : 'uint32',
+ 'state' : 'SevState',
+ 'handle' : 'uint32'
+ },
+ 'if': 'defined(TARGET_I386)'
+}
+
+##
+# @query-sev:
+#
+# Returns information about SEV
+#
+# Returns: @SevInfo
+#
+# Since: 2.12
+#
+# Example:
+#
+# -> { "execute": "query-sev" }
+# <- { "return": { "enabled": true, "api-major" : 0, "api-minor" : 0,
+# "build-id" : 0, "policy" : 0, "state" : "running",
+# "handle" : 1 } }
+#
+##
+{ 'command': 'query-sev', 'returns': 'SevInfo',
+ 'if': 'defined(TARGET_I386)' }
+
+
+##
+# @SevLaunchMeasureInfo:
+#
+# SEV Guest Launch measurement information
+#
+# @data: the measurement value encoded in base64
+#
+# Since: 2.12
+#
+##
+{ 'struct': 'SevLaunchMeasureInfo', 'data': {'data': 'str'},
+ 'if': 'defined(TARGET_I386)' }
+
+##
+# @query-sev-launch-measure:
+#
+# Query the SEV guest launch information.
+#
+# Returns: The @SevLaunchMeasureInfo for the guest
+#
+# Since: 2.12
+#
+# Example:
+#
+# -> { "execute": "query-sev-launch-measure" }
+# <- { "return": { "data": "4l8LXeNlSPUDlXPJG5966/8%YZ" } }
+#
+##
+{ 'command': 'query-sev-launch-measure', 'returns': 'SevLaunchMeasureInfo',
+ 'if': 'defined(TARGET_I386)' }
+
+
+##
+# @SevCapability:
+#
+# The struct describes capability for a Secure Encrypted Virtualization
+# feature.
+#
+# @pdh: Platform Diffie-Hellman key (base64 encoded)
+#
+# @cert-chain: PDH certificate chain (base64 encoded)
+#
+# @cbitpos: C-bit location in page table entry
+#
+# @reduced-phys-bits: Number of physical Address bit reduction when SEV is
+# enabled
+#
+# Since: 2.12
+##
+{ 'struct': 'SevCapability',
+ 'data': { 'pdh': 'str',
+ 'cert-chain': 'str',
+ 'cbitpos': 'int',
+ 'reduced-phys-bits': 'int'},
+ 'if': 'defined(TARGET_I386)' }
+
+##
+# @query-sev-capabilities:
+#
+# This command is used to get the SEV capabilities, and is supported on AMD
+# X86 platforms only.
+#
+# Returns: SevCapability objects.
+#
+# Since: 2.12
+#
+# Example:
+#
+# -> { "execute": "query-sev-capabilities" }
+# <- { "return": { "pdh": "8CCDD8DDD", "cert-chain": "888CCCDDDEE",
+# "cbitpos": 47, "reduced-phys-bits": 5}}
+#
+##
+{ 'command': 'query-sev-capabilities', 'returns': 'SevCapability',
+ 'if': 'defined(TARGET_I386)' }
+
+##
+# @dump-skeys:
+#
+# Dump guest's storage keys
+#
+# @filename: the path to the file to dump to
+#
+# This command is only supported on s390 architecture.
+#
+# Since: 2.5
+#
+# Example:
+#
+# -> { "execute": "dump-skeys",
+# "arguments": { "filename": "/tmp/skeys" } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'dump-skeys',
+ 'data': { 'filename': 'str' },
+ 'if': 'defined(TARGET_S390X)' }
+
+##
+# @GICCapability:
+#
+# The struct describes capability for a specific GIC (Generic
+# Interrupt Controller) version. These bits are not only decided by
+# QEMU/KVM software version, but also decided by the hardware that
+# the program is running upon.
+#
+# @version: version of GIC to be described. Currently, only 2 and 3
+# are supported.
+#
+# @emulated: whether current QEMU/hardware supports emulated GIC
+# device in user space.
+#
+# @kernel: whether current QEMU/hardware supports hardware
+# accelerated GIC device in kernel.
+#
+# Since: 2.6
+##
+{ 'struct': 'GICCapability',
+ 'data': { 'version': 'int',
+ 'emulated': 'bool',
+ 'kernel': 'bool' },
+ 'if': 'defined(TARGET_ARM)' }
+
+##
+# @query-gic-capabilities:
+#
+# This command is ARM-only. It will return a list of GICCapability
+# objects that describe its capability bits.
+#
+# Returns: a list of GICCapability objects.
+#
+# Since: 2.6
+#
+# Example:
+#
+# -> { "execute": "query-gic-capabilities" }
+# <- { "return": [{ "version": 2, "emulated": true, "kernel": false },
+# { "version": 3, "emulated": false, "kernel": true } ] }
+#
+##
+{ 'command': 'query-gic-capabilities', 'returns': ['GICCapability'],
+ 'if': 'defined(TARGET_ARM)' }
##
{ 'command': 'query-events', 'returns': ['EventInfo'] }
-##
-# @CpuInfoArch:
-#
-# An enumeration of cpu types that enable additional information during
-# @query-cpus and @query-cpus-fast.
-#
-# @s390: since 2.12
-#
-# @riscv: since 2.12
-#
-# Since: 2.6
-##
-{ 'enum': 'CpuInfoArch',
- 'data': ['x86', 'sparc', 'ppc', 'mips', 'tricore', 's390', 'riscv', 'other' ] }
-
-##
-# @CpuInfo:
-#
-# Information about a virtual CPU
-#
-# @CPU: the index of the virtual CPU
-#
-# @current: this only exists for backwards compatibility and should be ignored
-#
-# @halted: true if the virtual CPU is in the halt state. Halt usually refers
-# to a processor specific low power mode.
-#
-# @qom_path: path to the CPU object in the QOM tree (since 2.4)
-#
-# @thread_id: ID of the underlying host thread
-#
-# @props: properties describing to which node/socket/core/thread
-# virtual CPU belongs to, provided if supported by board (since 2.10)
-#
-# @arch: architecture of the cpu, which determines which additional fields
-# will be listed (since 2.6)
-#
-# Since: 0.14.0
-#
-# Notes: @halted is a transient state that changes frequently. By the time the
-# data is sent to the client, the guest may no longer be halted.
-##
-{ 'union': 'CpuInfo',
- 'base': {'CPU': 'int', 'current': 'bool', 'halted': 'bool',
- 'qom_path': 'str', 'thread_id': 'int',
- '*props': 'CpuInstanceProperties', 'arch': 'CpuInfoArch' },
- 'discriminator': 'arch',
- 'data': { 'x86': 'CpuInfoX86',
- 'sparc': 'CpuInfoSPARC',
- 'ppc': 'CpuInfoPPC',
- 'mips': 'CpuInfoMIPS',
- 'tricore': 'CpuInfoTricore',
- 's390': 'CpuInfoS390',
- 'riscv': 'CpuInfoRISCV' } }
-
-##
-# @CpuInfoX86:
-#
-# Additional information about a virtual i386 or x86_64 CPU
-#
-# @pc: the 64-bit instruction pointer
-#
-# Since: 2.6
-##
-{ 'struct': 'CpuInfoX86', 'data': { 'pc': 'int' } }
-
-##
-# @CpuInfoSPARC:
-#
-# Additional information about a virtual SPARC CPU
-#
-# @pc: the PC component of the instruction pointer
-#
-# @npc: the NPC component of the instruction pointer
-#
-# Since: 2.6
-##
-{ 'struct': 'CpuInfoSPARC', 'data': { 'pc': 'int', 'npc': 'int' } }
-
-##
-# @CpuInfoPPC:
-#
-# Additional information about a virtual PPC CPU
-#
-# @nip: the instruction pointer
-#
-# Since: 2.6
-##
-{ 'struct': 'CpuInfoPPC', 'data': { 'nip': 'int' } }
-
-##
-# @CpuInfoMIPS:
-#
-# Additional information about a virtual MIPS CPU
-#
-# @PC: the instruction pointer
-#
-# Since: 2.6
-##
-{ 'struct': 'CpuInfoMIPS', 'data': { 'PC': 'int' } }
-
-##
-# @CpuInfoTricore:
-#
-# Additional information about a virtual Tricore CPU
-#
-# @PC: the instruction pointer
-#
-# Since: 2.6
-##
-{ 'struct': 'CpuInfoTricore', 'data': { 'PC': 'int' } }
-
-##
-# @CpuInfoRISCV:
-#
-# Additional information about a virtual RISCV CPU
-#
-# @pc: the instruction pointer
-#
-# Since 2.12
-##
-{ 'struct': 'CpuInfoRISCV', 'data': { 'pc': 'int' } }
-
-##
-# @CpuS390State:
-#
-# An enumeration of cpu states that can be assumed by a virtual
-# S390 CPU
-#
-# Since: 2.12
-##
-{ 'enum': 'CpuS390State',
- 'prefix': 'S390_CPU_STATE',
- 'data': [ 'uninitialized', 'stopped', 'check-stop', 'operating', 'load' ] }
-
-##
-# @CpuInfoS390:
-#
-# Additional information about a virtual S390 CPU
-#
-# @cpu-state: the virtual CPU's state
-#
-# Since: 2.12
-##
-{ 'struct': 'CpuInfoS390', 'data': { 'cpu-state': 'CpuS390State' } }
-
-##
-# @query-cpus:
-#
-# Returns a list of information about each virtual CPU.
-#
-# This command causes vCPU threads to exit to userspace, which causes
-# a small interruption to guest CPU execution. This will have a negative
-# impact on realtime guests and other latency sensitive guest workloads.
-# It is recommended to use @query-cpus-fast instead of this command to
-# avoid the vCPU interruption.
-#
-# Returns: a list of @CpuInfo for each virtual CPU
-#
-# Since: 0.14.0
-#
-# Example:
-#
-# -> { "execute": "query-cpus" }
-# <- { "return": [
-# {
-# "CPU":0,
-# "current":true,
-# "halted":false,
-# "qom_path":"/machine/unattached/device[0]",
-# "arch":"x86",
-# "pc":3227107138,
-# "thread_id":3134
-# },
-# {
-# "CPU":1,
-# "current":false,
-# "halted":true,
-# "qom_path":"/machine/unattached/device[2]",
-# "arch":"x86",
-# "pc":7108165,
-# "thread_id":3135
-# }
-# ]
-# }
-#
-# Notes: This interface is deprecated (since 2.12.0), and it is strongly
-# recommended that you avoid using it. Use @query-cpus-fast to
-# obtain information about virtual CPUs.
-#
-##
-{ 'command': 'query-cpus', 'returns': ['CpuInfo'] }
-
-##
-# @CpuInfoFast:
-#
-# Information about a virtual CPU
-#
-# @cpu-index: index of the virtual CPU
-#
-# @qom-path: path to the CPU object in the QOM tree
-#
-# @thread-id: ID of the underlying host thread
-#
-# @props: properties describing to which node/socket/core/thread
-# virtual CPU belongs to, provided if supported by board
-#
-# @arch: base architecture of the cpu; deprecated since 3.0.0 in favor
-# of @target
-#
-# @target: the QEMU system emulation target, which determines which
-# additional fields will be listed (since 3.0)
-#
-# Since: 2.12
-#
-##
-{ 'union' : 'CpuInfoFast',
- 'base' : { 'cpu-index' : 'int',
- 'qom-path' : 'str',
- 'thread-id' : 'int',
- '*props' : 'CpuInstanceProperties',
- 'arch' : 'CpuInfoArch',
- 'target' : 'SysEmuTarget' },
- 'discriminator' : 'target',
- 'data' : { 's390x' : 'CpuInfoS390' } }
-
-##
-# @query-cpus-fast:
-#
-# Returns information about all virtual CPUs. This command does not
-# incur a performance penalty and should be used in production
-# instead of query-cpus.
-#
-# Returns: list of @CpuInfoFast
-#
-# Since: 2.12
-#
-# Example:
-#
-# -> { "execute": "query-cpus-fast" }
-# <- { "return": [
-# {
-# "thread-id": 25627,
-# "props": {
-# "core-id": 0,
-# "thread-id": 0,
-# "socket-id": 0
-# },
-# "qom-path": "/machine/unattached/device[0]",
-# "arch":"x86",
-# "target":"x86_64",
-# "cpu-index": 0
-# },
-# {
-# "thread-id": 25628,
-# "props": {
-# "core-id": 0,
-# "thread-id": 0,
-# "socket-id": 1
-# },
-# "qom-path": "/machine/unattached/device[2]",
-# "arch":"x86",
-# "target":"x86_64",
-# "cpu-index": 1
-# }
-# ]
-# }
-##
-{ 'command': 'query-cpus-fast', 'returns': [ 'CpuInfoFast' ] }
-
##
# @IOThreadInfo:
#
##
{ 'command': 'system_powerdown' }
-##
-# @cpu-add:
-#
-# Adds CPU with specified ID.
-#
-# @id: ID of CPU to be created, valid values [0..max_cpus)
-#
-# Returns: Nothing on success
-#
-# Since: 1.5
-#
-# Note: This command is deprecated. The `device_add` command should be
-# used instead. See the `query-hotpluggable-cpus` command for
-# details.
-#
-# Example:
-#
-# -> { "execute": "cpu-add", "arguments": { "id": 2 } }
-# <- { "return": {} }
-#
-##
-{ 'command': 'cpu-add', 'data': {'id': 'int'} }
-
##
# @memsave:
#
'data': {'command-line': 'str', '*cpu-index': 'int'},
'returns': 'str' }
-##
-# @ObjectPropertyInfo:
-#
-# @name: the name of the property
-#
-# @type: the type of the property. This will typically come in one of four
-# forms:
-#
-# 1) A primitive type such as 'u8', 'u16', 'bool', 'str', or 'double'.
-# These types are mapped to the appropriate JSON type.
-#
-# 2) A child type in the form 'child<subtype>' where subtype is a qdev
-# device type name. Child properties create the composition tree.
-#
-# 3) A link type in the form 'link<subtype>' where subtype is a qdev
-# device type name. Link properties form the device model graph.
-#
-# @description: if specified, the description of the property.
-#
-# Since: 1.2
-##
-{ 'struct': 'ObjectPropertyInfo',
- 'data': { 'name': 'str', 'type': 'str', '*description': 'str' } }
-
-##
-# @qom-list:
-#
-# This command will list any properties of a object given a path in the object
-# model.
-#
-# @path: the path within the object model. See @qom-get for a description of
-# this parameter.
-#
-# Returns: a list of @ObjectPropertyInfo that describe the properties of the
-# object.
-#
-# Since: 1.2
-#
-# Example:
-#
-# -> { "execute": "qom-list",
-# "arguments": { "path": "/chardevs" } }
-# <- { "return": [ { "name": "type", "type": "string" },
-# { "name": "parallel0", "type": "child<chardev-vc>" },
-# { "name": "serial0", "type": "child<chardev-vc>" },
-# { "name": "mon0", "type": "child<chardev-stdio>" } ] }
-#
-##
-{ 'command': 'qom-list',
- 'data': { 'path': 'str' },
- 'returns': [ 'ObjectPropertyInfo' ],
- 'allow-preconfig': true }
-
-##
-# @qom-get:
-#
-# This command will get a property from a object model path and return the
-# value.
-#
-# @path: The path within the object model. There are two forms of supported
-# paths--absolute and partial paths.
-#
-# Absolute paths are derived from the root object and can follow child<>
-# or link<> properties. Since they can follow link<> properties, they
-# can be arbitrarily long. Absolute paths look like absolute filenames
-# and are prefixed with a leading slash.
-#
-# Partial paths look like relative filenames. They do not begin
-# with a prefix. The matching rules for partial paths are subtle but
-# designed to make specifying objects easy. At each level of the
-# composition tree, the partial path is matched as an absolute path.
-# The first match is not returned. At least two matches are searched
-# for. A successful result is only returned if only one match is
-# found. If more than one match is found, a flag is return to
-# indicate that the match was ambiguous.
-#
-# @property: The property name to read
-#
-# Returns: The property value. The type depends on the property
-# type. child<> and link<> properties are returned as #str
-# pathnames. All integer property types (u8, u16, etc) are
-# returned as #int.
-#
-# Since: 1.2
-#
-# Example:
-#
-# 1. Use absolute path
-#
-# -> { "execute": "qom-get",
-# "arguments": { "path": "/machine/unattached/device[0]",
-# "property": "hotplugged" } }
-# <- { "return": false }
-#
-# 2. Use partial path
-#
-# -> { "execute": "qom-get",
-# "arguments": { "path": "unattached/sysbus",
-# "property": "type" } }
-# <- { "return": "System" }
-#
-##
-{ 'command': 'qom-get',
- 'data': { 'path': 'str', 'property': 'str' },
- 'returns': 'any',
- 'allow-preconfig': true }
-
-##
-# @qom-set:
-#
-# This command will set a property from a object model path.
-#
-# @path: see @qom-get for a description of this parameter
-#
-# @property: the property name to set
-#
-# @value: a value who's type is appropriate for the property type. See @qom-get
-# for a description of type mapping.
-#
-# Since: 1.2
-#
-# Example:
-#
-# -> { "execute": "qom-set",
-# "arguments": { "path": "/machine",
-# "property": "graphics",
-# "value": false } }
-# <- { "return": {} }
-#
-##
-{ 'command': 'qom-set',
- 'data': { 'path': 'str', 'property': 'str', 'value': 'any' },
- 'allow-preconfig': true }
-
##
# @change:
#
{ 'command': 'change',
'data': {'device': 'str', 'target': 'str', '*arg': 'str'} }
-##
-# @ObjectTypeInfo:
-#
-# This structure describes a search result from @qom-list-types
-#
-# @name: the type name found in the search
-#
-# @abstract: the type is abstract and can't be directly instantiated.
-# Omitted if false. (since 2.10)
-#
-# @parent: Name of parent type, if any (since 2.10)
-#
-# Since: 1.1
-##
-{ 'struct': 'ObjectTypeInfo',
- 'data': { 'name': 'str', '*abstract': 'bool', '*parent': 'str' } }
-
-##
-# @qom-list-types:
-#
-# This command will return a list of types given search parameters
-#
-# @implements: if specified, only return types that implement this type name
-#
-# @abstract: if true, include abstract types in the results
-#
-# Returns: a list of @ObjectTypeInfo or an empty list if no results are found
-#
-# Since: 1.1
-##
-{ 'command': 'qom-list-types',
- 'data': { '*implements': 'str', '*abstract': 'bool' },
- 'returns': [ 'ObjectTypeInfo' ],
- 'allow-preconfig': true }
-
-##
-# @device-list-properties:
-#
-# List properties associated with a device.
-#
-# @typename: the type name of a device
-#
-# Returns: a list of ObjectPropertyInfo describing a devices properties
-#
-# Note: objects can create properties at runtime, for example to describe
-# links between different devices and/or objects. These properties
-# are not included in the output of this command.
-#
-# Since: 1.2
-##
-{ 'command': 'device-list-properties',
- 'data': { 'typename': 'str'},
- 'returns': [ 'ObjectPropertyInfo' ] }
-
-##
-# @qom-list-properties:
-#
-# List properties associated with a QOM object.
-#
-# @typename: the type name of an object
-#
-# Note: objects can create properties at runtime, for example to describe
-# links between different devices and/or objects. These properties
-# are not included in the output of this command.
-#
-# Returns: a list of ObjectPropertyInfo describing object properties
-#
-# Since: 2.12
-##
-{ 'command': 'qom-list-properties',
- 'data': { 'typename': 'str'},
- 'returns': [ 'ObjectPropertyInfo' ],
- 'allow-preconfig': true }
-
##
# @xen-set-global-dirty-log:
#
{ 'command': 'xen-set-global-dirty-log', 'data': { 'enable': 'bool' } }
##
-# @device_add:
-#
-# @driver: the name of the new device's driver
+# @getfd:
#
-# @bus: the device's parent bus (device tree path)
+# Receive a file descriptor via SCM rights and assign it a name
#
-# @id: the device's ID, must be unique
+# @fdname: file descriptor name
#
-# Additional arguments depend on the type.
+# Returns: Nothing on success
#
-# Add a device.
+# Since: 0.14.0
#
-# Notes:
-# 1. For detailed information about this command, please refer to the
-# 'docs/qdev-device-use.txt' file.
+# Notes: If @fdname already exists, the file descriptor assigned to
+# it will be closed and replaced by the received file
+# descriptor.
#
-# 2. It's possible to list device properties by running QEMU with the
-# "-device DEVICE,help" command-line argument, where DEVICE is the
-# device's name
+# The 'closefd' command can be used to explicitly close the
+# file descriptor when it is no longer needed.
#
# Example:
#
-# -> { "execute": "device_add",
-# "arguments": { "driver": "e1000", "id": "net1",
-# "bus": "pci.0",
-# "mac": "52:54:00:12:34:56" } }
+# -> { "execute": "getfd", "arguments": { "fdname": "fd1" } }
# <- { "return": {} }
#
-# TODO: This command effectively bypasses QAPI completely due to its
-# "additional arguments" business. It shouldn't have been added to
-# the schema in this form. It should be qapified properly, or
-# replaced by a properly qapified command.
-#
-# Since: 0.13
##
-{ 'command': 'device_add',
- 'data': {'driver': 'str', '*bus': 'str', '*id': 'str'},
- 'gen': false } # so we can get the additional arguments
+{ 'command': 'getfd', 'data': {'fdname': 'str'} }
##
-# @device_del:
+# @closefd:
#
-# Remove a device from a guest
+# Close a file descriptor previously passed via SCM rights
#
-# @id: the device's ID or QOM path
+# @fdname: file descriptor name
#
# Returns: Nothing on success
-# If @id is not a valid device, DeviceNotFound
-#
-# Notes: When this command completes, the device may not be removed from the
-# guest. Hot removal is an operation that requires guest cooperation.
-# This command merely requests that the guest begin the hot removal
-# process. Completion of the device removal process is signaled with a
-# DEVICE_DELETED event. Guest reset will automatically complete removal
-# for all devices.
#
# Since: 0.14.0
#
# Example:
#
-# -> { "execute": "device_del",
-# "arguments": { "id": "net1" } }
-# <- { "return": {} }
-#
-# -> { "execute": "device_del",
-# "arguments": { "id": "/machine/peripheral-anon/device[0]" } }
+# -> { "execute": "closefd", "arguments": { "fdname": "fd1" } }
# <- { "return": {} }
#
##
-{ 'command': 'device_del', 'data': {'id': 'str'} }
+{ 'command': 'closefd', 'data': {'fdname': 'str'} }
##
-# @DEVICE_DELETED:
-#
-# Emitted whenever the device removal completion is acknowledged by the guest.
-# At this point, it's safe to reuse the specified device ID. Device removal can
-# be initiated by the guest or by HMP/QMP commands.
+# @MemoryInfo:
#
-# @device: device name
-#
-# @path: device path
-#
-# Since: 1.5
-#
-# Example:
-#
-# <- { "event": "DEVICE_DELETED",
-# "data": { "device": "virtio-net-pci-0",
-# "path": "/machine/peripheral/virtio-net-pci-0" },
-# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-#
-##
-{ 'event': 'DEVICE_DELETED',
- 'data': { '*device': 'str', 'path': 'str' } }
-
-##
-# @DumpGuestMemoryFormat:
-#
-# An enumeration of guest-memory-dump's format.
-#
-# @elf: elf format
-#
-# @kdump-zlib: kdump-compressed format with zlib-compressed
-#
-# @kdump-lzo: kdump-compressed format with lzo-compressed
-#
-# @kdump-snappy: kdump-compressed format with snappy-compressed
-#
-# @win-dmp: Windows full crashdump format,
-# can be used instead of ELF converting (since 2.13)
-#
-# Since: 2.0
-##
-{ 'enum': 'DumpGuestMemoryFormat',
- 'data': [ 'elf', 'kdump-zlib', 'kdump-lzo', 'kdump-snappy', 'win-dmp' ] }
-
-##
-# @dump-guest-memory:
-#
-# Dump guest's memory to vmcore. It is a synchronous operation that can take
-# very long depending on the amount of guest memory.
-#
-# @paging: if true, do paging to get guest's memory mapping. This allows
-# using gdb to process the core file.
-#
-# IMPORTANT: this option can make QEMU allocate several gigabytes
-# of RAM. This can happen for a large guest, or a
-# malicious guest pretending to be large.
-#
-# Also, paging=true has the following limitations:
-#
-# 1. The guest may be in a catastrophic state or can have corrupted
-# memory, which cannot be trusted
-# 2. The guest can be in real-mode even if paging is enabled. For
-# example, the guest uses ACPI to sleep, and ACPI sleep state
-# goes in real-mode
-# 3. Currently only supported on i386 and x86_64.
-#
-# @protocol: the filename or file descriptor of the vmcore. The supported
-# protocols are:
-#
-# 1. file: the protocol starts with "file:", and the following
-# string is the file's path.
-# 2. fd: the protocol starts with "fd:", and the following string
-# is the fd's name.
-#
-# @detach: if true, QMP will return immediately rather than
-# waiting for the dump to finish. The user can track progress
-# using "query-dump". (since 2.6).
-#
-# @begin: if specified, the starting physical address.
-#
-# @length: if specified, the memory size, in bytes. If you don't
-# want to dump all guest's memory, please specify the start @begin
-# and @length
-#
-# @format: if specified, the format of guest memory dump. But non-elf
-# format is conflict with paging and filter, ie. @paging, @begin and
-# @length is not allowed to be specified with non-elf @format at the
-# same time (since 2.0)
-#
-# Note: All boolean arguments default to false
-#
-# Returns: nothing on success
-#
-# Since: 1.2
-#
-# Example:
-#
-# -> { "execute": "dump-guest-memory",
-# "arguments": { "protocol": "fd:dump" } }
-# <- { "return": {} }
-#
-##
-{ 'command': 'dump-guest-memory',
- 'data': { 'paging': 'bool', 'protocol': 'str', '*detach': 'bool',
- '*begin': 'int', '*length': 'int',
- '*format': 'DumpGuestMemoryFormat'} }
-
-##
-# @DumpStatus:
-#
-# Describe the status of a long-running background guest memory dump.
-#
-# @none: no dump-guest-memory has started yet.
-#
-# @active: there is one dump running in background.
-#
-# @completed: the last dump has finished successfully.
-#
-# @failed: the last dump has failed.
-#
-# Since: 2.6
-##
-{ 'enum': 'DumpStatus',
- 'data': [ 'none', 'active', 'completed', 'failed' ] }
-
-##
-# @DumpQueryResult:
-#
-# The result format for 'query-dump'.
-#
-# @status: enum of @DumpStatus, which shows current dump status
-#
-# @completed: bytes written in latest dump (uncompressed)
-#
-# @total: total bytes to be written in latest dump (uncompressed)
-#
-# Since: 2.6
-##
-{ 'struct': 'DumpQueryResult',
- 'data': { 'status': 'DumpStatus',
- 'completed': 'int',
- 'total': 'int' } }
-
-##
-# @query-dump:
-#
-# Query latest dump status.
-#
-# Returns: A @DumpStatus object showing the dump status.
-#
-# Since: 2.6
-#
-# Example:
-#
-# -> { "execute": "query-dump" }
-# <- { "return": { "status": "active", "completed": 1024000,
-# "total": 2048000 } }
-#
-##
-{ 'command': 'query-dump', 'returns': 'DumpQueryResult' }
-
-##
-# @DUMP_COMPLETED:
-#
-# Emitted when background dump has completed
-#
-# @result: final dump status
-#
-# @error: human-readable error string that provides
-# hint on why dump failed. Only presents on failure. The
-# user should not try to interpret the error string.
-#
-# Since: 2.6
-#
-# Example:
-#
-# { "event": "DUMP_COMPLETED",
-# "data": {"result": {"total": 1090650112, "status": "completed",
-# "completed": 1090650112} } }
-#
-##
-{ 'event': 'DUMP_COMPLETED' ,
- 'data': { 'result': 'DumpQueryResult', '*error': 'str' } }
-
-##
-# @DumpGuestMemoryCapability:
-#
-# A list of the available formats for dump-guest-memory
-#
-# Since: 2.0
-##
-{ 'struct': 'DumpGuestMemoryCapability',
- 'data': {
- 'formats': ['DumpGuestMemoryFormat'] } }
-
-##
-# @query-dump-guest-memory-capability:
-#
-# Returns the available formats for dump-guest-memory
-#
-# Returns: A @DumpGuestMemoryCapability object listing available formats for
-# dump-guest-memory
-#
-# Since: 2.0
-#
-# Example:
-#
-# -> { "execute": "query-dump-guest-memory-capability" }
-# <- { "return": { "formats":
-# ["elf", "kdump-zlib", "kdump-lzo", "kdump-snappy"] }
-#
-##
-{ 'command': 'query-dump-guest-memory-capability',
- 'returns': 'DumpGuestMemoryCapability' }
-
-##
-# @object-add:
-#
-# Create a QOM object.
-#
-# @qom-type: the class name for the object to be created
-#
-# @id: the name of the new object
-#
-# @props: a dictionary of properties to be passed to the backend
-#
-# Returns: Nothing on success
-# Error if @qom-type is not a valid class name
-#
-# Since: 2.0
-#
-# Example:
-#
-# -> { "execute": "object-add",
-# "arguments": { "qom-type": "rng-random", "id": "rng1",
-# "props": { "filename": "/dev/hwrng" } } }
-# <- { "return": {} }
-#
-##
-{ 'command': 'object-add',
- 'data': {'qom-type': 'str', 'id': 'str', '*props': 'any'} }
-
-##
-# @object-del:
-#
-# Remove a QOM object.
-#
-# @id: the name of the QOM object to remove
-#
-# Returns: Nothing on success
-# Error if @id is not a valid id for a QOM object
-#
-# Since: 2.0
-#
-# Example:
-#
-# -> { "execute": "object-del", "arguments": { "id": "rng1" } }
-# <- { "return": {} }
-#
-##
-{ 'command': 'object-del', 'data': {'id': 'str'} }
-
-##
-# @getfd:
-#
-# Receive a file descriptor via SCM rights and assign it a name
-#
-# @fdname: file descriptor name
-#
-# Returns: Nothing on success
-#
-# Since: 0.14.0
-#
-# Notes: If @fdname already exists, the file descriptor assigned to
-# it will be closed and replaced by the received file
-# descriptor.
-#
-# The 'closefd' command can be used to explicitly close the
-# file descriptor when it is no longer needed.
-#
-# Example:
-#
-# -> { "execute": "getfd", "arguments": { "fdname": "fd1" } }
-# <- { "return": {} }
-#
-##
-{ 'command': 'getfd', 'data': {'fdname': 'str'} }
-
-##
-# @closefd:
-#
-# Close a file descriptor previously passed via SCM rights
-#
-# @fdname: file descriptor name
-#
-# Returns: Nothing on success
-#
-# Since: 0.14.0
-#
-# Example:
-#
-# -> { "execute": "closefd", "arguments": { "fdname": "fd1" } }
-# <- { "return": {} }
-#
-##
-{ 'command': 'closefd', 'data': {'fdname': 'str'} }
-
-##
-# @MachineInfo:
-#
-# Information describing a machine.
-#
-# @name: the name of the machine
-#
-# @alias: an alias for the machine name
-#
-# @is-default: whether the machine is default
-#
-# @cpu-max: maximum number of CPUs supported by the machine type
-# (since 1.5.0)
-#
-# @hotpluggable-cpus: cpu hotplug via -device is supported (since 2.7.0)
-#
-# Since: 1.2.0
-##
-{ 'struct': 'MachineInfo',
- 'data': { 'name': 'str', '*alias': 'str',
- '*is-default': 'bool', 'cpu-max': 'int',
- 'hotpluggable-cpus': 'bool'} }
-
-##
-# @query-machines:
-#
-# Return a list of supported machines
-#
-# Returns: a list of MachineInfo
-#
-# Since: 1.2.0
-##
-{ 'command': 'query-machines', 'returns': ['MachineInfo'] }
-
-##
-# @CurrentMachineParams:
-#
-# Information describing the running machine parameters.
-#
-# @wakeup-suspend-support: true if the machine supports wake up from
-# suspend
-#
-# Since: 4.0
-##
-{ 'struct': 'CurrentMachineParams',
- 'data': { 'wakeup-suspend-support': 'bool'} }
-
-##
-# @query-current-machine:
-#
-# Return information on the current virtual machine.
-#
-# Returns: CurrentMachineParams
-#
-# Since: 4.0
-##
-{ 'command': 'query-current-machine', 'returns': 'CurrentMachineParams' }
-
-##
-# @MemoryInfo:
-#
-# Actual memory information in bytes.
+# Actual memory information in bytes.
#
# @base-memory: size of "base" memory specified with command line
# option -m.
{ 'command': 'query-memory-size-summary', 'returns': 'MemoryInfo' }
-##
-# @CpuModelInfo:
-#
-# Virtual CPU model.
-#
-# A CPU model consists of the name of a CPU definition, to which
-# delta changes are applied (e.g. features added/removed). Most magic values
-# that an architecture might require should be hidden behind the name.
-# However, if required, architectures can expose relevant properties.
-#
-# @name: the name of the CPU definition the model is based on
-# @props: a dictionary of QOM properties to be applied
-#
-# Since: 2.8.0
-##
-{ 'struct': 'CpuModelInfo',
- 'data': { 'name': 'str',
- '*props': 'any' } }
-
-##
-# @CpuModelExpansionType:
-#
-# An enumeration of CPU model expansion types.
-#
-# @static: Expand to a static CPU model, a combination of a static base
-# model name and property delta changes. As the static base model will
-# never change, the expanded CPU model will be the same, independent of
-# QEMU version, machine type, machine options, and accelerator options.
-# Therefore, the resulting model can be used by tooling without having
-# to specify a compatibility machine - e.g. when displaying the "host"
-# model. The @static CPU models are migration-safe.
-
-# @full: Expand all properties. The produced model is not guaranteed to be
-# migration-safe, but allows tooling to get an insight and work with
-# model details.
-#
-# Note: When a non-migration-safe CPU model is expanded in static mode, some
-# features enabled by the CPU model may be omitted, because they can't be
-# implemented by a static CPU model definition (e.g. cache info passthrough and
-# PMU passthrough in x86). If you need an accurate representation of the
-# features enabled by a non-migration-safe CPU model, use @full. If you need a
-# static representation that will keep ABI compatibility even when changing QEMU
-# version or machine-type, use @static (but keep in mind that some features may
-# be omitted).
-#
-# Since: 2.8.0
-##
-{ 'enum': 'CpuModelExpansionType',
- 'data': [ 'static', 'full' ] }
-
-
-##
-# @CpuModelCompareResult:
-#
-# An enumeration of CPU model comparison results. The result is usually
-# calculated using e.g. CPU features or CPU generations.
-#
-# @incompatible: If model A is incompatible to model B, model A is not
-# guaranteed to run where model B runs and the other way around.
-#
-# @identical: If model A is identical to model B, model A is guaranteed to run
-# where model B runs and the other way around.
-#
-# @superset: If model A is a superset of model B, model B is guaranteed to run
-# where model A runs. There are no guarantees about the other way.
-#
-# @subset: If model A is a subset of model B, model A is guaranteed to run
-# where model B runs. There are no guarantees about the other way.
-#
-# Since: 2.8.0
-##
-{ 'enum': 'CpuModelCompareResult',
- 'data': [ 'incompatible', 'identical', 'superset', 'subset' ] }
-
##
# @AddfdInfo:
#
'returns': ['CommandLineOptionInfo'],
'allow-preconfig': true }
-##
-# @X86CPURegister32:
-#
-# A X86 32-bit register
-#
-# Since: 1.5
-##
-{ 'enum': 'X86CPURegister32',
- 'data': [ 'EAX', 'EBX', 'ECX', 'EDX', 'ESP', 'EBP', 'ESI', 'EDI' ] }
-
-##
-# @X86CPUFeatureWordInfo:
-#
-# Information about a X86 CPU feature word
-#
-# @cpuid-input-eax: Input EAX value for CPUID instruction for that feature word
-#
-# @cpuid-input-ecx: Input ECX value for CPUID instruction for that
-# feature word
-#
-# @cpuid-register: Output register containing the feature bits
-#
-# @features: value of output register, containing the feature bits
-#
-# Since: 1.5
-##
-{ 'struct': 'X86CPUFeatureWordInfo',
- 'data': { 'cpuid-input-eax': 'int',
- '*cpuid-input-ecx': 'int',
- 'cpuid-register': 'X86CPURegister32',
- 'features': 'int' } }
-
-##
-# @DummyForceArrays:
-#
-# Not used by QMP; hack to let us use X86CPUFeatureWordInfoList internally
-#
-# Since: 2.5
-##
-{ 'struct': 'DummyForceArrays',
- 'data': { 'unused': ['X86CPUFeatureWordInfo'] } }
-
-
-##
-# @NumaOptionsType:
-#
-# @node: NUMA nodes configuration
-#
-# @dist: NUMA distance configuration (since 2.10)
-#
-# @cpu: property based CPU(s) to node mapping (Since: 2.10)
-#
-# Since: 2.1
-##
-{ 'enum': 'NumaOptionsType',
- 'data': [ 'node', 'dist', 'cpu' ] }
-
-##
-# @NumaOptions:
-#
-# A discriminated record of NUMA options. (for OptsVisitor)
-#
-# Since: 2.1
-##
-{ 'union': 'NumaOptions',
- 'base': { 'type': 'NumaOptionsType' },
- 'discriminator': 'type',
- 'data': {
- 'node': 'NumaNodeOptions',
- 'dist': 'NumaDistOptions',
- 'cpu': 'NumaCpuOptions' }}
-
-##
-# @NumaNodeOptions:
-#
-# Create a guest NUMA node. (for OptsVisitor)
-#
-# @nodeid: NUMA node ID (increase by 1 from 0 if omitted)
-#
-# @cpus: VCPUs belonging to this node (assign VCPUS round-robin
-# if omitted)
-#
-# @mem: memory size of this node; mutually exclusive with @memdev.
-# Equally divide total memory among nodes if both @mem and @memdev are
-# omitted.
-#
-# @memdev: memory backend object. If specified for one node,
-# it must be specified for all nodes.
-#
-# Since: 2.1
-##
-{ 'struct': 'NumaNodeOptions',
- 'data': {
- '*nodeid': 'uint16',
- '*cpus': ['uint16'],
- '*mem': 'size',
- '*memdev': 'str' }}
-
-##
-# @NumaDistOptions:
-#
-# Set the distance between 2 NUMA nodes.
-#
-# @src: source NUMA node.
-#
-# @dst: destination NUMA node.
-#
-# @val: NUMA distance from source node to destination node.
-# When a node is unreachable from another node, set the distance
-# between them to 255.
-#
-# Since: 2.10
-##
-{ 'struct': 'NumaDistOptions',
- 'data': {
- 'src': 'uint16',
- 'dst': 'uint16',
- 'val': 'uint8' }}
-
-##
-# @NumaCpuOptions:
-#
-# Option "-numa cpu" overrides default cpu to node mapping.
-# It accepts the same set of cpu properties as returned by
-# query-hotpluggable-cpus[].props, where node-id could be used to
-# override default node mapping.
-#
-# Since: 2.10
-##
-{ 'struct': 'NumaCpuOptions',
- 'base': 'CpuInstanceProperties',
- 'data' : {} }
-
-##
-# @HostMemPolicy:
-#
-# Host memory policy types
-#
-# @default: restore default policy, remove any nondefault policy
-#
-# @preferred: set the preferred host nodes for allocation
-#
-# @bind: a strict policy that restricts memory allocation to the
-# host nodes specified
-#
-# @interleave: memory allocations are interleaved across the set
-# of host nodes specified
-#
-# Since: 2.1
-##
-{ 'enum': 'HostMemPolicy',
- 'data': [ 'default', 'preferred', 'bind', 'interleave' ] }
-
-##
-# @Memdev:
-#
-# Information about memory backend
-#
-# @id: backend's ID if backend has 'id' property (since 2.9)
-#
-# @size: memory backend size
-#
-# @merge: enables or disables memory merge support
-#
-# @dump: includes memory backend's memory in a core dump or not
-#
-# @prealloc: enables or disables memory preallocation
-#
-# @host-nodes: host nodes for its memory policy
-#
-# @policy: memory policy of memory backend
-#
-# Since: 2.1
-##
-{ 'struct': 'Memdev',
- 'data': {
- '*id': 'str',
- 'size': 'size',
- 'merge': 'bool',
- 'dump': 'bool',
- 'prealloc': 'bool',
- 'host-nodes': ['uint16'],
- 'policy': 'HostMemPolicy' }}
-
-##
-# @query-memdev:
-#
-# Returns information for all memory backends.
-#
-# Returns: a list of @Memdev.
-#
-# Since: 2.1
-#
-# Example:
-#
-# -> { "execute": "query-memdev" }
-# <- { "return": [
-# {
-# "id": "mem1",
-# "size": 536870912,
-# "merge": false,
-# "dump": true,
-# "prealloc": false,
-# "host-nodes": [0, 1],
-# "policy": "bind"
-# },
-# {
-# "size": 536870912,
-# "merge": false,
-# "dump": true,
-# "prealloc": true,
-# "host-nodes": [2, 3],
-# "policy": "preferred"
-# }
-# ]
-# }
-#
-##
-{ 'command': 'query-memdev', 'returns': ['Memdev'], 'allow-preconfig': true }
-
##
# @PCDIMMDeviceInfo:
#
##
{ 'command': 'xen-load-devices-state', 'data': {'filename': 'str'} }
-##
-# @CpuInstanceProperties:
-#
-# List of properties to be used for hotplugging a CPU instance,
-# it should be passed by management with device_add command when
-# a CPU is being hotplugged.
-#
-# @node-id: NUMA node ID the CPU belongs to
-# @socket-id: socket number within node/board the CPU belongs to
-# @core-id: core number within socket the CPU belongs to
-# @thread-id: thread number within core the CPU belongs to
-#
-# Note: currently there are 4 properties that could be present
-# but management should be prepared to pass through other
-# properties with device_add command to allow for future
-# interface extension. This also requires the filed names to be kept in
-# sync with the properties passed to -device/device_add.
-#
-# Since: 2.7
-##
-{ 'struct': 'CpuInstanceProperties',
- 'data': { '*node-id': 'int',
- '*socket-id': 'int',
- '*core-id': 'int',
- '*thread-id': 'int'
- }
-}
-
-##
-# @HotpluggableCPU:
-#
-# @type: CPU object type for usage with device_add command
-# @props: list of properties to be used for hotplugging CPU
-# @vcpus-count: number of logical VCPU threads @HotpluggableCPU provides
-# @qom-path: link to existing CPU object if CPU is present or
-# omitted if CPU is not present.
-#
-# Since: 2.7
-##
-{ 'struct': 'HotpluggableCPU',
- 'data': { 'type': 'str',
- 'vcpus-count': 'int',
- 'props': 'CpuInstanceProperties',
- '*qom-path': 'str'
- }
-}
-
-##
-# @query-hotpluggable-cpus:
-#
-# TODO: Better documentation; currently there is none.
-#
-# Returns: a list of HotpluggableCPU objects.
-#
-# Since: 2.7
-#
-# Example:
-#
-# For pseries machine type started with -smp 2,cores=2,maxcpus=4 -cpu POWER8:
-#
-# -> { "execute": "query-hotpluggable-cpus" }
-# <- {"return": [
-# { "props": { "core": 8 }, "type": "POWER8-spapr-cpu-core",
-# "vcpus-count": 1 },
-# { "props": { "core": 0 }, "type": "POWER8-spapr-cpu-core",
-# "vcpus-count": 1, "qom-path": "/machine/unattached/device[0]"}
-# ]}'
-#
-# For pc machine type started with -smp 1,maxcpus=2:
-#
-# -> { "execute": "query-hotpluggable-cpus" }
-# <- {"return": [
-# {
-# "type": "qemu64-x86_64-cpu", "vcpus-count": 1,
-# "props": {"core-id": 0, "socket-id": 1, "thread-id": 0}
-# },
-# {
-# "qom-path": "/machine/unattached/device[0]",
-# "type": "qemu64-x86_64-cpu", "vcpus-count": 1,
-# "props": {"core-id": 0, "socket-id": 0, "thread-id": 0}
-# }
-# ]}
-#
-# For s390x-virtio-ccw machine type started with -smp 1,maxcpus=2 -cpu qemu
-# (Since: 2.11):
-#
-# -> { "execute": "query-hotpluggable-cpus" }
-# <- {"return": [
-# {
-# "type": "qemu-s390x-cpu", "vcpus-count": 1,
-# "props": { "core-id": 1 }
-# },
-# {
-# "qom-path": "/machine/unattached/device[0]",
-# "type": "qemu-s390x-cpu", "vcpus-count": 1,
-# "props": { "core-id": 0 }
-# }
-# ]}
-#
-##
-{ 'command': 'query-hotpluggable-cpus', 'returns': ['HotpluggableCPU'],
- 'allow-preconfig': true }
-
##
# @GuidInfo:
#
##
{ 'command': 'query-vm-generation-id', 'returns': 'GuidInfo' }
-##
-# @set-numa-node:
-#
-# Runtime equivalent of '-numa' CLI option, available at
-# preconfigure stage to configure numa mapping before initializing
-# machine.
-#
-# Since 3.0
-##
-{ 'command': 'set-numa-node', 'boxed': true,
- 'data': 'NumaOptions',
- 'allow-preconfig': true
-}
#
# @step: Delay increase (in ms) after each self-announcement attempt
#
+# @interfaces: An optional list of interface names, which restricts the
+# announcement to the listed interfaces. (Since 4.1)
+#
+# @id: A name to be used to identify an instance of announce-timers
+# and to allow it to modified later. Not for use as
+# part of the migration parameters. (Since 4.1)
+#
# Since: 4.0
##
'data': { 'initial': 'int',
'max': 'int',
'rounds': 'int',
- 'step': 'int' } }
+ 'step': 'int',
+ '*interfaces': ['str'],
+ '*id' : 'str' } }
##
# @announce-self:
#
# Example:
#
-# -> { "execute": "announce-self"
+# -> { "execute": "announce-self",
# "arguments": {
-# "initial": 50, "max": 550, "rounds": 10, "step": 50 } }
+# "initial": 50, "max": 550, "rounds": 10, "step": 50,
+# "interfaces": ["vn2", "vn3"], "id": "bob" } }
# <- { "return": {} }
#
# Since: 4.0
{ 'include': 'crypto.json' }
{ 'include': 'block.json' }
{ 'include': 'char.json' }
+{ 'include': 'dump.json' }
{ 'include': 'job.json' }
{ 'include': 'net.json' }
{ 'include': 'rdma.json' }
{ 'include': 'transaction.json' }
{ 'include': 'trace.json' }
{ 'include': 'introspect.json' }
+{ 'include': 'qom.json' }
+{ 'include': 'qdev.json' }
+{ 'include': 'machine.json' }
+{ 'include': 'machine-target.json' }
{ 'include': 'misc.json' }
-{ 'include': 'target.json' }
+{ 'include': 'misc-target.json' }
{ 'include': 'audio.json' }
--- /dev/null
+# -*- Mode: Python -*-
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+##
+# = Device infrastructure (qdev)
+##
+
+{ 'include': 'qom.json' }
+
+##
+# @device-list-properties:
+#
+# List properties associated with a device.
+#
+# @typename: the type name of a device
+#
+# Returns: a list of ObjectPropertyInfo describing a devices properties
+#
+# Note: objects can create properties at runtime, for example to describe
+# links between different devices and/or objects. These properties
+# are not included in the output of this command.
+#
+# Since: 1.2
+##
+{ 'command': 'device-list-properties',
+ 'data': { 'typename': 'str'},
+ 'returns': [ 'ObjectPropertyInfo' ] }
+
+##
+# @device_add:
+#
+# @driver: the name of the new device's driver
+#
+# @bus: the device's parent bus (device tree path)
+#
+# @id: the device's ID, must be unique
+#
+# Additional arguments depend on the type.
+#
+# Add a device.
+#
+# Notes:
+# 1. For detailed information about this command, please refer to the
+# 'docs/qdev-device-use.txt' file.
+#
+# 2. It's possible to list device properties by running QEMU with the
+# "-device DEVICE,help" command-line argument, where DEVICE is the
+# device's name
+#
+# Example:
+#
+# -> { "execute": "device_add",
+# "arguments": { "driver": "e1000", "id": "net1",
+# "bus": "pci.0",
+# "mac": "52:54:00:12:34:56" } }
+# <- { "return": {} }
+#
+# TODO: This command effectively bypasses QAPI completely due to its
+# "additional arguments" business. It shouldn't have been added to
+# the schema in this form. It should be qapified properly, or
+# replaced by a properly qapified command.
+#
+# Since: 0.13
+##
+{ 'command': 'device_add',
+ 'data': {'driver': 'str', '*bus': 'str', '*id': 'str'},
+ 'gen': false } # so we can get the additional arguments
+
+##
+# @device_del:
+#
+# Remove a device from a guest
+#
+# @id: the device's ID or QOM path
+#
+# Returns: Nothing on success
+# If @id is not a valid device, DeviceNotFound
+#
+# Notes: When this command completes, the device may not be removed from the
+# guest. Hot removal is an operation that requires guest cooperation.
+# This command merely requests that the guest begin the hot removal
+# process. Completion of the device removal process is signaled with a
+# DEVICE_DELETED event. Guest reset will automatically complete removal
+# for all devices.
+#
+# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "device_del",
+# "arguments": { "id": "net1" } }
+# <- { "return": {} }
+#
+# -> { "execute": "device_del",
+# "arguments": { "id": "/machine/peripheral-anon/device[0]" } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'device_del', 'data': {'id': 'str'} }
+
+##
+# @DEVICE_DELETED:
+#
+# Emitted whenever the device removal completion is acknowledged by the guest.
+# At this point, it's safe to reuse the specified device ID. Device removal can
+# be initiated by the guest or by HMP/QMP commands.
+#
+# @device: device name
+#
+# @path: device path
+#
+# Since: 1.5
+#
+# Example:
+#
+# <- { "event": "DEVICE_DELETED",
+# "data": { "device": "virtio-net-pci-0",
+# "path": "/machine/peripheral/virtio-net-pci-0" },
+# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
+#
+##
+{ 'event': 'DEVICE_DELETED',
+ 'data': { '*device': 'str', 'path': 'str' } }
--- /dev/null
+# -*- Mode: Python -*-
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+##
+# = QEMU Object Model (QOM)
+##
+
+##
+# @ObjectPropertyInfo:
+#
+# @name: the name of the property
+#
+# @type: the type of the property. This will typically come in one of four
+# forms:
+#
+# 1) A primitive type such as 'u8', 'u16', 'bool', 'str', or 'double'.
+# These types are mapped to the appropriate JSON type.
+#
+# 2) A child type in the form 'child<subtype>' where subtype is a qdev
+# device type name. Child properties create the composition tree.
+#
+# 3) A link type in the form 'link<subtype>' where subtype is a qdev
+# device type name. Link properties form the device model graph.
+#
+# @description: if specified, the description of the property.
+#
+# Since: 1.2
+##
+{ 'struct': 'ObjectPropertyInfo',
+ 'data': { 'name': 'str', 'type': 'str', '*description': 'str' } }
+
+##
+# @qom-list:
+#
+# This command will list any properties of a object given a path in the object
+# model.
+#
+# @path: the path within the object model. See @qom-get for a description of
+# this parameter.
+#
+# Returns: a list of @ObjectPropertyInfo that describe the properties of the
+# object.
+#
+# Since: 1.2
+#
+# Example:
+#
+# -> { "execute": "qom-list",
+# "arguments": { "path": "/chardevs" } }
+# <- { "return": [ { "name": "type", "type": "string" },
+# { "name": "parallel0", "type": "child<chardev-vc>" },
+# { "name": "serial0", "type": "child<chardev-vc>" },
+# { "name": "mon0", "type": "child<chardev-stdio>" } ] }
+#
+##
+{ 'command': 'qom-list',
+ 'data': { 'path': 'str' },
+ 'returns': [ 'ObjectPropertyInfo' ],
+ 'allow-preconfig': true }
+
+##
+# @qom-get:
+#
+# This command will get a property from a object model path and return the
+# value.
+#
+# @path: The path within the object model. There are two forms of supported
+# paths--absolute and partial paths.
+#
+# Absolute paths are derived from the root object and can follow child<>
+# or link<> properties. Since they can follow link<> properties, they
+# can be arbitrarily long. Absolute paths look like absolute filenames
+# and are prefixed with a leading slash.
+#
+# Partial paths look like relative filenames. They do not begin
+# with a prefix. The matching rules for partial paths are subtle but
+# designed to make specifying objects easy. At each level of the
+# composition tree, the partial path is matched as an absolute path.
+# The first match is not returned. At least two matches are searched
+# for. A successful result is only returned if only one match is
+# found. If more than one match is found, a flag is return to
+# indicate that the match was ambiguous.
+#
+# @property: The property name to read
+#
+# Returns: The property value. The type depends on the property
+# type. child<> and link<> properties are returned as #str
+# pathnames. All integer property types (u8, u16, etc) are
+# returned as #int.
+#
+# Since: 1.2
+#
+# Example:
+#
+# 1. Use absolute path
+#
+# -> { "execute": "qom-get",
+# "arguments": { "path": "/machine/unattached/device[0]",
+# "property": "hotplugged" } }
+# <- { "return": false }
+#
+# 2. Use partial path
+#
+# -> { "execute": "qom-get",
+# "arguments": { "path": "unattached/sysbus",
+# "property": "type" } }
+# <- { "return": "System" }
+#
+##
+{ 'command': 'qom-get',
+ 'data': { 'path': 'str', 'property': 'str' },
+ 'returns': 'any',
+ 'allow-preconfig': true }
+
+##
+# @qom-set:
+#
+# This command will set a property from a object model path.
+#
+# @path: see @qom-get for a description of this parameter
+#
+# @property: the property name to set
+#
+# @value: a value who's type is appropriate for the property type. See @qom-get
+# for a description of type mapping.
+#
+# Since: 1.2
+#
+# Example:
+#
+# -> { "execute": "qom-set",
+# "arguments": { "path": "/machine",
+# "property": "graphics",
+# "value": false } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'qom-set',
+ 'data': { 'path': 'str', 'property': 'str', 'value': 'any' },
+ 'allow-preconfig': true }
+
+##
+# @ObjectTypeInfo:
+#
+# This structure describes a search result from @qom-list-types
+#
+# @name: the type name found in the search
+#
+# @abstract: the type is abstract and can't be directly instantiated.
+# Omitted if false. (since 2.10)
+#
+# @parent: Name of parent type, if any (since 2.10)
+#
+# Since: 1.1
+##
+{ 'struct': 'ObjectTypeInfo',
+ 'data': { 'name': 'str', '*abstract': 'bool', '*parent': 'str' } }
+
+##
+# @qom-list-types:
+#
+# This command will return a list of types given search parameters
+#
+# @implements: if specified, only return types that implement this type name
+#
+# @abstract: if true, include abstract types in the results
+#
+# Returns: a list of @ObjectTypeInfo or an empty list if no results are found
+#
+# Since: 1.1
+##
+{ 'command': 'qom-list-types',
+ 'data': { '*implements': 'str', '*abstract': 'bool' },
+ 'returns': [ 'ObjectTypeInfo' ],
+ 'allow-preconfig': true }
+
+##
+# @qom-list-properties:
+#
+# List properties associated with a QOM object.
+#
+# @typename: the type name of an object
+#
+# Note: objects can create properties at runtime, for example to describe
+# links between different devices and/or objects. These properties
+# are not included in the output of this command.
+#
+# Returns: a list of ObjectPropertyInfo describing object properties
+#
+# Since: 2.12
+##
+{ 'command': 'qom-list-properties',
+ 'data': { 'typename': 'str'},
+ 'returns': [ 'ObjectPropertyInfo' ],
+ 'allow-preconfig': true }
+
+##
+# @object-add:
+#
+# Create a QOM object.
+#
+# @qom-type: the class name for the object to be created
+#
+# @id: the name of the new object
+#
+# @props: a dictionary of properties to be passed to the backend
+#
+# Returns: Nothing on success
+# Error if @qom-type is not a valid class name
+#
+# Since: 2.0
+#
+# Example:
+#
+# -> { "execute": "object-add",
+# "arguments": { "qom-type": "rng-random", "id": "rng1",
+# "props": { "filename": "/dev/hwrng" } } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'object-add',
+ 'data': {'qom-type': 'str', 'id': 'str', '*props': 'any'} }
+
+##
+# @object-del:
+#
+# Remove a QOM object.
+#
+# @id: the name of the QOM object to remove
+#
+# Returns: Nothing on success
+# Error if @id is not a valid id for a QOM object
+#
+# Since: 2.0
+#
+# Example:
+#
+# -> { "execute": "object-del", "arguments": { "id": "rng1" } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'object-del', 'data': {'id': 'str'} }
+++ /dev/null
-# -*- Mode: Python -*-
-#
-
-##
-# = Target-specific commands & events
-##
-
-{ 'include': 'misc.json' }
-
-##
-# @RTC_CHANGE:
-#
-# Emitted when the guest changes the RTC time.
-#
-# @offset: offset between base RTC clock (as specified by -rtc base), and
-# new RTC clock value
-#
-# Note: This event is rate-limited.
-#
-# Since: 0.13.0
-#
-# Example:
-#
-# <- { "event": "RTC_CHANGE",
-# "data": { "offset": 78 },
-# "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
-#
-##
-{ 'event': 'RTC_CHANGE',
- 'data': { 'offset': 'int' },
- 'if': 'defined(TARGET_ALPHA) || defined(TARGET_ARM) || defined(TARGET_HPPA) || defined(TARGET_I386) || defined(TARGET_MIPS) || defined(TARGET_MIPS64) || defined(TARGET_MOXIE) || defined(TARGET_PPC) || defined(TARGET_PPC64) || defined(TARGET_S390X) || defined(TARGET_SH4) || defined(TARGET_SPARC)' }
-
-##
-# @rtc-reset-reinjection:
-#
-# This command will reset the RTC interrupt reinjection backlog.
-# Can be used if another mechanism to synchronize guest time
-# is in effect, for example QEMU guest agent's guest-set-time
-# command.
-#
-# Since: 2.1
-#
-# Example:
-#
-# -> { "execute": "rtc-reset-reinjection" }
-# <- { "return": {} }
-#
-##
-{ 'command': 'rtc-reset-reinjection',
- 'if': 'defined(TARGET_I386)' }
-
-
-##
-# @SevState:
-#
-# An enumeration of SEV state information used during @query-sev.
-#
-# @uninit: The guest is uninitialized.
-#
-# @launch-update: The guest is currently being launched; plaintext data and
-# register state is being imported.
-#
-# @launch-secret: The guest is currently being launched; ciphertext data
-# is being imported.
-#
-# @running: The guest is fully launched or migrated in.
-#
-# @send-update: The guest is currently being migrated out to another machine.
-#
-# @receive-update: The guest is currently being migrated from another machine.
-#
-# Since: 2.12
-##
-{ 'enum': 'SevState',
- 'data': ['uninit', 'launch-update', 'launch-secret', 'running',
- 'send-update', 'receive-update' ],
- 'if': 'defined(TARGET_I386)' }
-
-##
-# @SevInfo:
-#
-# Information about Secure Encrypted Virtualization (SEV) support
-#
-# @enabled: true if SEV is active
-#
-# @api-major: SEV API major version
-#
-# @api-minor: SEV API minor version
-#
-# @build-id: SEV FW build id
-#
-# @policy: SEV policy value
-#
-# @state: SEV guest state
-#
-# @handle: SEV firmware handle
-#
-# Since: 2.12
-##
-{ 'struct': 'SevInfo',
- 'data': { 'enabled': 'bool',
- 'api-major': 'uint8',
- 'api-minor' : 'uint8',
- 'build-id' : 'uint8',
- 'policy' : 'uint32',
- 'state' : 'SevState',
- 'handle' : 'uint32'
- },
- 'if': 'defined(TARGET_I386)'
-}
-
-##
-# @query-sev:
-#
-# Returns information about SEV
-#
-# Returns: @SevInfo
-#
-# Since: 2.12
-#
-# Example:
-#
-# -> { "execute": "query-sev" }
-# <- { "return": { "enabled": true, "api-major" : 0, "api-minor" : 0,
-# "build-id" : 0, "policy" : 0, "state" : "running",
-# "handle" : 1 } }
-#
-##
-{ 'command': 'query-sev', 'returns': 'SevInfo',
- 'if': 'defined(TARGET_I386)' }
-
-
-##
-# @SevLaunchMeasureInfo:
-#
-# SEV Guest Launch measurement information
-#
-# @data: the measurement value encoded in base64
-#
-# Since: 2.12
-#
-##
-{ 'struct': 'SevLaunchMeasureInfo', 'data': {'data': 'str'},
- 'if': 'defined(TARGET_I386)' }
-
-##
-# @query-sev-launch-measure:
-#
-# Query the SEV guest launch information.
-#
-# Returns: The @SevLaunchMeasureInfo for the guest
-#
-# Since: 2.12
-#
-# Example:
-#
-# -> { "execute": "query-sev-launch-measure" }
-# <- { "return": { "data": "4l8LXeNlSPUDlXPJG5966/8%YZ" } }
-#
-##
-{ 'command': 'query-sev-launch-measure', 'returns': 'SevLaunchMeasureInfo',
- 'if': 'defined(TARGET_I386)' }
-
-
-##
-# @SevCapability:
-#
-# The struct describes capability for a Secure Encrypted Virtualization
-# feature.
-#
-# @pdh: Platform Diffie-Hellman key (base64 encoded)
-#
-# @cert-chain: PDH certificate chain (base64 encoded)
-#
-# @cbitpos: C-bit location in page table entry
-#
-# @reduced-phys-bits: Number of physical Address bit reduction when SEV is
-# enabled
-#
-# Since: 2.12
-##
-{ 'struct': 'SevCapability',
- 'data': { 'pdh': 'str',
- 'cert-chain': 'str',
- 'cbitpos': 'int',
- 'reduced-phys-bits': 'int'},
- 'if': 'defined(TARGET_I386)' }
-
-##
-# @query-sev-capabilities:
-#
-# This command is used to get the SEV capabilities, and is supported on AMD
-# X86 platforms only.
-#
-# Returns: SevCapability objects.
-#
-# Since: 2.12
-#
-# Example:
-#
-# -> { "execute": "query-sev-capabilities" }
-# <- { "return": { "pdh": "8CCDD8DDD", "cert-chain": "888CCCDDDEE",
-# "cbitpos": 47, "reduced-phys-bits": 5}}
-#
-##
-{ 'command': 'query-sev-capabilities', 'returns': 'SevCapability',
- 'if': 'defined(TARGET_I386)' }
-
-##
-# @dump-skeys:
-#
-# Dump guest's storage keys
-#
-# @filename: the path to the file to dump to
-#
-# This command is only supported on s390 architecture.
-#
-# Since: 2.5
-#
-# Example:
-#
-# -> { "execute": "dump-skeys",
-# "arguments": { "filename": "/tmp/skeys" } }
-# <- { "return": {} }
-#
-##
-{ 'command': 'dump-skeys',
- 'data': { 'filename': 'str' },
- 'if': 'defined(TARGET_S390X)' }
-
-##
-# @CpuModelBaselineInfo:
-#
-# The result of a CPU model baseline.
-#
-# @model: the baselined CpuModelInfo.
-#
-# Since: 2.8.0
-##
-{ 'struct': 'CpuModelBaselineInfo',
- 'data': { 'model': 'CpuModelInfo' },
- 'if': 'defined(TARGET_S390X)' }
-
-##
-# @CpuModelCompareInfo:
-#
-# The result of a CPU model comparison.
-#
-# @result: The result of the compare operation.
-# @responsible-properties: List of properties that led to the comparison result
-# not being identical.
-#
-# @responsible-properties is a list of QOM property names that led to
-# both CPUs not being detected as identical. For identical models, this
-# list is empty.
-# If a QOM property is read-only, that means there's no known way to make the
-# CPU models identical. If the special property name "type" is included, the
-# models are by definition not identical and cannot be made identical.
-#
-# Since: 2.8.0
-##
-{ 'struct': 'CpuModelCompareInfo',
- 'data': { 'result': 'CpuModelCompareResult',
- 'responsible-properties': ['str'] },
- 'if': 'defined(TARGET_S390X)' }
-
-##
-# @query-cpu-model-comparison:
-#
-# Compares two CPU models, returning how they compare in a specific
-# configuration. The results indicates how both models compare regarding
-# runnability. This result can be used by tooling to make decisions if a
-# certain CPU model will run in a certain configuration or if a compatible
-# CPU model has to be created by baselining.
-#
-# Usually, a CPU model is compared against the maximum possible CPU model
-# of a certain configuration (e.g. the "host" model for KVM). If that CPU
-# model is identical or a subset, it will run in that configuration.
-#
-# The result returned by this command may be affected by:
-#
-# * QEMU version: CPU models may look different depending on the QEMU version.
-# (Except for CPU models reported as "static" in query-cpu-definitions.)
-# * machine-type: CPU model may look different depending on the machine-type.
-# (Except for CPU models reported as "static" in query-cpu-definitions.)
-# * machine options (including accelerator): in some architectures, CPU models
-# may look different depending on machine and accelerator options. (Except for
-# CPU models reported as "static" in query-cpu-definitions.)
-# * "-cpu" arguments and global properties: arguments to the -cpu option and
-# global properties may affect expansion of CPU models. Using
-# query-cpu-model-expansion while using these is not advised.
-#
-# Some architectures may not support comparing CPU models. s390x supports
-# comparing CPU models.
-#
-# Returns: a CpuModelBaselineInfo. Returns an error if comparing CPU models is
-# not supported, if a model cannot be used, if a model contains
-# an unknown cpu definition name, unknown properties or properties
-# with wrong types.
-#
-# Note: this command isn't specific to s390x, but is only implemented
-# on this architecture currently.
-#
-# Since: 2.8.0
-##
-{ 'command': 'query-cpu-model-comparison',
- 'data': { 'modela': 'CpuModelInfo', 'modelb': 'CpuModelInfo' },
- 'returns': 'CpuModelCompareInfo',
- 'if': 'defined(TARGET_S390X)' }
-
-##
-# @query-cpu-model-baseline:
-#
-# Baseline two CPU models, creating a compatible third model. The created
-# model will always be a static, migration-safe CPU model (see "static"
-# CPU model expansion for details).
-#
-# This interface can be used by tooling to create a compatible CPU model out
-# two CPU models. The created CPU model will be identical to or a subset of
-# both CPU models when comparing them. Therefore, the created CPU model is
-# guaranteed to run where the given CPU models run.
-#
-# The result returned by this command may be affected by:
-#
-# * QEMU version: CPU models may look different depending on the QEMU version.
-# (Except for CPU models reported as "static" in query-cpu-definitions.)
-# * machine-type: CPU model may look different depending on the machine-type.
-# (Except for CPU models reported as "static" in query-cpu-definitions.)
-# * machine options (including accelerator): in some architectures, CPU models
-# may look different depending on machine and accelerator options. (Except for
-# CPU models reported as "static" in query-cpu-definitions.)
-# * "-cpu" arguments and global properties: arguments to the -cpu option and
-# global properties may affect expansion of CPU models. Using
-# query-cpu-model-expansion while using these is not advised.
-#
-# Some architectures may not support baselining CPU models. s390x supports
-# baselining CPU models.
-#
-# Returns: a CpuModelBaselineInfo. Returns an error if baselining CPU models is
-# not supported, if a model cannot be used, if a model contains
-# an unknown cpu definition name, unknown properties or properties
-# with wrong types.
-#
-# Note: this command isn't specific to s390x, but is only implemented
-# on this architecture currently.
-#
-# Since: 2.8.0
-##
-{ 'command': 'query-cpu-model-baseline',
- 'data': { 'modela': 'CpuModelInfo',
- 'modelb': 'CpuModelInfo' },
- 'returns': 'CpuModelBaselineInfo',
- 'if': 'defined(TARGET_S390X)' }
-
-##
-# @GICCapability:
-#
-# The struct describes capability for a specific GIC (Generic
-# Interrupt Controller) version. These bits are not only decided by
-# QEMU/KVM software version, but also decided by the hardware that
-# the program is running upon.
-#
-# @version: version of GIC to be described. Currently, only 2 and 3
-# are supported.
-#
-# @emulated: whether current QEMU/hardware supports emulated GIC
-# device in user space.
-#
-# @kernel: whether current QEMU/hardware supports hardware
-# accelerated GIC device in kernel.
-#
-# Since: 2.6
-##
-{ 'struct': 'GICCapability',
- 'data': { 'version': 'int',
- 'emulated': 'bool',
- 'kernel': 'bool' },
- 'if': 'defined(TARGET_ARM)' }
-
-##
-# @query-gic-capabilities:
-#
-# This command is ARM-only. It will return a list of GICCapability
-# objects that describe its capability bits.
-#
-# Returns: a list of GICCapability objects.
-#
-# Since: 2.6
-#
-# Example:
-#
-# -> { "execute": "query-gic-capabilities" }
-# <- { "return": [{ "version": 2, "emulated": true, "kernel": false },
-# { "version": 3, "emulated": false, "kernel": true } ] }
-#
-##
-{ 'command': 'query-gic-capabilities', 'returns': ['GICCapability'],
- 'if': 'defined(TARGET_ARM)' }
-
-##
-# @CpuModelExpansionInfo:
-#
-# The result of a cpu model expansion.
-#
-# @model: the expanded CpuModelInfo.
-#
-# Since: 2.8.0
-##
-{ 'struct': 'CpuModelExpansionInfo',
- 'data': { 'model': 'CpuModelInfo' },
- 'if': 'defined(TARGET_S390X) || defined(TARGET_I386)' }
-
-##
-# @query-cpu-model-expansion:
-#
-# Expands a given CPU model (or a combination of CPU model + additional options)
-# to different granularities, allowing tooling to get an understanding what a
-# specific CPU model looks like in QEMU under a certain configuration.
-#
-# This interface can be used to query the "host" CPU model.
-#
-# The data returned by this command may be affected by:
-#
-# * QEMU version: CPU models may look different depending on the QEMU version.
-# (Except for CPU models reported as "static" in query-cpu-definitions.)
-# * machine-type: CPU model may look different depending on the machine-type.
-# (Except for CPU models reported as "static" in query-cpu-definitions.)
-# * machine options (including accelerator): in some architectures, CPU models
-# may look different depending on machine and accelerator options. (Except for
-# CPU models reported as "static" in query-cpu-definitions.)
-# * "-cpu" arguments and global properties: arguments to the -cpu option and
-# global properties may affect expansion of CPU models. Using
-# query-cpu-model-expansion while using these is not advised.
-#
-# Some architectures may not support all expansion types. s390x supports
-# "full" and "static".
-#
-# Returns: a CpuModelExpansionInfo. Returns an error if expanding CPU models is
-# not supported, if the model cannot be expanded, if the model contains
-# an unknown CPU definition name, unknown properties or properties
-# with a wrong type. Also returns an error if an expansion type is
-# not supported.
-#
-# Since: 2.8.0
-##
-{ 'command': 'query-cpu-model-expansion',
- 'data': { 'type': 'CpuModelExpansionType',
- 'model': 'CpuModelInfo' },
- 'returns': 'CpuModelExpansionInfo',
- 'if': 'defined(TARGET_S390X) || defined(TARGET_I386)' }
-
-##
-# @CpuDefinitionInfo:
-#
-# Virtual CPU definition.
-#
-# @name: the name of the CPU definition
-#
-# @migration-safe: whether a CPU definition can be safely used for
-# migration in combination with a QEMU compatibility machine
-# when migrating between different QEMU versions and between
-# hosts with different sets of (hardware or software)
-# capabilities. If not provided, information is not available
-# and callers should not assume the CPU definition to be
-# migration-safe. (since 2.8)
-#
-# @static: whether a CPU definition is static and will not change depending on
-# QEMU version, machine type, machine options and accelerator options.
-# A static model is always migration-safe. (since 2.8)
-#
-# @unavailable-features: List of properties that prevent
-# the CPU model from running in the current
-# host. (since 2.8)
-# @typename: Type name that can be used as argument to @device-list-properties,
-# to introspect properties configurable using -cpu or -global.
-# (since 2.9)
-#
-# @unavailable-features is a list of QOM property names that
-# represent CPU model attributes that prevent the CPU from running.
-# If the QOM property is read-only, that means there's no known
-# way to make the CPU model run in the current host. Implementations
-# that choose not to provide specific information return the
-# property name "type".
-# If the property is read-write, it means that it MAY be possible
-# to run the CPU model in the current host if that property is
-# changed. Management software can use it as hints to suggest or
-# choose an alternative for the user, or just to generate meaningful
-# error messages explaining why the CPU model can't be used.
-# If @unavailable-features is an empty list, the CPU model is
-# runnable using the current host and machine-type.
-# If @unavailable-features is not present, runnability
-# information for the CPU is not available.
-#
-# Since: 1.2.0
-##
-{ 'struct': 'CpuDefinitionInfo',
- 'data': { 'name': 'str',
- '*migration-safe': 'bool',
- 'static': 'bool',
- '*unavailable-features': [ 'str' ],
- 'typename': 'str' },
- 'if': 'defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_I386) || defined(TARGET_S390X) || defined(TARGET_MIPS)' }
-
-##
-# @query-cpu-definitions:
-#
-# Return a list of supported virtual CPU definitions
-#
-# Returns: a list of CpuDefInfo
-#
-# Since: 1.2.0
-##
-{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'],
- 'if': 'defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_I386) || defined(TARGET_S390X) || defined(TARGET_MIPS)' }
#include "monitor/qdev.h"
#include "sysemu/arch_init.h"
#include "qapi/error.h"
-#include "qapi/qapi-commands-misc.h"
+#include "qapi/qapi-commands-qdev.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
#include "qemu/config-file.h"
qdev_print_devinfos(true);
}
-typedef struct QOMCompositionState {
- Monitor *mon;
- int indent;
-} QOMCompositionState;
-
-static void print_qom_composition(Monitor *mon, Object *obj, int indent);
-
-static int print_qom_composition_child(Object *obj, void *opaque)
-{
- QOMCompositionState *s = opaque;
-
- print_qom_composition(s->mon, obj, s->indent);
-
- return 0;
-}
-
-static void print_qom_composition(Monitor *mon, Object *obj, int indent)
-{
- QOMCompositionState s = {
- .mon = mon,
- .indent = indent + 2,
- };
- char *name;
-
- if (obj == object_get_root()) {
- name = g_strdup("");
- } else {
- name = object_get_canonical_path_component(obj);
- }
- monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name,
- object_get_typename(obj));
- g_free(name);
- object_child_foreach(obj, print_qom_composition_child, &s);
-}
-
-void hmp_info_qom_tree(Monitor *mon, const QDict *dict)
-{
- const char *path = qdict_get_try_str(dict, "path");
- Object *obj;
- bool ambiguous = false;
-
- if (path) {
- obj = object_resolve_path(path, &ambiguous);
- if (!obj) {
- monitor_printf(mon, "Path '%s' could not be resolved.\n", path);
- return;
- }
- if (ambiguous) {
- monitor_printf(mon, "Warning: Path '%s' is ambiguous.\n", path);
- return;
- }
- } else {
- obj = qdev_get_machine();
- }
- print_qom_composition(mon, obj, 0);
-}
-
void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
{
Error *local_err = NULL;
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
- *
+ */
+
+/*
+ * Known shortcomings:
+ * - There is no manual page
+ * - The syntax of the ACL file is not documented anywhere
+ * - parse_acl_file() doesn't report fopen() failure properly, fails
+ * to check ferror() after fgets() failure, arbitrarily truncates
+ * long lines, handles whitespace inconsistently, error messages
+ * don't point to the offending file and line, errors in included
+ * files are reported, but otherwise ignored, ...
*/
#include "qemu/osdep.h"
``acl_remove'' commands are deprecated with no replacement. Authorization
for VNC should be performed using the pluggable QAuthZ objects.
+@section Guest Emulator ISAs
+
+@subsection RISC-V ISA privledge specification version 1.09.1 (since 4.1)
+
+The RISC-V ISA privledge specification version 1.09.1 has been deprecated.
+QEMU supports both the newer version 1.10.0 and the ratified version 1.11.0, these
+should be used instead of the 1.09.1 version.
+
@section System emulator CPUS
@subsection RISC-V ISA CPUs (since 4.1)
to just export the entire image and then mount only /dev/nbd0p1 than
it is to reinvoke @command{qemu-nbd -c /dev/nbd0} limited to just a
subset of the image.
+
+@section Build system
+
+@subsection Python 2 support (since 4.1.0)
+
+In the future, QEMU will require Python 3 to be available at
+build time. Support for Python 2 in scripts shipped with QEMU
+is deprecated.
* to take action
*/
ret = bdrv_is_allocated_above(backing_bs(bs), prefix_chain_bs,
- offset, n, &n);
+ false, offset, n, &n);
if (ret < 0) {
error_report("error while reading image metadata: %s",
strerror(-ret));
The file format is libpcap, so it can be analyzed with tools such as tcpdump
or Wireshark.
-@item -object colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},outdev=@var{chardevid},iothread=@var{id}[,vnet_hdr_support]
+@item -object colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},outdev=@var{chardevid},iothread=@var{id}[,vnet_hdr_support][,notify_dev=@var{id}]
Colo-compare gets packet from primary_in@var{chardevid} and secondary_in@var{chardevid}, than compare primary packet with
secondary packet. If the packets are same, we will output primary
In order to improve efficiency, we need to put the task of comparison
in another thread. If it has the vnet_hdr_support flag, colo compare
will send/recv packet with vnet_hdr_len.
+If you want to use Xen COLO, will need the notify_dev to notify Xen
+colo-frame to do checkpoint.
we must use it with the help of filter-mirror and filter-redirector.
@example
+KVM COLO
+
primary:
-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
-device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
+
+Xen COLO
+
+primary:
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
+-device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
+-chardev socket,id=mirror0,host=3.3.3.3,port=9003,server,nowait
+-chardev socket,id=compare1,host=3.3.3.3,port=9004,server,nowait
+-chardev socket,id=compare0,host=3.3.3.3,port=9001,server,nowait
+-chardev socket,id=compare0-0,host=3.3.3.3,port=9001
+-chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
+-chardev socket,id=compare_out0,host=3.3.3.3,port=9005
+-chardev socket,id=notify_way,host=3.3.3.3,port=9009,server,nowait
+-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0
+-object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out
+-object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0
+-object iothread,id=iothread1
+-object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,notify_dev=nofity_way,iothread=iothread1
+
+secondary:
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
+-device e1000,netdev=hn0,mac=52:a4:00:12:78:66
+-chardev socket,id=red0,host=3.3.3.3,port=9003
+-chardev socket,id=red1,host=3.3.3.3,port=9004
+-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
+-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
+
@end example
If you want to know the detail of above command line, you can read
qom-obj-y += object_interfaces.o
common-obj-y = cpu.o
+common-obj-$(CONFIG_SOFTMMU) += qom-hmp-cmds.o qom-qmp-cmds.o
--- /dev/null
+/*
+ * HMP commands related to QOM
+ *
+ * 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 "hw/qdev-core.h"
+#include "monitor/hmp.h"
+#include "monitor/monitor.h"
+#include "qapi/error.h"
+#include "qapi/qapi-commands-qom.h"
+#include "qapi/qmp/qdict.h"
+#include "qom/object.h"
+
+void hmp_qom_list(Monitor *mon, const QDict *qdict)
+{
+ const char *path = qdict_get_try_str(qdict, "path");
+ ObjectPropertyInfoList *list;
+ Error *err = NULL;
+
+ if (path == NULL) {
+ monitor_printf(mon, "/\n");
+ return;
+ }
+
+ list = qmp_qom_list(path, &err);
+ if (err == NULL) {
+ ObjectPropertyInfoList *start = list;
+ while (list != NULL) {
+ ObjectPropertyInfo *value = list->value;
+
+ monitor_printf(mon, "%s (%s)\n",
+ value->name, value->type);
+ list = list->next;
+ }
+ qapi_free_ObjectPropertyInfoList(start);
+ }
+ hmp_handle_error(mon, &err);
+}
+
+void hmp_qom_set(Monitor *mon, const QDict *qdict)
+{
+ const char *path = qdict_get_str(qdict, "path");
+ const char *property = qdict_get_str(qdict, "property");
+ const char *value = qdict_get_str(qdict, "value");
+ Error *err = NULL;
+ bool ambiguous = false;
+ Object *obj;
+
+ obj = object_resolve_path(path, &ambiguous);
+ if (obj == NULL) {
+ error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "Device '%s' not found", path);
+ } else {
+ if (ambiguous) {
+ monitor_printf(mon, "Warning: Path '%s' is ambiguous\n", path);
+ }
+ object_property_parse(obj, value, property, &err);
+ }
+ hmp_handle_error(mon, &err);
+}
+
+typedef struct QOMCompositionState {
+ Monitor *mon;
+ int indent;
+} QOMCompositionState;
+
+static void print_qom_composition(Monitor *mon, Object *obj, int indent);
+
+static int print_qom_composition_child(Object *obj, void *opaque)
+{
+ QOMCompositionState *s = opaque;
+
+ print_qom_composition(s->mon, obj, s->indent);
+
+ return 0;
+}
+
+static void print_qom_composition(Monitor *mon, Object *obj, int indent)
+{
+ QOMCompositionState s = {
+ .mon = mon,
+ .indent = indent + 2,
+ };
+ char *name;
+
+ if (obj == object_get_root()) {
+ name = g_strdup("");
+ } else {
+ name = object_get_canonical_path_component(obj);
+ }
+ monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name,
+ object_get_typename(obj));
+ g_free(name);
+ object_child_foreach(obj, print_qom_composition_child, &s);
+}
+
+void hmp_info_qom_tree(Monitor *mon, const QDict *dict)
+{
+ const char *path = qdict_get_try_str(dict, "path");
+ Object *obj;
+ bool ambiguous = false;
+
+ if (path) {
+ obj = object_resolve_path(path, &ambiguous);
+ if (!obj) {
+ monitor_printf(mon, "Path '%s' could not be resolved.\n", path);
+ return;
+ }
+ if (ambiguous) {
+ monitor_printf(mon, "Warning: Path '%s' is ambiguous.\n", path);
+ return;
+ }
+ } else {
+ obj = qdev_get_machine();
+ }
+ print_qom_composition(mon, obj, 0);
+}
--- /dev/null
+/*
+ * QMP commands related to QOM
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/qdev.h"
+#include "qapi/error.h"
+#include "qapi/qapi-commands-qdev.h"
+#include "qapi/qapi-commands-qom.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qerror.h"
+#include "qapi/qobject-input-visitor.h"
+#include "qemu/cutils.h"
+#include "qom/object_interfaces.h"
+#include "qom/qom-qobject.h"
+
+ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
+{
+ Object *obj;
+ bool ambiguous = false;
+ ObjectPropertyInfoList *props = NULL;
+ ObjectProperty *prop;
+ ObjectPropertyIterator iter;
+
+ obj = object_resolve_path(path, &ambiguous);
+ if (obj == NULL) {
+ if (ambiguous) {
+ error_setg(errp, "Path '%s' is ambiguous", path);
+ } else {
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "Device '%s' not found", path);
+ }
+ return NULL;
+ }
+
+ object_property_iter_init(&iter, obj);
+ while ((prop = object_property_iter_next(&iter))) {
+ ObjectPropertyInfoList *entry = g_malloc0(sizeof(*entry));
+
+ entry->value = g_malloc0(sizeof(ObjectPropertyInfo));
+ entry->next = props;
+ props = entry;
+
+ entry->value->name = g_strdup(prop->name);
+ entry->value->type = g_strdup(prop->type);
+ }
+
+ return props;
+}
+
+void qmp_qom_set(const char *path, const char *property, QObject *value,
+ Error **errp)
+{
+ Object *obj;
+
+ obj = object_resolve_path(path, NULL);
+ if (!obj) {
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "Device '%s' not found", path);
+ return;
+ }
+
+ object_property_set_qobject(obj, value, property, errp);
+}
+
+QObject *qmp_qom_get(const char *path, const char *property, Error **errp)
+{
+ Object *obj;
+
+ obj = object_resolve_path(path, NULL);
+ if (!obj) {
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "Device '%s' not found", path);
+ return NULL;
+ }
+
+ return object_property_get_qobject(obj, property, errp);
+}
+
+static void qom_list_types_tramp(ObjectClass *klass, void *data)
+{
+ ObjectTypeInfoList *e, **pret = data;
+ ObjectTypeInfo *info;
+ ObjectClass *parent = object_class_get_parent(klass);
+
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strdup(object_class_get_name(klass));
+ info->has_abstract = info->abstract = object_class_is_abstract(klass);
+ if (parent) {
+ info->has_parent = true;
+ info->parent = g_strdup(object_class_get_name(parent));
+ }
+
+ e = g_malloc0(sizeof(*e));
+ e->value = info;
+ e->next = *pret;
+ *pret = e;
+}
+
+ObjectTypeInfoList *qmp_qom_list_types(bool has_implements,
+ const char *implements,
+ bool has_abstract,
+ bool abstract,
+ Error **errp)
+{
+ ObjectTypeInfoList *ret = NULL;
+
+ object_class_foreach(qom_list_types_tramp, implements, abstract, &ret);
+
+ return ret;
+}
+
+/* Return a DevicePropertyInfo for a qdev property.
+ *
+ * If a qdev property with the given name does not exist, use the given default
+ * type. If the qdev property info should not be shown, return NULL.
+ *
+ * The caller must free the return value.
+ */
+static ObjectPropertyInfo *make_device_property_info(ObjectClass *klass,
+ const char *name,
+ const char *default_type,
+ const char *description)
+{
+ ObjectPropertyInfo *info;
+ Property *prop;
+
+ do {
+ for (prop = DEVICE_CLASS(klass)->props; prop && prop->name; prop++) {
+ if (strcmp(name, prop->name) != 0) {
+ continue;
+ }
+
+ /*
+ * TODO Properties without a parser are just for dirty hacks.
+ * qdev_prop_ptr is the only such PropertyInfo. It's marked
+ * for removal. This conditional should be removed along with
+ * it.
+ */
+ if (!prop->info->set && !prop->info->create) {
+ return NULL; /* no way to set it, don't show */
+ }
+
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strdup(prop->name);
+ info->type = default_type ? g_strdup(default_type)
+ : g_strdup(prop->info->name);
+ info->has_description = !!prop->info->description;
+ info->description = g_strdup(prop->info->description);
+ return info;
+ }
+ klass = object_class_get_parent(klass);
+ } while (klass != object_class_by_name(TYPE_DEVICE));
+
+ /* Not a qdev property, use the default type */
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strdup(name);
+ info->type = g_strdup(default_type);
+ info->has_description = !!description;
+ info->description = g_strdup(description);
+
+ return info;
+}
+
+ObjectPropertyInfoList *qmp_device_list_properties(const char *typename,
+ Error **errp)
+{
+ ObjectClass *klass;
+ Object *obj;
+ ObjectProperty *prop;
+ ObjectPropertyIterator iter;
+ ObjectPropertyInfoList *prop_list = NULL;
+
+ klass = object_class_by_name(typename);
+ if (klass == NULL) {
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "Device '%s' not found", typename);
+ return NULL;
+ }
+
+ klass = object_class_dynamic_cast(klass, TYPE_DEVICE);
+ if (klass == NULL) {
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename", TYPE_DEVICE);
+ return NULL;
+ }
+
+ if (object_class_is_abstract(klass)) {
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename",
+ "non-abstract device type");
+ return NULL;
+ }
+
+ obj = object_new(typename);
+
+ object_property_iter_init(&iter, obj);
+ while ((prop = object_property_iter_next(&iter))) {
+ ObjectPropertyInfo *info;
+ ObjectPropertyInfoList *entry;
+
+ /* Skip Object and DeviceState properties */
+ if (strcmp(prop->name, "type") == 0 ||
+ strcmp(prop->name, "realized") == 0 ||
+ strcmp(prop->name, "hotpluggable") == 0 ||
+ strcmp(prop->name, "hotplugged") == 0 ||
+ strcmp(prop->name, "parent_bus") == 0) {
+ continue;
+ }
+
+ /* Skip legacy properties since they are just string versions of
+ * properties that we already list.
+ */
+ if (strstart(prop->name, "legacy-", NULL)) {
+ continue;
+ }
+
+ info = make_device_property_info(klass, prop->name, prop->type,
+ prop->description);
+ if (!info) {
+ continue;
+ }
+
+ entry = g_malloc0(sizeof(*entry));
+ entry->value = info;
+ entry->next = prop_list;
+ prop_list = entry;
+ }
+
+ object_unref(obj);
+
+ return prop_list;
+}
+
+ObjectPropertyInfoList *qmp_qom_list_properties(const char *typename,
+ Error **errp)
+{
+ ObjectClass *klass;
+ Object *obj = NULL;
+ ObjectProperty *prop;
+ ObjectPropertyIterator iter;
+ ObjectPropertyInfoList *prop_list = NULL;
+
+ klass = object_class_by_name(typename);
+ if (klass == NULL) {
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "Class '%s' not found", typename);
+ return NULL;
+ }
+
+ klass = object_class_dynamic_cast(klass, TYPE_OBJECT);
+ if (klass == NULL) {
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "typename", TYPE_OBJECT);
+ return NULL;
+ }
+
+ if (object_class_is_abstract(klass)) {
+ object_class_property_iter_init(&iter, klass);
+ } else {
+ obj = object_new(typename);
+ object_property_iter_init(&iter, obj);
+ }
+ while ((prop = object_property_iter_next(&iter))) {
+ ObjectPropertyInfo *info;
+ ObjectPropertyInfoList *entry;
+
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strdup(prop->name);
+ info->type = g_strdup(prop->type);
+ info->has_description = !!prop->description;
+ info->description = g_strdup(prop->description);
+
+ entry = g_malloc0(sizeof(*entry));
+ entry->value = info;
+ entry->next = prop_list;
+ prop_list = entry;
+ }
+
+ object_unref(obj);
+
+ return prop_list;
+}
+
+void qmp_object_add(const char *type, const char *id,
+ bool has_props, QObject *props, Error **errp)
+{
+ QDict *pdict;
+ Visitor *v;
+ Object *obj;
+
+ if (props) {
+ pdict = qobject_to(QDict, props);
+ if (!pdict) {
+ error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict");
+ return;
+ }
+ qobject_ref(pdict);
+ } else {
+ pdict = qdict_new();
+ }
+
+ v = qobject_input_visitor_new(QOBJECT(pdict));
+ obj = user_creatable_add_type(type, id, pdict, v, errp);
+ visit_free(v);
+ if (obj) {
+ object_unref(obj);
+ }
+ qobject_unref(pdict);
+}
+
+void qmp_object_del(const char *id, Error **errp)
+{
+ user_creatable_del(id, errp);
+}
--- /dev/null
+CONFIG_QEMU=y
+CONFIG_BUILD_VGABIOS=y
+CONFIG_VGA_ATI=y
+CONFIG_VGA_PCI=y
-Subproject commit 3464681b2b5983df80086a40179d324102347da3
+Subproject commit c79e0ecb84f4f1ee3f73f521622e264edd1bf174
from itertools import chain
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'python'))
-from qemu import QEMUMachine
+from qemu.machine import QEMUMachine
logger = logging.getLogger('device-crash-test')
dbg = logger.debug
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
from qemu import qmp
+if sys.version_info[0] == 2:
+ input = raw_input
+
class QMPCompleter(list):
def complete(self, text, state):
for cmd in self:
@return True if execution was ok, return False if disconnected.
"""
try:
- cmdline = raw_input(prompt)
+ cmdline = input(prompt)
except EOFError:
print()
return False
from graphviz import Digraph
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'python'))
-from qemu import MonitorResponseError
+from qemu.machine import MonitorResponseError
def perm(arr):
obj-y += arm-semi.o
-obj-$(CONFIG_SOFTMMU) += machine.o psci.o arch_dump.o monitor.o
+obj-y += helper.o vfp_helper.o
+obj-y += cpu.o gdbstub.o
+obj-$(TARGET_AARCH64) += cpu64.o gdbstub64.o
+
+obj-$(CONFIG_SOFTMMU) += machine.o arch_dump.o monitor.o
+obj-$(CONFIG_SOFTMMU) += arm-powerctl.o
+
obj-$(CONFIG_KVM) += kvm.o
obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o
obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
-obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += neon_helper.o iwmmxt_helper.o vec_helper.o vfp_helper.o
-obj-y += gdbstub.o
-obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
-obj-$(TARGET_AARCH64) += pauth_helper.o
-obj-y += crypto_helper.o
-obj-$(CONFIG_SOFTMMU) += arm-powerctl.o
DECODETREE = $(SRC_PATH)/scripts/decodetree.py
target/arm/translate.o: target/arm/decode-vfp.inc.c
target/arm/translate.o: target/arm/decode-vfp-uncond.inc.c
+obj-y += tlb_helper.o
+obj-y += translate.o op_helper.o
+obj-y += crypto_helper.o
+obj-y += iwmmxt_helper.o vec_helper.o neon_helper.o
+
+obj-$(CONFIG_SOFTMMU) += psci.o
+
+obj-$(TARGET_AARCH64) += translate-a64.o helper-a64.o
obj-$(TARGET_AARCH64) += translate-sve.o sve_helper.o
+obj-$(TARGET_AARCH64) += pauth_helper.o
*/
#include "qemu/osdep.h"
+#include "qemu/qemu-print.h"
#include "qemu-common.h"
#include "target/arm/idau.h"
#include "qemu/module.h"
#endif
}
+#ifdef TARGET_AARCH64
+
+static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ CPUARMState *env = &cpu->env;
+ uint32_t psr = pstate_read(env);
+ int i;
+ int el = arm_current_el(env);
+ const char *ns_status;
+
+ qemu_fprintf(f, " PC=%016" PRIx64 " ", env->pc);
+ for (i = 0; i < 32; i++) {
+ if (i == 31) {
+ qemu_fprintf(f, " SP=%016" PRIx64 "\n", env->xregs[i]);
+ } else {
+ qemu_fprintf(f, "X%02d=%016" PRIx64 "%s", i, env->xregs[i],
+ (i + 2) % 3 ? " " : "\n");
+ }
+ }
+
+ if (arm_feature(env, ARM_FEATURE_EL3) && el != 3) {
+ ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
+ } else {
+ ns_status = "";
+ }
+ qemu_fprintf(f, "PSTATE=%08x %c%c%c%c %sEL%d%c",
+ psr,
+ psr & PSTATE_N ? 'N' : '-',
+ psr & PSTATE_Z ? 'Z' : '-',
+ psr & PSTATE_C ? 'C' : '-',
+ psr & PSTATE_V ? 'V' : '-',
+ ns_status,
+ el,
+ psr & PSTATE_SP ? 'h' : 't');
+
+ if (cpu_isar_feature(aa64_bti, cpu)) {
+ qemu_fprintf(f, " BTYPE=%d", (psr & PSTATE_BTYPE) >> 10);
+ }
+ if (!(flags & CPU_DUMP_FPU)) {
+ qemu_fprintf(f, "\n");
+ return;
+ }
+ if (fp_exception_el(env, el) != 0) {
+ qemu_fprintf(f, " FPU disabled\n");
+ return;
+ }
+ qemu_fprintf(f, " FPCR=%08x FPSR=%08x\n",
+ vfp_get_fpcr(env), vfp_get_fpsr(env));
+
+ if (cpu_isar_feature(aa64_sve, cpu) && sve_exception_el(env, el) == 0) {
+ int j, zcr_len = sve_zcr_len_for_el(env, el);
+
+ for (i = 0; i <= FFR_PRED_NUM; i++) {
+ bool eol;
+ if (i == FFR_PRED_NUM) {
+ qemu_fprintf(f, "FFR=");
+ /* It's last, so end the line. */
+ eol = true;
+ } else {
+ qemu_fprintf(f, "P%02d=", i);
+ switch (zcr_len) {
+ case 0:
+ eol = i % 8 == 7;
+ break;
+ case 1:
+ eol = i % 6 == 5;
+ break;
+ case 2:
+ case 3:
+ eol = i % 3 == 2;
+ break;
+ default:
+ /* More than one quadword per predicate. */
+ eol = true;
+ break;
+ }
+ }
+ for (j = zcr_len / 4; j >= 0; j--) {
+ int digits;
+ if (j * 4 + 4 <= zcr_len + 1) {
+ digits = 16;
+ } else {
+ digits = (zcr_len % 4 + 1) * 4;
+ }
+ qemu_fprintf(f, "%0*" PRIx64 "%s", digits,
+ env->vfp.pregs[i].p[j],
+ j ? ":" : eol ? "\n" : " ");
+ }
+ }
+
+ for (i = 0; i < 32; i++) {
+ if (zcr_len == 0) {
+ qemu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64 "%s",
+ i, env->vfp.zregs[i].d[1],
+ env->vfp.zregs[i].d[0], i & 1 ? "\n" : " ");
+ } else if (zcr_len == 1) {
+ qemu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64
+ ":%016" PRIx64 ":%016" PRIx64 "\n",
+ i, env->vfp.zregs[i].d[3], env->vfp.zregs[i].d[2],
+ env->vfp.zregs[i].d[1], env->vfp.zregs[i].d[0]);
+ } else {
+ for (j = zcr_len; j >= 0; j--) {
+ bool odd = (zcr_len - j) % 2 != 0;
+ if (j == zcr_len) {
+ qemu_fprintf(f, "Z%02d[%x-%x]=", i, j, j - 1);
+ } else if (!odd) {
+ if (j > 0) {
+ qemu_fprintf(f, " [%x-%x]=", j, j - 1);
+ } else {
+ qemu_fprintf(f, " [%x]=", j);
+ }
+ }
+ qemu_fprintf(f, "%016" PRIx64 ":%016" PRIx64 "%s",
+ env->vfp.zregs[i].d[j * 2 + 1],
+ env->vfp.zregs[i].d[j * 2],
+ odd || j == 0 ? "\n" : ":");
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < 32; i++) {
+ uint64_t *q = aa64_vfp_qreg(env, i);
+ qemu_fprintf(f, "Q%02d=%016" PRIx64 ":%016" PRIx64 "%s",
+ i, q[1], q[0], (i & 1 ? "\n" : " "));
+ }
+ }
+}
+
+#else
+
+static inline void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
+{
+ g_assert_not_reached();
+}
+
+#endif
+
+static void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ CPUARMState *env = &cpu->env;
+ int i;
+
+ if (is_a64(env)) {
+ aarch64_cpu_dump_state(cs, f, flags);
+ return;
+ }
+
+ for (i = 0; i < 16; i++) {
+ qemu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
+ if ((i % 4) == 3) {
+ qemu_fprintf(f, "\n");
+ } else {
+ qemu_fprintf(f, " ");
+ }
+ }
+
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ uint32_t xpsr = xpsr_read(env);
+ const char *mode;
+ const char *ns_status = "";
+
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
+ ns_status = env->v7m.secure ? "S " : "NS ";
+ }
+
+ if (xpsr & XPSR_EXCP) {
+ mode = "handler";
+ } else {
+ if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
+ mode = "unpriv-thread";
+ } else {
+ mode = "priv-thread";
+ }
+ }
+
+ qemu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
+ xpsr,
+ xpsr & XPSR_N ? 'N' : '-',
+ xpsr & XPSR_Z ? 'Z' : '-',
+ xpsr & XPSR_C ? 'C' : '-',
+ xpsr & XPSR_V ? 'V' : '-',
+ xpsr & XPSR_T ? 'T' : 'A',
+ ns_status,
+ mode);
+ } else {
+ uint32_t psr = cpsr_read(env);
+ const char *ns_status = "";
+
+ if (arm_feature(env, ARM_FEATURE_EL3) &&
+ (psr & CPSR_M) != ARM_CPU_MODE_MON) {
+ ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
+ }
+
+ qemu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
+ psr,
+ psr & CPSR_N ? 'N' : '-',
+ psr & CPSR_Z ? 'Z' : '-',
+ psr & CPSR_C ? 'C' : '-',
+ psr & CPSR_V ? 'V' : '-',
+ psr & CPSR_T ? 'T' : 'A',
+ ns_status,
+ aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
+ }
+
+ if (flags & CPU_DUMP_FPU) {
+ int numvfpregs = 0;
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
+ numvfpregs += 16;
+ }
+ if (arm_feature(env, ARM_FEATURE_VFP3)) {
+ numvfpregs += 16;
+ }
+ for (i = 0; i < numvfpregs; i++) {
+ uint64_t v = *aa32_vfp_dreg(env, i);
+ qemu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
+ i * 2, (uint32_t)v,
+ i * 2 + 1, (uint32_t)(v >> 32),
+ i, v);
+ }
+ qemu_fprintf(f, "FPSCR: %08x\n", vfp_get_fpscr(env));
+ }
+}
+
uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz)
{
uint32_t Aff1 = idx / clustersz;
cc->gdb_write_register = arm_cpu_gdb_write_register;
#ifndef CONFIG_USER_ONLY
cc->do_interrupt = arm_cpu_do_interrupt;
- cc->do_unaligned_access = arm_cpu_do_unaligned_access;
- cc->do_transaction_failed = arm_cpu_do_transaction_failed;
cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug;
cc->asidx_from_attrs = arm_asidx_from_attrs;
cc->vmsd = &vmstate_arm_cpu;
#ifdef CONFIG_TCG
cc->tcg_initialize = arm_translate_init;
cc->tlb_fill = arm_cpu_tlb_fill;
+#if !defined(CONFIG_USER_ONLY)
+ cc->do_unaligned_access = arm_cpu_do_unaligned_access;
+ cc->do_transaction_failed = arm_cpu_do_transaction_failed;
+#endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
#endif
}
void arm_v7m_cpu_do_interrupt(CPUState *cpu);
bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);
-void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags);
-
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
MemTxAttrs *attrs);
+/*
+ * ARM generic helpers.
+ *
+ * This code is licensed under the GNU GPL v2 or later.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "target/arm/idau.h"
#include "exec/gdbstub.h"
#include "exec/helper-proto.h"
#include "qemu/host-utils.h"
-#include "sysemu/arch_init.h"
#include "sysemu/sysemu.h"
#include "qemu/bitops.h"
#include "qemu/crc32c.h"
#include "hw/semihosting/semihost.h"
#include "sysemu/cpus.h"
#include "sysemu/kvm.h"
-#include "fpu/softfloat.h"
#include "qemu/range.h"
-#include "qapi/qapi-commands-target.h"
+#include "qapi/qapi-commands-machine-target.h"
#include "qapi/error.h"
#include "qemu/guest-random.h"
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
#ifndef CONFIG_USER_ONLY
-/* Cacheability and shareability attributes for a memory access */
-typedef struct ARMCacheAttrs {
- unsigned int attrs:8; /* as in the MAIR register encoding */
- unsigned int shareability:2; /* as in the SH field of the VMSAv8-64 PTEs */
-} ARMCacheAttrs;
-
-static bool get_phys_addr(CPUARMState *env, target_ulong address,
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
- hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
- target_ulong *page_size,
- ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
MMUAccessType access_type, ARMMMUIdx mmu_idx,
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
target_ulong *page_size_ptr,
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
-
-/* Security attributes for an address, as returned by v8m_security_lookup. */
-typedef struct V8M_SAttributes {
- bool subpage; /* true if these attrs don't cover the whole TARGET_PAGE */
- bool ns;
- bool nsc;
- uint8_t sregion;
- bool srvalid;
- uint8_t iregion;
- bool irvalid;
-} V8M_SAttributes;
-
-static void v8m_security_lookup(CPUARMState *env, uint32_t address,
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
- V8M_SAttributes *sattrs);
#endif
static void switch_mode(CPUARMState *env, int mode);
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
{
- /* The TT instructions can be used by unprivileged code, but in
+ /*
+ * The TT instructions can be used by unprivileged code, but in
* user-only emulation we don't have the MPU.
* Luckily since we know we are NonSecure unprivileged (and that in
* turn means that the A flag wasn't specified), all the bits in the
return target_el;
}
-/*
- * Return true if the v7M CPACR permits access to the FPU for the specified
- * security state and privilege level.
- */
-static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
+void arm_log_exception(int idx)
{
- switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
- case 0:
- case 2: /* UNPREDICTABLE: we treat like 0 */
- return false;
- case 1:
- return is_priv;
- case 3:
- return true;
- default:
- g_assert_not_reached();
+ if (qemu_loglevel_mask(CPU_LOG_INT)) {
+ const char *exc = NULL;
+ static const char * const excnames[] = {
+ [EXCP_UDEF] = "Undefined Instruction",
+ [EXCP_SWI] = "SVC",
+ [EXCP_PREFETCH_ABORT] = "Prefetch Abort",
+ [EXCP_DATA_ABORT] = "Data Abort",
+ [EXCP_IRQ] = "IRQ",
+ [EXCP_FIQ] = "FIQ",
+ [EXCP_BKPT] = "Breakpoint",
+ [EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit",
+ [EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage",
+ [EXCP_HVC] = "Hypervisor Call",
+ [EXCP_HYP_TRAP] = "Hypervisor Trap",
+ [EXCP_SMC] = "Secure Monitor Call",
+ [EXCP_VIRQ] = "Virtual IRQ",
+ [EXCP_VFIQ] = "Virtual FIQ",
+ [EXCP_SEMIHOST] = "Semihosting call",
+ [EXCP_NOCP] = "v7M NOCP UsageFault",
+ [EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
+ [EXCP_STKOF] = "v8M STKOF UsageFault",
+ [EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
+ [EXCP_LSERR] = "v8M LSERR UsageFault",
+ [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
+ };
+
+ if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
+ exc = excnames[idx];
+ }
+ if (!exc) {
+ exc = "unknown";
+ }
+ qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc);
}
}
return true;
pend_fault:
- /* By pending the exception at this point we are making
+ /*
+ * By pending the exception at this point we are making
* the IMPDEF choice "overridden exceptions pended" (see the
* MergeExcInfo() pseudocode). The other choice would be to not
* pend them now and then make a choice about which to throw away
return true;
pend_fault:
- /* By pending the exception at this point we are making
+ /*
+ * By pending the exception at this point we are making
* the IMPDEF choice "overridden exceptions pended" (see the
* MergeExcInfo() pseudocode). The other choice would be to not
* pend them now and then make a choice about which to throw away
*/
}
-/* Write to v7M CONTROL.SPSEL bit for the specified security bank.
+/*
+ * Write to v7M CONTROL.SPSEL bit for the specified security bank.
* This may change the current stack pointer between Main and Process
* stack pointers if it is done for the CONTROL register for the current
* security state.
}
}
-/* Write to v7M CONTROL.SPSEL bit. This may change the current
+/*
+ * Write to v7M CONTROL.SPSEL bit. This may change the current
* stack pointer between Main and Process stack pointers.
*/
static void write_v7m_control_spsel(CPUARMState *env, bool new_spsel)
void write_v7m_exception(CPUARMState *env, uint32_t new_exc)
{
- /* Write a new value to v7m.exception, thus transitioning into or out
+ /*
+ * Write a new value to v7m.exception, thus transitioning into or out
* of Handler mode; this may result in a change of active stack pointer.
*/
bool new_is_psp, old_is_psp = v7m_using_psp(env);
return;
}
- /* All the banked state is accessed by looking at env->v7m.secure
+ /*
+ * All the banked state is accessed by looking at env->v7m.secure
* except for the stack pointer; rearrange the SP appropriately.
*/
new_ss_msp = env->v7m.other_ss_msp;
void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
{
- /* Handle v7M BXNS:
+ /*
+ * Handle v7M BXNS:
* - if the return value is a magic value, do exception return (like BX)
* - otherwise bit 0 of the return value is the target security state
*/
}
if (dest >= min_magic) {
- /* This is an exception return magic value; put it where
+ /*
+ * This is an exception return magic value; put it where
* do_v7m_exception_exit() expects and raise EXCEPTION_EXIT.
* Note that if we ever add gen_ss_advance() singlestep support to
* M profile this should count as an "instruction execution complete"
void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
{
- /* Handle v7M BLXNS:
+ /*
+ * Handle v7M BLXNS:
* - bit 0 of the destination address is the target security state
*/
assert(env->v7m.secure);
if (dest & 1) {
- /* target is Secure, so this is just a normal BLX,
+ /*
+ * Target is Secure, so this is just a normal BLX,
* except that the low bit doesn't indicate Thumb/not.
*/
env->regs[14] = nextinst;
env->regs[13] = sp;
env->regs[14] = 0xfeffffff;
if (arm_v7m_is_handler_mode(env)) {
- /* Write a dummy value to IPSR, to avoid leaking the current secure
+ /*
+ * Write a dummy value to IPSR, to avoid leaking the current secure
* exception number to non-secure code. This is guaranteed not
* to cause write_v7m_exception() to actually change stacks.
*/
static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
bool spsel)
{
- /* Return a pointer to the location where we currently store the
+ /*
+ * Return a pointer to the location where we currently store the
* stack pointer for the requested security state and thread mode.
* This pointer will become invalid if the CPU state is updated
* such that the stack pointers are switched around (eg changing
mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, targets_secure, true);
- /* We don't do a get_phys_addr() here because the rules for vector
+ /*
+ * We don't do a get_phys_addr() here because the rules for vector
* loads are special: they always use the default memory map, and
* the default memory map permits reads from all addresses.
* Since there's no easy way to pass through to pmsav8_mpu_lookup()
return true;
load_fail:
- /* All vector table fetch fails are reported as HardFault, with
+ /*
+ * All vector table fetch fails are reported as HardFault, with
* HFSR.VECTTBL and .FORCED set. (FORCED is set because
* technically the underlying exception is a MemManage or BusFault
* that is escalated to HardFault.) This is a terminal exception,
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
bool ignore_faults)
{
- /* For v8M, push the callee-saves register part of the stack frame.
+ /*
+ * For v8M, push the callee-saves register part of the stack frame.
* Compare the v8M pseudocode PushCalleeStack().
* In the tailchaining case this may not be the current stack.
*/
return true;
}
- /* Write as much of the stack frame as we can. A write failure may
+ /*
+ * Write as much of the stack frame as we can. A write failure may
* cause us to pend a derived exception.
*/
sig = v7m_integrity_sig(env, lr);
static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
bool ignore_stackfaults)
{
- /* Do the "take the exception" parts of exception entry,
+ /*
+ * Do the "take the exception" parts of exception entry,
* but not the pushing of state to the stack. This is
* similar to the pseudocode ExceptionTaken() function.
*/
if (arm_feature(env, ARM_FEATURE_V8)) {
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
(lr & R_V7M_EXCRET_S_MASK)) {
- /* The background code (the owner of the registers in the
+ /*
+ * The background code (the owner of the registers in the
* exception frame) is Secure. This means it may either already
* have or now needs to push callee-saves registers.
*/
if (targets_secure) {
if (dotailchain && !(lr & R_V7M_EXCRET_ES_MASK)) {
- /* We took an exception from Secure to NonSecure
+ /*
+ * We took an exception from Secure to NonSecure
* (which means the callee-saved registers got stacked)
* and are now tailchaining to a Secure exception.
* Clear DCRS so eventual return from this Secure
lr &= ~R_V7M_EXCRET_DCRS_MASK;
}
} else {
- /* We're going to a non-secure exception; push the
+ /*
+ * We're going to a non-secure exception; push the
* callee-saves registers to the stack now, if they're
* not already saved.
*/
lr |= R_V7M_EXCRET_SPSEL_MASK;
}
- /* Clear registers if necessary to prevent non-secure exception
+ /*
+ * Clear registers if necessary to prevent non-secure exception
* code being able to see register values from secure code.
* Where register values become architecturally UNKNOWN we leave
* them with their previous values.
*/
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
if (!targets_secure) {
- /* Always clear the caller-saved registers (they have been
+ /*
+ * Always clear the caller-saved registers (they have been
* pushed to the stack earlier in v7m_push_stack()).
* Clear callee-saved registers if the background code is
* Secure (in which case these regs were saved in
}
if (push_failed && !ignore_stackfaults) {
- /* Derived exception on callee-saves register stacking:
+ /*
+ * Derived exception on callee-saves register stacking:
* we might now want to take a different exception which
* targets a different security state, so try again from the top.
*/
return;
}
- /* Now we've done everything that might cause a derived exception
+ /*
+ * Now we've done everything that might cause a derived exception
* we can go ahead and activate whichever exception we're going to
* take (which might now be the derived exception).
*/
static bool v7m_push_stack(ARMCPU *cpu)
{
- /* Do the "set up stack frame" part of exception entry,
+ /*
+ * Do the "set up stack frame" part of exception entry,
* similar to pseudocode PushStack().
* Return true if we generate a derived exception (and so
* should ignore further stack faults trying to process
}
}
- /* Write as much of the stack frame as we can. If we fail a stack
+ /*
+ * Write as much of the stack frame as we can. If we fail a stack
* write this will result in a derived exception being pended
* (which may be taken in preference to the one we started with
* if it has higher priority).
bool ftype;
bool restore_s16_s31;
- /* If we're not in Handler mode then jumps to magic exception-exit
+ /*
+ * If we're not in Handler mode then jumps to magic exception-exit
* addresses don't have magic behaviour. However for the v8M
* security extensions the magic secure-function-return has to
* work in thread mode too, so to avoid doing an extra check in
return;
}
- /* In the spec pseudocode ExceptionReturn() is called directly
+ /*
+ * In the spec pseudocode ExceptionReturn() is called directly
* from BXWritePC() and gets the full target PC value including
* bit zero. In QEMU's implementation we treat it as a normal
* jump-to-register (which is then caught later on), and so split
}
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
- /* EXC_RETURN.ES validation check (R_SMFL). We must do this before
+ /*
+ * EXC_RETURN.ES validation check (R_SMFL). We must do this before
* we pick which FAULTMASK to clear.
*/
if (!env->v7m.secure &&
}
if (env->v7m.exception != ARMV7M_EXCP_NMI) {
- /* Auto-clear FAULTMASK on return from other than NMI.
+ /*
+ * Auto-clear FAULTMASK on return from other than NMI.
* If the security extension is implemented then this only
* happens if the raw execution priority is >= 0; the
* value of the ES bit in the exception return value indicates
/* still an irq active now */
break;
case 1:
- /* we returned to base exception level, no nesting.
+ /*
+ * We returned to base exception level, no nesting.
* (In the pseudocode this is written using "NestedActivation != 1"
* where we have 'rettobase == false'.)
*/
if (arm_feature(env, ARM_FEATURE_V8)) {
if (!arm_feature(env, ARM_FEATURE_M_SECURITY)) {
- /* UNPREDICTABLE if S == 1 or DCRS == 0 or ES == 1 (R_XLCP);
+ /*
+ * UNPREDICTABLE if S == 1 or DCRS == 0 or ES == 1 (R_XLCP);
* we choose to take the UsageFault.
*/
if ((excret & R_V7M_EXCRET_S_MASK) ||
break;
case 13: /* Return to Thread using Process stack */
case 9: /* Return to Thread using Main stack */
- /* We only need to check NONBASETHRDENA for v7M, because in
+ /*
+ * We only need to check NONBASETHRDENA for v7M, because in
* v8M this bit does not exist (it is RES1).
*/
if (!rettobase &&
}
if (ufault) {
- /* Bad exception return: instead of popping the exception
+ /*
+ * Bad exception return: instead of popping the exception
* stack, directly take a usage fault on the current stack.
*/
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
switch_v7m_security_state(env, return_to_secure);
{
- /* The stack pointer we should be reading the exception frame from
+ /*
+ * The stack pointer we should be reading the exception frame from
* depends on bits in the magic exception return type value (and
* for v8M isn't necessarily the stack pointer we will eventually
* end up resuming execution with). Get a pointer to the location
v7m_stack_read(cpu, &xpsr, frameptr + 0x1c, mmu_idx);
if (!pop_ok) {
- /* v7m_stack_read() pended a fault, so take it (as a tail
+ /*
+ * v7m_stack_read() pended a fault, so take it (as a tail
* chained exception on the same stack frame)
*/
qemu_log_mask(CPU_LOG_INT, "...derived exception on unstacking\n");
return;
}
- /* Returning from an exception with a PC with bit 0 set is defined
+ /*
+ * Returning from an exception with a PC with bit 0 set is defined
* behaviour on v8M (bit 0 is ignored), but for v7M it was specified
* to be UNPREDICTABLE. In practice actual v7M hardware seems to ignore
* the lsbit, and there are several RTOSes out there which incorrectly
}
if (arm_feature(env, ARM_FEATURE_V8)) {
- /* For v8M we have to check whether the xPSR exception field
+ /*
+ * For v8M we have to check whether the xPSR exception field
* matches the EXCRET value for return to handler/thread
* before we commit to changing the SP and xPSR.
*/
bool will_be_handler = (xpsr & XPSR_EXCP) != 0;
if (return_to_handler != will_be_handler) {
- /* Take an INVPC UsageFault on the current stack.
+ /*
+ * Take an INVPC UsageFault on the current stack.
* By this point we will have switched to the security state
* for the background state, so this UsageFault will target
* that state.
frameptr += 0x40;
}
}
- /* Undo stack alignment (the SPREALIGN bit indicates that the original
+ /*
+ * Undo stack alignment (the SPREALIGN bit indicates that the original
* pre-exception SP was not 8-aligned and we added a padding word to
* align it, so we undo this by ORing in the bit that increases it
* from the current 8-aligned value to the 8-unaligned value. (Adding 4
V7M_CONTROL, SFPA, sfpa);
}
- /* The restored xPSR exception field will be zero if we're
+ /*
+ * The restored xPSR exception field will be zero if we're
* resuming in Thread mode. If that doesn't match what the
* exception return excret specified then this is a UsageFault.
* v7M requires we make this check here; v8M did it earlier.
*/
if (return_to_handler != arm_v7m_is_handler_mode(env)) {
- /* Take an INVPC UsageFault by pushing the stack again;
+ /*
+ * Take an INVPC UsageFault by pushing the stack again;
* we know we're v7M so this is never a Secure UsageFault.
*/
bool ignore_stackfaults;
static bool do_v7m_function_return(ARMCPU *cpu)
{
- /* v8M security extensions magic function return.
+ /*
+ * v8M security extensions magic function return.
* We may either:
* (1) throw an exception (longjump)
* (2) return true if we successfully handled the function return
frame_sp_p = get_v7m_sp_ptr(env, true, threadmode, spsel);
frameptr = *frame_sp_p;
- /* These loads may throw an exception (for MPU faults). We want to
+ /*
+ * These loads may throw an exception (for MPU faults). We want to
* do them as secure, so work out what MMU index that is.
*/
mmu_idx = arm_v7m_mmu_idx_for_secstate(env, true);
return true;
}
-static void arm_log_exception(int idx)
-{
- if (qemu_loglevel_mask(CPU_LOG_INT)) {
- const char *exc = NULL;
- static const char * const excnames[] = {
- [EXCP_UDEF] = "Undefined Instruction",
- [EXCP_SWI] = "SVC",
- [EXCP_PREFETCH_ABORT] = "Prefetch Abort",
- [EXCP_DATA_ABORT] = "Data Abort",
- [EXCP_IRQ] = "IRQ",
- [EXCP_FIQ] = "FIQ",
- [EXCP_BKPT] = "Breakpoint",
- [EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit",
- [EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage",
- [EXCP_HVC] = "Hypervisor Call",
- [EXCP_HYP_TRAP] = "Hypervisor Trap",
- [EXCP_SMC] = "Secure Monitor Call",
- [EXCP_VIRQ] = "Virtual IRQ",
- [EXCP_VFIQ] = "Virtual FIQ",
- [EXCP_SEMIHOST] = "Semihosting call",
- [EXCP_NOCP] = "v7M NOCP UsageFault",
- [EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
- [EXCP_STKOF] = "v8M STKOF UsageFault",
- [EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
- [EXCP_LSERR] = "v8M LSERR UsageFault",
- [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
- };
-
- if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
- exc = excnames[idx];
- }
- if (!exc) {
- exc = "unknown";
- }
- qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc);
- }
-}
-
static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
uint32_t addr, uint16_t *insn)
{
- /* Load a 16-bit portion of a v7M instruction, returning true on success,
+ /*
+ * Load a 16-bit portion of a v7M instruction, returning true on success,
* or false on failure (in which case we will have pended the appropriate
* exception).
* We need to do the instruction fetch's MPU and SAU checks
v8m_security_lookup(env, addr, MMU_INST_FETCH, mmu_idx, &sattrs);
if (!sattrs.nsc || sattrs.ns) {
- /* This must be the second half of the insn, and it straddles a
+ /*
+ * This must be the second half of the insn, and it straddles a
* region boundary with the second half not being S&NSC.
*/
env->v7m.sfsr |= R_V7M_SFSR_INVEP_MASK;
static bool v7m_handle_execute_nsc(ARMCPU *cpu)
{
- /* Check whether this attempt to execute code in a Secure & NS-Callable
+ /*
+ * Check whether this attempt to execute code in a Secure & NS-Callable
* memory region is for an SG instruction; if so, then emulate the
* effect of the SG instruction and return true. Otherwise pend
* the correct kind of exception and return false.
ARMMMUIdx mmu_idx;
uint16_t insn;
- /* We should never get here unless get_phys_addr_pmsav8() caused
+ /*
+ * We should never get here unless get_phys_addr_pmsav8() caused
* an exception for NS executing in S&NSC memory.
*/
assert(!env->v7m.secure);
}
if (insn != 0xe97f) {
- /* Not an SG instruction first half (we choose the IMPDEF
+ /*
+ * Not an SG instruction first half (we choose the IMPDEF
* early-SG-check option).
*/
goto gen_invep;
}
if (insn != 0xe97f) {
- /* Not an SG instruction second half (yes, both halves of the SG
+ /*
+ * Not an SG instruction second half (yes, both halves of the SG
* insn have the same hex value)
*/
goto gen_invep;
}
- /* OK, we have confirmed that we really have an SG instruction.
+ /*
+ * OK, we have confirmed that we really have an SG instruction.
* We know we're NS in S memory so don't need to repeat those checks.
*/
qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
arm_log_exception(cs->exception_index);
- /* For exceptions we just mark as pending on the NVIC, and let that
- handle it. */
+ /*
+ * For exceptions we just mark as pending on the NVIC, and let that
+ * handle it.
+ */
switch (cs->exception_index) {
case EXCP_UDEF:
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
break;
case EXCP_PREFETCH_ABORT:
case EXCP_DATA_ABORT:
- /* Note that for M profile we don't have a guest facing FSR, but
+ /*
+ * Note that for M profile we don't have a guest facing FSR, but
* the env->exception.fsr will be populated by the code that
* raises the fault, in the A profile short-descriptor format.
*/
switch (env->exception.fsr & 0xf) {
case M_FAKE_FSR_NSC_EXEC:
- /* Exception generated when we try to execute code at an address
+ /*
+ * Exception generated when we try to execute code at an address
* which is marked as Secure & Non-Secure Callable and the CPU
* is in the Non-Secure state. The only instruction which can
* be executed like this is SG (and that only if both halves of
}
break;
case M_FAKE_FSR_SFAULT:
- /* Various flavours of SecureFault for attempts to execute or
+ /*
+ * Various flavours of SecureFault for attempts to execute or
* access data in the wrong security state.
*/
switch (cs->exception_index) {
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
break;
default:
- /* All other FSR values are either MPU faults or "can't happen
+ /*
+ * All other FSR values are either MPU faults or "can't happen
* for M profile" cases.
*/
switch (cs->exception_index) {
if (arm_feature(env, ARM_FEATURE_V8)) {
lr = R_V7M_EXCRET_RES1_MASK |
R_V7M_EXCRET_DCRS_MASK;
- /* The S bit indicates whether we should return to Secure
+ /*
+ * The S bit indicates whether we should return to Secure
* or NonSecure (ie our current state).
* The ES bit indicates whether we're taking this exception
* to Secure or NonSecure (ie our target state). We set it
v7m_exception_taken(cpu, lr, false, ignore_stackfaults);
}
-/* Function used to synchronize QEMU's AArch64 register set with AArch32
+/*
+ * Function used to synchronize QEMU's AArch64 register set with AArch32
* register set. This is necessary when switching between AArch32 and AArch64
* execution state.
*/
env->xregs[i] = env->regs[i];
}
- /* Unless we are in FIQ mode, x8-x12 come from the user registers r8-r12.
+ /*
+ * Unless we are in FIQ mode, x8-x12 come from the user registers r8-r12.
* Otherwise, they come from the banked user regs.
*/
if (mode == ARM_CPU_MODE_FIQ) {
}
}
- /* Registers x13-x23 are the various mode SP and FP registers. Registers
+ /*
+ * Registers x13-x23 are the various mode SP and FP registers. Registers
* r13 and r14 are only copied if we are in that mode, otherwise we copy
* from the mode banked register.
*/
env->xregs[23] = env->banked_r13[bank_number(ARM_CPU_MODE_UND)];
}
- /* Registers x24-x30 are mapped to r8-r14 in FIQ mode. If we are in FIQ
+ /*
+ * Registers x24-x30 are mapped to r8-r14 in FIQ mode. If we are in FIQ
* mode, then we can copy from r8-r14. Otherwise, we copy from the
* FIQ bank for r8-r14.
*/
env->pc = env->regs[15];
}
-/* Function used to synchronize QEMU's AArch32 register set with AArch64
+/*
+ * Function used to synchronize QEMU's AArch32 register set with AArch64
* register set. This is necessary when switching between AArch32 and AArch64
* execution state.
*/
env->regs[i] = env->xregs[i];
}
- /* Unless we are in FIQ mode, r8-r12 come from the user registers x8-x12.
+ /*
+ * Unless we are in FIQ mode, r8-r12 come from the user registers x8-x12.
* Otherwise, we copy x8-x12 into the banked user regs.
*/
if (mode == ARM_CPU_MODE_FIQ) {
}
}
- /* Registers r13 & r14 depend on the current mode.
+ /*
+ * Registers r13 & r14 depend on the current mode.
* If we are in a given mode, we copy the corresponding x registers to r13
* and r14. Otherwise, we copy the x register to the banked r13 and r14
* for the mode.
} else {
env->banked_r13[bank_number(ARM_CPU_MODE_USR)] = env->xregs[13];
- /* HYP is an exception in that it does not have its own banked r14 but
+ /*
+ * HYP is an exception in that it does not have its own banked r14 but
* shares the USR r14
*/
if (mode == ARM_CPU_MODE_HYP) {
(address >= 0xe00ff000 && address <= 0xe00fffff);
}
-static void v8m_security_lookup(CPUARMState *env, uint32_t address,
+void v8m_security_lookup(CPUARMState *env, uint32_t address,
MMUAccessType access_type, ARMMMUIdx mmu_idx,
V8M_SAttributes *sattrs)
{
}
}
-static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
+bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
MMUAccessType access_type, ARMMMUIdx mmu_idx,
hwaddr *phys_ptr, MemTxAttrs *txattrs,
int *prot, bool *is_subpage,
* @fi: set to fault info if the translation fails
* @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
*/
-static bool get_phys_addr(CPUARMState *env, target_ulong address,
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
- hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
- target_ulong *page_size,
- ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
+bool get_phys_addr(CPUARMState *env, target_ulong address,
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
+ hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
+ target_ulong *page_size,
+ ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
{
if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
/* Call ourselves recursively to do the stage 1 and then stage 2
return value;
}
case 0x94: /* CONTROL_NS */
- /* We have to handle this here because unprivileged Secure code
+ /*
+ * We have to handle this here because unprivileged Secure code
* can read the NS CONTROL register.
*/
if (!env->v7m.secure) {
return env->v7m.faultmask[M_REG_NS];
case 0x98: /* SP_NS */
{
- /* This gives the non-secure SP selected based on whether we're
+ /*
+ * This gives the non-secure SP selected based on whether we're
* currently in handler mode or not, using the NS CONTROL.SPSEL.
*/
bool spsel = env->v7m.control[M_REG_NS] & R_V7M_CONTROL_SPSEL_MASK;
void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
{
- /* We're passed bits [11..0] of the instruction; extract
+ /*
+ * We're passed bits [11..0] of the instruction; extract
* SYSm and the mask bits.
* Invalid combinations of SYSm and mask are UNPREDICTABLE;
* we choose to treat them as if the mask bits were valid.
return;
case 0x98: /* SP_NS */
{
- /* This gives the non-secure SP selected based on whether we're
+ /*
+ * This gives the non-secure SP selected based on whether we're
* currently in handler mode or not, using the NS CONTROL.SPSEL.
*/
bool spsel = env->v7m.control[M_REG_NS] & R_V7M_CONTROL_SPSEL_MASK;
bool targetsec = env->v7m.secure;
bool is_subpage;
- /* Work out what the security state and privilege level we're
+ /*
+ * Work out what the security state and privilege level we're
* interested in is...
*/
if (alt) {
/* ...and then figure out which MMU index this is */
mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, targetsec, targetpriv);
- /* We know that the MPU and SAU don't care about the access type
+ /*
+ * We know that the MPU and SAU don't care about the access type
* for our purposes beyond that we don't want to claim to be
* an insn fetch, so we arbitrarily call this a read.
*/
- /* MPU region info only available for privileged or if
+ /*
+ * MPU region info only available for privileged or if
* inspecting the other MPU state.
*/
if (arm_current_el(env) != 0 || alt) {
#endif
-bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
- ARMCPU *cpu = ARM_CPU(cs);
-
-#ifdef CONFIG_USER_ONLY
- cpu->env.exception.vaddress = address;
- if (access_type == MMU_INST_FETCH) {
- cs->exception_index = EXCP_PREFETCH_ABORT;
- } else {
- cs->exception_index = EXCP_DATA_ABORT;
- }
- cpu_loop_exit_restore(cs, retaddr);
-#else
- hwaddr phys_addr;
- target_ulong page_size;
- int prot, ret;
- MemTxAttrs attrs = {};
- ARMMMUFaultInfo fi = {};
-
- /*
- * Walk the page table and (if the mapping exists) add the page
- * to the TLB. On success, return true. Otherwise, if probing,
- * return false. Otherwise populate fsr with ARM DFSR/IFSR fault
- * register format, and signal the fault.
- */
- ret = get_phys_addr(&cpu->env, address, access_type,
- core_to_arm_mmu_idx(&cpu->env, mmu_idx),
- &phys_addr, &attrs, &prot, &page_size, &fi, NULL);
- if (likely(!ret)) {
- /*
- * Map a single [sub]page. Regions smaller than our declared
- * target page size are handled specially, so for those we
- * pass in the exact addresses.
- */
- if (page_size >= TARGET_PAGE_SIZE) {
- phys_addr &= TARGET_PAGE_MASK;
- address &= TARGET_PAGE_MASK;
- }
- tlb_set_page_with_attrs(cs, address, phys_addr, attrs,
- prot, mmu_idx, page_size);
- return true;
- } else if (probe) {
- return false;
- } else {
- /* now we have a real cpu fault */
- cpu_restore_state(cs, retaddr, true);
- arm_deliver_fault(cpu, address, access_type, mmu_idx, &fi);
- }
-#endif
-}
-
-void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
-{
- /* Implement DC ZVA, which zeroes a fixed-length block of memory.
- * Note that we do not implement the (architecturally mandated)
- * alignment fault for attempts to use this on Device memory
- * (which matches the usual QEMU behaviour of not implementing either
- * alignment faults or any memory attribute handling).
- */
-
- ARMCPU *cpu = env_archcpu(env);
- uint64_t blocklen = 4 << cpu->dcz_blocksize;
- uint64_t vaddr = vaddr_in & ~(blocklen - 1);
-
-#ifndef CONFIG_USER_ONLY
- {
- /* Slightly awkwardly, QEMU's TARGET_PAGE_SIZE may be less than
- * the block size so we might have to do more than one TLB lookup.
- * We know that in fact for any v8 CPU the page size is at least 4K
- * and the block size must be 2K or less, but TARGET_PAGE_SIZE is only
- * 1K as an artefact of legacy v5 subpage support being present in the
- * same QEMU executable. So in practice the hostaddr[] array has
- * two entries, given the current setting of TARGET_PAGE_BITS_MIN.
- */
- int maxidx = DIV_ROUND_UP(blocklen, TARGET_PAGE_SIZE);
- void *hostaddr[DIV_ROUND_UP(2 * KiB, 1 << TARGET_PAGE_BITS_MIN)];
- int try, i;
- unsigned mmu_idx = cpu_mmu_index(env, false);
- TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
-
- assert(maxidx <= ARRAY_SIZE(hostaddr));
-
- for (try = 0; try < 2; try++) {
-
- for (i = 0; i < maxidx; i++) {
- hostaddr[i] = tlb_vaddr_to_host(env,
- vaddr + TARGET_PAGE_SIZE * i,
- 1, mmu_idx);
- if (!hostaddr[i]) {
- break;
- }
- }
- if (i == maxidx) {
- /* If it's all in the TLB it's fair game for just writing to;
- * we know we don't need to update dirty status, etc.
- */
- for (i = 0; i < maxidx - 1; i++) {
- memset(hostaddr[i], 0, TARGET_PAGE_SIZE);
- }
- memset(hostaddr[i], 0, blocklen - (i * TARGET_PAGE_SIZE));
- return;
- }
- /* OK, try a store and see if we can populate the tlb. This
- * might cause an exception if the memory isn't writable,
- * in which case we will longjmp out of here. We must for
- * this purpose use the actual register value passed to us
- * so that we get the fault address right.
- */
- helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETPC());
- /* Now we can populate the other TLB entries, if any */
- for (i = 0; i < maxidx; i++) {
- uint64_t va = vaddr + TARGET_PAGE_SIZE * i;
- if (va != (vaddr_in & TARGET_PAGE_MASK)) {
- helper_ret_stb_mmu(env, va, 0, oi, GETPC());
- }
- }
- }
-
- /* Slow path (probably attempt to do this to an I/O device or
- * similar, or clearing of a block of code we have translations
- * cached for). Just do a series of byte writes as the architecture
- * demands. It's not worth trying to use a cpu_physical_memory_map(),
- * memset(), unmap() sequence here because:
- * + we'd need to account for the blocksize being larger than a page
- * + the direct-RAM access case is almost always going to be dealt
- * with in the fastpath code above, so there's no speed benefit
- * + we would have to deal with the map returning NULL because the
- * bounce buffer was in use
- */
- for (i = 0; i < blocklen; i++) {
- helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETPC());
- }
- }
-#else
- memset(g2h(vaddr), 0, blocklen);
-#endif
-}
-
/* Note that signed overflow is undefined in C. The following routines are
careful to use unsigned types where modulo arithmetic is required.
Failure to do so _will_ break on newer gcc. */
/* Callback function for when a watchpoint or breakpoint triggers. */
void arm_debug_excp_handler(CPUState *cs);
-#ifdef CONFIG_USER_ONLY
+#if defined(CONFIG_USER_ONLY) || !defined(CONFIG_TCG)
static inline bool arm_is_psci_call(ARMCPU *cpu, int excp_type)
{
return false;
}
+static inline void arm_handle_psci_call(ARMCPU *cpu)
+{
+ g_assert_not_reached();
+}
#else
/* Return true if the r0/x0 value indicates that this SMC/HVC is a PSCI call. */
bool arm_is_psci_call(ARMCPU *cpu, int excp_type);
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
-void arm_deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,
- int mmu_idx, ARMMMUFaultInfo *fi) QEMU_NORETURN;
-
/* Return true if the stage 1 translation regime is using LPAE format page
* tables */
bool arm_s1_regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx);
}
}
+/**
+ * v7m_cpacr_pass:
+ * Return true if the v7M CPACR permits access to the FPU for the specified
+ * security state and privilege level.
+ */
+static inline bool v7m_cpacr_pass(CPUARMState *env,
+ bool is_secure, bool is_priv)
+{
+ switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
+ case 0:
+ case 2: /* UNPREDICTABLE: we treat like 0 */
+ return false;
+ case 1:
+ return is_priv;
+ case 3:
+ return true;
+ default:
+ g_assert_not_reached();
+ }
+}
+
/**
* aarch32_mode_name(): Return name of the AArch32 CPU mode
* @psr: Program Status Register indicating CPU mode
return target_el;
}
+#ifndef CONFIG_USER_ONLY
+
+/* Security attributes for an address, as returned by v8m_security_lookup. */
+typedef struct V8M_SAttributes {
+ bool subpage; /* true if these attrs don't cover the whole TARGET_PAGE */
+ bool ns;
+ bool nsc;
+ uint8_t sregion;
+ bool srvalid;
+ uint8_t iregion;
+ bool irvalid;
+} V8M_SAttributes;
+
+void v8m_security_lookup(CPUARMState *env, uint32_t address,
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
+ V8M_SAttributes *sattrs);
+
+bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
+ hwaddr *phys_ptr, MemTxAttrs *txattrs,
+ int *prot, bool *is_subpage,
+ ARMMMUFaultInfo *fi, uint32_t *mregion);
+
+/* Cacheability and shareability attributes for a memory access */
+typedef struct ARMCacheAttrs {
+ unsigned int attrs:8; /* as in the MAIR register encoding */
+ unsigned int shareability:2; /* as in the SH field of the VMSAv8-64 PTEs */
+} ARMCacheAttrs;
+
+bool get_phys_addr(CPUARMState *env, target_ulong address,
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
+ hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
+ target_ulong *page_size,
+ ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
+
+void arm_log_exception(int idx);
+
+#endif /* !CONFIG_USER_ONLY */
+
#endif
#include "qemu/osdep.h"
#include "hw/boards.h"
#include "kvm_arm.h"
-#include "qapi/qapi-commands-target.h"
+#include "qapi/qapi-commands-misc-target.h"
static GICCapability *gic_cap_new(int version)
{
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
+#include "qemu/units.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "cpu.h"
return val;
}
-#if !defined(CONFIG_USER_ONLY)
-
-static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
- unsigned int target_el,
- bool same_el, bool ea,
- bool s1ptw, bool is_write,
- int fsc)
-{
- uint32_t syn;
-
- /* ISV is only set for data aborts routed to EL2 and
- * never for stage-1 page table walks faulting on stage 2.
- *
- * Furthermore, ISV is only set for certain kinds of load/stores.
- * If the template syndrome does not have ISV set, we should leave
- * it cleared.
- *
- * See ARMv8 specs, D7-1974:
- * ISS encoding for an exception from a Data Abort, the
- * ISV field.
- */
- if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) {
- syn = syn_data_abort_no_iss(same_el,
- ea, 0, s1ptw, is_write, fsc);
- } else {
- /* Fields: IL, ISV, SAS, SSE, SRT, SF and AR come from the template
- * syndrome created at translation time.
- * Now we create the runtime syndrome with the remaining fields.
- */
- syn = syn_data_abort_with_iss(same_el,
- 0, 0, 0, 0, 0,
- ea, 0, s1ptw, is_write, fsc,
- false);
- /* Merge the runtime syndrome with the template syndrome. */
- syn |= template_syn;
- }
- return syn;
-}
-
-void arm_deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,
- int mmu_idx, ARMMMUFaultInfo *fi)
-{
- CPUARMState *env = &cpu->env;
- int target_el;
- bool same_el;
- uint32_t syn, exc, fsr, fsc;
- ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
-
- target_el = exception_target_el(env);
- if (fi->stage2) {
- target_el = 2;
- env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
- }
- same_el = (arm_current_el(env) == target_el);
-
- if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
- arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
- /* LPAE format fault status register : bottom 6 bits are
- * status code in the same form as needed for syndrome
- */
- fsr = arm_fi_to_lfsc(fi);
- fsc = extract32(fsr, 0, 6);
- } else {
- fsr = arm_fi_to_sfsc(fi);
- /* Short format FSR : this fault will never actually be reported
- * to an EL that uses a syndrome register. Use a (currently)
- * reserved FSR code in case the constructed syndrome does leak
- * into the guest somehow.
- */
- fsc = 0x3f;
- }
-
- if (access_type == MMU_INST_FETCH) {
- syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc);
- exc = EXCP_PREFETCH_ABORT;
- } else {
- syn = merge_syn_data_abort(env->exception.syndrome, target_el,
- same_el, fi->ea, fi->s1ptw,
- access_type == MMU_DATA_STORE,
- fsc);
- if (access_type == MMU_DATA_STORE
- && arm_feature(env, ARM_FEATURE_V6)) {
- fsr |= (1 << 11);
- }
- exc = EXCP_DATA_ABORT;
- }
-
- env->exception.vaddress = addr;
- env->exception.fsr = fsr;
- raise_exception(env, exc, syn, target_el);
-}
-
-/* Raise a data fault alignment exception for the specified virtual address */
-void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
- MMUAccessType access_type,
- int mmu_idx, uintptr_t retaddr)
-{
- ARMCPU *cpu = ARM_CPU(cs);
- ARMMMUFaultInfo fi = {};
-
- /* now we have a real cpu fault */
- cpu_restore_state(cs, retaddr, true);
-
- fi.type = ARMFault_Alignment;
- arm_deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi);
-}
-
-/* arm_cpu_do_transaction_failed: handle a memory system error response
- * (eg "no device/memory present at address") by raising an external abort
- * exception
- */
-void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
- vaddr addr, unsigned size,
- MMUAccessType access_type,
- int mmu_idx, MemTxAttrs attrs,
- MemTxResult response, uintptr_t retaddr)
-{
- ARMCPU *cpu = ARM_CPU(cs);
- ARMMMUFaultInfo fi = {};
-
- /* now we have a real cpu fault */
- cpu_restore_state(cs, retaddr, true);
-
- fi.ea = arm_extabort_type(response);
- fi.type = ARMFault_SyncExternal;
- arm_deliver_fault(cpu, addr, access_type, mmu_idx, &fi);
-}
-
-#endif /* !defined(CONFIG_USER_ONLY) */
-
void HELPER(v8m_stackcheck)(CPUARMState *env, uint32_t newvalue)
{
/*
int bt;
uint32_t contextidr;
- /* Links to unimplemented or non-context aware breakpoints are
+ /*
+ * Links to unimplemented or non-context aware breakpoints are
* CONSTRAINED UNPREDICTABLE: either behave as if disabled, or
* as if linked to an UNKNOWN context-aware breakpoint (in which
* case DBGWCR<n>_EL1.LBN must indicate that breakpoint).
bt = extract64(bcr, 20, 4);
- /* We match the whole register even if this is AArch32 using the
+ /*
+ * We match the whole register even if this is AArch32 using the
* short descriptor format (in which case it holds both PROCID and ASID),
* since we don't implement the optional v7 context ID masking.
*/
case 9: /* linked VMID match (reserved if no EL2) */
case 11: /* linked context ID and VMID match (reserved if no EL2) */
default:
- /* Links to Unlinked context breakpoints must generate no
+ /*
+ * Links to Unlinked context breakpoints must generate no
* events; we choose to do the same for reserved values too.
*/
return false;
CPUARMState *env = &cpu->env;
uint64_t cr;
int pac, hmc, ssc, wt, lbn;
- /* Note that for watchpoints the check is against the CPU security
+ /*
+ * Note that for watchpoints the check is against the CPU security
* state, not the S/NS attribute on the offending data access.
*/
bool is_secure = arm_is_secure(env);
}
cr = env->cp15.dbgwcr[n];
if (wp->hitattrs.user) {
- /* The LDRT/STRT/LDT/STT "unprivileged access" instructions should
+ /*
+ * The LDRT/STRT/LDT/STT "unprivileged access" instructions should
* match watchpoints as if they were accesses done at EL0, even if
* the CPU is at EL1 or higher.
*/
}
cr = env->cp15.dbgbcr[n];
}
- /* The WATCHPOINT_HIT flag guarantees us that the watchpoint is
+ /*
+ * The WATCHPOINT_HIT flag guarantees us that the watchpoint is
* enabled and that the address and access type match; for breakpoints
* we know the address matched; check the remaining fields, including
* linked breakpoints. We rely on WCR and BCR having the same layout
CPUARMState *env = &cpu->env;
int n;
- /* If watchpoints are disabled globally or we can't take debug
+ /*
+ * If watchpoints are disabled globally or we can't take debug
* exceptions here then watchpoint firings are ignored.
*/
if (extract32(env->cp15.mdscr_el1, 15, 1) == 0
CPUARMState *env = &cpu->env;
int n;
- /* If breakpoints are disabled globally or we can't take debug
+ /*
+ * If breakpoints are disabled globally or we can't take debug
* exceptions here then breakpoint firings are ignored.
*/
if (extract32(env->cp15.mdscr_el1, 15, 1) == 0
bool arm_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
{
- /* Called by core code when a CPU watchpoint fires; need to check if this
+ /*
+ * Called by core code when a CPU watchpoint fires; need to check if this
* is also an architectural watchpoint match.
*/
ARMCPU *cpu = ARM_CPU(cs);
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
- /* In BE32 system mode, target memory is stored byteswapped (on a
+ /*
+ * In BE32 system mode, target memory is stored byteswapped (on a
* little-endian host system), and by the time we reach here (via an
* opcode helper) the addresses of subword accesses have been adjusted
* to account for that, which means that watchpoints will not match.
void arm_debug_excp_handler(CPUState *cs)
{
- /* Called by core code when a watchpoint or breakpoint fires;
+ /*
+ * Called by core code when a watchpoint or breakpoint fires;
* need to check which one and raise the appropriate exception.
*/
ARMCPU *cpu = ARM_CPU(cs);
uint64_t pc = is_a64(env) ? env->pc : env->regs[15];
bool same_el = (arm_debug_target_el(env) == arm_current_el(env));
- /* (1) GDB breakpoints should be handled first.
+ /*
+ * (1) GDB breakpoints should be handled first.
* (2) Do not raise a CPU exception if no CPU breakpoint has fired,
* since singlestep is also done by generating a debug internal
* exception.
}
env->exception.fsr = arm_debug_exception_fsr(env);
- /* FAR is UNKNOWN: clear vaddress to avoid potentially exposing
+ /*
+ * FAR is UNKNOWN: clear vaddress to avoid potentially exposing
* values to the guest that it shouldn't be able to see at its
* exception/security level.
*/
return ((uint32_t)x >> shift) | (x << (32 - shift));
}
}
+
+void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
+{
+ /*
+ * Implement DC ZVA, which zeroes a fixed-length block of memory.
+ * Note that we do not implement the (architecturally mandated)
+ * alignment fault for attempts to use this on Device memory
+ * (which matches the usual QEMU behaviour of not implementing either
+ * alignment faults or any memory attribute handling).
+ */
+
+ ARMCPU *cpu = env_archcpu(env);
+ uint64_t blocklen = 4 << cpu->dcz_blocksize;
+ uint64_t vaddr = vaddr_in & ~(blocklen - 1);
+
+#ifndef CONFIG_USER_ONLY
+ {
+ /*
+ * Slightly awkwardly, QEMU's TARGET_PAGE_SIZE may be less than
+ * the block size so we might have to do more than one TLB lookup.
+ * We know that in fact for any v8 CPU the page size is at least 4K
+ * and the block size must be 2K or less, but TARGET_PAGE_SIZE is only
+ * 1K as an artefact of legacy v5 subpage support being present in the
+ * same QEMU executable. So in practice the hostaddr[] array has
+ * two entries, given the current setting of TARGET_PAGE_BITS_MIN.
+ */
+ int maxidx = DIV_ROUND_UP(blocklen, TARGET_PAGE_SIZE);
+ void *hostaddr[DIV_ROUND_UP(2 * KiB, 1 << TARGET_PAGE_BITS_MIN)];
+ int try, i;
+ unsigned mmu_idx = cpu_mmu_index(env, false);
+ TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
+
+ assert(maxidx <= ARRAY_SIZE(hostaddr));
+
+ for (try = 0; try < 2; try++) {
+
+ for (i = 0; i < maxidx; i++) {
+ hostaddr[i] = tlb_vaddr_to_host(env,
+ vaddr + TARGET_PAGE_SIZE * i,
+ 1, mmu_idx);
+ if (!hostaddr[i]) {
+ break;
+ }
+ }
+ if (i == maxidx) {
+ /*
+ * If it's all in the TLB it's fair game for just writing to;
+ * we know we don't need to update dirty status, etc.
+ */
+ for (i = 0; i < maxidx - 1; i++) {
+ memset(hostaddr[i], 0, TARGET_PAGE_SIZE);
+ }
+ memset(hostaddr[i], 0, blocklen - (i * TARGET_PAGE_SIZE));
+ return;
+ }
+ /*
+ * OK, try a store and see if we can populate the tlb. This
+ * might cause an exception if the memory isn't writable,
+ * in which case we will longjmp out of here. We must for
+ * this purpose use the actual register value passed to us
+ * so that we get the fault address right.
+ */
+ helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETPC());
+ /* Now we can populate the other TLB entries, if any */
+ for (i = 0; i < maxidx; i++) {
+ uint64_t va = vaddr + TARGET_PAGE_SIZE * i;
+ if (va != (vaddr_in & TARGET_PAGE_MASK)) {
+ helper_ret_stb_mmu(env, va, 0, oi, GETPC());
+ }
+ }
+ }
+
+ /*
+ * Slow path (probably attempt to do this to an I/O device or
+ * similar, or clearing of a block of code we have translations
+ * cached for). Just do a series of byte writes as the architecture
+ * demands. It's not worth trying to use a cpu_physical_memory_map(),
+ * memset(), unmap() sequence here because:
+ * + we'd need to account for the blocksize being larger than a page
+ * + the direct-RAM access case is almost always going to be dealt
+ * with in the fastpath code above, so there's no speed benefit
+ * + we would have to deal with the map returning NULL because the
+ * bounce buffer was in use
+ */
+ for (i = 0; i < blocklen; i++) {
+ helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETPC());
+ }
+ }
+#else
+ memset(g2h(vaddr), 0, blocklen);
+#endif
+}
--- /dev/null
+/*
+ * ARM TLB (Translation lookaside buffer) helpers.
+ *
+ * This code is licensed under the GNU GPL v2 or later.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "internals.h"
+#include "exec/exec-all.h"
+
+#if !defined(CONFIG_USER_ONLY)
+
+static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
+ unsigned int target_el,
+ bool same_el, bool ea,
+ bool s1ptw, bool is_write,
+ int fsc)
+{
+ uint32_t syn;
+
+ /*
+ * ISV is only set for data aborts routed to EL2 and
+ * never for stage-1 page table walks faulting on stage 2.
+ *
+ * Furthermore, ISV is only set for certain kinds of load/stores.
+ * If the template syndrome does not have ISV set, we should leave
+ * it cleared.
+ *
+ * See ARMv8 specs, D7-1974:
+ * ISS encoding for an exception from a Data Abort, the
+ * ISV field.
+ */
+ if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) {
+ syn = syn_data_abort_no_iss(same_el,
+ ea, 0, s1ptw, is_write, fsc);
+ } else {
+ /*
+ * Fields: IL, ISV, SAS, SSE, SRT, SF and AR come from the template
+ * syndrome created at translation time.
+ * Now we create the runtime syndrome with the remaining fields.
+ */
+ syn = syn_data_abort_with_iss(same_el,
+ 0, 0, 0, 0, 0,
+ ea, 0, s1ptw, is_write, fsc,
+ false);
+ /* Merge the runtime syndrome with the template syndrome. */
+ syn |= template_syn;
+ }
+ return syn;
+}
+
+static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
+ MMUAccessType access_type,
+ int mmu_idx, ARMMMUFaultInfo *fi)
+{
+ CPUARMState *env = &cpu->env;
+ int target_el;
+ bool same_el;
+ uint32_t syn, exc, fsr, fsc;
+ ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
+
+ target_el = exception_target_el(env);
+ if (fi->stage2) {
+ target_el = 2;
+ env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
+ }
+ same_el = (arm_current_el(env) == target_el);
+
+ if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
+ arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
+ /*
+ * LPAE format fault status register : bottom 6 bits are
+ * status code in the same form as needed for syndrome
+ */
+ fsr = arm_fi_to_lfsc(fi);
+ fsc = extract32(fsr, 0, 6);
+ } else {
+ fsr = arm_fi_to_sfsc(fi);
+ /*
+ * Short format FSR : this fault will never actually be reported
+ * to an EL that uses a syndrome register. Use a (currently)
+ * reserved FSR code in case the constructed syndrome does leak
+ * into the guest somehow.
+ */
+ fsc = 0x3f;
+ }
+
+ if (access_type == MMU_INST_FETCH) {
+ syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc);
+ exc = EXCP_PREFETCH_ABORT;
+ } else {
+ syn = merge_syn_data_abort(env->exception.syndrome, target_el,
+ same_el, fi->ea, fi->s1ptw,
+ access_type == MMU_DATA_STORE,
+ fsc);
+ if (access_type == MMU_DATA_STORE
+ && arm_feature(env, ARM_FEATURE_V6)) {
+ fsr |= (1 << 11);
+ }
+ exc = EXCP_DATA_ABORT;
+ }
+
+ env->exception.vaddress = addr;
+ env->exception.fsr = fsr;
+ raise_exception(env, exc, syn, target_el);
+}
+
+/* Raise a data fault alignment exception for the specified virtual address */
+void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
+ MMUAccessType access_type,
+ int mmu_idx, uintptr_t retaddr)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ ARMMMUFaultInfo fi = {};
+
+ /* now we have a real cpu fault */
+ cpu_restore_state(cs, retaddr, true);
+
+ fi.type = ARMFault_Alignment;
+ arm_deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi);
+}
+
+/*
+ * arm_cpu_do_transaction_failed: handle a memory system error response
+ * (eg "no device/memory present at address") by raising an external abort
+ * exception
+ */
+void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
+ vaddr addr, unsigned size,
+ MMUAccessType access_type,
+ int mmu_idx, MemTxAttrs attrs,
+ MemTxResult response, uintptr_t retaddr)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ ARMMMUFaultInfo fi = {};
+
+ /* now we have a real cpu fault */
+ cpu_restore_state(cs, retaddr, true);
+
+ fi.ea = arm_extabort_type(response);
+ fi.type = ARMFault_SyncExternal;
+ arm_deliver_fault(cpu, addr, access_type, mmu_idx, &fi);
+}
+
+#endif /* !defined(CONFIG_USER_ONLY) */
+
+bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+
+#ifdef CONFIG_USER_ONLY
+ cpu->env.exception.vaddress = address;
+ if (access_type == MMU_INST_FETCH) {
+ cs->exception_index = EXCP_PREFETCH_ABORT;
+ } else {
+ cs->exception_index = EXCP_DATA_ABORT;
+ }
+ cpu_loop_exit_restore(cs, retaddr);
+#else
+ hwaddr phys_addr;
+ target_ulong page_size;
+ int prot, ret;
+ MemTxAttrs attrs = {};
+ ARMMMUFaultInfo fi = {};
+
+ /*
+ * Walk the page table and (if the mapping exists) add the page
+ * to the TLB. On success, return true. Otherwise, if probing,
+ * return false. Otherwise populate fsr with ARM DFSR/IFSR fault
+ * register format, and signal the fault.
+ */
+ ret = get_phys_addr(&cpu->env, address, access_type,
+ core_to_arm_mmu_idx(&cpu->env, mmu_idx),
+ &phys_addr, &attrs, &prot, &page_size, &fi, NULL);
+ if (likely(!ret)) {
+ /*
+ * Map a single [sub]page. Regions smaller than our declared
+ * target page size are handled specially, so for those we
+ * pass in the exact addresses.
+ */
+ if (page_size >= TARGET_PAGE_SIZE) {
+ phys_addr &= TARGET_PAGE_MASK;
+ address &= TARGET_PAGE_MASK;
+ }
+ tlb_set_page_with_attrs(cs, address, phys_addr, attrs,
+ prot, mmu_idx, page_size);
+ return true;
+ } else if (probe) {
+ return false;
+ } else {
+ /* now we have a real cpu fault */
+ cpu_restore_state(cs, retaddr, true);
+ arm_deliver_fault(cpu, address, access_type, mmu_idx, &fi);
+ }
+#endif
+}
#include "translate.h"
#include "internals.h"
#include "qemu/host-utils.h"
-#include "qemu/qemu-print.h"
#include "hw/semihosting/semihost.h"
#include "exec/gen-icount.h"
s->btype = -1;
}
-void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
-{
- ARMCPU *cpu = ARM_CPU(cs);
- CPUARMState *env = &cpu->env;
- uint32_t psr = pstate_read(env);
- int i;
- int el = arm_current_el(env);
- const char *ns_status;
-
- qemu_fprintf(f, " PC=%016" PRIx64 " ", env->pc);
- for (i = 0; i < 32; i++) {
- if (i == 31) {
- qemu_fprintf(f, " SP=%016" PRIx64 "\n", env->xregs[i]);
- } else {
- qemu_fprintf(f, "X%02d=%016" PRIx64 "%s", i, env->xregs[i],
- (i + 2) % 3 ? " " : "\n");
- }
- }
-
- if (arm_feature(env, ARM_FEATURE_EL3) && el != 3) {
- ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
- } else {
- ns_status = "";
- }
- qemu_fprintf(f, "PSTATE=%08x %c%c%c%c %sEL%d%c",
- psr,
- psr & PSTATE_N ? 'N' : '-',
- psr & PSTATE_Z ? 'Z' : '-',
- psr & PSTATE_C ? 'C' : '-',
- psr & PSTATE_V ? 'V' : '-',
- ns_status,
- el,
- psr & PSTATE_SP ? 'h' : 't');
-
- if (cpu_isar_feature(aa64_bti, cpu)) {
- qemu_fprintf(f, " BTYPE=%d", (psr & PSTATE_BTYPE) >> 10);
- }
- if (!(flags & CPU_DUMP_FPU)) {
- qemu_fprintf(f, "\n");
- return;
- }
- if (fp_exception_el(env, el) != 0) {
- qemu_fprintf(f, " FPU disabled\n");
- return;
- }
- qemu_fprintf(f, " FPCR=%08x FPSR=%08x\n",
- vfp_get_fpcr(env), vfp_get_fpsr(env));
-
- if (cpu_isar_feature(aa64_sve, cpu) && sve_exception_el(env, el) == 0) {
- int j, zcr_len = sve_zcr_len_for_el(env, el);
-
- for (i = 0; i <= FFR_PRED_NUM; i++) {
- bool eol;
- if (i == FFR_PRED_NUM) {
- qemu_fprintf(f, "FFR=");
- /* It's last, so end the line. */
- eol = true;
- } else {
- qemu_fprintf(f, "P%02d=", i);
- switch (zcr_len) {
- case 0:
- eol = i % 8 == 7;
- break;
- case 1:
- eol = i % 6 == 5;
- break;
- case 2:
- case 3:
- eol = i % 3 == 2;
- break;
- default:
- /* More than one quadword per predicate. */
- eol = true;
- break;
- }
- }
- for (j = zcr_len / 4; j >= 0; j--) {
- int digits;
- if (j * 4 + 4 <= zcr_len + 1) {
- digits = 16;
- } else {
- digits = (zcr_len % 4 + 1) * 4;
- }
- qemu_fprintf(f, "%0*" PRIx64 "%s", digits,
- env->vfp.pregs[i].p[j],
- j ? ":" : eol ? "\n" : " ");
- }
- }
-
- for (i = 0; i < 32; i++) {
- if (zcr_len == 0) {
- qemu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64 "%s",
- i, env->vfp.zregs[i].d[1],
- env->vfp.zregs[i].d[0], i & 1 ? "\n" : " ");
- } else if (zcr_len == 1) {
- qemu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64
- ":%016" PRIx64 ":%016" PRIx64 "\n",
- i, env->vfp.zregs[i].d[3], env->vfp.zregs[i].d[2],
- env->vfp.zregs[i].d[1], env->vfp.zregs[i].d[0]);
- } else {
- for (j = zcr_len; j >= 0; j--) {
- bool odd = (zcr_len - j) % 2 != 0;
- if (j == zcr_len) {
- qemu_fprintf(f, "Z%02d[%x-%x]=", i, j, j - 1);
- } else if (!odd) {
- if (j > 0) {
- qemu_fprintf(f, " [%x-%x]=", j, j - 1);
- } else {
- qemu_fprintf(f, " [%x]=", j);
- }
- }
- qemu_fprintf(f, "%016" PRIx64 ":%016" PRIx64 "%s",
- env->vfp.zregs[i].d[j * 2 + 1],
- env->vfp.zregs[i].d[j * 2],
- odd || j == 0 ? "\n" : ":");
- }
- }
- }
- } else {
- for (i = 0; i < 32; i++) {
- uint64_t *q = aa64_vfp_qreg(env, i);
- qemu_fprintf(f, "Q%02d=%016" PRIx64 ":%016" PRIx64 "%s",
- i, q[1], q[0], (i & 1 ? "\n" : " "));
- }
- }
-}
-
void gen_a64_set_pc_im(uint64_t val)
{
tcg_gen_movi_i64(cpu_pc, val);
#include "tcg-op-gvec.h"
#include "qemu/log.h"
#include "qemu/bitops.h"
-#include "qemu/qemu-print.h"
#include "arm_ldst.h"
#include "hw/semihosting/semihost.h"
loaded_base = 0;
loaded_var = NULL;
n = 0;
- for(i=0;i<16;i++) {
+ for (i = 0; i < 16; i++) {
if (insn & (1 << i))
n++;
}
}
}
j = 0;
- for(i=0;i<16;i++) {
+ for (i = 0; i < 16; i++) {
if (insn & (1 << i)) {
if (is_load) {
/* load */
translator_loop(ops, &dc.base, cpu, tb, max_insns);
}
-void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
-{
- ARMCPU *cpu = ARM_CPU(cs);
- CPUARMState *env = &cpu->env;
- int i;
-
- if (is_a64(env)) {
- aarch64_cpu_dump_state(cs, f, flags);
- return;
- }
-
- for(i=0;i<16;i++) {
- qemu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
- if ((i % 4) == 3)
- qemu_fprintf(f, "\n");
- else
- qemu_fprintf(f, " ");
- }
-
- if (arm_feature(env, ARM_FEATURE_M)) {
- uint32_t xpsr = xpsr_read(env);
- const char *mode;
- const char *ns_status = "";
-
- if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
- ns_status = env->v7m.secure ? "S " : "NS ";
- }
-
- if (xpsr & XPSR_EXCP) {
- mode = "handler";
- } else {
- if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
- mode = "unpriv-thread";
- } else {
- mode = "priv-thread";
- }
- }
-
- qemu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
- xpsr,
- xpsr & XPSR_N ? 'N' : '-',
- xpsr & XPSR_Z ? 'Z' : '-',
- xpsr & XPSR_C ? 'C' : '-',
- xpsr & XPSR_V ? 'V' : '-',
- xpsr & XPSR_T ? 'T' : 'A',
- ns_status,
- mode);
- } else {
- uint32_t psr = cpsr_read(env);
- const char *ns_status = "";
-
- if (arm_feature(env, ARM_FEATURE_EL3) &&
- (psr & CPSR_M) != ARM_CPU_MODE_MON) {
- ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
- }
-
- qemu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
- psr,
- psr & CPSR_N ? 'N' : '-',
- psr & CPSR_Z ? 'Z' : '-',
- psr & CPSR_C ? 'C' : '-',
- psr & CPSR_V ? 'V' : '-',
- psr & CPSR_T ? 'T' : 'A',
- ns_status,
- aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
- }
-
- if (flags & CPU_DUMP_FPU) {
- int numvfpregs = 0;
- if (arm_feature(env, ARM_FEATURE_VFP)) {
- numvfpregs += 16;
- }
- if (arm_feature(env, ARM_FEATURE_VFP3)) {
- numvfpregs += 16;
- }
- for (i = 0; i < numvfpregs; i++) {
- uint64_t v = *aa32_vfp_dreg(env, i);
- qemu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
- i * 2, (uint32_t)v,
- i * 2 + 1, (uint32_t)(v >> 32),
- i, v);
- }
- qemu_fprintf(f, "FPSCR: %08x\n", vfp_get_fpscr(env));
- }
-}
-
void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
target_ulong *data)
{
#ifdef TARGET_AARCH64
void a64_translate_init(void);
void gen_a64_set_pc_im(uint64_t val);
-void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags);
extern const TranslatorOps aarch64_translator_ops;
#else
static inline void a64_translate_init(void)
static inline void gen_a64_set_pc_im(uint64_t val)
{
}
-
-static inline void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
-{
-}
#endif
void arm_test_cc(DisasCompare *cmp, int cc);
*/
#include "qemu/osdep.h"
-#include "qemu/log.h"
#include "cpu.h"
#include "exec/helper-proto.h"
-#include "fpu/softfloat.h"
#include "internals.h"
-
+#ifdef CONFIG_TCG
+#include "qemu/log.h"
+#include "fpu/softfloat.h"
+#endif
/* VFP support. We follow the convention used for VFP instructions:
Single precision routines have a "s" suffix, double precision a
"d" suffix. */
+#ifdef CONFIG_TCG
+
/* Convert host exception flags to vfp form. */
static inline int vfp_exceptbits_from_host(int host_bits)
{
int target_bits = 0;
- if (host_bits & float_flag_invalid)
+ if (host_bits & float_flag_invalid) {
target_bits |= 1;
- if (host_bits & float_flag_divbyzero)
+ }
+ if (host_bits & float_flag_divbyzero) {
target_bits |= 2;
- if (host_bits & float_flag_overflow)
+ }
+ if (host_bits & float_flag_overflow) {
target_bits |= 4;
- if (host_bits & (float_flag_underflow | float_flag_output_denormal))
+ }
+ if (host_bits & (float_flag_underflow | float_flag_output_denormal)) {
target_bits |= 8;
- if (host_bits & float_flag_inexact)
+ }
+ if (host_bits & float_flag_inexact) {
target_bits |= 0x10;
- if (host_bits & float_flag_input_denormal)
+ }
+ if (host_bits & float_flag_input_denormal) {
target_bits |= 0x80;
+ }
return target_bits;
}
-uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
-{
- uint32_t i, fpscr;
-
- fpscr = env->vfp.xregs[ARM_VFP_FPSCR]
- | (env->vfp.vec_len << 16)
- | (env->vfp.vec_stride << 20);
-
- i = get_float_exception_flags(&env->vfp.fp_status);
- i |= get_float_exception_flags(&env->vfp.standard_fp_status);
- /* FZ16 does not generate an input denormal exception. */
- i |= (get_float_exception_flags(&env->vfp.fp_status_f16)
- & ~float_flag_input_denormal);
- fpscr |= vfp_exceptbits_from_host(i);
-
- i = env->vfp.qc[0] | env->vfp.qc[1] | env->vfp.qc[2] | env->vfp.qc[3];
- fpscr |= i ? FPCR_QC : 0;
-
- return fpscr;
-}
-
-uint32_t vfp_get_fpscr(CPUARMState *env)
-{
- return HELPER(vfp_get_fpscr)(env);
-}
-
/* Convert vfp exception flags to target form. */
static inline int vfp_exceptbits_to_host(int target_bits)
{
int host_bits = 0;
- if (target_bits & 1)
+ if (target_bits & 1) {
host_bits |= float_flag_invalid;
- if (target_bits & 2)
+ }
+ if (target_bits & 2) {
host_bits |= float_flag_divbyzero;
- if (target_bits & 4)
+ }
+ if (target_bits & 4) {
host_bits |= float_flag_overflow;
- if (target_bits & 8)
+ }
+ if (target_bits & 8) {
host_bits |= float_flag_underflow;
- if (target_bits & 0x10)
+ }
+ if (target_bits & 0x10) {
host_bits |= float_flag_inexact;
- if (target_bits & 0x80)
+ }
+ if (target_bits & 0x80) {
host_bits |= float_flag_input_denormal;
+ }
return host_bits;
}
-void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
+static uint32_t vfp_get_fpscr_from_host(CPUARMState *env)
{
- int i;
- uint32_t changed = env->vfp.xregs[ARM_VFP_FPSCR];
-
- /* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
- if (!cpu_isar_feature(aa64_fp16, env_archcpu(env))) {
- val &= ~FPCR_FZ16;
- }
-
- if (arm_feature(env, ARM_FEATURE_M)) {
- /*
- * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
- * and also for the trapped-exception-handling bits IxE.
- */
- val &= 0xf7c0009f;
- }
+ uint32_t i;
- /*
- * We don't implement trapped exception handling, so the
- * trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
- *
- * If we exclude the exception flags, IOC|DZC|OFC|UFC|IXC|IDC
- * (which are stored in fp_status), and the other RES0 bits
- * in between, then we clear all of the low 16 bits.
- */
- env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xf7c80000;
- env->vfp.vec_len = (val >> 16) & 7;
- env->vfp.vec_stride = (val >> 20) & 3;
+ i = get_float_exception_flags(&env->vfp.fp_status);
+ i |= get_float_exception_flags(&env->vfp.standard_fp_status);
+ /* FZ16 does not generate an input denormal exception. */
+ i |= (get_float_exception_flags(&env->vfp.fp_status_f16)
+ & ~float_flag_input_denormal);
+ return vfp_exceptbits_from_host(i);
+}
- /*
- * The bit we set within fpscr_q is arbitrary; the register as a
- * whole being zero/non-zero is what counts.
- */
- env->vfp.qc[0] = val & FPCR_QC;
- env->vfp.qc[1] = 0;
- env->vfp.qc[2] = 0;
- env->vfp.qc[3] = 0;
+static void vfp_set_fpscr_to_host(CPUARMState *env, uint32_t val)
+{
+ int i;
+ uint32_t changed = env->vfp.xregs[ARM_VFP_FPSCR];
changed ^= val;
if (changed & (3 << 22)) {
set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16);
}
- /* The exception flags are ORed together when we read fpscr so we
+ /*
+ * The exception flags are ORed together when we read fpscr so we
* only need to preserve the current state in one of our
* float_status values.
*/
set_float_exception_flags(0, &env->vfp.standard_fp_status);
}
+#else
+
+static uint32_t vfp_get_fpscr_from_host(CPUARMState *env)
+{
+ return 0;
+}
+
+static void vfp_set_fpscr_to_host(CPUARMState *env, uint32_t val)
+{
+}
+
+#endif
+
+uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
+{
+ uint32_t i, fpscr;
+
+ fpscr = env->vfp.xregs[ARM_VFP_FPSCR]
+ | (env->vfp.vec_len << 16)
+ | (env->vfp.vec_stride << 20);
+
+ fpscr |= vfp_get_fpscr_from_host(env);
+
+ i = env->vfp.qc[0] | env->vfp.qc[1] | env->vfp.qc[2] | env->vfp.qc[3];
+ fpscr |= i ? FPCR_QC : 0;
+
+ return fpscr;
+}
+
+uint32_t vfp_get_fpscr(CPUARMState *env)
+{
+ return HELPER(vfp_get_fpscr)(env);
+}
+
+void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
+{
+ /* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
+ if (!cpu_isar_feature(aa64_fp16, env_archcpu(env))) {
+ val &= ~FPCR_FZ16;
+ }
+
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ /*
+ * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
+ * and also for the trapped-exception-handling bits IxE.
+ */
+ val &= 0xf7c0009f;
+ }
+
+ /*
+ * We don't implement trapped exception handling, so the
+ * trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
+ *
+ * If we exclude the exception flags, IOC|DZC|OFC|UFC|IXC|IDC
+ * (which are stored in fp_status), and the other RES0 bits
+ * in between, then we clear all of the low 16 bits.
+ */
+ env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xf7c80000;
+ env->vfp.vec_len = (val >> 16) & 7;
+ env->vfp.vec_stride = (val >> 20) & 3;
+
+ /*
+ * The bit we set within fpscr_q is arbitrary; the register as a
+ * whole being zero/non-zero is what counts.
+ */
+ env->vfp.qc[0] = val & FPCR_QC;
+ env->vfp.qc[1] = 0;
+ env->vfp.qc[2] = 0;
+ env->vfp.qc[3] = 0;
+
+ vfp_set_fpscr_to_host(env, val);
+}
+
void vfp_set_fpscr(CPUARMState *env, uint32_t val)
{
HELPER(vfp_set_fpscr)(env, val);
}
+#ifdef CONFIG_TCG
+
#define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p))
#define VFP_BINOP(name) \
{
return frint_d(f, fpst, 64);
}
+
+#endif
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "qapi/error.h"
-#include "qapi/qapi-visit-misc.h"
+#include "qapi/qapi-visit-machine.h"
#include "qapi/qapi-visit-run-state.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
#include "qapi/visitor.h"
#include "qom/qom-qobject.h"
#include "sysemu/arch_init.h"
-#include "qapi/qapi-commands-target.h"
+#include "qapi/qapi-commands-machine-target.h"
#include "standard-headers/asm-x86/kvm_para.h"
#include "cpu.h"
#include "monitor/monitor.h"
#include "monitor/hmp-target.h"
+#include "monitor/hmp.h"
#include "qapi/qmp/qdict.h"
#include "hw/i386/pc.h"
#include "sysemu/kvm.h"
#include "sysemu/sev.h"
-#include "hmp.h"
#include "qapi/error.h"
#include "sev_i386.h"
#include "qapi/qapi-commands-misc.h"
#include "sysemu/kvm.h"
#include "sysemu/sev.h"
#include "qemu/error-report.h"
-#include "qapi/qapi-commands-target.h"
+#include "qapi/qapi-commands-misc-target.h"
#define SEV_POLICY_NODBG 0x1
#define SEV_POLICY_NOKS 0x2
#define M68K_CPU_GET_CLASS(obj) \
OBJECT_GET_CLASS(M68kCPUClass, (obj), TYPE_M68K_CPU)
-/**
+/*
* M68kCPUClass:
* @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC);
m68k_set_feature(env, M68K_FEATURE_BRAL);
m68k_set_feature(env, M68K_FEATURE_CF_FPU);
- /* MAC and EMAC are mututally exclusive, so pick EMAC.
- It's mostly backwards compatible. */
+ /*
+ * MAC and EMAC are mututally exclusive, so pick EMAC.
+ * It's mostly backwards compatible.
+ */
m68k_set_feature(env, M68K_FEATURE_CF_EMAC);
m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B);
m68k_set_feature(env, M68K_FEATURE_USP);
float_status fp_status;
uint64_t mactmp;
- /* EMAC Hardware deals with 48-bit values composed of one 32-bit and
- two 8-bit parts. We store a single 64-bit value and
- rearrange/extend this when changing modes. */
+ /*
+ * EMAC Hardware deals with 48-bit values composed of one 32-bit and
+ * two 8-bit parts. We store a single 64-bit value and
+ * rearrange/extend this when changing modes.
+ */
uint64_t macc[4];
uint32_t macsr;
uint32_t mac_mask;
uint32_t features;
} CPUM68KState;
-/**
+/*
* M68kCPU:
* @env: #CPUM68KState
*
void m68k_tcg_init(void);
void m68k_cpu_init_gdb(M68kCPU *cpu);
-/* you can call this signal handler from your SIGBUS and SIGSEGV
- signal handlers to inform the virtual CPU of exceptions. non zero
- is returned if the signal was handled by the virtual CPU. */
+/*
+ * you can call this signal handler from your SIGBUS and SIGSEGV
+ * signal handlers to inform the virtual CPU of exceptions. non zero
+ * is returned if the signal was handled by the virtual CPU.
+ */
int cpu_m68k_signal_handler(int host_signum, void *pinfo,
void *puc);
uint32_t cpu_m68k_get_ccr(CPUM68KState *env);
void cpu_m68k_set_fpcr(CPUM68KState *env, uint32_t val);
-/* Instead of computing the condition codes after each m68k instruction,
+/*
+ * Instead of computing the condition codes after each m68k instruction,
* QEMU just stores one operand (called CC_SRC), the result
* (called CC_DEST) and the type of operation (called CC_OP). When the
* condition codes are needed, the condition codes can be calculated
void do_m68k_semihosting(CPUM68KState *env, int nr);
-/* There are 4 ColdFire core ISA revisions: A, A+, B and C.
- Each feature covers the subset of instructions common to the
- ISA revisions mentioned. */
+/*
+ * There are 4 ColdFire core ISA revisions: A, A+, B and C.
+ * Each feature covers the subset of instructions common to the
+ * ISA revisions mentioned.
+ */
enum m68k_features {
M68K_FEATURE_M68000,
#include "exec/cpu_ldst.h"
#include "softfloat.h"
-/* Undefined offsets may be different on various FPU.
+/*
+ * Undefined offsets may be different on various FPU.
* On 68040 they return 0.0 (floatx80_zero)
*/
void HELPER(fsincos)(CPUM68KState *env, FPReg *res0, FPReg *res1, FPReg *val)
{
floatx80 a = val->d;
- /* If res0 and res1 specify the same floating-point data register,
+ /*
+ * If res0 and res1 specify the same floating-point data register,
* the sine result is stored in the register, and the cosine
* result is discarded.
*/
} else {
switch (n) {
case 16:
- return gdb_get_reg32(mem_buf, env->sr);
+ /* SR is made of SR+CCR, CCR is many 1bit flags so uses helper */
+ return gdb_get_reg32(mem_buf, env->sr | cpu_m68k_get_ccr(env));
case 17:
return gdb_get_reg32(mem_buf, env->pc);
}
}
- /* FP registers not included here because they vary between
- ColdFire and m68k. Use XML bits for these. */
+ /*
+ * FP registers not included here because they vary between
+ * ColdFire and m68k. Use XML bits for these.
+ */
return 0;
}
}
/* MAC unit. */
-/* FIXME: The MAC unit implementation is a bit of a mess. Some helpers
- take values, others take register numbers and manipulate the contents
- in-place. */
+/*
+ * FIXME: The MAC unit implementation is a bit of a mess. Some helpers
+ * take values, others take register numbers and manipulate the contents
+ * in-place.
+ */
void HELPER(mac_move)(CPUM68KState *env, uint32_t dest, uint32_t src)
{
uint32_t mask;
if (env->macsr & MACSR_V) {
env->macsr |= MACSR_PAV0 << acc;
if (env->macsr & MACSR_OMC) {
- /* The result is saturated to 32 bits, despite overflow occurring
- at 48 bits. Seems weird, but that's what the hardware docs
- say. */
+ /*
+ * The result is saturated to 32 bits, despite overflow occurring
+ * at 48 bits. Seems weird, but that's what the hardware docs
+ * say.
+ */
result = (result >> 63) ^ 0x7fffffff;
}
}
target_ulong args = env->dregs[1];
if (put_user_u32(ret, args) ||
put_user_u32(err, args + 4)) {
- /* The m68k semihosting ABI does not provide any way to report this
+ /*
+ * The m68k semihosting ABI does not provide any way to report this
* error to the guest, so the best we can do is log it in qemu.
* It is always a guest error not to pass us a valid argument block.
*/
CPUM68KState *env = &cpu->env;
if (m68k_semi_is_fseek) {
- /* FIXME: We've already lost the high bits of the fseek
- return value. */
+ /*
+ * FIXME: We've already lost the high bits of the fseek
+ * return value.
+ */
m68k_semi_return_u64(env, ret, err);
m68k_semi_is_fseek = 0;
} else {
}
}
-/* Read the input value from the argument block; fail the semihosting
+/*
+ * Read the input value from the argument block; fail the semihosting
* call if the memory read fails.
*/
#define GET_ARG(n) do { \
}
ts->heap_limit = base + size;
}
- /* This call may happen before we have writable memory, so return
- values directly in registers. */
+ /*
+ * This call may happen before we have writable memory, so return
+ * values directly in registers.
+ */
env->dregs[1] = ts->heap_limit;
env->aregs[7] = ts->stack_base;
}
#else
- /* FIXME: This is wrong for boards where RAM does not start at
- address zero. */
+ /*
+ * FIXME: This is wrong for boards where RAM does not start at
+ * address zero.
+ */
env->dregs[1] = ram_size;
env->aregs[7] = ram_size;
#endif
if (interrupt_request & CPU_INTERRUPT_HARD
&& ((env->sr & SR_I) >> SR_I_SHIFT) < env->pending_level) {
- /* Real hardware gets the interrupt vector via an IACK cycle
- at this point. Current emulated hardware doesn't rely on
- this, so we provide/save the vector when the interrupt is
- first signalled. */
+ /*
+ * Real hardware gets the interrupt vector via an IACK cycle
+ * at this point. Current emulated hardware doesn't rely on
+ * this, so we provide/save the vector when the interrupt is
+ * first signalled.
+ */
cs->exception_index = env->pending_vector;
do_interrupt_m68k_hardirq(env);
return true;
env->cc_c = 0; /* always cleared, even if overflow */
if (quot > 0xffff) {
env->cc_v = -1;
- /* real 68040 keeps N and unset Z on overflow,
+ /*
+ * real 68040 keeps N and unset Z on overflow,
* whereas documentation says "undefined"
*/
env->cc_z = 1;
if (quot != (int16_t)quot) {
env->cc_v = -1;
/* nothing else is modified */
- /* real 68040 keeps N and unset Z on overflow,
+ /*
+ * real 68040 keeps N and unset Z on overflow,
* whereas documentation says "undefined"
*/
env->cc_z = 1;
env->cc_c = 0; /* always cleared, even if overflow */
if (quot > 0xffffffffULL) {
env->cc_v = -1;
- /* real 68040 keeps N and unset Z on overflow,
+ /*
+ * real 68040 keeps N and unset Z on overflow,
* whereas documentation says "undefined"
*/
env->cc_z = 1;
env->cc_c = 0; /* always cleared, even if overflow */
if (quot != (int32_t)quot) {
env->cc_v = -1;
- /* real 68040 keeps N and unset Z on overflow,
+ /*
+ * real 68040 keeps N and unset Z on overflow,
* whereas documentation says "undefined"
*/
env->cc_z = 1;
addr -= 1;
}
- /* Compute the number of bytes required (minus one) to
- satisfy the bitfield. */
+ /*
+ * Compute the number of bytes required (minus one) to
+ * satisfy the bitfield.
+ */
blen = (bofs + len - 1) / 8;
- /* Canonicalize the bit offset for data loaded into a 64-bit big-endian
- word. For the cases where BLEN is not a power of 2, adjust ADDR so
- that we can use the next power of two sized load without crossing a
- page boundary, unless the field itself crosses the boundary. */
+ /*
+ * Canonicalize the bit offset for data loaded into a 64-bit big-endian
+ * word. For the cases where BLEN is not a power of 2, adjust ADDR so
+ * that we can use the next power of two sized load without crossing a
+ * page boundary, unless the field itself crosses the boundary.
+ */
switch (blen) {
case 0:
bofs += 56;
struct bf_data d = bf_prep(addr, ofs, len);
uint64_t data = bf_load(env, d.addr, d.blen, ra);
- /* Put CC_N at the top of the high word; put the zero-extended value
- at the bottom of the low word. */
+ /*
+ * Put CC_N at the top of the high word; put the zero-extended value
+ * at the bottom of the low word.
+ */
data <<= d.bofs;
data >>= 64 - d.len;
data |= data << (64 - d.len);
uint64_t n = (data & mask) << d.bofs;
uint32_t ffo = helper_bfffo_reg(n >> 32, ofs, d.len);
- /* Return FFO in the low word and N in the high word.
- Note that because of MASK and the shift, the low word
- is already zero. */
+ /*
+ * Return FFO in the low word and N in the high word.
+ * Note that because of MASK and the shift, the low word
+ * is already zero.
+ */
return n | ffo;
}
void HELPER(chk)(CPUM68KState *env, int32_t val, int32_t ub)
{
- /* From the specs:
+ /*
+ * From the specs:
* X: Not affected, C,V,Z: Undefined,
* N: Set if val < 0; cleared if val > ub, undefined otherwise
* We implement here values found from a real MC68040:
void HELPER(chk2)(CPUM68KState *env, int32_t val, int32_t lb, int32_t ub)
{
- /* From the specs:
+ /*
+ * From the specs:
* X: Not affected, N,V: Undefined,
* Z: Set if val is equal to lb or ub
* C: Set if val < lb or val > ub, cleared otherwise
* the Softfloat-2a license unless specifically indicated otherwise.
*/
-/* Portions of this work are licensed under the terms of the GNU GPL,
+/*
+ * Portions of this work are licensed under the terms of the GNU GPL,
* version 2 or later. See the COPYING file in the top-level directory.
*/
return a;
}
-/*----------------------------------------------------------------------------
- | Returns the modulo remainder of the extended double-precision floating-point
- | value `a' with respect to the corresponding value `b'.
- *----------------------------------------------------------------------------*/
+/*
+ * Returns the modulo remainder of the extended double-precision floating-point
+ * value `a' with respect to the corresponding value `b'.
+ */
floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)
{
80, zSign, bExp + expDiff, aSig0, aSig1, status);
}
-/*----------------------------------------------------------------------------
- | Returns the mantissa of the extended double-precision floating-point
- | value `a'.
- *----------------------------------------------------------------------------*/
+/*
+ * Returns the mantissa of the extended double-precision floating-point
+ * value `a'.
+ */
floatx80 floatx80_getman(floatx80 a, float_status *status)
{
0x3FFF, aSig, 0, status);
}
-/*----------------------------------------------------------------------------
- | Returns the exponent of the extended double-precision floating-point
- | value `a' as an extended double-precision value.
- *----------------------------------------------------------------------------*/
+/*
+ * Returns the exponent of the extended double-precision floating-point
+ * value `a' as an extended double-precision value.
+ */
floatx80 floatx80_getexp(floatx80 a, float_status *status)
{
return int32_to_floatx80(aExp - 0x3FFF, status);
}
-/*----------------------------------------------------------------------------
- | Scales extended double-precision floating-point value in operand `a' by
- | value `b'. The function truncates the value in the second operand 'b' to
- | an integral value and adds that value to the exponent of the operand 'a'.
- | The operation performed according to the IEC/IEEE Standard for Binary
- | Floating-Point Arithmetic.
- *----------------------------------------------------------------------------*/
+/*
+ * Scales extended double-precision floating-point value in operand `a' by
+ * value `b'. The function truncates the value in the second operand 'b' to
+ * an integral value and adds that value to the exponent of the operand 'a'.
+ * The operation performed according to the IEC/IEEE Standard for Binary
+ * Floating-Point Arithmetic.
+ */
floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status)
{
aExp, aSig, 0, status);
}
-/*----------------------------------------------------------------------------
-| Algorithms for transcendental functions supported by MC68881 and MC68882
-| mathematical coprocessors. The functions are derived from FPSP library.
-*----------------------------------------------------------------------------*/
+/*
+ * Algorithms for transcendental functions supported by MC68881 and MC68882
+ * mathematical coprocessors. The functions are derived from FPSP library.
+ */
#define one_exp 0x3FFF
#define one_sig LIT64(0x8000000000000000)
-/*----------------------------------------------------------------------------
- | Function for compactifying extended double-precision floating point values.
- *----------------------------------------------------------------------------*/
+/*
+ * Function for compactifying extended double-precision floating point values.
+ */
static int32_t floatx80_make_compact(int32_t aExp, uint64_t aSig)
{
return (aExp << 16) | (aSig >> 48);
}
-/*----------------------------------------------------------------------------
- | Log base e of x plus 1
- *----------------------------------------------------------------------------*/
+/*
+ * Log base e of x plus 1
+ */
floatx80 floatx80_lognp1(floatx80 a, float_status *status)
{
}
}
-/*----------------------------------------------------------------------------
- | Log base e
- *----------------------------------------------------------------------------*/
+/*
+ * Log base e
+ */
floatx80 floatx80_logn(floatx80 a, float_status *status)
{
}
}
-/*----------------------------------------------------------------------------
- | Log base 10
- *----------------------------------------------------------------------------*/
+/*
+ * Log base 10
+ */
floatx80 floatx80_log10(floatx80 a, float_status *status)
{
return a;
}
-/*----------------------------------------------------------------------------
- | Log base 2
- *----------------------------------------------------------------------------*/
+/*
+ * Log base 2
+ */
floatx80 floatx80_log2(floatx80 a, float_status *status)
{
return a;
}
-/*----------------------------------------------------------------------------
- | e to x
- *----------------------------------------------------------------------------*/
+/*
+ * e to x
+ */
floatx80 floatx80_etox(floatx80 a, float_status *status)
{
j = n & 0x3F; /* J = N mod 64 */
m = n / 64; /* NOTE: this is really arithmetic right shift by 6 */
if (n < 0 && j) {
- /* arithmetic right shift is division and
+ /*
+ * arithmetic right shift is division and
* round towards minus infinity
*/
m--;
}
}
-/*----------------------------------------------------------------------------
- | 2 to x
- *----------------------------------------------------------------------------*/
+/*
+ * 2 to x
+ */
floatx80 floatx80_twotox(floatx80 a, float_status *status)
{
j = n & 0x3F;
l = n / 64; /* NOTE: this is really arithmetic right shift by 6 */
if (n < 0 && j) {
- /* arithmetic right shift is division and
+ /*
+ * arithmetic right shift is division and
* round towards minus infinity
*/
l--;
}
m = l / 2; /* NOTE: this is really arithmetic right shift by 1 */
if (l < 0 && (l & 1)) {
- /* arithmetic right shift is division and
+ /*
+ * arithmetic right shift is division and
* round towards minus infinity
*/
m--;
}
}
-/*----------------------------------------------------------------------------
- | 10 to x
- *----------------------------------------------------------------------------*/
+/*
+ * 10 to x
+ */
floatx80 floatx80_tentox(floatx80 a, float_status *status)
{
j = n & 0x3F;
l = n / 64; /* NOTE: this is really arithmetic right shift by 6 */
if (n < 0 && j) {
- /* arithmetic right shift is division and
+ /*
+ * arithmetic right shift is division and
* round towards minus infinity
*/
l--;
}
m = l / 2; /* NOTE: this is really arithmetic right shift by 1 */
if (l < 0 && (l & 1)) {
- /* arithmetic right shift is division and
+ /*
+ * arithmetic right shift is division and
* round towards minus infinity
*/
m--;
}
}
-/*----------------------------------------------------------------------------
- | Tangent
- *----------------------------------------------------------------------------*/
+/*
+ * Tangent
+ */
floatx80 floatx80_tan(floatx80 a, float_status *status)
{
}
}
-/*----------------------------------------------------------------------------
- | Sine
- *----------------------------------------------------------------------------*/
+/*
+ * Sine
+ */
floatx80 floatx80_sin(floatx80 a, float_status *status)
{
}
}
-/*----------------------------------------------------------------------------
- | Cosine
- *----------------------------------------------------------------------------*/
+/*
+ * Cosine
+ */
floatx80 floatx80_cos(floatx80 a, float_status *status)
{
}
}
-/*----------------------------------------------------------------------------
- | Arc tangent
- *----------------------------------------------------------------------------*/
+/*
+ * Arc tangent
+ */
floatx80 floatx80_atan(floatx80 a, float_status *status)
{
}
}
-/*----------------------------------------------------------------------------
- | Arc sine
- *----------------------------------------------------------------------------*/
+/*
+ * Arc sine
+ */
floatx80 floatx80_asin(floatx80 a, float_status *status)
{
return a;
}
-/*----------------------------------------------------------------------------
- | Arc cosine
- *----------------------------------------------------------------------------*/
+/*
+ * Arc cosine
+ */
floatx80 floatx80_acos(floatx80 a, float_status *status)
{
return a;
}
-/*----------------------------------------------------------------------------
- | Hyperbolic arc tangent
- *----------------------------------------------------------------------------*/
+/*
+ * Hyperbolic arc tangent
+ */
floatx80 floatx80_atanh(floatx80 a, float_status *status)
{
return a;
}
-/*----------------------------------------------------------------------------
- | e to x minus 1
- *----------------------------------------------------------------------------*/
+/*
+ * e to x minus 1
+ */
floatx80 floatx80_etoxm1(floatx80 a, float_status *status)
{
j = n & 0x3F; /* J = N mod 64 */
m = n / 64; /* NOTE: this is really arithmetic right shift by 6 */
if (n < 0 && j) {
- /* arithmetic right shift is division and
+ /*
+ * arithmetic right shift is division and
* round towards minus infinity
*/
m--;
}
}
-/*----------------------------------------------------------------------------
- | Hyperbolic tangent
- *----------------------------------------------------------------------------*/
+/*
+ * Hyperbolic tangent
+ */
floatx80 floatx80_tanh(floatx80 a, float_status *status)
{
}
}
-/*----------------------------------------------------------------------------
- | Hyperbolic sine
- *----------------------------------------------------------------------------*/
+/*
+ * Hyperbolic sine
+ */
floatx80 floatx80_sinh(floatx80 a, float_status *status)
{
}
}
-/*----------------------------------------------------------------------------
- | Hyperbolic cosine
- *----------------------------------------------------------------------------*/
+/*
+ * Hyperbolic cosine
+ */
floatx80 floatx80_cosh(floatx80 a, float_status *status)
{
* the Softfloat-2a license unless specifically indicated otherwise.
*/
-/* Portions of this work are licensed under the terms of the GNU GPL,
+/*
+ * Portions of this work are licensed under the terms of the GNU GPL,
* version 2 or later. See the COPYING file in the top-level directory.
*/
* the Softfloat-2a license unless specifically indicated otherwise.
*/
-/* Portions of this work are licensed under the terms of the GNU GPL,
+/*
+ * Portions of this work are licensed under the terms of the GNU GPL,
* version 2 or later. See the COPYING file in the top-level directory.
*/
s->cc_op = op;
s->cc_op_synced = 0;
- /* Discard CC computation that will no longer be used.
- Note that X and N are never dead. */
+ /*
+ * Discard CC computation that will no longer be used.
+ * Note that X and N are never dead.
+ */
dead = cc_op_live[old_op] & ~cc_op_live[op];
if (dead & CCF_C) {
tcg_gen_discard_i32(QREG_CC_C);
gen_exception(s, s->base.pc_next, EXCP_ADDRESS);
}
-/* Generate a load from the specified address. Narrow values are
- sign extended to full register width. */
+/*
+ * Generate a load from the specified address. Narrow values are
+ * sign extended to full register width.
+ */
static inline TCGv gen_load(DisasContext *s, int opsize, TCGv addr,
int sign, int index)
{
EA_LOADS
} ea_what;
-/* Generate an unsigned load if VAL is 0 a signed load if val is -1,
- otherwise generate a store. */
+/*
+ * Generate an unsigned load if VAL is 0 a signed load if val is -1,
+ * otherwise generate a store.
+ */
static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val,
ea_what what, int index)
{
return add;
}
-/* Handle a base + index + displacement effective addresss.
- A NULL_QREG base means pc-relative. */
+/*
+ * Handle a base + index + displacement effective addresss.
+ * A NULL_QREG base means pc-relative.
+ */
static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base)
{
uint32_t offset;
}
}
-/* Assign value to a register. If the width is less than the register width
- only the low part of the register is set. */
+/*
+ * Assign value to a register. If the width is less than the register width
+ * only the low part of the register is set.
+ */
static void gen_partset_reg(int opsize, TCGv reg, TCGv val)
{
TCGv tmp;
}
}
-/* Generate code for an "effective address". Does not adjust the base
- register for autoincrement addressing modes. */
+/*
+ * Generate code for an "effective address". Does not adjust the base
+ * register for autoincrement addressing modes.
+ */
static TCGv gen_lea_mode(CPUM68KState *env, DisasContext *s,
int mode, int reg0, int opsize)
{
return gen_lea_mode(env, s, mode, reg0, opsize);
}
-/* Generate code to load/store a value from/into an EA. If WHAT > 0 this is
- a write otherwise it is a read (0 == sign extend, -1 == zero extend).
- ADDRP is non-null for readwrite operands. */
+/*
+ * Generate code to load/store a value from/into an EA. If WHAT > 0 this is
+ * a write otherwise it is a read (0 == sign extend, -1 == zero extend).
+ * ADDRP is non-null for readwrite operands.
+ */
static TCGv gen_ea_mode(CPUM68KState *env, DisasContext *s, int mode, int reg0,
int opsize, TCGv val, TCGv *addrp, ea_what what,
int index)
tcg_gen_st_i64(t64, fp, offsetof(FPReg, l.lower));
break;
case OS_PACKED:
- /* unimplemented data type on 68040/ColdFire
+ /*
+ * unimplemented data type on 68040/ColdFire
* FIXME if needed for another FPU
*/
gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP);
tcg_gen_qemu_st64(t64, tmp, index);
break;
case OS_PACKED:
- /* unimplemented data type on 68040/ColdFire
+ /*
+ * unimplemented data type on 68040/ColdFire
* FIXME if needed for another FPU
*/
gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP);
tcg_temp_free_i64(t64);
break;
case OS_PACKED:
- /* unimplemented data type on 68040/ColdFire
+ /*
+ * unimplemented data type on 68040/ColdFire
* FIXME if needed for another FPU
*/
gen_exception(s, s->base.pc_next, EXCP_FP_UNIMP);
goto done;
case 14: /* GT (!(Z || (N ^ V))) */
case 15: /* LE (Z || (N ^ V)) */
- /* Logic operations clear V, which simplifies LE to (Z || N),
- and since Z and N are co-located, this becomes a normal
- comparison vs N. */
+ /*
+ * Logic operations clear V, which simplifies LE to (Z || N),
+ * and since Z and N are co-located, this becomes a normal
+ * comparison vs N.
+ */
if (op == CC_OP_LOGIC) {
c->v1 = QREG_CC_N;
tcond = TCG_COND_LE;
DISAS_INSN(undef)
{
- /* ??? This is both instructions that are as yet unimplemented
- for the 680x0 series, as well as those that are implemented
- but actually illegal for CPU32 or pre-68020. */
+ /*
+ * ??? This is both instructions that are as yet unimplemented
+ * for the 680x0 series, as well as those that are implemented
+ * but actually illegal for CPU32 or pre-68020.
+ */
qemu_log_mask(LOG_UNIMP, "Illegal instruction: %04x @ %08x\n",
insn, s->base.pc_next);
gen_exception(s, s->base.pc_next, EXCP_ILLEGAL);
{
TCGv t0, t1;
- /* dest10 = dest10 + src10 + X
+ /*
+ * dest10 = dest10 + src10 + X
*
* t1 = src
* t2 = t1 + 0x066
* return t3 - t7
*/
- /* t1 = (src + 0x066) + dest + X
+ /*
+ * t1 = (src + 0x066) + dest + X
* = result with some possible exceding 0x6
*/
/* we will remove exceding 0x6 where there is no carry */
- /* t0 = (src + 0x0066) ^ dest
+ /*
+ * t0 = (src + 0x0066) ^ dest
* = t1 without carries
*/
tcg_gen_xor_i32(t0, t0, dest);
- /* extract the carries
+ /*
+ * extract the carries
* t0 = t0 ^ t1
* = only the carries
*/
tcg_gen_xor_i32(t0, t0, t1);
- /* generate 0x1 where there is no carry
+ /*
+ * generate 0x1 where there is no carry
* and for each 0x10, generate a 0x6
*/
tcg_gen_add_i32(dest, dest, t0);
tcg_temp_free(t0);
- /* remove the exceding 0x6
+ /*
+ * remove the exceding 0x6
* for digits that have not generated a carry
*/
{
TCGv t0, t1, t2;
- /* dest10 = dest10 - src10 - X
+ /*
+ * dest10 = dest10 - src10 - X
* = bcd_add(dest + 1 - X, 0x199 - src)
*/
tcg_gen_xor_i32(t0, t1, t2);
- /* t2 = ~t0 & 0x110
+ /*
+ * t2 = ~t0 & 0x110
* t0 = (t2 >> 2) | (t2 >> 3)
*
* to fit on 8bit operands, changed in:
/* pre-decrement is not allowed */
goto do_addr_fault;
}
- /* We want a bare copy of the address reg, without any pre-decrement
- adjustment, as gen_lea would provide. */
+ /*
+ * We want a bare copy of the address reg, without any pre-decrement
+ * adjustment, as gen_lea would provide.
+ */
break;
default:
tcg_gen_sub_i32(addr, addr, incr);
if (reg0 + 8 == i &&
m68k_feature(s->env, M68K_FEATURE_EXT_FULL)) {
- /* M68020+: if the addressing register is the
+ /*
+ * M68020+: if the addressing register is the
* register moved to memory, the value written
* is the initial value decremented by the size of
* the operation, regardless of how many actual
cmp = gen_extend(s, DREG(ext, 0), opsize, 1);
- /* if <EA> == Dc then
+ /*
+ * if <EA> == Dc then
* <EA> = Du
* Dc = <EA> (because <EA> == Dc)
* else
addr2 = DREG(ext2, 12);
}
- /* if (R1) == Dc1 && (R2) == Dc2 then
+ /*
+ * if (R1) == Dc1 && (R2) == Dc2 then
* (R1) = Du1
* (R2) = Du2
* else
addr2 = DREG(ext2, 12);
}
- /* if (R1) == Dc1 && (R2) == Dc2 then
+ /*
+ * if (R1) == Dc1 && (R2) == Dc2 then
* (R1) = Du1
* (R2) = Du2
* else
gen_flush_flags(s); /* compute old Z */
- /* Perform substract with borrow.
+ /*
+ * Perform substract with borrow.
* (X, N) = -(src + X);
*/
tcg_gen_andi_i32(QREG_CC_X, QREG_CC_X, 1);
- /* Compute signed-overflow for negation. The normal formula for
+ /*
+ * Compute signed-overflow for negation. The normal formula for
* subtraction is (res ^ src) & (src ^ dest), but with dest==0
* this simplies to res & src.
*/
set_cc_op(s, CC_OP_FLAGS);
} else {
- /* The upper 32 bits of the product are discarded, so
- muls.l and mulu.l are functionally equivalent. */
+ /*
+ * The upper 32 bits of the product are discarded, so
+ * muls.l and mulu.l are functionally equivalent.
+ */
tcg_gen_mul_i32(DREG(ext, 12), src1, DREG(ext, 12));
gen_logic_cc(s, DREG(ext, 12), OS_LONG);
}
{
TCGv tmp;
- /* Load the target address first to ensure correct exception
- behavior. */
+ /*
+ * Load the target address first to ensure correct exception
+ * behavior.
+ */
tmp = gen_lea(env, s, insn, OS_LONG);
if (IS_NULL_QREG(tmp)) {
gen_addr_fault(s);
dest = tcg_temp_new();
tcg_gen_mov_i32(dest, src);
if ((insn & 0x38) == 0x08) {
- /* Don't update condition codes if the destination is an
- address register. */
+ /*
+ * Don't update condition codes if the destination is an
+ * address register.
+ */
if (insn & 0x0100) {
tcg_gen_sub_i32(dest, dest, val);
} else {
gen_flush_flags(s); /* compute old Z */
- /* Perform substract with borrow.
+ /*
+ * Perform substract with borrow.
* (X, N) = dest - (src + X);
*/
gen_flush_flags(s); /* compute old Z */
- /* Perform addition with carry.
+ /*
+ * Perform addition with carry.
* (X, N) = src + dest + X;
*/
tcg_gen_shri_i32(QREG_CC_C, reg, bits - count);
tcg_gen_shli_i32(QREG_CC_N, reg, count);
- /* Note that ColdFire always clears V (done above),
- while M68000 sets if the most significant bit is changed at
- any time during the shift operation */
+ /*
+ * Note that ColdFire always clears V (done above),
+ * while M68000 sets if the most significant bit is changed at
+ * any time during the shift operation.
+ */
if (!logical && m68k_feature(s->env, M68K_FEATURE_M68000)) {
/* if shift count >= bits, V is (reg != 0) */
if (count >= bits) {
s64 = tcg_temp_new_i64();
s32 = tcg_temp_new();
- /* Note that m68k truncates the shift count modulo 64, not 32.
- In addition, a 64-bit shift makes it easy to find "the last
- bit shifted out", for the carry flag. */
+ /*
+ * Note that m68k truncates the shift count modulo 64, not 32.
+ * In addition, a 64-bit shift makes it easy to find "the last
+ * bit shifted out", for the carry flag.
+ */
tcg_gen_andi_i32(s32, DREG(insn, 9), 63);
tcg_gen_extu_i32_i64(s64, s32);
tcg_gen_extu_i32_i64(t64, reg);
tcg_gen_movcond_i32(TCG_COND_NE, QREG_CC_X, s32, QREG_CC_V,
QREG_CC_C, QREG_CC_X);
- /* M68000 sets V if the most significant bit is changed at
+ /*
+ * M68000 sets V if the most significant bit is changed at
* any time during the shift operation. Do this via creating
* an extension of the sign bit, comparing, and discarding
* the bits below the sign bit. I.e.
tcg_gen_shri_i32(QREG_CC_C, src, 15);
tcg_gen_shli_i32(QREG_CC_N, src, 1);
- /* Note that ColdFire always clears V,
- while M68000 sets if the most significant bit is changed at
- any time during the shift operation */
+ /*
+ * Note that ColdFire always clears V,
+ * while M68000 sets if the most significant bit is changed at
+ * any time during the shift operation
+ */
if (!logical && m68k_feature(s->env, M68K_FEATURE_M68000)) {
src = gen_extend(s, src, OS_WORD, 1);
tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, src);
TCGv tmp = tcg_temp_new();
TCGv shift;
- /* In general, we're going to rotate the field so that it's at the
- top of the word and then right-shift by the complement of the
- width to extend the field. */
+ /*
+ * In general, we're going to rotate the field so that it's at the
+ * top of the word and then right-shift by the complement of the
+ * width to extend the field.
+ */
if (ext & 0x20) {
/* Variable width. */
if (ext & 0x800) {
src = tmp;
pos = 32 - len;
} else {
- /* Immediate offset. If the field doesn't wrap around the
- end of the word, rely on (s)extract completely. */
+ /*
+ * Immediate offset. If the field doesn't wrap around the
+ * end of the word, rely on (s)extract completely.
+ */
if (pos < 0) {
tcg_gen_rotli_i32(tmp, src, ofs);
src = tmp;
addr = tcg_temp_new();
tcg_gen_mov_i32(addr, tmp);
- /* mask:
+ /*
+ * mask:
*
* 0b100 Floating-Point Control Register
* 0b010 Floating-Point Status Register
}
if (!is_load && (mode & 2) == 0) {
- /* predecrement addressing mode
+ /*
+ * predecrement addressing mode
* only available to store register to memory
*/
if (opsize == OS_EXTENDED) {
tcg_temp_free(tmp);
}
-/* ??? FP exceptions are not implemented. Most exceptions are deferred until
- immediately before the next FP instruction is executed. */
+/*
+ * ??? FP exceptions are not implemented. Most exceptions are deferred until
+ * immediately before the next FP instruction is executed.
+ */
DISAS_INSN(fpu)
{
uint16_t ext;
tmp = gen_lea(env, s, insn, OS_LONG);
addr = tcg_temp_new();
tcg_gen_and_i32(addr, tmp, QREG_MAC_MASK);
- /* Load the value now to ensure correct exception behavior.
- Perform writeback after reading the MAC inputs. */
+ /*
+ * Load the value now to ensure correct exception behavior.
+ * Perform writeback after reading the MAC inputs.
+ */
loadval = gen_load(s, OS_LONG, addr, 0, IS_USER(s));
acc ^= 1;
TCGv rw;
rw = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);
tcg_gen_mov_i32(rw, loadval);
- /* FIXME: Should address writeback happen with the masked or
- unmasked value? */
+ /*
+ * FIXME: Should address writeback happen with the masked or
+ * unmasked value?
+ */
switch ((insn >> 3) & 7) {
case 3: /* Post-increment. */
tcg_gen_addi_i32(AREG(insn, 0), addr, 4);
opcode, mask);
abort();
}
- /* This could probably be cleverer. For now just optimize the case where
- the top bits are known. */
+ /*
+ * This could probably be cleverer. For now just optimize the case where
+ * the top bits are known.
+ */
/* Find the first zero bit in the mask. */
i = 0x8000;
while ((i & mask) != 0)
}
}
-/* Register m68k opcode handlers. Order is important.
- Later insn override earlier ones. */
+/*
+ * Register m68k opcode handlers. Order is important.
+ * Later insn override earlier ones.
+ */
void register_m68k_insns (CPUM68KState *env)
{
- /* Build the opcode table only once to avoid
- multithreading issues. */
+ /*
+ * Build the opcode table only once to avoid
+ * multithreading issues.
+ */
if (opcode_table[0] != NULL) {
return;
}
- /* use BASE() for instruction available
+ /*
+ * use BASE() for instruction available
* for CF_ISA_A and M68000.
*/
#define BASE(name, opcode, mask) \
DisasContext *dc = container_of(dcbase, DisasContext, base);
gen_exception(dc, dc->base.pc_next, EXCP_DEBUG);
- /* The address covered by the breakpoint must be included in
- [tb->pc, tb->pc + tb->size) in order to for it to be
- properly cleared -- thus we increment the PC here so that
- the logic setting tb->size below does the right thing. */
+ /*
+ * The address covered by the breakpoint must be included in
+ * [tb->pc, tb->pc + tb->size) in order to for it to be
+ * properly cleared -- thus we increment the PC here so that
+ * the logic setting tb->size below does the right thing.
+ */
dc->base.pc_next += 2;
return true;
dc->base.pc_next = dc->pc;
if (dc->base.is_jmp == DISAS_NEXT) {
- /* Stop translation when the next insn might touch a new page.
+ /*
+ * Stop translation when the next insn might touch a new page.
* This ensures that prefetch aborts at the right place.
*
* We cannot determine the size of the next insn without
tcg_gen_lookup_and_goto_ptr();
break;
case DISAS_EXIT:
- /* We updated CC_OP and PC in gen_exit_tb, but also modified
- other state that may require returning to the main loop. */
+ /*
+ * We updated CC_OP and PC in gen_exit_tb, but also modified
+ * other state that may require returning to the main loop.
+ */
tcg_gen_exit_tb(NULL, 0);
break;
default:
#include "exec/cpu_ldst.h"
#include "exec/log.h"
#include "hw/mips/cpudevs.h"
-#include "qapi/qapi-commands-target.h"
+#include "qapi/qapi-commands-machine-target.h"
enum {
TLBRET_XI = -6,
* --------
*
* +---------------+----------------------------------------------------------+
- * | BMNZ.V | Vector Bit Move If Not Zero |
- * | BMZ.V | Vector Bit Move If Zero |
- * | BSEL.V | Vector Bit Select |
* | BINSL.B | Vector Bit Insert Left (byte) |
* | BINSL.H | Vector Bit Insert Left (halfword) |
* | BINSL.W | Vector Bit Insert Left (word) |
* | BINSR.H | Vector Bit Insert Right (halfword) |
* | BINSR.W | Vector Bit Insert Right (word) |
* | BINSR.D | Vector Bit Insert Right (doubleword) |
+ * | BMNZ.V | Vector Bit Move If Not Zero |
+ * | BMZ.V | Vector Bit Move If Zero |
+ * | BSEL.V | Vector Bit Select |
* +---------------+----------------------------------------------------------+
*/
* | ADDV.H | Vector Add (halfword) |
* | ADDV.W | Vector Add (word) |
* | ADDV.D | Vector Add (doubleword) |
- * | HSUB_S.H | Vector Signed Horizontal Add (halfword) |
- * | HSUB_S.W | Vector Signed Horizontal Add (word) |
- * | HSUB_S.D | Vector Signed Horizontal Add (doubleword) |
- * | HSUB_U.H | Vector Unigned Horizontal Add (halfword) |
- * | HSUB_U.W | Vector Unigned Horizontal Add (word) |
- * | HSUB_U.D | Vector Unigned Horizontal Add (doubleword) |
+ * | HADD_S.H | Vector Signed Horizontal Add (halfword) |
+ * | HADD_S.W | Vector Signed Horizontal Add (word) |
+ * | HADD_S.D | Vector Signed Horizontal Add (doubleword) |
+ * | HADD_U.H | Vector Unigned Horizontal Add (halfword) |
+ * | HADD_U.W | Vector Unigned Horizontal Add (word) |
+ * | HADD_U.D | Vector Unigned Horizontal Add (doubleword) |
* +---------------+----------------------------------------------------------+
*/
* | DOTP_U.H | Vector Unsigned Dot Product (halfword) |
* | DOTP_U.W | Vector Unsigned Dot Product (word) |
* | DOTP_U.D | Vector Unsigned Dot Product (doubleword) |
+ * | DPADD_S.H | Vector Signed Dot Product (halfword) |
+ * | DPADD_S.W | Vector Signed Dot Product (word) |
+ * | DPADD_S.D | Vector Signed Dot Product (doubleword) |
+ * | DPADD_U.H | Vector Unsigned Dot Product (halfword) |
+ * | DPADD_U.W | Vector Unsigned Dot Product (word) |
+ * | DPADD_U.D | Vector Unsigned Dot Product (doubleword) |
+ * | DPSUB_S.H | Vector Signed Dot Product (halfword) |
+ * | DPSUB_S.W | Vector Signed Dot Product (word) |
+ * | DPSUB_S.D | Vector Signed Dot Product (doubleword) |
+ * | DPSUB_U.H | Vector Unsigned Dot Product (halfword) |
+ * | DPSUB_U.W | Vector Unsigned Dot Product (word) |
+ * | DPSUB_U.D | Vector Unsigned Dot Product (doubleword) |
* +---------------+----------------------------------------------------------+
*/
* | SUBS_U.H | Vector Unsigned Saturated Subtract (of Uns.) (halfword) |
* | SUBS_U.W | Vector Unsigned Saturated Subtract (of Uns.) (word) |
* | SUBS_U.D | Vector Unsigned Saturated Subtract (of Uns.) (doubleword)|
- * | SUBSUS_S.B | Vector Uns. Sat. Subtract (of S. from Uns.) (byte) |
- * | SUBSUS_S.H | Vector Uns. Sat. Subtract (of S. from Uns.) (halfword) |
- * | SUBSUS_S.W | Vector Uns. Sat. Subtract (of S. from Uns.) (word) |
- * | SUBSUS_S.D | Vector Uns. Sat. Subtract (of S. from Uns.) (doubleword) |
- * | SUBSUU_U.B | Vector Signed Saturated Subtract (of Uns.) (byte) |
- * | SUBSUU_U.H | Vector Signed Saturated Subtract (of Uns.) (halfword) |
- * | SUBSUU_U.W | Vector Signed Saturated Subtract (of Uns.) (word) |
- * | SUBSUU_U.D | Vector Signed Saturated Subtract (of Uns.) (doubleword) |
+ * | SUBSUS_U.B | Vector Uns. Sat. Subtract (of S. from Uns.) (byte) |
+ * | SUBSUS_U.H | Vector Uns. Sat. Subtract (of S. from Uns.) (halfword) |
+ * | SUBSUS_U.W | Vector Uns. Sat. Subtract (of S. from Uns.) (word) |
+ * | SUBSUS_U.D | Vector Uns. Sat. Subtract (of S. from Uns.) (doubleword) |
+ * | SUBSUU_S.B | Vector Signed Saturated Subtract (of Uns.) (byte) |
+ * | SUBSUU_S.H | Vector Signed Saturated Subtract (of Uns.) (halfword) |
+ * | SUBSUU_S.W | Vector Signed Saturated Subtract (of Uns.) (word) |
+ * | SUBSUU_S.D | Vector Signed Saturated Subtract (of Uns.) (doubleword) |
* | SUBV.B | Vector Subtract (byte) |
* | SUBV.H | Vector Subtract (halfword) |
* | SUBV.W | Vector Subtract (word) |
/* TODO: insert Logic group helpers here */
+/*
+ * Move
+ * ----
+ *
+ * +---------------+----------------------------------------------------------+
+ * | MOVE.V | Vector Move |
+ * +---------------+----------------------------------------------------------+
+ */
+
+/* TODO: insert Move group helpers here */
+
+
/*
* Pack
* ----
switch (df) {
case DF_BYTE:
-#if defined(TARGET_WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN)
pwd->b[8] = pws->b[9];
pwd->b[9] = pwt->b[9];
pwd->b[10] = pws->b[11];
#endif
break;
case DF_HALF:
-#if defined(TARGET_WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN)
pwd->h[4] = pws->h[5];
pwd->h[5] = pwt->h[5];
pwd->h[6] = pws->h[7];
#endif
break;
case DF_WORD:
-#if defined(TARGET_WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN)
pwd->w[2] = pws->w[3];
pwd->w[3] = pwt->w[3];
pwd->w[0] = pws->w[1];
switch (df) {
case DF_BYTE:
-#if defined(TARGET_WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN)
pwd->b[7] = pwt->b[6];
pwd->b[6] = pws->b[6];
pwd->b[5] = pwt->b[4];
#endif
break;
case DF_HALF:
-#if defined(TARGET_WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN)
pwd->h[3] = pwt->h[2];
pwd->h[2] = pws->h[2];
pwd->h[1] = pwt->h[0];
#endif
break;
case DF_WORD:
-#if defined(TARGET_WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN)
pwd->w[1] = pwt->w[0];
pwd->w[0] = pws->w[0];
pwd->w[3] = pwt->w[2];
switch (df) {
case DF_BYTE:
-#if defined(TARGET_WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN)
pwd->b[7] = pwt->b[15];
pwd->b[6] = pws->b[15];
pwd->b[5] = pwt->b[14];
#endif
break;
case DF_HALF:
-#if defined(TARGET_WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN)
pwd->h[3] = pwt->h[7];
pwd->h[2] = pws->h[7];
pwd->h[1] = pwt->h[6];
#endif
break;
case DF_WORD:
-#if defined(TARGET_WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN)
pwd->w[1] = pwt->w[3];
pwd->w[0] = pws->w[3];
pwd->w[3] = pwt->w[2];
switch (df) {
case DF_BYTE:
-#if defined(TARGET_WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN)
pwd->b[8] = pws->b[0];
pwd->b[9] = pwt->b[0];
pwd->b[10] = pws->b[1];
#endif
break;
case DF_HALF:
-#if defined(TARGET_WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN)
pwd->h[4] = pws->h[0];
pwd->h[5] = pwt->h[0];
pwd->h[6] = pws->h[1];
#endif
break;
case DF_WORD:
-#if defined(TARGET_WORDS_BIGENDIAN)
+#if defined(HOST_WORDS_BIGENDIAN)
pwd->w[2] = pws->w[0];
pwd->w[3] = pwt->w[0];
pwd->w[0] = pws->w[1];
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
- uint32_t i;
clear_msacsr_cause(env);
- switch (df) {
- case DF_WORD:
- for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
- if (NUMBER_QNAN_PAIR(pws->w[i], pwt->w[i], 32, status)) {
- MSA_FLOAT_MAXOP(pwx->w[i], min, pws->w[i], pws->w[i], 32);
- } else if (NUMBER_QNAN_PAIR(pwt->w[i], pws->w[i], 32, status)) {
- MSA_FLOAT_MAXOP(pwx->w[i], min, pwt->w[i], pwt->w[i], 32);
- } else {
- MSA_FLOAT_MAXOP(pwx->w[i], min, pws->w[i], pwt->w[i], 32);
- }
+ if (df == DF_WORD) {
+
+ if (NUMBER_QNAN_PAIR(pws->w[0], pwt->w[0], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[0], min, pws->w[0], pws->w[0], 32);
+ } else if (NUMBER_QNAN_PAIR(pwt->w[0], pws->w[0], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[0], min, pwt->w[0], pwt->w[0], 32);
+ } else {
+ MSA_FLOAT_MAXOP(pwx->w[0], min, pws->w[0], pwt->w[0], 32);
}
- break;
- case DF_DOUBLE:
- for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
- if (NUMBER_QNAN_PAIR(pws->d[i], pwt->d[i], 64, status)) {
- MSA_FLOAT_MAXOP(pwx->d[i], min, pws->d[i], pws->d[i], 64);
- } else if (NUMBER_QNAN_PAIR(pwt->d[i], pws->d[i], 64, status)) {
- MSA_FLOAT_MAXOP(pwx->d[i], min, pwt->d[i], pwt->d[i], 64);
- } else {
- MSA_FLOAT_MAXOP(pwx->d[i], min, pws->d[i], pwt->d[i], 64);
- }
+
+ if (NUMBER_QNAN_PAIR(pws->w[1], pwt->w[1], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[1], min, pws->w[1], pws->w[1], 32);
+ } else if (NUMBER_QNAN_PAIR(pwt->w[1], pws->w[1], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[1], min, pwt->w[1], pwt->w[1], 32);
+ } else {
+ MSA_FLOAT_MAXOP(pwx->w[1], min, pws->w[1], pwt->w[1], 32);
}
- break;
- default:
+
+ if (NUMBER_QNAN_PAIR(pws->w[2], pwt->w[2], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[2], min, pws->w[2], pws->w[2], 32);
+ } else if (NUMBER_QNAN_PAIR(pwt->w[2], pws->w[2], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[2], min, pwt->w[2], pwt->w[2], 32);
+ } else {
+ MSA_FLOAT_MAXOP(pwx->w[2], min, pws->w[2], pwt->w[2], 32);
+ }
+
+ if (NUMBER_QNAN_PAIR(pws->w[3], pwt->w[3], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[3], min, pws->w[3], pws->w[3], 32);
+ } else if (NUMBER_QNAN_PAIR(pwt->w[3], pws->w[3], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[3], min, pwt->w[3], pwt->w[3], 32);
+ } else {
+ MSA_FLOAT_MAXOP(pwx->w[3], min, pws->w[3], pwt->w[3], 32);
+ }
+
+ } else if (df == DF_DOUBLE) {
+
+ if (NUMBER_QNAN_PAIR(pws->d[0], pwt->d[0], 64, status)) {
+ MSA_FLOAT_MAXOP(pwx->d[0], min, pws->d[0], pws->d[0], 64);
+ } else if (NUMBER_QNAN_PAIR(pwt->d[0], pws->d[0], 64, status)) {
+ MSA_FLOAT_MAXOP(pwx->d[0], min, pwt->d[0], pwt->d[0], 64);
+ } else {
+ MSA_FLOAT_MAXOP(pwx->d[0], min, pws->d[0], pwt->d[0], 64);
+ }
+
+ if (NUMBER_QNAN_PAIR(pws->d[1], pwt->d[1], 64, status)) {
+ MSA_FLOAT_MAXOP(pwx->d[1], min, pws->d[1], pws->d[1], 64);
+ } else if (NUMBER_QNAN_PAIR(pwt->d[1], pws->d[1], 64, status)) {
+ MSA_FLOAT_MAXOP(pwx->d[1], min, pwt->d[1], pwt->d[1], 64);
+ } else {
+ MSA_FLOAT_MAXOP(pwx->d[1], min, pws->d[1], pwt->d[1], 64);
+ }
+
+ } else {
+
assert(0);
+
}
check_msacsr_cause(env, GETPC());
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
- uint32_t i;
clear_msacsr_cause(env);
- switch (df) {
- case DF_WORD:
- for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
- FMAXMIN_A(min, max, pwx->w[i], pws->w[i], pwt->w[i], 32, status);
- }
- break;
- case DF_DOUBLE:
- for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
- FMAXMIN_A(min, max, pwx->d[i], pws->d[i], pwt->d[i], 64, status);
- }
- break;
- default:
+ if (df == DF_WORD) {
+ FMAXMIN_A(min, max, pwx->w[0], pws->w[0], pwt->w[0], 32, status);
+ FMAXMIN_A(min, max, pwx->w[1], pws->w[1], pwt->w[1], 32, status);
+ FMAXMIN_A(min, max, pwx->w[2], pws->w[2], pwt->w[2], 32, status);
+ FMAXMIN_A(min, max, pwx->w[3], pws->w[3], pwt->w[3], 32, status);
+ } else if (df == DF_DOUBLE) {
+ FMAXMIN_A(min, max, pwx->d[0], pws->d[0], pwt->d[0], 64, status);
+ FMAXMIN_A(min, max, pwx->d[1], pws->d[1], pwt->d[1], 64, status);
+ } else {
assert(0);
}
void helper_msa_fmax_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
uint32_t ws, uint32_t wt)
{
- float_status *status = &env->active_tc.msa_fp_status;
+ float_status *status = &env->active_tc.msa_fp_status;
wr_t wx, *pwx = &wx;
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
- uint32_t i;
clear_msacsr_cause(env);
- switch (df) {
- case DF_WORD:
- for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
- if (NUMBER_QNAN_PAIR(pws->w[i], pwt->w[i], 32, status)) {
- MSA_FLOAT_MAXOP(pwx->w[i], max, pws->w[i], pws->w[i], 32);
- } else if (NUMBER_QNAN_PAIR(pwt->w[i], pws->w[i], 32, status)) {
- MSA_FLOAT_MAXOP(pwx->w[i], max, pwt->w[i], pwt->w[i], 32);
- } else {
- MSA_FLOAT_MAXOP(pwx->w[i], max, pws->w[i], pwt->w[i], 32);
- }
+ if (df == DF_WORD) {
+
+ if (NUMBER_QNAN_PAIR(pws->w[0], pwt->w[0], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[0], max, pws->w[0], pws->w[0], 32);
+ } else if (NUMBER_QNAN_PAIR(pwt->w[0], pws->w[0], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[0], max, pwt->w[0], pwt->w[0], 32);
+ } else {
+ MSA_FLOAT_MAXOP(pwx->w[0], max, pws->w[0], pwt->w[0], 32);
}
- break;
- case DF_DOUBLE:
- for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
- if (NUMBER_QNAN_PAIR(pws->d[i], pwt->d[i], 64, status)) {
- MSA_FLOAT_MAXOP(pwx->d[i], max, pws->d[i], pws->d[i], 64);
- } else if (NUMBER_QNAN_PAIR(pwt->d[i], pws->d[i], 64, status)) {
- MSA_FLOAT_MAXOP(pwx->d[i], max, pwt->d[i], pwt->d[i], 64);
- } else {
- MSA_FLOAT_MAXOP(pwx->d[i], max, pws->d[i], pwt->d[i], 64);
- }
+
+ if (NUMBER_QNAN_PAIR(pws->w[1], pwt->w[1], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[1], max, pws->w[1], pws->w[1], 32);
+ } else if (NUMBER_QNAN_PAIR(pwt->w[1], pws->w[1], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[1], max, pwt->w[1], pwt->w[1], 32);
+ } else {
+ MSA_FLOAT_MAXOP(pwx->w[1], max, pws->w[1], pwt->w[1], 32);
}
- break;
- default:
+
+ if (NUMBER_QNAN_PAIR(pws->w[2], pwt->w[2], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[2], max, pws->w[2], pws->w[2], 32);
+ } else if (NUMBER_QNAN_PAIR(pwt->w[2], pws->w[2], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[2], max, pwt->w[2], pwt->w[2], 32);
+ } else {
+ MSA_FLOAT_MAXOP(pwx->w[2], max, pws->w[2], pwt->w[2], 32);
+ }
+
+ if (NUMBER_QNAN_PAIR(pws->w[3], pwt->w[3], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[3], max, pws->w[3], pws->w[3], 32);
+ } else if (NUMBER_QNAN_PAIR(pwt->w[3], pws->w[3], 32, status)) {
+ MSA_FLOAT_MAXOP(pwx->w[3], max, pwt->w[3], pwt->w[3], 32);
+ } else {
+ MSA_FLOAT_MAXOP(pwx->w[3], max, pws->w[3], pwt->w[3], 32);
+ }
+
+ } else if (df == DF_DOUBLE) {
+
+ if (NUMBER_QNAN_PAIR(pws->d[0], pwt->d[0], 64, status)) {
+ MSA_FLOAT_MAXOP(pwx->d[0], max, pws->d[0], pws->d[0], 64);
+ } else if (NUMBER_QNAN_PAIR(pwt->d[0], pws->d[0], 64, status)) {
+ MSA_FLOAT_MAXOP(pwx->d[0], max, pwt->d[0], pwt->d[0], 64);
+ } else {
+ MSA_FLOAT_MAXOP(pwx->d[0], max, pws->d[0], pwt->d[0], 64);
+ }
+
+ if (NUMBER_QNAN_PAIR(pws->d[1], pwt->d[1], 64, status)) {
+ MSA_FLOAT_MAXOP(pwx->d[1], max, pws->d[1], pws->d[1], 64);
+ } else if (NUMBER_QNAN_PAIR(pwt->d[1], pws->d[1], 64, status)) {
+ MSA_FLOAT_MAXOP(pwx->d[1], max, pwt->d[1], pwt->d[1], 64);
+ } else {
+ MSA_FLOAT_MAXOP(pwx->d[1], max, pws->d[1], pwt->d[1], 64);
+ }
+
+ } else {
+
assert(0);
+
}
check_msacsr_cause(env, GETPC());
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
wr_t *pws = &(env->active_fpu.fpr[ws].wr);
wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
- uint32_t i;
clear_msacsr_cause(env);
- switch (df) {
- case DF_WORD:
- for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
- FMAXMIN_A(max, min, pwx->w[i], pws->w[i], pwt->w[i], 32, status);
- }
- break;
- case DF_DOUBLE:
- for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
- FMAXMIN_A(max, min, pwx->d[i], pws->d[i], pwt->d[i], 64, status);
- }
- break;
- default:
+ if (df == DF_WORD) {
+ FMAXMIN_A(max, min, pwx->w[0], pws->w[0], pwt->w[0], 32, status);
+ FMAXMIN_A(max, min, pwx->w[1], pws->w[1], pwt->w[1], 32, status);
+ FMAXMIN_A(max, min, pwx->w[2], pws->w[2], pwt->w[2], 32, status);
+ FMAXMIN_A(max, min, pwx->w[3], pws->w[3], pwt->w[3], 32, status);
+ } else if (df == DF_DOUBLE) {
+ FMAXMIN_A(max, min, pwx->d[0], pws->d[0], pwt->d[0], 64, status);
+ FMAXMIN_A(max, min, pwx->d[1], pws->d[1], pwt->d[1], 64, status);
+ } else {
assert(0);
}
pwd->w[1] = float_class_s(pws->w[1], status);
pwd->w[2] = float_class_s(pws->w[2], status);
pwd->w[3] = float_class_s(pws->w[3], status);
- } else {
+ } else if (df == DF_DOUBLE) {
pwd->d[0] = float_class_d(pws->d[0], status);
pwd->d[1] = float_class_d(pws->d[1], status);
+ } else {
+ assert(0);
}
}
OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
};
-/* R6 Multiply and Divide instructions have the same Opcode
- and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
+/*
+ * R6 Multiply and Divide instructions have the same opcode
+ * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
+ */
#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
enum {
}
}
-/* Verify that the processor is running with COP1X instructions enabled.
- This is associated with the nabla symbol in the MIPS32 and MIPS64
- opcode tables. */
-
+/*
+ * Verify that the processor is running with COP1X instructions enabled.
+ * This is associated with the nabla symbol in the MIPS32 and MIPS64
+ * opcode tables.
+ */
static inline void check_cop1x(DisasContext *ctx)
{
if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
}
}
-/* Verify that the processor is running with 64-bit floating-point
- operations enabled. */
-
+/*
+ * Verify that the processor is running with 64-bit floating-point
+ * operations enabled.
+ */
static inline void check_cp1_64bitmode(DisasContext *ctx)
{
if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
}
}
-/* Verify that the processor is running with DSP instructions enabled.
- This is enabled by CP0 Status register MX(24) bit.
+/*
+ * Verify that the processor is running with DSP instructions enabled.
+ * This is enabled by CP0 Status register MX(24) bit.
*/
-
static inline void check_dsp(DisasContext *ctx)
{
if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
}
}
-/* This code generates a "reserved instruction" exception if the
- CPU does not support the instruction set corresponding to flags. */
+/*
+ * This code generates a "reserved instruction" exception if the
+ * CPU does not support the instruction set corresponding to flags.
+ */
static inline void check_insn(DisasContext *ctx, uint64_t flags)
{
if (unlikely(!(ctx->insn_flags & flags))) {
}
}
-/* This code generates a "reserved instruction" exception if the
- CPU has corresponding flag set which indicates that the instruction
- has been removed. */
+/*
+ * This code generates a "reserved instruction" exception if the
+ * CPU has corresponding flag set which indicates that the instruction
+ * has been removed.
+ */
static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
{
if (unlikely(ctx->insn_flags & flags)) {
#endif
}
-/* This code generates a "reserved instruction" exception if the
- CPU does not support 64-bit paired-single (PS) floating point data type */
+/*
+ * This code generates a "reserved instruction" exception if the
+ * CPU does not support 64-bit paired-single (PS) floating point data type.
+ */
static inline void check_ps(DisasContext *ctx)
{
if (unlikely(!ctx->ps)) {
}
#ifdef TARGET_MIPS64
-/* This code generates a "reserved instruction" exception if 64-bit
- instructions are not enabled. */
+/*
+ * This code generates a "reserved instruction" exception if 64-bit
+ * instructions are not enabled.
+ */
static inline void check_mips_64(DisasContext *ctx)
{
if (unlikely(!(ctx->hflags & MIPS_HFLAG_64))) {
}
-/* Define small wrappers for gen_load_fpr* so that we have a uniform
- calling interface for 32 and 64-bit FPRs. No sense in changing
- all callers for gen_load_fpr32 when we need the CTX parameter for
- this one use. */
+/*
+ * Define small wrappers for gen_load_fpr* so that we have a uniform
+ * calling interface for 32 and 64-bit FPRs. No sense in changing
+ * all callers for gen_load_fpr32 when we need the CTX parameter for
+ * this one use.
+ */
#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
int mem_idx = ctx->mem_idx;
if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
- /* Loongson CPU uses a load to zero register for prefetch.
- We emulate it as a NOP. On other CPU we must perform the
- actual memory access. */
+ /*
+ * Loongson CPU uses a load to zero register for prefetch.
+ * We emulate it as a NOP. On other CPU we must perform the
+ * actual memory access.
+ */
return;
}
break;
case OPC_LDL:
t1 = tcg_temp_new();
- /* Do a byte access to possibly trigger a page
- fault with the unaligned address. */
+ /*
+ * Do a byte access to possibly trigger a page
+ * fault with the unaligned address.
+ */
tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
tcg_gen_andi_tl(t1, t0, 7);
#ifndef TARGET_WORDS_BIGENDIAN
break;
case OPC_LDR:
t1 = tcg_temp_new();
- /* Do a byte access to possibly trigger a page
- fault with the unaligned address. */
+ /*
+ * Do a byte access to possibly trigger a page
+ * fault with the unaligned address.
+ */
tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
tcg_gen_andi_tl(t1, t0, 7);
#ifdef TARGET_WORDS_BIGENDIAN
/* fall through */
case OPC_LWL:
t1 = tcg_temp_new();
- /* Do a byte access to possibly trigger a page
- fault with the unaligned address. */
+ /*
+ * Do a byte access to possibly trigger a page
+ * fault with the unaligned address.
+ */
tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
tcg_gen_andi_tl(t1, t0, 3);
#ifndef TARGET_WORDS_BIGENDIAN
/* fall through */
case OPC_LWR:
t1 = tcg_temp_new();
- /* Do a byte access to possibly trigger a page
- fault with the unaligned address. */
+ /*
+ * Do a byte access to possibly trigger a page
+ * fault with the unaligned address.
+ */
tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
tcg_gen_andi_tl(t1, t0, 3);
#ifdef TARGET_WORDS_BIGENDIAN
static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
TCGv t0)
{
- /* Don't do NOP if destination is zero: we must perform the actual
- memory access. */
+ /*
+ * Don't do NOP if destination is zero: we must perform the actual
+ * memory access.
+ */
switch (opc) {
case OPC_LWC1:
{
target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
- /* If no destination, treat it as a NOP.
- For addi, we must generate the overflow exception when needed. */
+ /*
+ * If no destination, treat it as a NOP.
+ * For addi, we must generate the overflow exception when needed.
+ */
return;
}
switch (opc) {
{
if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
&& opc != OPC_DADD && opc != OPC_DSUB) {
- /* If no destination, treat it as a NOP.
- For add & sub, we must generate the overflow exception when needed. */
+ /*
+ * If no destination, treat it as a NOP.
+ * For add & sub, we must generate the overflow exception when needed.
+ */
return;
}
tcg_temp_free(t2);
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
tcg_temp_free(t1);
- /* operands of different sign, first operand and result different sign */
+ /*
+ * operands of different sign, first operand and the result
+ * of different sign
+ */
generate_exception(ctx, EXCP_OVERFLOW);
gen_set_label(l1);
gen_store_gpr(t0, rd);
TCGv t0, t1;
if (rd == 0) {
- /* If no destination, treat it as a NOP.
- For add & sub, we must generate the overflow exception when needed. */
+ /*
+ * If no destination, treat it as a NOP.
+ * For add & sub, we must generate the overflow exception when needed.
+ */
return;
}
break;
case OPC_SRA_CP2:
case OPC_DSRA_CP2:
- /* Since SRA is UndefinedResult without sign-extended inputs,
- we can treat SRA and DSRA the same. */
+ /*
+ * Since SRA is UndefinedResult without sign-extended inputs,
+ * we can treat SRA and DSRA the same.
+ */
tcg_gen_sar_i64(t0, t0, t1);
break;
case OPC_SRL_CP2:
case OPC_SLT_CP2:
case OPC_SLEU_CP2:
case OPC_SLE_CP2:
- /* ??? Document is unclear: Set FCC[CC]. Does that mean the
- FD field is the CC field? */
+ /*
+ * ??? Document is unclear: Set FCC[CC]. Does that mean the
+ * FD field is the CC field?
+ */
default:
MIPS_INVAL("loongson_cp2");
generate_exception_end(ctx, EXCP_RI);
case OPC_JALR:
/* Jump to register */
if (offset != 0 && offset != 16) {
- /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
- others are reserved. */
+ /*
+ * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
+ * others are reserved.
+ */
MIPS_INVAL("jump hint");
generate_exception_end(ctx, EXCP_RI);
goto out;
/* Treat as NOP. */
goto out;
case OPC_BLTZAL: /* 0 < 0 */
- /* Handle as an unconditional branch to get correct delay
- slot checking. */
+ /*
+ * Handle as an unconditional branch to get correct delay
+ * slot checking.
+ */
blink = 31;
btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
ctx->hflags |= MIPS_HFLAG_B;
case OPC_JALR:
/* Jump to register */
if (offset != 0 && offset != 16) {
- /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
- others are reserved. */
+ /*
+ * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
+ * others are reserved.
+ */
MIPS_INVAL("jump hint");
generate_exception_end(ctx, EXCP_RI);
goto out;
if (msb != 31) {
tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
} else {
- /* The two checks together imply that lsb == 0,
- so this is a simple sign-extension. */
+ /*
+ * The two checks together imply that lsb == 0,
+ * so this is a simple sign-extension.
+ */
tcg_gen_ext32s_tl(t0, t1);
}
break;
case CP0_REGISTER_17:
switch (sel) {
case 0:
- /* LLAddr is read-only (the only exception is bit 0 if LLB is
- supported); the CP0_LLAddr_rw_bitmask does not seem to be
- relevant for modern MIPS cores supporting MTHC0, therefore
- treating MTHC0 to LLAddr as NOP. */
+ /*
+ * LLAddr is read-only (the only exception is bit 0 if LLB is
+ * supported); the CP0_LLAddr_rw_bitmask does not seem to be
+ * relevant for modern MIPS cores supporting MTHC0, therefore
+ * treating MTHC0 to LLAddr as NOP.
+ */
register_name = "LLAddr";
break;
case 1:
register_name = "Context";
break;
case 1:
-// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
+ /* gen_helper_mfc0_contextconfig(arg); - SmartMIPS ASE */
register_name = "ContextConfig";
goto cp0_unimplemented;
case 2:
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
gen_io_end();
}
- /* Break the TB to be able to take timer interrupts immediately
- after reading count. DISAS_STOP isn't sufficient, we need to
- ensure we break completely out of translated code. */
+ /*
+ * Break the TB to be able to take timer interrupts immediately
+ * after reading count. DISAS_STOP isn't sufficient, we need to
+ * ensure we break completely out of translated code.
+ */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
register_name = "Count";
register_name = "Performance0";
break;
case 1:
-// gen_helper_mfc0_performance1(arg);
+ /* gen_helper_mfc0_performance1(arg); */
register_name = "Performance1";
goto cp0_unimplemented;
case 2:
-// gen_helper_mfc0_performance2(arg);
+ /* gen_helper_mfc0_performance2(arg); */
register_name = "Performance2";
goto cp0_unimplemented;
case 3:
-// gen_helper_mfc0_performance3(arg);
+ /* gen_helper_mfc0_performance3(arg); */
register_name = "Performance3";
goto cp0_unimplemented;
case 4:
-// gen_helper_mfc0_performance4(arg);
+ /* gen_helper_mfc0_performance4(arg); */
register_name = "Performance4";
goto cp0_unimplemented;
case 5:
-// gen_helper_mfc0_performance5(arg);
+ /* gen_helper_mfc0_performance5(arg); */
register_name = "Performance5";
goto cp0_unimplemented;
case 6:
-// gen_helper_mfc0_performance6(arg);
+ /* gen_helper_mfc0_performance6(arg); */
register_name = "Performance6";
goto cp0_unimplemented;
case 7:
-// gen_helper_mfc0_performance7(arg);
+ /* gen_helper_mfc0_performance7(arg); */
register_name = "Performance7";
goto cp0_unimplemented;
default:
case 0:
save_cpu_state(ctx, 1);
gen_helper_mtc0_cause(cpu_env, arg);
- /* Stop translation as we may have triggered an interrupt.
+ /*
+ * Stop translation as we may have triggered an interrupt.
* DISAS_STOP isn't sufficient, we need to ensure we break out of
- * translated code to check for pending interrupts. */
+ * translated code to check for pending interrupts.
+ */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
register_name = "Cause";
register_name = "Performance0";
break;
case 1:
-// gen_helper_mtc0_performance1(arg);
+ /* gen_helper_mtc0_performance1(arg); */
register_name = "Performance1";
goto cp0_unimplemented;
case 2:
-// gen_helper_mtc0_performance2(arg);
+ /* gen_helper_mtc0_performance2(arg); */
register_name = "Performance2";
goto cp0_unimplemented;
case 3:
-// gen_helper_mtc0_performance3(arg);
+ /* gen_helper_mtc0_performance3(arg); */
register_name = "Performance3";
goto cp0_unimplemented;
case 4:
-// gen_helper_mtc0_performance4(arg);
+ /* gen_helper_mtc0_performance4(arg); */
register_name = "Performance4";
goto cp0_unimplemented;
case 5:
-// gen_helper_mtc0_performance5(arg);
+ /* gen_helper_mtc0_performance5(arg); */
register_name = "Performance5";
goto cp0_unimplemented;
case 6:
-// gen_helper_mtc0_performance6(arg);
+ /* gen_helper_mtc0_performance6(arg); */
register_name = "Performance6";
goto cp0_unimplemented;
case 7:
-// gen_helper_mtc0_performance7(arg);
+ /* gen_helper_mtc0_performance7(arg); */
register_name = "Performance7";
goto cp0_unimplemented;
default:
/* For simplicity assume that all writes can cause interrupts. */
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
gen_io_end();
- /* DISAS_STOP isn't sufficient, we need to ensure we break out of
- * translated code to check for pending interrupts. */
+ /*
+ * DISAS_STOP isn't sufficient, we need to ensure we break out of
+ * translated code to check for pending interrupts.
+ */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
}
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
gen_io_end();
}
- /* Break the TB to be able to take timer interrupts immediately
- after reading count. DISAS_STOP isn't sufficient, we need to
- ensure we break completely out of translated code. */
+ /*
+ * Break the TB to be able to take timer interrupts immediately
+ * after reading count. DISAS_STOP isn't sufficient, we need to
+ * ensure we break completely out of translated code.
+ */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
register_name = "Count";
register_name = "Performance0";
break;
case 1:
-// gen_helper_dmfc0_performance1(arg);
+ /* gen_helper_dmfc0_performance1(arg); */
register_name = "Performance1";
goto cp0_unimplemented;
case 2:
-// gen_helper_dmfc0_performance2(arg);
+ /* gen_helper_dmfc0_performance2(arg); */
register_name = "Performance2";
goto cp0_unimplemented;
case 3:
-// gen_helper_dmfc0_performance3(arg);
+ /* gen_helper_dmfc0_performance3(arg); */
register_name = "Performance3";
goto cp0_unimplemented;
case 4:
-// gen_helper_dmfc0_performance4(arg);
+ /* gen_helper_dmfc0_performance4(arg); */
register_name = "Performance4";
goto cp0_unimplemented;
case 5:
-// gen_helper_dmfc0_performance5(arg);
+ /* gen_helper_dmfc0_performance5(arg); */
register_name = "Performance5";
goto cp0_unimplemented;
case 6:
-// gen_helper_dmfc0_performance6(arg);
+ /* gen_helper_dmfc0_performance6(arg); */
register_name = "Performance6";
goto cp0_unimplemented;
case 7:
-// gen_helper_dmfc0_performance7(arg);
+ /* gen_helper_dmfc0_performance7(arg); */
register_name = "Performance7";
goto cp0_unimplemented;
default:
case 0:
save_cpu_state(ctx, 1);
gen_helper_mtc0_cause(cpu_env, arg);
- /* Stop translation as we may have triggered an interrupt.
+ /*
+ * Stop translation as we may have triggered an interrupt.
* DISAS_STOP isn't sufficient, we need to ensure we break out of
- * translated code to check for pending interrupts. */
+ * translated code to check for pending interrupts.
+ */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
register_name = "Cause";
register_name = "Performance0";
break;
case 1:
-// gen_helper_mtc0_performance1(cpu_env, arg);
+ /* gen_helper_mtc0_performance1(cpu_env, arg); */
register_name = "Performance1";
goto cp0_unimplemented;
case 2:
-// gen_helper_mtc0_performance2(cpu_env, arg);
+ /* gen_helper_mtc0_performance2(cpu_env, arg); */
register_name = "Performance2";
goto cp0_unimplemented;
case 3:
-// gen_helper_mtc0_performance3(cpu_env, arg);
+ /* gen_helper_mtc0_performance3(cpu_env, arg); */
register_name = "Performance3";
goto cp0_unimplemented;
case 4:
-// gen_helper_mtc0_performance4(cpu_env, arg);
+ /* gen_helper_mtc0_performance4(cpu_env, arg); */
register_name = "Performance4";
goto cp0_unimplemented;
case 5:
-// gen_helper_mtc0_performance5(cpu_env, arg);
+ /* gen_helper_mtc0_performance5(cpu_env, arg); */
register_name = "Performance5";
goto cp0_unimplemented;
case 6:
-// gen_helper_mtc0_performance6(cpu_env, arg);
+ /* gen_helper_mtc0_performance6(cpu_env, arg); */
register_name = "Performance6";
goto cp0_unimplemented;
case 7:
-// gen_helper_mtc0_performance7(cpu_env, arg);
+ /* gen_helper_mtc0_performance7(cpu_env, arg); */
register_name = "Performance7";
goto cp0_unimplemented;
default:
/* For simplicity assume that all writes can cause interrupts. */
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
gen_io_end();
- /* DISAS_STOP isn't sufficient, we need to ensure we break out of
- * translated code to check for pending interrupts. */
+ /*
+ * DISAS_STOP isn't sufficient, we need to ensure we break out of
+ * translated code to check for pending interrupts.
+ */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
}
if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
(env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
- /* NOP */ ;
+ /* NOP */
+ ;
} else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
(env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
- /* NOP */ ;
+ /* NOP */
+ ;
} else if (u == 0) {
switch (rd) {
case 1:
} else {
gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
}
- /* Don't do NOP if destination is zero: we must perform the actual
- memory access. */
+ /*
+ * Don't do NOP if destination is zero: we must perform the actual
+ * memory access.
+ */
switch (opc) {
case OPC_LWXC1:
check_cop1x(ctx);
TCGv t0;
#if !defined(CONFIG_USER_ONLY)
- /* The Linux kernel will emulate rdhwr if it's not supported natively.
- Therefore only check the ISA in system mode. */
+ /*
+ * The Linux kernel will emulate rdhwr if it's not supported natively.
+ * Therefore only check the ISA in system mode.
+ */
check_insn(ctx, ISA_MIPS32R2);
#endif
t0 = tcg_temp_new();
gen_io_end();
}
gen_store_gpr(t0, rt);
- /* Break the TB to be able to take timer interrupts immediately
- after reading count. DISAS_STOP isn't sufficient, we need to ensure
- we break completely out of translated code. */
+ /*
+ * Break the TB to be able to take timer interrupts immediately
+ * after reading count. DISAS_STOP isn't sufficient, we need to ensure
+ * we break completely out of translated code.
+ */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
break;
case 4:
check_insn(ctx, ISA_MIPS32R6);
if (sel != 0) {
- /* Performance counter registers are not implemented other than
+ /*
+ * Performance counter registers are not implemented other than
* control register 0.
*/
generate_exception(ctx, EXCP_RI);
if (ctx->base.is_jmp == DISAS_NEXT) {
save_cpu_state(ctx, 0);
} else {
- /* it is not safe to save ctx->hflags as hflags may be changed
- in execution time by the instruction in delay / forbidden slot. */
+ /*
+ * It is not safe to save ctx->hflags as hflags may be changed
+ * in execution time by the instruction in delay / forbidden slot.
+ */
tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
}
}
| ((ctx->opcode >> 21) & 0x3f) << 5
| (ctx->opcode & 0x1f));
- /* The extended opcodes cleverly reuse the opcodes from their 16-bit
- counterparts. */
+ /*
+ * The extended opcodes cleverly reuse the opcodes from their 16-bit
+ * counterparts.
+ */
switch (op) {
case M16_OPC_ADDIUSP:
gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
if (is_uhi(extract32(ctx->opcode, 5, 6))) {
gen_helper_do_semihosting(cpu_env);
} else {
- /* XXX: not clear which exception should be raised
+ /*
+ * XXX: not clear which exception should be raised
* when in debug mode...
*/
check_insn(ctx, ISA_MIPS32);
/* POOL32A encoding of minor opcode field */
enum {
- /* These opcodes are distinguished only by bits 9..6; those bits are
- * what are recorded below. */
+ /*
+ * These opcodes are distinguished only by bits 9..6; those bits are
+ * what are recorded below.
+ */
SLL32 = 0x0,
SRL32 = 0x1,
SRA = 0x2,
{
int reg = ctx->opcode & 0x1f;
gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
- /* Let normal delay slot handling in our caller take us
- to the branch target. */
+ /*
+ * Let normal delay slot handling in our caller take us
+ * to the branch target.
+ */
}
break;
case JALR16 + 0:
if (is_uhi(extract32(ctx->opcode, 0, 4))) {
gen_helper_do_semihosting(cpu_env);
} else {
- /* XXX: not clear which exception should be raised
+ /*
+ * XXX: not clear which exception should be raised
* when in debug mode...
*/
check_insn(ctx, ISA_MIPS32);
int imm = ZIMM(ctx->opcode, 0, 5);
gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
- /* Let normal delay slot handling in our caller take us
- to the branch target. */
+ /*
+ * Let normal delay slot handling in our caller take us
+ * to the branch target.
+ */
}
break;
default:
save_cpu_state(ctx, 1);
gen_helper_ei(t0, cpu_env);
gen_store_gpr(t0, rs);
- /* DISAS_STOP isn't sufficient, we need to ensure we break out
- of translated code to check for pending interrupts. */
+ /*
+ * DISAS_STOP isn't sufficient, we need to ensure we break out
+ * of translated code to check for pending interrupts.
+ */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
tcg_temp_free(t0);
}
}
-/* Values for microMIPS fmt field. Variable-width, depending on which
- formats the instruction supports. */
-
+/*
+ * Values for microMIPS fmt field. Variable-width, depending on which
+ * formats the instruction supports.
+ */
enum {
FMT_SD_S = 0,
FMT_SD_D = 1,
case TNEI: /* SYNCI */
if (ctx->insn_flags & ISA_MIPS32R6) {
/* SYNCI */
- /* Break the TB to be able to sync copied instructions
- immediately */
+ /*
+ * Break the TB to be able to sync copied instructions
+ * immediately.
+ */
ctx->base.is_jmp = DISAS_STOP;
} else {
/* TNEI */
check_insn_opc_removed(ctx, ISA_MIPS32R6);
gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
4, rs, 0, imm << 1, 0);
- /* Compact branches don't have a delay slot, so just let
- the normal delay slot handling take us to the branch
- target. */
+ /*
+ * Compact branches don't have a delay slot, so just let
+ * the normal delay slot handling take us to the branch
+ * target.
+ */
break;
case LUI:
check_insn_opc_removed(ctx, ISA_MIPS32R6);
break;
case SYNCI:
check_insn_opc_removed(ctx, ISA_MIPS32R6);
- /* Break the TB to be able to sync copied instructions
- immediately */
+ /*
+ * Break the TB to be able to sync copied instructions
+ * immediately.
+ */
ctx->base.is_jmp = DISAS_STOP;
break;
case BC2F:
break;
}
if (ctx->insn_flags & ISA_MIPS32R6) {
- /* In the Release 6 the register number location in
+ /*
+ * In the Release 6, the register number location in
* the instruction encoding has changed.
*/
gen_arith(ctx, opc, rs1, rd, rs2);
gen_p_lsx(ctx, rd, rs, rt);
break;
case NM_LSA:
- /* In nanoMIPS, the shift field directly encodes the shift
+ /*
+ * In nanoMIPS, the shift field directly encodes the shift
* amount, meaning that the supported shift values are in
- * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
+ * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
+ */
gen_lsa(ctx, OPC_LSA, rd, rs, rt,
extract32(ctx->opcode, 9, 2) - 1);
break;
case NM_P_PREFU12:
if (rt == 31) {
/* SYNCI */
- /* Break the TB to be able to sync copied instructions
- immediately */
+ /*
+ * Break the TB to be able to sync copied instructions
+ * immediately.
+ */
ctx->base.is_jmp = DISAS_STOP;
} else {
/* PREF */
case NM_P_PREFS9:
if (rt == 31) {
/* SYNCI */
- /* Break the TB to be able to sync copied instructions
- immediately */
+ /*
+ * Break the TB to be able to sync copied instructions
+ * immediately.
+ */
ctx->base.is_jmp = DISAS_STOP;
} else {
/* PREF */
/* case NM_SYNCIE */
check_eva(ctx);
check_cp0_enabled(ctx);
- /* Break the TB to be able to sync copied instructions
- immediately */
+ /*
+ * Break the TB to be able to sync copied instructions
+ * immediately.
+ */
ctx->base.is_jmp = DISAS_STOP;
} else {
/* case NM_PREFE */
gen_load_gpr(v2_t, v2);
switch (op1) {
- /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
- * the same mask and op1. */
+ /*
+ * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
+ * the same mask and op1.
+ */
case OPC_MULT_G_2E:
check_dsp_r2(ctx);
switch (op2) {
case R6_OPC_CLO:
case R6_OPC_CLZ:
if (rt == 0 && sa == 1) {
- /* Major opcode and function field is shared with preR6 MFHI/MTHI.
- We need additionally to check other fields */
+ /*
+ * Major opcode and function field is shared with preR6 MFHI/MTHI.
+ * We need additionally to check other fields.
+ */
gen_cl(ctx, op1, rd, rs);
} else {
generate_exception_end(ctx, EXCP_RI);
case R6_OPC_DCLO:
case R6_OPC_DCLZ:
if (rt == 0 && sa == 1) {
- /* Major opcode and function field is shared with preR6 MFHI/MTHI.
- We need additionally to check other fields */
+ /*
+ * Major opcode and function field is shared with preR6 MFHI/MTHI.
+ * We need additionally to check other fields.
+ */
check_mips_64(ctx);
gen_cl(ctx, op1, rd, rs);
} else {
* | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
* +-----------+---------+-+-------------------+-------+-----------+
*
-*/
+ */
static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
{
uint32_t opcode = extract32(ctx->opcode, 20, 1);
if (is_uhi(extract32(ctx->opcode, 6, 20))) {
gen_helper_do_semihosting(cpu_env);
} else {
- /* XXX: not clear which exception should be raised
+ /*
+ * XXX: not clear which exception should be raised
* when in debug mode...
*/
check_insn(ctx, ISA_MIPS32);
case OPC_MODU_G_2E:
case OPC_MULT_G_2E:
case OPC_MULTU_G_2E:
- /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
- * the same mask and op1. */
+ /*
+ * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
+ * the same mask and op1.
+ */
if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
op2 = MASK_ADDUH_QB(ctx->opcode);
switch (op2) {
break;
case OPC_SYNCI:
check_insn(ctx, ISA_MIPS32R2);
- /* Break the TB to be able to sync copied instructions
- immediately */
+ /*
+ * Break the TB to be able to sync copied instructions
+ * immediately.
+ */
ctx->base.is_jmp = DISAS_STOP;
break;
case OPC_BPOSGE32: /* MIPS DSP branch */
save_cpu_state(ctx, 1);
gen_helper_di(t0, cpu_env);
gen_store_gpr(t0, rt);
- /* Stop translation as we may have switched
- the execution mode. */
+ /*
+ * Stop translation as we may have switched
+ * the execution mode.
+ */
ctx->base.is_jmp = DISAS_STOP;
break;
case OPC_EI:
save_cpu_state(ctx, 1);
gen_helper_ei(t0, cpu_env);
gen_store_gpr(t0, rt);
- /* DISAS_STOP isn't sufficient, we need to ensure we break
- out of translated code to check for pending interrupts */
+ /*
+ * DISAS_STOP isn't sufficient, we need to ensure we break
+ * out of translated code to check for pending interrupts.
+ */
gen_save_pc(ctx->base.pc_next + 4);
ctx->base.is_jmp = DISAS_EXIT;
break;
save_cpu_state(ctx, 1);
ctx->base.is_jmp = DISAS_NORETURN;
gen_helper_raise_exception_debug(cpu_env);
- /* The address covered by the breakpoint must be included in
- [tb->pc, tb->pc + tb->size) in order to for it to be
- properly cleared -- thus we increment the PC here so that
- the logic setting tb->size below does the right thing. */
+ /*
+ * The address covered by the breakpoint must be included in
+ * [tb->pc, tb->pc + tb->size) in order to for it to be
+ * properly cleared -- thus we increment the PC here so that
+ * the logic setting tb->size below does the right thing.
+ */
ctx->base.pc_next += 4;
return true;
}
if (ctx->hflags & MIPS_HFLAG_BMASK) {
if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
MIPS_HFLAG_FBNSLOT))) {
- /* force to generate branch as there is neither delay nor
- forbidden slot */
+ /*
+ * Force to generate branch as there is neither delay nor
+ * forbidden slot.
+ */
is_slot = 1;
}
if ((ctx->hflags & MIPS_HFLAG_M16) &&
(ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
- /* Force to generate branch as microMIPS R6 doesn't restrict
- branches in the forbidden slot. */
+ /*
+ * Force to generate branch as microMIPS R6 doesn't restrict
+ * branches in the forbidden slot.
+ */
is_slot = 1;
}
}
if (ctx->base.is_jmp != DISAS_NEXT) {
return;
}
- /* Execute a branch and its delay slot as a single instruction.
- This is what GDB expects and is consistent with what the
- hardware does (e.g. if a delay slot instruction faults, the
- reported PC is the PC of the branch). */
+ /*
+ * Execute a branch and its delay slot as a single instruction.
+ * This is what GDB expects and is consistent with what the
+ * hardware does (e.g. if a delay slot instruction faults, the
+ * reported PC is the PC of the branch).
+ */
if (ctx->base.singlestep_enabled &&
(ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
ctx->base.is_jmp = DISAS_TOO_MANY;
int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
msa_wr_d[i * 2] =
tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
- /* The scalar floating-point unit (FPU) registers are mapped on
- * the MSA vector registers. */
+ /*
+ * The scalar floating-point unit (FPU) registers are mapped on
+ * the MSA vector registers.
+ */
fpu_f64[i] = msa_wr_d[i * 2];
off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
msa_wr_d[i * 2 + 1] =
/* Enable 64-bit address mode. */
env->CP0_Status |= (1 << CP0St_UX);
# endif
- /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
- hardware registers. */
+ /*
+ * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
+ * hardware registers.
+ */
env->CP0_HWREna |= 0x0000000F;
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
env->CP0_Status |= (1 << CP0St_CU1);
# endif
#else
if (env->hflags & MIPS_HFLAG_BMASK) {
- /* If the exception was raised from a delay slot,
- come back to the jump. */
+ /*
+ * If the exception was raised from a delay slot,
+ * come back to the jump.
+ */
env->CP0_ErrorEPC = (env->active_tc.PC
- (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
} else {
env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
0x3ff : 0xff;
env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
- /* vectored interrupts not implemented, timer on int 7,
- no performance counters. */
+ /*
+ * Vectored interrupts not implemented, timer on int 7,
+ * no performance counters.
+ */
env->CP0_IntCtl = 0xe0000000;
{
int i;
#include "cpu.h"
#include "monitor/monitor.h"
#include "monitor/hmp-target.h"
-#include "hmp.h"
+#include "monitor/hmp.h"
void hmp_info_tlb(Monitor *mon, const QDict *qdict)
{
* sfprf - set FPRF
*/
#define VSX_ADD_SUB(name, op, nels, tp, fld, sfprf, r2sp) \
-void helper_##name(CPUPPCState *env, uint32_t opcode) \
+void helper_##name(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
helper_reset_fpstatus(env); \
\
for (i = 0; i < nels; i++) { \
float_status tstat = env->fp_status; \
set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_##op(xa.fld, xb.fld, &tstat); \
+ t.fld = tp##_##op(xa->fld, xb->fld, &tstat); \
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
float_invalid_op_addsub(env, sfprf, GETPC(), \
- tp##_classify(xa.fld) | \
- tp##_classify(xb.fld)); \
+ tp##_classify(xa->fld) | \
+ tp##_classify(xb->fld)); \
} \
\
if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
+ t.fld = helper_frsp(env, t.fld); \
} \
\
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
VSX_ADD_SUB(xvsubdp, sub, 2, float64, VsrD(i), 0, 0)
VSX_ADD_SUB(xvsubsp, sub, 4, float32, VsrW(i), 0, 0)
-void helper_xsaddqp(CPUPPCState *env, uint32_t opcode)
+void helper_xsaddqp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
{
- ppc_vsr_t xt, xa, xb;
+ ppc_vsr_t t = *xt;
float_status tstat;
- getVSR(rA(opcode) + 32, &xa, env);
- getVSR(rB(opcode) + 32, &xb, env);
- getVSR(rD(opcode) + 32, &xt, env);
helper_reset_fpstatus(env);
tstat = env->fp_status;
}
set_float_exception_flags(0, &tstat);
- xt.f128 = float128_add(xa.f128, xb.f128, &tstat);
+ t.f128 = float128_add(xa->f128, xb->f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
float_invalid_op_addsub(env, 1, GETPC(),
- float128_classify(xa.f128) |
- float128_classify(xb.f128));
+ float128_classify(xa->f128) |
+ float128_classify(xb->f128));
}
- helper_compute_fprf_float128(env, xt.f128);
+ helper_compute_fprf_float128(env, t.f128);
- putVSR(rD(opcode) + 32, &xt, env);
+ *xt = t;
do_float_check_status(env, GETPC());
}
* sfprf - set FPRF
*/
#define VSX_MUL(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
helper_reset_fpstatus(env); \
\
for (i = 0; i < nels; i++) { \
float_status tstat = env->fp_status; \
set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_mul(xa.fld, xb.fld, &tstat); \
+ t.fld = tp##_mul(xa->fld, xb->fld, &tstat); \
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
float_invalid_op_mul(env, sfprf, GETPC(), \
- tp##_classify(xa.fld) | \
- tp##_classify(xb.fld)); \
+ tp##_classify(xa->fld) | \
+ tp##_classify(xb->fld)); \
} \
\
if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
+ t.fld = helper_frsp(env, t.fld); \
} \
\
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
VSX_MUL(xvmuldp, 2, float64, VsrD(i), 0, 0)
VSX_MUL(xvmulsp, 4, float32, VsrW(i), 0, 0)
-void helper_xsmulqp(CPUPPCState *env, uint32_t opcode)
+void helper_xsmulqp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
{
- ppc_vsr_t xt, xa, xb;
+ ppc_vsr_t t = *xt;
float_status tstat;
- getVSR(rA(opcode) + 32, &xa, env);
- getVSR(rB(opcode) + 32, &xb, env);
- getVSR(rD(opcode) + 32, &xt, env);
-
helper_reset_fpstatus(env);
tstat = env->fp_status;
if (unlikely(Rc(opcode) != 0)) {
}
set_float_exception_flags(0, &tstat);
- xt.f128 = float128_mul(xa.f128, xb.f128, &tstat);
+ t.f128 = float128_mul(xa->f128, xb->f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
float_invalid_op_mul(env, 1, GETPC(),
- float128_classify(xa.f128) |
- float128_classify(xb.f128));
+ float128_classify(xa->f128) |
+ float128_classify(xb->f128));
}
- helper_compute_fprf_float128(env, xt.f128);
+ helper_compute_fprf_float128(env, t.f128);
- putVSR(rD(opcode) + 32, &xt, env);
+ *xt = t;
do_float_check_status(env, GETPC());
}
* sfprf - set FPRF
*/
#define VSX_DIV(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
helper_reset_fpstatus(env); \
\
for (i = 0; i < nels; i++) { \
float_status tstat = env->fp_status; \
set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_div(xa.fld, xb.fld, &tstat); \
+ t.fld = tp##_div(xa->fld, xb->fld, &tstat); \
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
float_invalid_op_div(env, sfprf, GETPC(), \
- tp##_classify(xa.fld) | \
- tp##_classify(xb.fld)); \
+ tp##_classify(xa->fld) | \
+ tp##_classify(xb->fld)); \
} \
if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) { \
float_zero_divide_excp(env, GETPC()); \
} \
\
if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
+ t.fld = helper_frsp(env, t.fld); \
} \
\
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
VSX_DIV(xvdivdp, 2, float64, VsrD(i), 0, 0)
VSX_DIV(xvdivsp, 4, float32, VsrW(i), 0, 0)
-void helper_xsdivqp(CPUPPCState *env, uint32_t opcode)
+void helper_xsdivqp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
{
- ppc_vsr_t xt, xa, xb;
+ ppc_vsr_t t = *xt;
float_status tstat;
- getVSR(rA(opcode) + 32, &xa, env);
- getVSR(rB(opcode) + 32, &xb, env);
- getVSR(rD(opcode) + 32, &xt, env);
-
helper_reset_fpstatus(env);
tstat = env->fp_status;
if (unlikely(Rc(opcode) != 0)) {
}
set_float_exception_flags(0, &tstat);
- xt.f128 = float128_div(xa.f128, xb.f128, &tstat);
+ t.f128 = float128_div(xa->f128, xb->f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
float_invalid_op_div(env, 1, GETPC(),
- float128_classify(xa.f128) |
- float128_classify(xb.f128));
+ float128_classify(xa->f128) |
+ float128_classify(xb->f128));
}
if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) {
float_zero_divide_excp(env, GETPC());
}
- helper_compute_fprf_float128(env, xt.f128);
- putVSR(rD(opcode) + 32, &xt, env);
+ helper_compute_fprf_float128(env, t.f128);
+ *xt = t;
do_float_check_status(env, GETPC());
}
* sfprf - set FPRF
*/
#define VSX_RE(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
helper_reset_fpstatus(env); \
\
for (i = 0; i < nels; i++) { \
- if (unlikely(tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \
+ if (unlikely(tp##_is_signaling_nan(xb->fld, &env->fp_status))) { \
float_invalid_op_vxsnan(env, GETPC()); \
} \
- xt.fld = tp##_div(tp##_one, xb.fld, &env->fp_status); \
+ t.fld = tp##_div(tp##_one, xb->fld, &env->fp_status); \
\
if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
+ t.fld = helper_frsp(env, t.fld); \
} \
\
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
* sfprf - set FPRF
*/
#define VSX_SQRT(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
helper_reset_fpstatus(env); \
\
for (i = 0; i < nels; i++) { \
float_status tstat = env->fp_status; \
set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_sqrt(xb.fld, &tstat); \
+ t.fld = tp##_sqrt(xb->fld, &tstat); \
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
- if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) { \
+ if (tp##_is_neg(xb->fld) && !tp##_is_zero(xb->fld)) { \
float_invalid_op_vxsqrt(env, sfprf, GETPC()); \
- } else if (tp##_is_signaling_nan(xb.fld, &tstat)) { \
+ } else if (tp##_is_signaling_nan(xb->fld, &tstat)) { \
float_invalid_op_vxsnan(env, GETPC()); \
} \
} \
\
if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
+ t.fld = helper_frsp(env, t.fld); \
} \
\
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
* sfprf - set FPRF
*/
#define VSX_RSQRTE(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
helper_reset_fpstatus(env); \
\
for (i = 0; i < nels; i++) { \
float_status tstat = env->fp_status; \
set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_sqrt(xb.fld, &tstat); \
- xt.fld = tp##_div(tp##_one, xt.fld, &tstat); \
+ t.fld = tp##_sqrt(xb->fld, &tstat); \
+ t.fld = tp##_div(tp##_one, t.fld, &tstat); \
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
- if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) { \
+ if (tp##_is_neg(xb->fld) && !tp##_is_zero(xb->fld)) { \
float_invalid_op_vxsqrt(env, sfprf, GETPC()); \
- } else if (tp##_is_signaling_nan(xb.fld, &tstat)) { \
+ } else if (tp##_is_signaling_nan(xb->fld, &tstat)) { \
float_invalid_op_vxsnan(env, GETPC()); \
} \
} \
\
if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
+ t.fld = helper_frsp(env, t.fld); \
} \
\
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
* nbits - number of fraction bits
*/
#define VSX_TDIV(op, nels, tp, fld, emin, emax, nbits) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xa, xb; \
int i; \
int fe_flag = 0; \
int fg_flag = 0; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- \
for (i = 0; i < nels; i++) { \
- if (unlikely(tp##_is_infinity(xa.fld) || \
- tp##_is_infinity(xb.fld) || \
- tp##_is_zero(xb.fld))) { \
+ if (unlikely(tp##_is_infinity(xa->fld) || \
+ tp##_is_infinity(xb->fld) || \
+ tp##_is_zero(xb->fld))) { \
fe_flag = 1; \
fg_flag = 1; \
} else { \
- int e_a = ppc_##tp##_get_unbiased_exp(xa.fld); \
- int e_b = ppc_##tp##_get_unbiased_exp(xb.fld); \
+ int e_a = ppc_##tp##_get_unbiased_exp(xa->fld); \
+ int e_b = ppc_##tp##_get_unbiased_exp(xb->fld); \
\
- if (unlikely(tp##_is_any_nan(xa.fld) || \
- tp##_is_any_nan(xb.fld))) { \
+ if (unlikely(tp##_is_any_nan(xa->fld) || \
+ tp##_is_any_nan(xb->fld))) { \
fe_flag = 1; \
} else if ((e_b <= emin) || (e_b >= (emax - 2))) { \
fe_flag = 1; \
- } else if (!tp##_is_zero(xa.fld) && \
+ } else if (!tp##_is_zero(xa->fld) && \
(((e_a - e_b) >= emax) || \
((e_a - e_b) <= (emin + 1)) || \
(e_a <= (emin + nbits)))) { \
fe_flag = 1; \
} \
\
- if (unlikely(tp##_is_zero_or_denormal(xb.fld))) { \
+ if (unlikely(tp##_is_zero_or_denormal(xb->fld))) { \
/* \
* XB is not zero because of the above check and so \
* must be denormalized. \
* nbits - number of fraction bits
*/
#define VSX_TSQRT(op, nels, tp, fld, emin, nbits) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xa, xb; \
int i; \
int fe_flag = 0; \
int fg_flag = 0; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- \
for (i = 0; i < nels; i++) { \
- if (unlikely(tp##_is_infinity(xb.fld) || \
- tp##_is_zero(xb.fld))) { \
+ if (unlikely(tp##_is_infinity(xb->fld) || \
+ tp##_is_zero(xb->fld))) { \
fe_flag = 1; \
fg_flag = 1; \
} else { \
- int e_b = ppc_##tp##_get_unbiased_exp(xb.fld); \
+ int e_b = ppc_##tp##_get_unbiased_exp(xb->fld); \
\
- if (unlikely(tp##_is_any_nan(xb.fld))) { \
+ if (unlikely(tp##_is_any_nan(xb->fld))) { \
fe_flag = 1; \
- } else if (unlikely(tp##_is_zero(xb.fld))) { \
+ } else if (unlikely(tp##_is_zero(xb->fld))) { \
fe_flag = 1; \
- } else if (unlikely(tp##_is_neg(xb.fld))) { \
+ } else if (unlikely(tp##_is_neg(xb->fld))) { \
fe_flag = 1; \
- } else if (!tp##_is_zero(xb.fld) && \
+ } else if (!tp##_is_zero(xb->fld) && \
(e_b <= (emin + nbits))) { \
fe_flag = 1; \
} \
\
- if (unlikely(tp##_is_zero_or_denormal(xb.fld))) { \
+ if (unlikely(tp##_is_zero_or_denormal(xb->fld))) { \
/* \
* XB is not zero because of the above check and \
* therefore must be denormalized. \
* fld - vsr_t field (VsrD(*) or VsrW(*))
* maddflgs - flags for the float*muladd routine that control the
* various forms (madd, msub, nmadd, nmsub)
- * afrm - A form (1=A, 0=M)
* sfprf - set FPRF
*/
-#define VSX_MADD(op, nels, tp, fld, maddflgs, afrm, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+#define VSX_MADD(op, nels, tp, fld, maddflgs, sfprf, r2sp) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *b, ppc_vsr_t *c) \
{ \
- ppc_vsr_t xt_in, xa, xb, xt_out; \
- ppc_vsr_t *b, *c; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- if (afrm) { /* AxB + T */ \
- b = &xb; \
- c = &xt_in; \
- } else { /* AxT + B */ \
- b = &xt_in; \
- c = &xb; \
- } \
- \
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt_in, env); \
- \
- xt_out = xt_in; \
- \
helper_reset_fpstatus(env); \
\
for (i = 0; i < nels; i++) { \
* result to odd. \
*/ \
set_float_rounding_mode(float_round_to_zero, &tstat); \
- xt_out.fld = tp##_muladd(xa.fld, b->fld, c->fld, \
- maddflgs, &tstat); \
- xt_out.fld |= (get_float_exception_flags(&tstat) & \
- float_flag_inexact) != 0; \
+ t.fld = tp##_muladd(xa->fld, b->fld, c->fld, \
+ maddflgs, &tstat); \
+ t.fld |= (get_float_exception_flags(&tstat) & \
+ float_flag_inexact) != 0; \
} else { \
- xt_out.fld = tp##_muladd(xa.fld, b->fld, c->fld, \
- maddflgs, &tstat); \
+ t.fld = tp##_muladd(xa->fld, b->fld, c->fld, \
+ maddflgs, &tstat); \
} \
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
- tp##_maddsub_update_excp(env, xa.fld, b->fld, \
+ tp##_maddsub_update_excp(env, xa->fld, b->fld, \
c->fld, maddflgs, GETPC()); \
} \
\
if (r2sp) { \
- xt_out.fld = helper_frsp(env, xt_out.fld); \
+ t.fld = helper_frsp(env, t.fld); \
} \
\
if (sfprf) { \
- helper_compute_fprf_float64(env, xt_out.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
- putVSR(xT(opcode), &xt_out, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
-VSX_MADD(xsmaddadp, 1, float64, VsrD(0), MADD_FLGS, 1, 1, 0)
-VSX_MADD(xsmaddmdp, 1, float64, VsrD(0), MADD_FLGS, 0, 1, 0)
-VSX_MADD(xsmsubadp, 1, float64, VsrD(0), MSUB_FLGS, 1, 1, 0)
-VSX_MADD(xsmsubmdp, 1, float64, VsrD(0), MSUB_FLGS, 0, 1, 0)
-VSX_MADD(xsnmaddadp, 1, float64, VsrD(0), NMADD_FLGS, 1, 1, 0)
-VSX_MADD(xsnmaddmdp, 1, float64, VsrD(0), NMADD_FLGS, 0, 1, 0)
-VSX_MADD(xsnmsubadp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 1, 0)
-VSX_MADD(xsnmsubmdp, 1, float64, VsrD(0), NMSUB_FLGS, 0, 1, 0)
-
-VSX_MADD(xsmaddasp, 1, float64, VsrD(0), MADD_FLGS, 1, 1, 1)
-VSX_MADD(xsmaddmsp, 1, float64, VsrD(0), MADD_FLGS, 0, 1, 1)
-VSX_MADD(xsmsubasp, 1, float64, VsrD(0), MSUB_FLGS, 1, 1, 1)
-VSX_MADD(xsmsubmsp, 1, float64, VsrD(0), MSUB_FLGS, 0, 1, 1)
-VSX_MADD(xsnmaddasp, 1, float64, VsrD(0), NMADD_FLGS, 1, 1, 1)
-VSX_MADD(xsnmaddmsp, 1, float64, VsrD(0), NMADD_FLGS, 0, 1, 1)
-VSX_MADD(xsnmsubasp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 1, 1)
-VSX_MADD(xsnmsubmsp, 1, float64, VsrD(0), NMSUB_FLGS, 0, 1, 1)
-
-VSX_MADD(xvmaddadp, 2, float64, VsrD(i), MADD_FLGS, 1, 0, 0)
-VSX_MADD(xvmaddmdp, 2, float64, VsrD(i), MADD_FLGS, 0, 0, 0)
-VSX_MADD(xvmsubadp, 2, float64, VsrD(i), MSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvmsubmdp, 2, float64, VsrD(i), MSUB_FLGS, 0, 0, 0)
-VSX_MADD(xvnmaddadp, 2, float64, VsrD(i), NMADD_FLGS, 1, 0, 0)
-VSX_MADD(xvnmaddmdp, 2, float64, VsrD(i), NMADD_FLGS, 0, 0, 0)
-VSX_MADD(xvnmsubadp, 2, float64, VsrD(i), NMSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvnmsubmdp, 2, float64, VsrD(i), NMSUB_FLGS, 0, 0, 0)
-
-VSX_MADD(xvmaddasp, 4, float32, VsrW(i), MADD_FLGS, 1, 0, 0)
-VSX_MADD(xvmaddmsp, 4, float32, VsrW(i), MADD_FLGS, 0, 0, 0)
-VSX_MADD(xvmsubasp, 4, float32, VsrW(i), MSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvmsubmsp, 4, float32, VsrW(i), MSUB_FLGS, 0, 0, 0)
-VSX_MADD(xvnmaddasp, 4, float32, VsrW(i), NMADD_FLGS, 1, 0, 0)
-VSX_MADD(xvnmaddmsp, 4, float32, VsrW(i), NMADD_FLGS, 0, 0, 0)
-VSX_MADD(xvnmsubasp, 4, float32, VsrW(i), NMSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvnmsubmsp, 4, float32, VsrW(i), NMSUB_FLGS, 0, 0, 0)
+VSX_MADD(xsmadddp, 1, float64, VsrD(0), MADD_FLGS, 1, 0)
+VSX_MADD(xsmsubdp, 1, float64, VsrD(0), MSUB_FLGS, 1, 0)
+VSX_MADD(xsnmadddp, 1, float64, VsrD(0), NMADD_FLGS, 1, 0)
+VSX_MADD(xsnmsubdp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 0)
+VSX_MADD(xsmaddsp, 1, float64, VsrD(0), MADD_FLGS, 1, 1)
+VSX_MADD(xsmsubsp, 1, float64, VsrD(0), MSUB_FLGS, 1, 1)
+VSX_MADD(xsnmaddsp, 1, float64, VsrD(0), NMADD_FLGS, 1, 1)
+VSX_MADD(xsnmsubsp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 1)
+
+VSX_MADD(xvmadddp, 2, float64, VsrD(i), MADD_FLGS, 0, 0)
+VSX_MADD(xvmsubdp, 2, float64, VsrD(i), MSUB_FLGS, 0, 0)
+VSX_MADD(xvnmadddp, 2, float64, VsrD(i), NMADD_FLGS, 0, 0)
+VSX_MADD(xvnmsubdp, 2, float64, VsrD(i), NMSUB_FLGS, 0, 0)
+
+VSX_MADD(xvmaddsp, 4, float32, VsrW(i), MADD_FLGS, 0, 0)
+VSX_MADD(xvmsubsp, 4, float32, VsrW(i), MSUB_FLGS, 0, 0)
+VSX_MADD(xvnmaddsp, 4, float32, VsrW(i), NMADD_FLGS, 0, 0)
+VSX_MADD(xvnmsubsp, 4, float32, VsrW(i), NMSUB_FLGS, 0, 0)
/*
* VSX_SCALAR_CMP_DP - VSX scalar floating point compare double precision
* svxvc - set VXVC bit
*/
#define VSX_SCALAR_CMP_DP(op, cmp, exp, svxvc) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
bool vxsnan_flag = false, vxvc_flag = false, vex_flag = false; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
- if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \
- float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \
+ if (float64_is_signaling_nan(xa->VsrD(0), &env->fp_status) || \
+ float64_is_signaling_nan(xb->VsrD(0), &env->fp_status)) { \
vxsnan_flag = true; \
if (fpscr_ve == 0 && svxvc) { \
vxvc_flag = true; \
} \
} else if (svxvc) { \
- vxvc_flag = float64_is_quiet_nan(xa.VsrD(0), &env->fp_status) || \
- float64_is_quiet_nan(xb.VsrD(0), &env->fp_status); \
+ vxvc_flag = float64_is_quiet_nan(xa->VsrD(0), &env->fp_status) || \
+ float64_is_quiet_nan(xb->VsrD(0), &env->fp_status); \
} \
if (vxsnan_flag) { \
float_invalid_op_vxsnan(env, GETPC()); \
vex_flag = fpscr_ve && (vxvc_flag || vxsnan_flag); \
\
if (!vex_flag) { \
- if (float64_##cmp(xb.VsrD(0), xa.VsrD(0), &env->fp_status) == exp) { \
- xt.VsrD(0) = -1; \
- xt.VsrD(1) = 0; \
+ if (float64_##cmp(xb->VsrD(0), xa->VsrD(0), \
+ &env->fp_status) == exp) { \
+ t.VsrD(0) = -1; \
+ t.VsrD(1) = 0; \
} else { \
- xt.VsrD(0) = 0; \
- xt.VsrD(1) = 0; \
+ t.VsrD(0) = 0; \
+ t.VsrD(1) = 0; \
} \
} \
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
VSX_SCALAR_CMP_DP(xscmpgtdp, lt, 1, 1)
VSX_SCALAR_CMP_DP(xscmpnedp, eq, 0, 0)
-void helper_xscmpexpdp(CPUPPCState *env, uint32_t opcode)
+void helper_xscmpexpdp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xa, ppc_vsr_t *xb)
{
- ppc_vsr_t xa, xb;
int64_t exp_a, exp_b;
uint32_t cc;
- getVSR(xA(opcode), &xa, env);
- getVSR(xB(opcode), &xb, env);
-
- exp_a = extract64(xa.VsrD(0), 52, 11);
- exp_b = extract64(xb.VsrD(0), 52, 11);
+ exp_a = extract64(xa->VsrD(0), 52, 11);
+ exp_b = extract64(xb->VsrD(0), 52, 11);
- if (unlikely(float64_is_any_nan(xa.VsrD(0)) ||
- float64_is_any_nan(xb.VsrD(0)))) {
+ if (unlikely(float64_is_any_nan(xa->VsrD(0)) ||
+ float64_is_any_nan(xb->VsrD(0)))) {
cc = CRF_SO;
} else {
if (exp_a < exp_b) {
do_float_check_status(env, GETPC());
}
-void helper_xscmpexpqp(CPUPPCState *env, uint32_t opcode)
+void helper_xscmpexpqp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xa, ppc_vsr_t *xb)
{
- ppc_vsr_t xa, xb;
int64_t exp_a, exp_b;
uint32_t cc;
- getVSR(rA(opcode) + 32, &xa, env);
- getVSR(rB(opcode) + 32, &xb, env);
+ exp_a = extract64(xa->VsrD(0), 48, 15);
+ exp_b = extract64(xb->VsrD(0), 48, 15);
- exp_a = extract64(xa.VsrD(0), 48, 15);
- exp_b = extract64(xb.VsrD(0), 48, 15);
-
- if (unlikely(float128_is_any_nan(xa.f128) ||
- float128_is_any_nan(xb.f128))) {
+ if (unlikely(float128_is_any_nan(xa->f128) ||
+ float128_is_any_nan(xb->f128))) {
cc = CRF_SO;
} else {
if (exp_a < exp_b) {
}
#define VSX_SCALAR_CMP(op, ordered) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xa, xb; \
uint32_t cc = 0; \
bool vxsnan_flag = false, vxvc_flag = false; \
\
helper_reset_fpstatus(env); \
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
\
- if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \
- float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \
+ if (float64_is_signaling_nan(xa->VsrD(0), &env->fp_status) || \
+ float64_is_signaling_nan(xb->VsrD(0), &env->fp_status)) { \
vxsnan_flag = true; \
cc = CRF_SO; \
if (fpscr_ve == 0 && ordered) { \
vxvc_flag = true; \
} \
- } else if (float64_is_quiet_nan(xa.VsrD(0), &env->fp_status) || \
- float64_is_quiet_nan(xb.VsrD(0), &env->fp_status)) { \
+ } else if (float64_is_quiet_nan(xa->VsrD(0), &env->fp_status) || \
+ float64_is_quiet_nan(xb->VsrD(0), &env->fp_status)) { \
cc = CRF_SO; \
if (ordered) { \
vxvc_flag = true; \
float_invalid_op_vxvc(env, 0, GETPC()); \
} \
\
- if (float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) { \
+ if (float64_lt(xa->VsrD(0), xb->VsrD(0), &env->fp_status)) { \
cc |= CRF_LT; \
- } else if (!float64_le(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) { \
+ } else if (!float64_le(xa->VsrD(0), xb->VsrD(0), &env->fp_status)) { \
cc |= CRF_GT; \
} else { \
cc |= CRF_EQ; \
VSX_SCALAR_CMP(xscmpudp, 0)
#define VSX_SCALAR_CMPQ(op, ordered) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xa, xb; \
uint32_t cc = 0; \
bool vxsnan_flag = false, vxvc_flag = false; \
\
helper_reset_fpstatus(env); \
- getVSR(rA(opcode) + 32, &xa, env); \
- getVSR(rB(opcode) + 32, &xb, env); \
\
- if (float128_is_signaling_nan(xa.f128, &env->fp_status) || \
- float128_is_signaling_nan(xb.f128, &env->fp_status)) { \
+ if (float128_is_signaling_nan(xa->f128, &env->fp_status) || \
+ float128_is_signaling_nan(xb->f128, &env->fp_status)) { \
vxsnan_flag = true; \
cc = CRF_SO; \
if (fpscr_ve == 0 && ordered) { \
vxvc_flag = true; \
} \
- } else if (float128_is_quiet_nan(xa.f128, &env->fp_status) || \
- float128_is_quiet_nan(xb.f128, &env->fp_status)) { \
+ } else if (float128_is_quiet_nan(xa->f128, &env->fp_status) || \
+ float128_is_quiet_nan(xb->f128, &env->fp_status)) { \
cc = CRF_SO; \
if (ordered) { \
vxvc_flag = true; \
float_invalid_op_vxvc(env, 0, GETPC()); \
} \
\
- if (float128_lt(xa.f128, xb.f128, &env->fp_status)) { \
+ if (float128_lt(xa->f128, xb->f128, &env->fp_status)) { \
cc |= CRF_LT; \
- } else if (!float128_le(xa.f128, xb.f128, &env->fp_status)) { \
+ } else if (!float128_le(xa->f128, xb->f128, &env->fp_status)) { \
cc |= CRF_GT; \
} else { \
cc |= CRF_EQ; \
* fld - vsr_t field (VsrD(*) or VsrW(*))
*/
#define VSX_MAX_MIN(name, op, nels, tp, fld) \
-void helper_##name(CPUPPCState *env, uint32_t opcode) \
+void helper_##name(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
for (i = 0; i < nels; i++) { \
- xt.fld = tp##_##op(xa.fld, xb.fld, &env->fp_status); \
- if (unlikely(tp##_is_signaling_nan(xa.fld, &env->fp_status) || \
- tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \
+ t.fld = tp##_##op(xa->fld, xb->fld, &env->fp_status); \
+ if (unlikely(tp##_is_signaling_nan(xa->fld, &env->fp_status) || \
+ tp##_is_signaling_nan(xb->fld, &env->fp_status))) { \
float_invalid_op_vxsnan(env, GETPC()); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
VSX_MAX_MIN(xvminsp, minnum, 4, float32, VsrW(i))
#define VSX_MAX_MINC(name, max) \
-void helper_##name(CPUPPCState *env, uint32_t opcode) \
+void helper_##name(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
bool vxsnan_flag = false, vex_flag = false; \
\
- getVSR(rA(opcode) + 32, &xa, env); \
- getVSR(rB(opcode) + 32, &xb, env); \
- getVSR(rD(opcode) + 32, &xt, env); \
- \
- if (unlikely(float64_is_any_nan(xa.VsrD(0)) || \
- float64_is_any_nan(xb.VsrD(0)))) { \
- if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \
- float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \
+ if (unlikely(float64_is_any_nan(xa->VsrD(0)) || \
+ float64_is_any_nan(xb->VsrD(0)))) { \
+ if (float64_is_signaling_nan(xa->VsrD(0), &env->fp_status) || \
+ float64_is_signaling_nan(xb->VsrD(0), &env->fp_status)) { \
vxsnan_flag = true; \
} \
- xt.VsrD(0) = xb.VsrD(0); \
+ t.VsrD(0) = xb->VsrD(0); \
} else if ((max && \
- !float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) || \
+ !float64_lt(xa->VsrD(0), xb->VsrD(0), &env->fp_status)) || \
(!max && \
- float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status))) { \
- xt.VsrD(0) = xa.VsrD(0); \
+ float64_lt(xa->VsrD(0), xb->VsrD(0), &env->fp_status))) { \
+ t.VsrD(0) = xa->VsrD(0); \
} else { \
- xt.VsrD(0) = xb.VsrD(0); \
+ t.VsrD(0) = xb->VsrD(0); \
} \
\
vex_flag = fpscr_ve & vxsnan_flag; \
float_invalid_op_vxsnan(env, GETPC()); \
} \
if (!vex_flag) { \
- putVSR(rD(opcode) + 32, &xt, env); \
+ *xt = t; \
} \
} \
VSX_MAX_MINC(xsmincdp, 0);
#define VSX_MAX_MINJ(name, max) \
-void helper_##name(CPUPPCState *env, uint32_t opcode) \
+void helper_##name(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
bool vxsnan_flag = false, vex_flag = false; \
\
- getVSR(rA(opcode) + 32, &xa, env); \
- getVSR(rB(opcode) + 32, &xb, env); \
- getVSR(rD(opcode) + 32, &xt, env); \
- \
- if (unlikely(float64_is_any_nan(xa.VsrD(0)))) { \
- if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status)) { \
+ if (unlikely(float64_is_any_nan(xa->VsrD(0)))) { \
+ if (float64_is_signaling_nan(xa->VsrD(0), &env->fp_status)) { \
vxsnan_flag = true; \
} \
- xt.VsrD(0) = xa.VsrD(0); \
- } else if (unlikely(float64_is_any_nan(xb.VsrD(0)))) { \
- if (float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \
+ t.VsrD(0) = xa->VsrD(0); \
+ } else if (unlikely(float64_is_any_nan(xb->VsrD(0)))) { \
+ if (float64_is_signaling_nan(xb->VsrD(0), &env->fp_status)) { \
vxsnan_flag = true; \
} \
- xt.VsrD(0) = xb.VsrD(0); \
- } else if (float64_is_zero(xa.VsrD(0)) && float64_is_zero(xb.VsrD(0))) { \
+ t.VsrD(0) = xb->VsrD(0); \
+ } else if (float64_is_zero(xa->VsrD(0)) && \
+ float64_is_zero(xb->VsrD(0))) { \
if (max) { \
- if (!float64_is_neg(xa.VsrD(0)) || !float64_is_neg(xb.VsrD(0))) { \
- xt.VsrD(0) = 0ULL; \
+ if (!float64_is_neg(xa->VsrD(0)) || \
+ !float64_is_neg(xb->VsrD(0))) { \
+ t.VsrD(0) = 0ULL; \
} else { \
- xt.VsrD(0) = 0x8000000000000000ULL; \
+ t.VsrD(0) = 0x8000000000000000ULL; \
} \
} else { \
- if (float64_is_neg(xa.VsrD(0)) || float64_is_neg(xb.VsrD(0))) { \
- xt.VsrD(0) = 0x8000000000000000ULL; \
+ if (float64_is_neg(xa->VsrD(0)) || \
+ float64_is_neg(xb->VsrD(0))) { \
+ t.VsrD(0) = 0x8000000000000000ULL; \
} else { \
- xt.VsrD(0) = 0ULL; \
+ t.VsrD(0) = 0ULL; \
} \
} \
} else if ((max && \
- !float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) || \
+ !float64_lt(xa->VsrD(0), xb->VsrD(0), &env->fp_status)) || \
(!max && \
- float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status))) { \
- xt.VsrD(0) = xa.VsrD(0); \
+ float64_lt(xa->VsrD(0), xb->VsrD(0), &env->fp_status))) { \
+ t.VsrD(0) = xa->VsrD(0); \
} else { \
- xt.VsrD(0) = xb.VsrD(0); \
+ t.VsrD(0) = xb->VsrD(0); \
} \
\
vex_flag = fpscr_ve & vxsnan_flag; \
float_invalid_op_vxsnan(env, GETPC()); \
} \
if (!vex_flag) { \
- putVSR(rD(opcode) + 32, &xt, env); \
+ *xt = t; \
} \
} \
* exp - expected result of comparison
*/
#define VSX_CMP(op, nels, tp, fld, cmp, svxvc, exp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+uint32_t helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xa, xb; \
+ ppc_vsr_t t = *xt; \
+ uint32_t crf6 = 0; \
int i; \
int all_true = 1; \
int all_false = 1; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
for (i = 0; i < nels; i++) { \
- if (unlikely(tp##_is_any_nan(xa.fld) || \
- tp##_is_any_nan(xb.fld))) { \
- if (tp##_is_signaling_nan(xa.fld, &env->fp_status) || \
- tp##_is_signaling_nan(xb.fld, &env->fp_status)) { \
+ if (unlikely(tp##_is_any_nan(xa->fld) || \
+ tp##_is_any_nan(xb->fld))) { \
+ if (tp##_is_signaling_nan(xa->fld, &env->fp_status) || \
+ tp##_is_signaling_nan(xb->fld, &env->fp_status)) { \
float_invalid_op_vxsnan(env, GETPC()); \
} \
if (svxvc) { \
float_invalid_op_vxvc(env, 0, GETPC()); \
} \
- xt.fld = 0; \
+ t.fld = 0; \
all_true = 0; \
} else { \
- if (tp##_##cmp(xb.fld, xa.fld, &env->fp_status) == exp) { \
- xt.fld = -1; \
+ if (tp##_##cmp(xb->fld, xa->fld, &env->fp_status) == exp) { \
+ t.fld = -1; \
all_false = 0; \
} else { \
- xt.fld = 0; \
+ t.fld = 0; \
all_true = 0; \
} \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
- if ((opcode >> (31 - 21)) & 1) { \
- env->crf[6] = (all_true ? 0x8 : 0) | (all_false ? 0x2 : 0); \
- } \
- do_float_check_status(env, GETPC()); \
- }
+ *xt = t; \
+ crf6 = (all_true ? 0x8 : 0) | (all_false ? 0x2 : 0); \
+ return crf6; \
+}
VSX_CMP(xvcmpeqdp, 2, float64, VsrD(i), eq, 0, 1)
VSX_CMP(xvcmpgedp, 2, float64, VsrD(i), le, 1, 1)
* sfprf - set FPRF
*/
#define VSX_CVT_FP_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
for (i = 0; i < nels; i++) { \
- xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
- if (unlikely(stp##_is_signaling_nan(xb.sfld, \
+ t.tfld = stp##_to_##ttp(xb->sfld, &env->fp_status); \
+ if (unlikely(stp##_is_signaling_nan(xb->sfld, \
&env->fp_status))) { \
float_invalid_op_vxsnan(env, GETPC()); \
- xt.tfld = ttp##_snan_to_qnan(xt.tfld); \
+ t.tfld = ttp##_snan_to_qnan(t.tfld); \
} \
if (sfprf) { \
- helper_compute_fprf_##ttp(env, xt.tfld); \
+ helper_compute_fprf_##ttp(env, t.tfld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
* sfprf - set FPRF
*/
#define VSX_CVT_FP_TO_FP_VECTOR(op, nels, stp, ttp, sfld, tfld, sfprf) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(rB(opcode) + 32, &xb, env); \
- getVSR(rD(opcode) + 32, &xt, env); \
- \
for (i = 0; i < nels; i++) { \
- xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
- if (unlikely(stp##_is_signaling_nan(xb.sfld, \
+ t.tfld = stp##_to_##ttp(xb->sfld, &env->fp_status); \
+ if (unlikely(stp##_is_signaling_nan(xb->sfld, \
&env->fp_status))) { \
float_invalid_op_vxsnan(env, GETPC()); \
- xt.tfld = ttp##_snan_to_qnan(xt.tfld); \
+ t.tfld = ttp##_snan_to_qnan(t.tfld); \
} \
if (sfprf) { \
- helper_compute_fprf_##ttp(env, xt.tfld); \
+ helper_compute_fprf_##ttp(env, t.tfld); \
} \
} \
\
- putVSR(rD(opcode) + 32, &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
* sfprf - set FPRF
*/
#define VSX_CVT_FP_TO_FP_HP(op, nels, stp, ttp, sfld, tfld, sfprf) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = { }; \
int i; \
\
- getVSR(xB(opcode), &xb, env); \
- memset(&xt, 0, sizeof(xt)); \
- \
for (i = 0; i < nels; i++) { \
- xt.tfld = stp##_to_##ttp(xb.sfld, 1, &env->fp_status); \
- if (unlikely(stp##_is_signaling_nan(xb.sfld, \
+ t.tfld = stp##_to_##ttp(xb->sfld, 1, &env->fp_status); \
+ if (unlikely(stp##_is_signaling_nan(xb->sfld, \
&env->fp_status))) { \
float_invalid_op_vxsnan(env, GETPC()); \
- xt.tfld = ttp##_snan_to_qnan(xt.tfld); \
+ t.tfld = ttp##_snan_to_qnan(t.tfld); \
} \
if (sfprf) { \
- helper_compute_fprf_##ttp(env, xt.tfld); \
+ helper_compute_fprf_##ttp(env, t.tfld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
* xscvqpdp isn't using VSX_CVT_FP_TO_FP() because xscvqpdpo will be
* added to this later.
*/
-void helper_xscvqpdp(CPUPPCState *env, uint32_t opcode)
+void helper_xscvqpdp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xb)
{
- ppc_vsr_t xt, xb;
+ ppc_vsr_t t = { };
float_status tstat;
- getVSR(rB(opcode) + 32, &xb, env);
- memset(&xt, 0, sizeof(xt));
-
tstat = env->fp_status;
if (unlikely(Rc(opcode) != 0)) {
tstat.float_rounding_mode = float_round_to_odd;
}
- xt.VsrD(0) = float128_to_float64(xb.f128, &tstat);
+ t.VsrD(0) = float128_to_float64(xb->f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
- if (unlikely(float128_is_signaling_nan(xb.f128, &tstat))) {
+ if (unlikely(float128_is_signaling_nan(xb->f128, &tstat))) {
float_invalid_op_vxsnan(env, GETPC());
- xt.VsrD(0) = float64_snan_to_qnan(xt.VsrD(0));
+ t.VsrD(0) = float64_snan_to_qnan(t.VsrD(0));
}
- helper_compute_fprf_float64(env, xt.VsrD(0));
+ helper_compute_fprf_float64(env, t.VsrD(0));
- putVSR(rD(opcode) + 32, &xt, env);
+ *xt = t;
do_float_check_status(env, GETPC());
}
* rnan - resulting NaN
*/
#define VSX_CVT_FP_TO_INT(op, nels, stp, ttp, sfld, tfld, rnan) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
int all_flags = env->fp_status.float_exception_flags, flags; \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
for (i = 0; i < nels; i++) { \
env->fp_status.float_exception_flags = 0; \
- xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld, &env->fp_status); \
+ t.tfld = stp##_to_##ttp##_round_to_zero(xb->sfld, &env->fp_status); \
flags = env->fp_status.float_exception_flags; \
if (unlikely(flags & float_flag_invalid)) { \
- float_invalid_cvt(env, 0, GETPC(), stp##_classify(xb.sfld)); \
- xt.tfld = rnan; \
+ float_invalid_cvt(env, 0, GETPC(), stp##_classify(xb->sfld)); \
+ t.tfld = rnan; \
} \
all_flags |= flags; \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
env->fp_status.float_exception_flags = all_flags; \
do_float_check_status(env, GETPC()); \
}
* rnan - resulting NaN
*/
#define VSX_CVT_FP_TO_INT_VECTOR(op, stp, ttp, sfld, tfld, rnan) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = { }; \
\
- getVSR(rB(opcode) + 32, &xb, env); \
- memset(&xt, 0, sizeof(xt)); \
- \
- xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld, &env->fp_status); \
+ t.tfld = stp##_to_##ttp##_round_to_zero(xb->sfld, &env->fp_status); \
if (env->fp_status.float_exception_flags & float_flag_invalid) { \
- float_invalid_cvt(env, 0, GETPC(), stp##_classify(xb.sfld)); \
- xt.tfld = rnan; \
+ float_invalid_cvt(env, 0, GETPC(), stp##_classify(xb->sfld)); \
+ t.tfld = rnan; \
} \
\
- putVSR(rD(opcode) + 32, &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
* sfprf - set FPRF
*/
#define VSX_CVT_INT_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
\
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
for (i = 0; i < nels; i++) { \
- xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
+ t.tfld = stp##_to_##ttp(xb->sfld, &env->fp_status); \
if (r2sp) { \
- xt.tfld = helper_frsp(env, xt.tfld); \
+ t.tfld = helper_frsp(env, t.tfld); \
} \
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.tfld); \
+ helper_compute_fprf_float64(env, t.tfld); \
} \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
* tfld - target vsr_t field
*/
#define VSX_CVT_INT_TO_FP_VECTOR(op, stp, ttp, sfld, tfld) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, uint32_t opcode, \
+ ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
\
- getVSR(rB(opcode) + 32, &xb, env); \
- getVSR(rD(opcode) + 32, &xt, env); \
+ t.tfld = stp##_to_##ttp(xb->sfld, &env->fp_status); \
+ helper_compute_fprf_##ttp(env, t.tfld); \
\
- xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
- helper_compute_fprf_##ttp(env, xt.tfld); \
- \
- putVSR(xT(opcode) + 32, &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
* sfprf - set FPRF
*/
#define VSX_ROUND(op, nels, tp, fld, rmode, sfprf) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb) \
{ \
- ppc_vsr_t xt, xb; \
+ ppc_vsr_t t = *xt; \
int i; \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
\
if (rmode != FLOAT_ROUND_CURRENT) { \
set_float_rounding_mode(rmode, &env->fp_status); \
} \
\
for (i = 0; i < nels; i++) { \
- if (unlikely(tp##_is_signaling_nan(xb.fld, \
+ if (unlikely(tp##_is_signaling_nan(xb->fld, \
&env->fp_status))) { \
float_invalid_op_vxsnan(env, GETPC()); \
- xt.fld = tp##_snan_to_qnan(xb.fld); \
+ t.fld = tp##_snan_to_qnan(xb->fld); \
} else { \
- xt.fld = tp##_round_to_int(xb.fld, &env->fp_status); \
+ t.fld = tp##_round_to_int(xb->fld, &env->fp_status); \
} \
if (sfprf) { \
- helper_compute_fprf_float64(env, xt.fld); \
+ helper_compute_fprf_float64(env, t.fld); \
} \
} \
\
env->fp_status.float_exception_flags &= ~float_flag_inexact; \
} \
\
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
do_float_check_status(env, GETPC()); \
}
}
#define VSX_XXPERM(op, indexed) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
+void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
+ ppc_vsr_t *xa, ppc_vsr_t *pcv) \
{ \
- ppc_vsr_t xt, xa, pcv, xto; \
+ ppc_vsr_t t = *xt; \
int i, idx; \
\
- getVSR(xA(opcode), &xa, env); \
- getVSR(xT(opcode), &xt, env); \
- getVSR(xB(opcode), &pcv, env); \
- \
for (i = 0; i < 16; i++) { \
- idx = pcv.VsrB(i) & 0x1F; \
+ idx = pcv->VsrB(i) & 0x1F; \
if (indexed) { \
idx = 31 - idx; \
} \
- xto.VsrB(i) = (idx <= 15) ? xa.VsrB(idx) : xt.VsrB(idx - 16); \
+ t.VsrB(i) = (idx <= 15) ? xa->VsrB(idx) \
+ : xt->VsrB(idx - 16); \
} \
- putVSR(xT(opcode), &xto, env); \
+ *xt = t; \
}
VSX_XXPERM(xxperm, 0)
VSX_XXPERM(xxpermr, 1)
-void helper_xvxsigsp(CPUPPCState *env, uint32_t opcode)
+void helper_xvxsigsp(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)
{
- ppc_vsr_t xt, xb;
+ ppc_vsr_t t = { };
uint32_t exp, i, fraction;
- getVSR(xB(opcode), &xb, env);
- memset(&xt, 0, sizeof(xt));
-
for (i = 0; i < 4; i++) {
- exp = (xb.VsrW(i) >> 23) & 0xFF;
- fraction = xb.VsrW(i) & 0x7FFFFF;
+ exp = (xb->VsrW(i) >> 23) & 0xFF;
+ fraction = xb->VsrW(i) & 0x7FFFFF;
if (exp != 0 && exp != 255) {
- xt.VsrW(i) = fraction | 0x00800000;
+ t.VsrW(i) = fraction | 0x00800000;
} else {
- xt.VsrW(i) = fraction;
+ t.VsrW(i) = fraction;
}
}
- putVSR(xT(opcode), &xt, env);
+ *xt = t;
}
/*
#define VSX_TEST_DC(op, nels, xbn, tp, fld, tfld, fld_max, scrf) \
void helper_##op(CPUPPCState *env, uint32_t opcode) \
{ \
- ppc_vsr_t xt, xb; \
+ 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; \
\
- getVSR(xbn, &xb, env); \
if (!scrf) { \
- memset(&xt, 0, sizeof(xt)); \
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)) { \
+ 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)) { \
+ } else if (tp##_is_infinity(xb->fld)) { \
match = extract32(dcmx, 4 + !sign, 1); \
- } else if (tp##_is_zero(xb.fld)) { \
+ } else if (tp##_is_zero(xb->fld)) { \
match = extract32(dcmx, 2 + !sign, 1); \
- } else if (tp##_is_zero_or_denormal(xb.fld)) { \
+ } else if (tp##_is_zero_or_denormal(xb->fld)) { \
match = extract32(dcmx, 0 + !sign, 1); \
} \
\
env->fpscr |= cc << FPSCR_FPRF; \
env->crf[BF(opcode)] = cc; \
} else { \
- xt.tfld = match ? fld_max : 0; \
+ t.tfld = match ? fld_max : 0; \
} \
match = 0; \
} \
if (!scrf) { \
- putVSR(xT(opcode), &xt, env); \
+ *xt = t; \
} \
}
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)
-void helper_xststdcsp(CPUPPCState *env, uint32_t opcode)
+void helper_xststdcsp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xb)
{
- ppc_vsr_t xb;
uint32_t dcmx, sign, exp;
uint32_t cc, match = 0, not_sp = 0;
- getVSR(xB(opcode), &xb, env);
dcmx = DCMX(opcode);
- exp = (xb.VsrD(0) >> 52) & 0x7FF;
+ exp = (xb->VsrD(0) >> 52) & 0x7FF;
- sign = float64_is_neg(xb.VsrD(0));
- if (float64_is_any_nan(xb.VsrD(0))) {
+ sign = float64_is_neg(xb->VsrD(0));
+ if (float64_is_any_nan(xb->VsrD(0))) {
match = extract32(dcmx, 6, 1);
- } else if (float64_is_infinity(xb.VsrD(0))) {
+ } else if (float64_is_infinity(xb->VsrD(0))) {
match = extract32(dcmx, 4 + !sign, 1);
- } else if (float64_is_zero(xb.VsrD(0))) {
+ } else if (float64_is_zero(xb->VsrD(0))) {
match = extract32(dcmx, 2 + !sign, 1);
- } else if (float64_is_zero_or_denormal(xb.VsrD(0)) ||
+ } else if (float64_is_zero_or_denormal(xb->VsrD(0)) ||
(exp > 0 && exp < 0x381)) {
match = extract32(dcmx, 0 + !sign, 1);
}
- not_sp = !float64_eq(xb.VsrD(0),
+ not_sp = !float64_eq(xb->VsrD(0),
float32_to_float64(
- float64_to_float32(xb.VsrD(0), &env->fp_status),
+ float64_to_float32(xb->VsrD(0), &env->fp_status),
&env->fp_status), &env->fp_status);
cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT | not_sp << CRF_SO_BIT;
env->crf[BF(opcode)] = cc;
}
-void helper_xsrqpi(CPUPPCState *env, uint32_t opcode)
+void helper_xsrqpi(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xb)
{
- ppc_vsr_t xb;
- ppc_vsr_t xt;
+ ppc_vsr_t t = { };
uint8_t r = Rrm(opcode);
uint8_t ex = Rc(opcode);
uint8_t rmc = RMC(opcode);
uint8_t rmode = 0;
float_status tstat;
- getVSR(rB(opcode) + 32, &xb, env);
- memset(&xt, 0, sizeof(xt));
helper_reset_fpstatus(env);
if (r == 0 && rmc == 0) {
tstat = env->fp_status;
set_float_exception_flags(0, &tstat);
set_float_rounding_mode(rmode, &tstat);
- xt.f128 = float128_round_to_int(xb.f128, &tstat);
+ t.f128 = float128_round_to_int(xb->f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
- if (float128_is_signaling_nan(xb.f128, &tstat)) {
+ if (float128_is_signaling_nan(xb->f128, &tstat)) {
float_invalid_op_vxsnan(env, GETPC());
- xt.f128 = float128_snan_to_qnan(xt.f128);
+ t.f128 = float128_snan_to_qnan(t.f128);
}
}
env->fp_status.float_exception_flags &= ~float_flag_inexact;
}
- helper_compute_fprf_float128(env, xt.f128);
+ helper_compute_fprf_float128(env, t.f128);
do_float_check_status(env, GETPC());
- putVSR(rD(opcode) + 32, &xt, env);
+ *xt = t;
}
-void helper_xsrqpxp(CPUPPCState *env, uint32_t opcode)
+void helper_xsrqpxp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xb)
{
- ppc_vsr_t xb;
- ppc_vsr_t xt;
+ ppc_vsr_t t = { };
uint8_t r = Rrm(opcode);
uint8_t rmc = RMC(opcode);
uint8_t rmode = 0;
floatx80 round_res;
float_status tstat;
- getVSR(rB(opcode) + 32, &xb, env);
- memset(&xt, 0, sizeof(xt));
helper_reset_fpstatus(env);
if (r == 0 && rmc == 0) {
tstat = env->fp_status;
set_float_exception_flags(0, &tstat);
set_float_rounding_mode(rmode, &tstat);
- round_res = float128_to_floatx80(xb.f128, &tstat);
- xt.f128 = floatx80_to_float128(round_res, &tstat);
+ round_res = float128_to_floatx80(xb->f128, &tstat);
+ t.f128 = floatx80_to_float128(round_res, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
- if (float128_is_signaling_nan(xb.f128, &tstat)) {
+ if (float128_is_signaling_nan(xb->f128, &tstat)) {
float_invalid_op_vxsnan(env, GETPC());
- xt.f128 = float128_snan_to_qnan(xt.f128);
+ t.f128 = float128_snan_to_qnan(t.f128);
}
}
- helper_compute_fprf_float128(env, xt.f128);
- putVSR(rD(opcode) + 32, &xt, env);
+ helper_compute_fprf_float128(env, t.f128);
+ *xt = t;
do_float_check_status(env, GETPC());
}
-void helper_xssqrtqp(CPUPPCState *env, uint32_t opcode)
+void helper_xssqrtqp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xb)
{
- ppc_vsr_t xb;
- ppc_vsr_t xt;
+ ppc_vsr_t t = { };
float_status tstat;
- getVSR(rB(opcode) + 32, &xb, env);
- memset(&xt, 0, sizeof(xt));
helper_reset_fpstatus(env);
tstat = env->fp_status;
}
set_float_exception_flags(0, &tstat);
- xt.f128 = float128_sqrt(xb.f128, &tstat);
+ t.f128 = float128_sqrt(xb->f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
- if (float128_is_signaling_nan(xb.f128, &tstat)) {
+ if (float128_is_signaling_nan(xb->f128, &tstat)) {
float_invalid_op_vxsnan(env, GETPC());
- xt.f128 = float128_snan_to_qnan(xb.f128);
- } else if (float128_is_quiet_nan(xb.f128, &tstat)) {
- xt.f128 = xb.f128;
- } else if (float128_is_neg(xb.f128) && !float128_is_zero(xb.f128)) {
+ t.f128 = float128_snan_to_qnan(xb->f128);
+ } else if (float128_is_quiet_nan(xb->f128, &tstat)) {
+ t.f128 = xb->f128;
+ } else if (float128_is_neg(xb->f128) && !float128_is_zero(xb->f128)) {
float_invalid_op_vxsqrt(env, 1, GETPC());
- xt.f128 = float128_default_nan(&env->fp_status);
+ t.f128 = float128_default_nan(&env->fp_status);
}
}
- helper_compute_fprf_float128(env, xt.f128);
- putVSR(rD(opcode) + 32, &xt, env);
+ helper_compute_fprf_float128(env, t.f128);
+ *xt = t;
do_float_check_status(env, GETPC());
}
-void helper_xssubqp(CPUPPCState *env, uint32_t opcode)
+void helper_xssubqp(CPUPPCState *env, uint32_t opcode,
+ ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
{
- ppc_vsr_t xt, xa, xb;
+ ppc_vsr_t t = *xt;
float_status tstat;
- getVSR(rA(opcode) + 32, &xa, env);
- getVSR(rB(opcode) + 32, &xb, env);
- getVSR(rD(opcode) + 32, &xt, env);
helper_reset_fpstatus(env);
tstat = env->fp_status;
}
set_float_exception_flags(0, &tstat);
- xt.f128 = float128_sub(xa.f128, xb.f128, &tstat);
+ t.f128 = float128_sub(xa->f128, xb->f128, &tstat);
env->fp_status.float_exception_flags |= tstat.float_exception_flags;
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
float_invalid_op_addsub(env, 1, GETPC(),
- float128_classify(xa.f128) |
- float128_classify(xb.f128));
+ float128_classify(xa->f128) |
+ float128_classify(xb->f128));
}
- helper_compute_fprf_float128(env, xt.f128);
- putVSR(rD(opcode) + 32, &xt, env);
+ helper_compute_fprf_float128(env, t.f128);
+ *xt = t;
do_float_check_status(env, GETPC());
}
#define dh_ctype_avr ppc_avr_t *
#define dh_is_signed_avr dh_is_signed_ptr
+#define dh_alias_vsr ptr
+#define dh_ctype_vsr ppc_vsr_t *
+#define dh_is_signed_vsr dh_is_signed_ptr
+
DEF_HELPER_3(vavgub, void, avr, avr, avr)
DEF_HELPER_3(vavguh, void, avr, avr, avr)
DEF_HELPER_3(vavguw, void, avr, avr, avr)
DEF_HELPER_3(stvehx, void, env, avr, tl)
DEF_HELPER_3(stvewx, void, env, avr, tl)
#if defined(TARGET_PPC64)
-DEF_HELPER_4(lxvl, void, env, tl, tl, tl)
-DEF_HELPER_4(lxvll, void, env, tl, tl, tl)
-DEF_HELPER_4(stxvl, void, env, tl, tl, tl)
-DEF_HELPER_4(stxvll, void, env, tl, tl, tl)
+DEF_HELPER_4(lxvl, void, env, tl, vsr, tl)
+DEF_HELPER_4(lxvll, void, env, tl, vsr, tl)
+DEF_HELPER_4(stxvl, void, env, tl, vsr, tl)
+DEF_HELPER_4(stxvll, void, env, tl, vsr, tl)
#endif
DEF_HELPER_4(vsumsws, void, env, avr, avr, avr)
DEF_HELPER_4(vsum2sws, void, env, avr, avr, avr)
DEF_HELPER_4(bcdtrunc, i32, avr, avr, avr, i32)
DEF_HELPER_4(bcdutrunc, i32, avr, avr, avr, i32)
-DEF_HELPER_2(xsadddp, void, env, i32)
-DEF_HELPER_2(xsaddqp, void, env, i32)
-DEF_HELPER_2(xssubdp, void, env, i32)
-DEF_HELPER_2(xsmuldp, void, env, i32)
-DEF_HELPER_2(xsmulqp, void, env, i32)
-DEF_HELPER_2(xsdivdp, void, env, i32)
-DEF_HELPER_2(xsdivqp, void, env, i32)
-DEF_HELPER_2(xsredp, void, env, i32)
-DEF_HELPER_2(xssqrtdp, void, env, i32)
-DEF_HELPER_2(xsrsqrtedp, void, env, i32)
-DEF_HELPER_2(xstdivdp, void, env, i32)
-DEF_HELPER_2(xstsqrtdp, void, env, i32)
-DEF_HELPER_2(xsmaddadp, void, env, i32)
-DEF_HELPER_2(xsmaddmdp, void, env, i32)
-DEF_HELPER_2(xsmsubadp, void, env, i32)
-DEF_HELPER_2(xsmsubmdp, void, env, i32)
-DEF_HELPER_2(xsnmaddadp, void, env, i32)
-DEF_HELPER_2(xsnmaddmdp, void, env, i32)
-DEF_HELPER_2(xsnmsubadp, void, env, i32)
-DEF_HELPER_2(xsnmsubmdp, void, env, i32)
-DEF_HELPER_2(xscmpeqdp, void, env, i32)
-DEF_HELPER_2(xscmpgtdp, void, env, i32)
-DEF_HELPER_2(xscmpgedp, void, env, i32)
-DEF_HELPER_2(xscmpnedp, void, env, i32)
-DEF_HELPER_2(xscmpexpdp, void, env, i32)
-DEF_HELPER_2(xscmpexpqp, void, env, i32)
-DEF_HELPER_2(xscmpodp, void, env, i32)
-DEF_HELPER_2(xscmpudp, void, env, i32)
-DEF_HELPER_2(xscmpoqp, void, env, i32)
-DEF_HELPER_2(xscmpuqp, void, env, i32)
-DEF_HELPER_2(xsmaxdp, void, env, i32)
-DEF_HELPER_2(xsmindp, void, env, i32)
-DEF_HELPER_2(xsmaxcdp, void, env, i32)
-DEF_HELPER_2(xsmincdp, void, env, i32)
-DEF_HELPER_2(xsmaxjdp, void, env, i32)
-DEF_HELPER_2(xsminjdp, void, env, i32)
-DEF_HELPER_2(xscvdphp, void, env, i32)
-DEF_HELPER_2(xscvdpqp, void, env, i32)
-DEF_HELPER_2(xscvdpsp, void, env, i32)
+DEF_HELPER_4(xsadddp, void, env, vsr, vsr, vsr)
+DEF_HELPER_5(xsaddqp, void, env, i32, vsr, vsr, vsr)
+DEF_HELPER_4(xssubdp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xsmuldp, void, env, vsr, vsr, vsr)
+DEF_HELPER_5(xsmulqp, void, env, i32, vsr, vsr, vsr)
+DEF_HELPER_4(xsdivdp, void, env, vsr, vsr, vsr)
+DEF_HELPER_5(xsdivqp, void, env, i32, vsr, vsr, vsr)
+DEF_HELPER_3(xsredp, void, env, vsr, vsr)
+DEF_HELPER_3(xssqrtdp, void, env, vsr, vsr)
+DEF_HELPER_3(xsrsqrtedp, void, env, vsr, vsr)
+DEF_HELPER_4(xstdivdp, void, env, i32, vsr, vsr)
+DEF_HELPER_3(xstsqrtdp, void, env, i32, vsr)
+DEF_HELPER_5(xsmadddp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_5(xsmsubdp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_5(xsnmadddp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_5(xsnmsubdp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_4(xscmpeqdp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xscmpgtdp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xscmpgedp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xscmpnedp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xscmpexpdp, void, env, i32, vsr, vsr)
+DEF_HELPER_4(xscmpexpqp, void, env, i32, vsr, vsr)
+DEF_HELPER_4(xscmpodp, void, env, i32, vsr, vsr)
+DEF_HELPER_4(xscmpudp, void, env, i32, vsr, vsr)
+DEF_HELPER_4(xscmpoqp, void, env, i32, vsr, vsr)
+DEF_HELPER_4(xscmpuqp, void, env, i32, vsr, vsr)
+DEF_HELPER_4(xsmaxdp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xsmindp, void, env, vsr, vsr, vsr)
+DEF_HELPER_5(xsmaxcdp, void, env, i32, vsr, vsr, vsr)
+DEF_HELPER_5(xsmincdp, void, env, i32, vsr, vsr, vsr)
+DEF_HELPER_5(xsmaxjdp, void, env, i32, vsr, vsr, vsr)
+DEF_HELPER_5(xsminjdp, void, env, i32, vsr, vsr, vsr)
+DEF_HELPER_3(xscvdphp, void, env, vsr, vsr)
+DEF_HELPER_4(xscvdpqp, void, env, i32, vsr, vsr)
+DEF_HELPER_3(xscvdpsp, void, env, vsr, vsr)
DEF_HELPER_2(xscvdpspn, i64, env, i64)
-DEF_HELPER_2(xscvqpdp, void, env, i32)
-DEF_HELPER_2(xscvqpsdz, void, env, i32)
-DEF_HELPER_2(xscvqpswz, void, env, i32)
-DEF_HELPER_2(xscvqpudz, void, env, i32)
-DEF_HELPER_2(xscvqpuwz, void, env, i32)
-DEF_HELPER_2(xscvhpdp, void, env, i32)
-DEF_HELPER_2(xscvsdqp, void, env, i32)
-DEF_HELPER_2(xscvspdp, void, env, i32)
+DEF_HELPER_4(xscvqpdp, void, env, i32, vsr, vsr)
+DEF_HELPER_4(xscvqpsdz, void, env, i32, vsr, vsr)
+DEF_HELPER_4(xscvqpswz, void, env, i32, vsr, vsr)
+DEF_HELPER_4(xscvqpudz, void, env, i32, vsr, vsr)
+DEF_HELPER_4(xscvqpuwz, void, env, i32, vsr, vsr)
+DEF_HELPER_3(xscvhpdp, void, env, vsr, vsr)
+DEF_HELPER_4(xscvsdqp, void, env, i32, vsr, vsr)
+DEF_HELPER_3(xscvspdp, void, env, vsr, vsr)
DEF_HELPER_2(xscvspdpn, i64, env, i64)
-DEF_HELPER_2(xscvdpsxds, void, env, i32)
-DEF_HELPER_2(xscvdpsxws, void, env, i32)
-DEF_HELPER_2(xscvdpuxds, void, env, i32)
-DEF_HELPER_2(xscvdpuxws, void, env, i32)
-DEF_HELPER_2(xscvsxddp, void, env, i32)
-DEF_HELPER_2(xscvuxdsp, void, env, i32)
-DEF_HELPER_2(xscvsxdsp, void, env, i32)
-DEF_HELPER_2(xscvudqp, void, env, i32)
-DEF_HELPER_2(xscvuxddp, void, env, i32)
-DEF_HELPER_2(xststdcsp, void, env, i32)
+DEF_HELPER_3(xscvdpsxds, void, env, vsr, vsr)
+DEF_HELPER_3(xscvdpsxws, void, env, vsr, vsr)
+DEF_HELPER_3(xscvdpuxds, void, env, vsr, vsr)
+DEF_HELPER_3(xscvdpuxws, void, env, vsr, vsr)
+DEF_HELPER_3(xscvsxddp, void, env, vsr, vsr)
+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_2(xsrdpi, void, env, i32)
-DEF_HELPER_2(xsrdpic, void, env, i32)
-DEF_HELPER_2(xsrdpim, void, env, i32)
-DEF_HELPER_2(xsrdpip, void, env, i32)
-DEF_HELPER_2(xsrdpiz, void, env, i32)
-DEF_HELPER_2(xsrqpi, void, env, i32)
-DEF_HELPER_2(xsrqpxp, void, env, i32)
-DEF_HELPER_2(xssqrtqp, void, env, i32)
-DEF_HELPER_2(xssubqp, void, env, i32)
+DEF_HELPER_3(xsrdpi, void, env, vsr, vsr)
+DEF_HELPER_3(xsrdpic, void, env, vsr, vsr)
+DEF_HELPER_3(xsrdpim, void, env, vsr, vsr)
+DEF_HELPER_3(xsrdpip, void, env, vsr, vsr)
+DEF_HELPER_3(xsrdpiz, void, env, vsr, vsr)
+DEF_HELPER_4(xsrqpi, void, env, i32, vsr, vsr)
+DEF_HELPER_4(xsrqpxp, void, env, i32, vsr, vsr)
+DEF_HELPER_4(xssqrtqp, void, env, i32, vsr, vsr)
+DEF_HELPER_5(xssubqp, void, env, i32, vsr, vsr, vsr)
-DEF_HELPER_2(xsaddsp, void, env, i32)
-DEF_HELPER_2(xssubsp, void, env, i32)
-DEF_HELPER_2(xsmulsp, void, env, i32)
-DEF_HELPER_2(xsdivsp, void, env, i32)
-DEF_HELPER_2(xsresp, void, env, i32)
+DEF_HELPER_4(xsaddsp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xssubsp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xsmulsp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xsdivsp, void, env, vsr, vsr, vsr)
+DEF_HELPER_3(xsresp, void, env, vsr, vsr)
DEF_HELPER_2(xsrsp, i64, env, i64)
-DEF_HELPER_2(xssqrtsp, void, env, i32)
-DEF_HELPER_2(xsrsqrtesp, void, env, i32)
-DEF_HELPER_2(xsmaddasp, void, env, i32)
-DEF_HELPER_2(xsmaddmsp, void, env, i32)
-DEF_HELPER_2(xsmsubasp, void, env, i32)
-DEF_HELPER_2(xsmsubmsp, void, env, i32)
-DEF_HELPER_2(xsnmaddasp, void, env, i32)
-DEF_HELPER_2(xsnmaddmsp, void, env, i32)
-DEF_HELPER_2(xsnmsubasp, void, env, i32)
-DEF_HELPER_2(xsnmsubmsp, void, env, i32)
+DEF_HELPER_3(xssqrtsp, void, env, vsr, vsr)
+DEF_HELPER_3(xsrsqrtesp, void, env, vsr, vsr)
+DEF_HELPER_5(xsmaddsp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_5(xsmsubsp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_5(xsnmaddsp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_5(xsnmsubsp, void, env, vsr, vsr, vsr, vsr)
-DEF_HELPER_2(xvadddp, void, env, i32)
-DEF_HELPER_2(xvsubdp, void, env, i32)
-DEF_HELPER_2(xvmuldp, void, env, i32)
-DEF_HELPER_2(xvdivdp, void, env, i32)
-DEF_HELPER_2(xvredp, void, env, i32)
-DEF_HELPER_2(xvsqrtdp, void, env, i32)
-DEF_HELPER_2(xvrsqrtedp, void, env, i32)
-DEF_HELPER_2(xvtdivdp, void, env, i32)
-DEF_HELPER_2(xvtsqrtdp, void, env, i32)
-DEF_HELPER_2(xvmaddadp, void, env, i32)
-DEF_HELPER_2(xvmaddmdp, void, env, i32)
-DEF_HELPER_2(xvmsubadp, void, env, i32)
-DEF_HELPER_2(xvmsubmdp, void, env, i32)
-DEF_HELPER_2(xvnmaddadp, void, env, i32)
-DEF_HELPER_2(xvnmaddmdp, void, env, i32)
-DEF_HELPER_2(xvnmsubadp, void, env, i32)
-DEF_HELPER_2(xvnmsubmdp, void, env, i32)
-DEF_HELPER_2(xvmaxdp, void, env, i32)
-DEF_HELPER_2(xvmindp, void, env, i32)
-DEF_HELPER_2(xvcmpeqdp, void, env, i32)
-DEF_HELPER_2(xvcmpgedp, void, env, i32)
-DEF_HELPER_2(xvcmpgtdp, void, env, i32)
-DEF_HELPER_2(xvcmpnedp, void, env, i32)
-DEF_HELPER_2(xvcvdpsp, void, env, i32)
-DEF_HELPER_2(xvcvdpsxds, void, env, i32)
-DEF_HELPER_2(xvcvdpsxws, void, env, i32)
-DEF_HELPER_2(xvcvdpuxds, void, env, i32)
-DEF_HELPER_2(xvcvdpuxws, void, env, i32)
-DEF_HELPER_2(xvcvsxddp, void, env, i32)
-DEF_HELPER_2(xvcvuxddp, void, env, i32)
-DEF_HELPER_2(xvcvsxwdp, void, env, i32)
-DEF_HELPER_2(xvcvuxwdp, void, env, i32)
-DEF_HELPER_2(xvrdpi, void, env, i32)
-DEF_HELPER_2(xvrdpic, void, env, i32)
-DEF_HELPER_2(xvrdpim, void, env, i32)
-DEF_HELPER_2(xvrdpip, void, env, i32)
-DEF_HELPER_2(xvrdpiz, void, env, i32)
+DEF_HELPER_4(xvadddp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xvsubdp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xvmuldp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xvdivdp, void, env, vsr, vsr, vsr)
+DEF_HELPER_3(xvredp, void, env, vsr, vsr)
+DEF_HELPER_3(xvsqrtdp, void, env, vsr, vsr)
+DEF_HELPER_3(xvrsqrtedp, void, env, vsr, vsr)
+DEF_HELPER_4(xvtdivdp, void, env, i32, vsr, vsr)
+DEF_HELPER_3(xvtsqrtdp, void, env, i32, vsr)
+DEF_HELPER_5(xvmadddp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_5(xvmsubdp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_5(xvnmadddp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_5(xvnmsubdp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_4(xvmaxdp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xvmindp, void, env, vsr, vsr, vsr)
+DEF_HELPER_FLAGS_4(xvcmpeqdp, TCG_CALL_NO_RWG, i32, env, vsr, vsr, vsr)
+DEF_HELPER_FLAGS_4(xvcmpgedp, TCG_CALL_NO_RWG, i32, env, vsr, vsr, vsr)
+DEF_HELPER_FLAGS_4(xvcmpgtdp, TCG_CALL_NO_RWG, i32, env, vsr, vsr, vsr)
+DEF_HELPER_FLAGS_4(xvcmpnedp, TCG_CALL_NO_RWG, i32, env, vsr, vsr, vsr)
+DEF_HELPER_3(xvcvdpsp, void, env, vsr, vsr)
+DEF_HELPER_3(xvcvdpsxds, void, env, vsr, vsr)
+DEF_HELPER_3(xvcvdpsxws, void, env, vsr, vsr)
+DEF_HELPER_3(xvcvdpuxds, void, env, vsr, vsr)
+DEF_HELPER_3(xvcvdpuxws, void, env, vsr, vsr)
+DEF_HELPER_3(xvcvsxddp, void, env, vsr, vsr)
+DEF_HELPER_3(xvcvuxddp, void, env, vsr, vsr)
+DEF_HELPER_3(xvcvsxwdp, void, env, vsr, vsr)
+DEF_HELPER_3(xvcvuxwdp, void, env, vsr, vsr)
+DEF_HELPER_3(xvrdpi, void, env, vsr, vsr)
+DEF_HELPER_3(xvrdpic, void, env, vsr, vsr)
+DEF_HELPER_3(xvrdpim, void, env, vsr, vsr)
+DEF_HELPER_3(xvrdpip, void, env, vsr, vsr)
+DEF_HELPER_3(xvrdpiz, void, env, vsr, vsr)
-DEF_HELPER_2(xvaddsp, void, env, i32)
-DEF_HELPER_2(xvsubsp, void, env, i32)
-DEF_HELPER_2(xvmulsp, void, env, i32)
-DEF_HELPER_2(xvdivsp, void, env, i32)
-DEF_HELPER_2(xvresp, void, env, i32)
-DEF_HELPER_2(xvsqrtsp, void, env, i32)
-DEF_HELPER_2(xvrsqrtesp, void, env, i32)
-DEF_HELPER_2(xvtdivsp, void, env, i32)
-DEF_HELPER_2(xvtsqrtsp, void, env, i32)
-DEF_HELPER_2(xvmaddasp, void, env, i32)
-DEF_HELPER_2(xvmaddmsp, void, env, i32)
-DEF_HELPER_2(xvmsubasp, void, env, i32)
-DEF_HELPER_2(xvmsubmsp, void, env, i32)
-DEF_HELPER_2(xvnmaddasp, void, env, i32)
-DEF_HELPER_2(xvnmaddmsp, void, env, i32)
-DEF_HELPER_2(xvnmsubasp, void, env, i32)
-DEF_HELPER_2(xvnmsubmsp, void, env, i32)
-DEF_HELPER_2(xvmaxsp, void, env, i32)
-DEF_HELPER_2(xvminsp, void, env, i32)
-DEF_HELPER_2(xvcmpeqsp, void, env, i32)
-DEF_HELPER_2(xvcmpgesp, void, env, i32)
-DEF_HELPER_2(xvcmpgtsp, void, env, i32)
-DEF_HELPER_2(xvcmpnesp, void, env, i32)
-DEF_HELPER_2(xvcvspdp, void, env, i32)
-DEF_HELPER_2(xvcvsphp, void, env, i32)
-DEF_HELPER_2(xvcvhpsp, void, env, i32)
-DEF_HELPER_2(xvcvspsxds, void, env, i32)
-DEF_HELPER_2(xvcvspsxws, void, env, i32)
-DEF_HELPER_2(xvcvspuxds, void, env, i32)
-DEF_HELPER_2(xvcvspuxws, void, env, i32)
-DEF_HELPER_2(xvcvsxdsp, void, env, i32)
-DEF_HELPER_2(xvcvuxdsp, void, env, i32)
-DEF_HELPER_2(xvcvsxwsp, void, env, i32)
-DEF_HELPER_2(xvcvuxwsp, void, env, i32)
+DEF_HELPER_4(xvaddsp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xvsubsp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xvmulsp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xvdivsp, void, env, vsr, vsr, vsr)
+DEF_HELPER_3(xvresp, void, env, vsr, vsr)
+DEF_HELPER_3(xvsqrtsp, void, env, vsr, vsr)
+DEF_HELPER_3(xvrsqrtesp, void, env, vsr, vsr)
+DEF_HELPER_4(xvtdivsp, void, env, i32, vsr, vsr)
+DEF_HELPER_3(xvtsqrtsp, void, env, i32, vsr)
+DEF_HELPER_5(xvmaddsp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_5(xvmsubsp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_5(xvnmaddsp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_5(xvnmsubsp, void, env, vsr, vsr, vsr, vsr)
+DEF_HELPER_4(xvmaxsp, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xvminsp, void, env, vsr, vsr, vsr)
+DEF_HELPER_FLAGS_4(xvcmpeqsp, TCG_CALL_NO_RWG, i32, env, vsr, vsr, vsr)
+DEF_HELPER_FLAGS_4(xvcmpgesp, TCG_CALL_NO_RWG, i32, env, vsr, vsr, vsr)
+DEF_HELPER_FLAGS_4(xvcmpgtsp, TCG_CALL_NO_RWG, i32, env, vsr, vsr, vsr)
+DEF_HELPER_FLAGS_4(xvcmpnesp, TCG_CALL_NO_RWG, i32, env, vsr, vsr, vsr)
+DEF_HELPER_3(xvcvspdp, void, env, vsr, vsr)
+DEF_HELPER_3(xvcvsphp, void, env, vsr, vsr)
+DEF_HELPER_3(xvcvhpsp, void, env, vsr, vsr)
+DEF_HELPER_3(xvcvspsxds, void, env, vsr, vsr)
+DEF_HELPER_3(xvcvspsxws, void, env, vsr, vsr)
+DEF_HELPER_3(xvcvspuxds, void, env, vsr, vsr)
+DEF_HELPER_3(xvcvspuxws, void, env, vsr, vsr)
+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_2(xvrspi, void, env, i32)
-DEF_HELPER_2(xvrspic, void, env, i32)
-DEF_HELPER_2(xvrspim, void, env, i32)
-DEF_HELPER_2(xvrspip, void, env, i32)
-DEF_HELPER_2(xvrspiz, void, env, i32)
-DEF_HELPER_2(xxperm, void, env, i32)
-DEF_HELPER_2(xxpermr, void, env, i32)
-DEF_HELPER_4(xxextractuw, void, env, tl, tl, i32)
-DEF_HELPER_4(xxinsertw, void, env, tl, tl, i32)
-DEF_HELPER_2(xvxsigsp, void, env, 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)
+DEF_HELPER_3(xvrspip, void, env, vsr, vsr)
+DEF_HELPER_3(xvrspiz, void, env, vsr, vsr)
+DEF_HELPER_4(xxperm, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xxpermr, void, env, vsr, vsr, vsr)
+DEF_HELPER_4(xxextractuw, void, env, vsr, vsr, i32)
+DEF_HELPER_4(xxinsertw, void, env, vsr, vsr, i32)
+DEF_HELPER_3(xvxsigsp, void, env, vsr, vsr)
DEF_HELPER_2(efscfsi, i32, env, i32)
DEF_HELPER_2(efscfui, i32, env, i32)
VEXTRACT(d, u64)
#undef VEXTRACT
-void helper_xxextractuw(CPUPPCState *env, target_ulong xtn,
- target_ulong xbn, uint32_t index)
+void helper_xxextractuw(CPUPPCState *env, ppc_vsr_t *xt,
+ ppc_vsr_t *xb, uint32_t index)
{
- ppc_vsr_t xt, xb;
+ ppc_vsr_t t = { };
size_t es = sizeof(uint32_t);
uint32_t ext_index;
int i;
- getVSR(xbn, &xb, env);
- memset(&xt, 0, sizeof(xt));
-
ext_index = index;
for (i = 0; i < es; i++, ext_index++) {
- xt.VsrB(8 - es + i) = xb.VsrB(ext_index % 16);
+ t.VsrB(8 - es + i) = xb->VsrB(ext_index % 16);
}
- putVSR(xtn, &xt, env);
+ *xt = t;
}
-void helper_xxinsertw(CPUPPCState *env, target_ulong xtn,
- target_ulong xbn, uint32_t index)
+void helper_xxinsertw(CPUPPCState *env, ppc_vsr_t *xt,
+ ppc_vsr_t *xb, uint32_t index)
{
- ppc_vsr_t xt, xb;
+ ppc_vsr_t t = *xt;
size_t es = sizeof(uint32_t);
int ins_index, i = 0;
- getVSR(xbn, &xb, env);
- getVSR(xtn, &xt, env);
-
ins_index = index;
for (i = 0; i < es && ins_index < 16; i++, ins_index++) {
- xt.VsrB(ins_index) = xb.VsrB(8 - es + i);
+ t.VsrB(ins_index) = xb->VsrB(8 - es + i);
}
- putVSR(xtn, &xt, env);
+ *xt = t;
}
#define VEXT_SIGNED(name, element, cast) \
EXTRACT_HELPER(DCMX, 16, 7);
EXTRACT_HELPER_SPLIT_3(DCMX_XV, 5, 16, 0, 1, 2, 5, 1, 6, 6);
-static inline void getVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
-{
- vsr->VsrD(0) = env->vsr[n].VsrD(0);
- vsr->VsrD(1) = env->vsr[n].VsrD(1);
-}
-
-static inline void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
-{
- env->vsr[n].VsrD(0) = vsr->VsrD(0);
- env->vsr[n].VsrD(1) = vsr->VsrD(1);
-}
-
void helper_compute_fprf_float16(CPUPPCState *env, float16 arg);
void helper_compute_fprf_float32(CPUPPCState *env, float32 arg);
void helper_compute_fprf_float128(CPUPPCState *env, float128 arg);
return -ENOENT;
}
- strncpy(args.name, function, sizeof(args.name));
+ strncpy(args.name, function, sizeof(args.name) - 1);
return kvm_vm_ioctl(kvm_state, KVM_PPC_RTAS_DEFINE_TOKEN, &args);
}
kvm_set_one_reg(cs, KVM_REG_PPC_ONLINE, &online);
}
}
+
+void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t tb_offset)
+{
+ CPUState *cs = CPU(cpu);
+
+ if (kvm_enabled()) {
+ kvm_set_one_reg(cs, KVM_REG_PPC_TB_OFFSET, &tb_offset);
+ }
+}
bool kvmppc_hpt_needs_host_contiguous_pages(void);
void kvm_check_mmu(PowerPCCPU *cpu, Error **errp);
void kvmppc_set_reg_ppc_online(PowerPCCPU *cpu, unsigned int online);
+void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t tb_offset);
#else
return;
}
+static inline void kvmppc_set_reg_tb_offset(PowerPCCPU *cpu, int64_t tb_offset)
+{
+}
+
#ifndef CONFIG_USER_ONLY
static inline bool kvmppc_spapr_use_multitce(void)
{
return -ENOSYS;
}
+static inline bool kvmppc_pvr_workaround_required(PowerPCCPU *cpu)
+{
+ return false;
+}
+
#endif
#ifndef CONFIG_KVM
* receive the PVR it expects as a workaround.
*
*/
-#if defined(CONFIG_KVM)
if (kvmppc_pvr_workaround_required(cpu)) {
env->spr[SPR_PVR] = env->spr_cb[SPR_PVR].default_value;
}
-#endif
env->lr = env->spr[SPR_LR];
env->ctr = env->spr[SPR_CTR];
#define VSX_LXVL(name, lj) \
void helper_##name(CPUPPCState *env, target_ulong addr, \
- target_ulong xt_num, target_ulong rb) \
+ ppc_vsr_t *xt, target_ulong rb) \
{ \
- int i; \
- ppc_vsr_t xt; \
+ ppc_vsr_t t; \
uint64_t nb = GET_NB(rb); \
+ int i; \
\
- xt.s128 = int128_zero(); \
+ t.s128 = int128_zero(); \
if (nb) { \
nb = (nb >= 16) ? 16 : nb; \
if (msr_le && !lj) { \
for (i = 16; i > 16 - nb; i--) { \
- xt.VsrB(i - 1) = cpu_ldub_data_ra(env, addr, GETPC()); \
+ t.VsrB(i - 1) = cpu_ldub_data_ra(env, addr, GETPC()); \
addr = addr_add(env, addr, 1); \
} \
} else { \
for (i = 0; i < nb; i++) { \
- xt.VsrB(i) = cpu_ldub_data_ra(env, addr, GETPC()); \
+ t.VsrB(i) = cpu_ldub_data_ra(env, addr, GETPC()); \
addr = addr_add(env, addr, 1); \
} \
} \
} \
- putVSR(xt_num, &xt, env); \
+ *xt = t; \
}
VSX_LXVL(lxvl, 0)
#define VSX_STXVL(name, lj) \
void helper_##name(CPUPPCState *env, target_ulong addr, \
- target_ulong xt_num, target_ulong rb) \
+ ppc_vsr_t *xt, target_ulong rb) \
{ \
- int i; \
- ppc_vsr_t xt; \
target_ulong nb = GET_NB(rb); \
+ int i; \
\
if (!nb) { \
return; \
} \
- getVSR(xt_num, &xt, env); \
+ \
nb = (nb >= 16) ? 16 : nb; \
if (msr_le && !lj) { \
for (i = 16; i > 16 - nb; i--) { \
- cpu_stb_data_ra(env, addr, xt.VsrB(i - 1), GETPC()); \
+ cpu_stb_data_ra(env, addr, xt->VsrB(i - 1), GETPC()); \
addr = addr_add(env, addr, 1); \
} \
} else { \
for (i = 0; i < nb; i++) { \
- cpu_stb_data_ra(env, addr, xt.VsrB(i), GETPC()); \
+ cpu_stb_data_ra(env, addr, xt->VsrB(i), GETPC()); \
addr = addr_add(env, addr, 1); \
} \
} \
#include "monitor/monitor.h"
#include "qemu/ctype.h"
#include "monitor/hmp-target.h"
-#include "hmp.h"
+#include "monitor/hmp.h"
static target_long monitor_get_ccr(const struct MonitorDef *md, int val)
{
tcg_gen_st_i64(src, cpu_env, vsr64_offset(n, false));
}
+static inline TCGv_ptr gen_vsr_ptr(int reg)
+{
+ TCGv_ptr r = tcg_temp_new_ptr();
+ tcg_gen_addi_ptr(r, cpu_env, vsr_full_offset(reg));
+ return r;
+}
+
#define VSX_LOAD_SCALAR(name, operation) \
static void gen_##name(DisasContext *ctx) \
{ \
VSX_VECTOR_STORE(stxvx, st_i64, 1)
#ifdef TARGET_PPC64
-#define VSX_VECTOR_LOAD_STORE_LENGTH(name) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- TCGv EA, xt; \
- \
- if (xT(ctx->opcode) < 32) { \
- if (unlikely(!ctx->vsx_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VSXU); \
- return; \
- } \
- } else { \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- } \
- EA = tcg_temp_new(); \
- xt = tcg_const_tl(xT(ctx->opcode)); \
- gen_set_access_type(ctx, ACCESS_INT); \
- gen_addr_register(ctx, EA); \
- gen_helper_##name(cpu_env, EA, xt, cpu_gpr[rB(ctx->opcode)]); \
- tcg_temp_free(EA); \
- tcg_temp_free(xt); \
+#define VSX_VECTOR_LOAD_STORE_LENGTH(name) \
+static void gen_##name(DisasContext *ctx) \
+{ \
+ TCGv EA; \
+ TCGv_ptr xt; \
+ \
+ if (xT(ctx->opcode) < 32) { \
+ if (unlikely(!ctx->vsx_enabled)) { \
+ gen_exception(ctx, POWERPC_EXCP_VSXU); \
+ return; \
+ } \
+ } else { \
+ if (unlikely(!ctx->altivec_enabled)) { \
+ gen_exception(ctx, POWERPC_EXCP_VPU); \
+ return; \
+ } \
+ } \
+ EA = tcg_temp_new(); \
+ xt = gen_vsr_ptr(xT(ctx->opcode)); \
+ gen_set_access_type(ctx, ACCESS_INT); \
+ gen_addr_register(ctx, EA); \
+ gen_helper_##name(cpu_env, EA, xt, cpu_gpr[rB(ctx->opcode)]); \
+ tcg_temp_free(EA); \
+ tcg_temp_free_ptr(xt); \
}
VSX_VECTOR_LOAD_STORE_LENGTH(lxvl)
VSX_VECTOR_MOVE(xvnegsp, OP_NEG, SGN_MASK_SP)
VSX_VECTOR_MOVE(xvcpsgnsp, OP_CPSGN, SGN_MASK_SP)
+#define VSX_CMP(name, op1, op2, inval, type) \
+static void gen_##name(DisasContext *ctx) \
+{ \
+ TCGv_i32 ignored; \
+ TCGv_ptr xt, xa, xb; \
+ if (unlikely(!ctx->vsx_enabled)) { \
+ gen_exception(ctx, POWERPC_EXCP_VSXU); \
+ return; \
+ } \
+ xt = gen_vsr_ptr(xT(ctx->opcode)); \
+ xa = gen_vsr_ptr(xA(ctx->opcode)); \
+ xb = gen_vsr_ptr(xB(ctx->opcode)); \
+ if ((ctx->opcode >> (31 - 21)) & 1) { \
+ gen_helper_##name(cpu_crf[6], cpu_env, xt, xa, xb); \
+ } else { \
+ ignored = tcg_temp_new_i32(); \
+ gen_helper_##name(ignored, cpu_env, xt, xa, xb); \
+ tcg_temp_free_i32(ignored); \
+ } \
+ gen_helper_float_check_status(cpu_env); \
+ tcg_temp_free_ptr(xt); \
+ tcg_temp_free_ptr(xa); \
+ tcg_temp_free_ptr(xb); \
+}
+
+VSX_CMP(xvcmpeqdp, 0x0C, 0x0C, 0, PPC2_VSX)
+VSX_CMP(xvcmpgedp, 0x0C, 0x0E, 0, PPC2_VSX)
+VSX_CMP(xvcmpgtdp, 0x0C, 0x0D, 0, PPC2_VSX)
+VSX_CMP(xvcmpnedp, 0x0C, 0x0F, 0, PPC2_ISA300)
+VSX_CMP(xvcmpeqsp, 0x0C, 0x08, 0, PPC2_VSX)
+VSX_CMP(xvcmpgesp, 0x0C, 0x0A, 0, PPC2_VSX)
+VSX_CMP(xvcmpgtsp, 0x0C, 0x09, 0, PPC2_VSX)
+VSX_CMP(xvcmpnesp, 0x0C, 0x0B, 0, PPC2_VSX)
+
+static void gen_xscvqpdp(DisasContext *ctx)
+{
+ TCGv_i32 opc;
+ TCGv_ptr xt, xb;
+ if (unlikely(!ctx->vsx_enabled)) {
+ gen_exception(ctx, POWERPC_EXCP_VSXU);
+ return;
+ }
+ opc = tcg_const_i32(ctx->opcode);
+ xt = gen_vsr_ptr(xT(ctx->opcode));
+ xb = gen_vsr_ptr(xB(ctx->opcode));
+ gen_helper_xscvqpdp(cpu_env, opc, xt, xb);
+ tcg_temp_free_i32(opc);
+ tcg_temp_free_ptr(xt);
+ tcg_temp_free_ptr(xb);
+}
+
#define GEN_VSX_HELPER_2(name, op1, op2, inval, type) \
static void gen_##name(DisasContext *ctx) \
{ \
tcg_temp_free_i32(opc); \
}
+#define GEN_VSX_HELPER_X3(name, op1, op2, inval, type) \
+static void gen_##name(DisasContext *ctx) \
+{ \
+ TCGv_ptr xt, xa, xb; \
+ if (unlikely(!ctx->vsx_enabled)) { \
+ gen_exception(ctx, POWERPC_EXCP_VSXU); \
+ return; \
+ } \
+ xt = gen_vsr_ptr(xT(ctx->opcode)); \
+ xa = gen_vsr_ptr(xA(ctx->opcode)); \
+ xb = gen_vsr_ptr(xB(ctx->opcode)); \
+ gen_helper_##name(cpu_env, xt, xa, xb); \
+ tcg_temp_free_ptr(xt); \
+ tcg_temp_free_ptr(xa); \
+ tcg_temp_free_ptr(xb); \
+}
+
+#define GEN_VSX_HELPER_X2(name, op1, op2, inval, type) \
+static void gen_##name(DisasContext *ctx) \
+{ \
+ TCGv_ptr xt, xb; \
+ if (unlikely(!ctx->vsx_enabled)) { \
+ gen_exception(ctx, POWERPC_EXCP_VSXU); \
+ return; \
+ } \
+ xt = gen_vsr_ptr(xT(ctx->opcode)); \
+ xb = gen_vsr_ptr(xB(ctx->opcode)); \
+ gen_helper_##name(cpu_env, xt, xb); \
+ tcg_temp_free_ptr(xt); \
+ tcg_temp_free_ptr(xb); \
+}
+
+#define GEN_VSX_HELPER_X2_AB(name, op1, op2, inval, type) \
+static void gen_##name(DisasContext *ctx) \
+{ \
+ TCGv_i32 opc; \
+ TCGv_ptr xa, xb; \
+ if (unlikely(!ctx->vsx_enabled)) { \
+ gen_exception(ctx, POWERPC_EXCP_VSXU); \
+ return; \
+ } \
+ opc = tcg_const_i32(ctx->opcode); \
+ xa = gen_vsr_ptr(xA(ctx->opcode)); \
+ xb = gen_vsr_ptr(xB(ctx->opcode)); \
+ gen_helper_##name(cpu_env, opc, xa, xb); \
+ tcg_temp_free_i32(opc); \
+ tcg_temp_free_ptr(xa); \
+ tcg_temp_free_ptr(xb); \
+}
+
+#define GEN_VSX_HELPER_X1(name, op1, op2, inval, type) \
+static void gen_##name(DisasContext *ctx) \
+{ \
+ TCGv_i32 opc; \
+ TCGv_ptr xb; \
+ if (unlikely(!ctx->vsx_enabled)) { \
+ gen_exception(ctx, POWERPC_EXCP_VSXU); \
+ return; \
+ } \
+ opc = tcg_const_i32(ctx->opcode); \
+ xb = gen_vsr_ptr(xB(ctx->opcode)); \
+ gen_helper_##name(cpu_env, opc, xb); \
+ tcg_temp_free_i32(opc); \
+ tcg_temp_free_ptr(xb); \
+}
+
+#define GEN_VSX_HELPER_R3(name, op1, op2, inval, type) \
+static void gen_##name(DisasContext *ctx) \
+{ \
+ TCGv_i32 opc; \
+ TCGv_ptr xt, xa, xb; \
+ if (unlikely(!ctx->vsx_enabled)) { \
+ gen_exception(ctx, POWERPC_EXCP_VSXU); \
+ return; \
+ } \
+ opc = tcg_const_i32(ctx->opcode); \
+ xt = gen_vsr_ptr(rD(ctx->opcode) + 32); \
+ xa = gen_vsr_ptr(rA(ctx->opcode) + 32); \
+ xb = gen_vsr_ptr(rB(ctx->opcode) + 32); \
+ gen_helper_##name(cpu_env, opc, xt, xa, xb); \
+ tcg_temp_free_i32(opc); \
+ tcg_temp_free_ptr(xt); \
+ tcg_temp_free_ptr(xa); \
+ tcg_temp_free_ptr(xb); \
+}
+
+#define GEN_VSX_HELPER_R2(name, op1, op2, inval, type) \
+static void gen_##name(DisasContext *ctx) \
+{ \
+ TCGv_i32 opc; \
+ TCGv_ptr xt, xb; \
+ if (unlikely(!ctx->vsx_enabled)) { \
+ gen_exception(ctx, POWERPC_EXCP_VSXU); \
+ return; \
+ } \
+ opc = tcg_const_i32(ctx->opcode); \
+ xt = gen_vsr_ptr(rD(ctx->opcode) + 32); \
+ xb = gen_vsr_ptr(rB(ctx->opcode) + 32); \
+ gen_helper_##name(cpu_env, opc, xt, xb); \
+ tcg_temp_free_i32(opc); \
+ tcg_temp_free_ptr(xt); \
+ tcg_temp_free_ptr(xb); \
+}
+
+#define GEN_VSX_HELPER_R2_AB(name, op1, op2, inval, type) \
+static void gen_##name(DisasContext *ctx) \
+{ \
+ TCGv_i32 opc; \
+ TCGv_ptr xa, xb; \
+ if (unlikely(!ctx->vsx_enabled)) { \
+ gen_exception(ctx, POWERPC_EXCP_VSXU); \
+ return; \
+ } \
+ opc = tcg_const_i32(ctx->opcode); \
+ xa = gen_vsr_ptr(rA(ctx->opcode) + 32); \
+ xb = gen_vsr_ptr(rB(ctx->opcode) + 32); \
+ gen_helper_##name(cpu_env, opc, xa, xb); \
+ tcg_temp_free_i32(opc); \
+ tcg_temp_free_ptr(xa); \
+ tcg_temp_free_ptr(xb); \
+}
+
#define GEN_VSX_HELPER_XT_XB_ENV(name, op1, op2, inval, type) \
static void gen_##name(DisasContext *ctx) \
{ \
tcg_temp_free_i64(t1); \
}
-GEN_VSX_HELPER_2(xsadddp, 0x00, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsaddqp, 0x04, 0x00, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xssubdp, 0x00, 0x05, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmuldp, 0x00, 0x06, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmulqp, 0x04, 0x01, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xsdivdp, 0x00, 0x07, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsdivqp, 0x04, 0x11, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xsredp, 0x14, 0x05, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xssqrtdp, 0x16, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsrsqrtedp, 0x14, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xstdivdp, 0x14, 0x07, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xstsqrtdp, 0x14, 0x06, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmaddadp, 0x04, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmaddmdp, 0x04, 0x05, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmsubadp, 0x04, 0x06, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmsubmdp, 0x04, 0x07, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsnmaddadp, 0x04, 0x14, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsnmaddmdp, 0x04, 0x15, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsnmsubadp, 0x04, 0x16, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsnmsubmdp, 0x04, 0x17, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscmpeqdp, 0x0C, 0x00, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscmpgtdp, 0x0C, 0x01, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscmpgedp, 0x0C, 0x02, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscmpnedp, 0x0C, 0x03, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscmpexpdp, 0x0C, 0x07, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscmpexpqp, 0x04, 0x05, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscmpodp, 0x0C, 0x05, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscmpudp, 0x0C, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscmpoqp, 0x04, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscmpuqp, 0x04, 0x14, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmindp, 0x00, 0x15, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmaxcdp, 0x00, 0x10, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xsmincdp, 0x00, 0x11, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xsmaxjdp, 0x00, 0x12, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xsminjdp, 0x00, 0x12, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscvdphp, 0x16, 0x15, 0x11, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscvdpsp, 0x12, 0x10, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscvdpqp, 0x04, 0x1A, 0x16, PPC2_ISA300)
+GEN_VSX_HELPER_X3(xsadddp, 0x00, 0x04, 0, PPC2_VSX)
+GEN_VSX_HELPER_R3(xsaddqp, 0x04, 0x00, 0, PPC2_ISA300)
+GEN_VSX_HELPER_X3(xssubdp, 0x00, 0x05, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xsmuldp, 0x00, 0x06, 0, PPC2_VSX)
+GEN_VSX_HELPER_R3(xsmulqp, 0x04, 0x01, 0, PPC2_ISA300)
+GEN_VSX_HELPER_X3(xsdivdp, 0x00, 0x07, 0, PPC2_VSX)
+GEN_VSX_HELPER_R3(xsdivqp, 0x04, 0x11, 0, PPC2_ISA300)
+GEN_VSX_HELPER_X2(xsredp, 0x14, 0x05, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xssqrtdp, 0x16, 0x04, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xsrsqrtedp, 0x14, 0x04, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2_AB(xstdivdp, 0x14, 0x07, 0, PPC2_VSX)
+GEN_VSX_HELPER_X1(xstsqrtdp, 0x14, 0x06, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xscmpeqdp, 0x0C, 0x00, 0, PPC2_ISA300)
+GEN_VSX_HELPER_X3(xscmpgtdp, 0x0C, 0x01, 0, PPC2_ISA300)
+GEN_VSX_HELPER_X3(xscmpgedp, 0x0C, 0x02, 0, PPC2_ISA300)
+GEN_VSX_HELPER_X3(xscmpnedp, 0x0C, 0x03, 0, PPC2_ISA300)
+GEN_VSX_HELPER_X2_AB(xscmpexpdp, 0x0C, 0x07, 0, PPC2_ISA300)
+GEN_VSX_HELPER_R2_AB(xscmpexpqp, 0x04, 0x05, 0, PPC2_ISA300)
+GEN_VSX_HELPER_X2_AB(xscmpodp, 0x0C, 0x05, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2_AB(xscmpudp, 0x0C, 0x04, 0, PPC2_VSX)
+GEN_VSX_HELPER_R2_AB(xscmpoqp, 0x04, 0x04, 0, PPC2_VSX)
+GEN_VSX_HELPER_R2_AB(xscmpuqp, 0x04, 0x14, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xsmindp, 0x00, 0x15, 0, PPC2_VSX)
+GEN_VSX_HELPER_R3(xsmaxcdp, 0x00, 0x10, 0, PPC2_ISA300)
+GEN_VSX_HELPER_R3(xsmincdp, 0x00, 0x11, 0, PPC2_ISA300)
+GEN_VSX_HELPER_R3(xsmaxjdp, 0x00, 0x12, 0, PPC2_ISA300)
+GEN_VSX_HELPER_R3(xsminjdp, 0x00, 0x12, 0, PPC2_ISA300)
+GEN_VSX_HELPER_X2(xscvdphp, 0x16, 0x15, 0x11, PPC2_ISA300)
+GEN_VSX_HELPER_X2(xscvdpsp, 0x12, 0x10, 0, PPC2_VSX)
+GEN_VSX_HELPER_R2(xscvdpqp, 0x04, 0x1A, 0x16, PPC2_ISA300)
GEN_VSX_HELPER_XT_XB_ENV(xscvdpspn, 0x16, 0x10, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xscvqpdp, 0x04, 0x1A, 0x14, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscvqpsdz, 0x04, 0x1A, 0x19, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscvqpswz, 0x04, 0x1A, 0x09, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscvqpudz, 0x04, 0x1A, 0x11, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscvqpuwz, 0x04, 0x1A, 0x01, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscvhpdp, 0x16, 0x15, 0x10, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscvsdqp, 0x04, 0x1A, 0x0A, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscvspdp, 0x12, 0x14, 0, PPC2_VSX)
+GEN_VSX_HELPER_R2(xscvqpsdz, 0x04, 0x1A, 0x19, PPC2_ISA300)
+GEN_VSX_HELPER_R2(xscvqpswz, 0x04, 0x1A, 0x09, PPC2_ISA300)
+GEN_VSX_HELPER_R2(xscvqpudz, 0x04, 0x1A, 0x11, PPC2_ISA300)
+GEN_VSX_HELPER_R2(xscvqpuwz, 0x04, 0x1A, 0x01, PPC2_ISA300)
+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)
GEN_VSX_HELPER_XT_XB_ENV(xscvspdpn, 0x16, 0x14, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xscvdpsxds, 0x10, 0x15, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscvdpsxws, 0x10, 0x05, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscvdpuxds, 0x10, 0x14, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscvdpuxws, 0x10, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscvsxddp, 0x10, 0x17, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscvudqp, 0x04, 0x1A, 0x02, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscvuxddp, 0x10, 0x16, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsrdpi, 0x12, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsrdpic, 0x16, 0x06, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsrdpim, 0x12, 0x07, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsrdpip, 0x12, 0x06, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsrdpiz, 0x12, 0x05, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xscvdpsxds, 0x10, 0x15, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xscvdpsxws, 0x10, 0x05, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xscvdpuxds, 0x10, 0x14, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xscvdpuxws, 0x10, 0x04, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xscvsxddp, 0x10, 0x17, 0, PPC2_VSX)
+GEN_VSX_HELPER_R2(xscvudqp, 0x04, 0x1A, 0x02, PPC2_ISA300)
+GEN_VSX_HELPER_X2(xscvuxddp, 0x10, 0x16, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xsrdpi, 0x12, 0x04, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xsrdpic, 0x16, 0x06, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xsrdpim, 0x12, 0x07, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xsrdpip, 0x12, 0x06, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xsrdpiz, 0x12, 0x05, 0, PPC2_VSX)
GEN_VSX_HELPER_XT_XB_ENV(xsrsp, 0x12, 0x11, 0, PPC2_VSX207)
-
-GEN_VSX_HELPER_2(xsrqpi, 0x05, 0x00, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xsrqpxp, 0x05, 0x01, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xssqrtqp, 0x04, 0x19, 0x1B, PPC2_ISA300)
-GEN_VSX_HELPER_2(xssubqp, 0x04, 0x10, 0, PPC2_ISA300)
-
-GEN_VSX_HELPER_2(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsresp, 0x14, 0x01, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xssqrtsp, 0x16, 0x00, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsrsqrtesp, 0x14, 0x00, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsmaddasp, 0x04, 0x00, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsmaddmsp, 0x04, 0x01, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsmsubasp, 0x04, 0x02, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsmsubmsp, 0x04, 0x03, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsnmaddasp, 0x04, 0x10, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsnmaddmsp, 0x04, 0x11, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsnmsubasp, 0x04, 0x12, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsnmsubmsp, 0x04, 0x13, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xscvsxdsp, 0x10, 0x13, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xscvuxdsp, 0x10, 0x12, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xststdcsp, 0x14, 0x12, 0, PPC2_ISA300)
+GEN_VSX_HELPER_R2(xsrqpi, 0x05, 0x00, 0, PPC2_ISA300)
+GEN_VSX_HELPER_R2(xsrqpxp, 0x05, 0x01, 0, PPC2_ISA300)
+GEN_VSX_HELPER_R2(xssqrtqp, 0x04, 0x19, 0x1B, PPC2_ISA300)
+GEN_VSX_HELPER_R3(xssubqp, 0x04, 0x10, 0, PPC2_ISA300)
+GEN_VSX_HELPER_X3(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207)
+GEN_VSX_HELPER_X3(xssubsp, 0x00, 0x01, 0, PPC2_VSX207)
+GEN_VSX_HELPER_X3(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207)
+GEN_VSX_HELPER_X3(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207)
+GEN_VSX_HELPER_X2(xsresp, 0x14, 0x01, 0, PPC2_VSX207)
+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_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmuldp, 0x00, 0x0E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvdivdp, 0x00, 0x0F, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvredp, 0x14, 0x0D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvsqrtdp, 0x16, 0x0C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrsqrtedp, 0x14, 0x0C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvtdivdp, 0x14, 0x0F, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvtsqrtdp, 0x14, 0x0E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmaddadp, 0x04, 0x0C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmaddmdp, 0x04, 0x0D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmsubadp, 0x04, 0x0E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmsubmdp, 0x04, 0x0F, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmaddadp, 0x04, 0x1C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmaddmdp, 0x04, 0x1D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmsubadp, 0x04, 0x1E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmsubmdp, 0x04, 0x1F, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmaxdp, 0x00, 0x1C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmindp, 0x00, 0x1D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpeqdp, 0x0C, 0x0C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpgtdp, 0x0C, 0x0D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpgedp, 0x0C, 0x0E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpnedp, 0x0C, 0x0F, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xvcvdpsp, 0x12, 0x18, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvdpsxds, 0x10, 0x1D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvdpsxws, 0x10, 0x0D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvdpuxds, 0x10, 0x1C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvdpuxws, 0x10, 0x0C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvsxddp, 0x10, 0x1F, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvuxddp, 0x10, 0x1E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvsxwdp, 0x10, 0x0F, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvuxwdp, 0x10, 0x0E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrdpi, 0x12, 0x0C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrdpic, 0x16, 0x0E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrdpim, 0x12, 0x0F, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrdpip, 0x12, 0x0E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrdpiz, 0x12, 0x0D, 0, PPC2_VSX)
-
-GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmulsp, 0x00, 0x0A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvdivsp, 0x00, 0x0B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvresp, 0x14, 0x09, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvsqrtsp, 0x16, 0x08, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrsqrtesp, 0x14, 0x08, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvtdivsp, 0x14, 0x0B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvtsqrtsp, 0x14, 0x0A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmaddasp, 0x04, 0x08, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmaddmsp, 0x04, 0x09, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmsubasp, 0x04, 0x0A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmsubmsp, 0x04, 0x0B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmaddasp, 0x04, 0x18, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmaddmsp, 0x04, 0x19, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmsubasp, 0x04, 0x1A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmsubmsp, 0x04, 0x1B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmaxsp, 0x00, 0x18, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvminsp, 0x00, 0x19, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpeqsp, 0x0C, 0x08, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpgtsp, 0x0C, 0x09, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpgesp, 0x0C, 0x0A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpnesp, 0x0C, 0x0B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvspdp, 0x12, 0x1C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvhpsp, 0x16, 0x1D, 0x18, PPC2_ISA300)
-GEN_VSX_HELPER_2(xvcvsphp, 0x16, 0x1D, 0x19, PPC2_ISA300)
-GEN_VSX_HELPER_2(xvcvspsxds, 0x10, 0x19, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvspsxws, 0x10, 0x09, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvspuxds, 0x10, 0x18, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvspuxws, 0x10, 0x08, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvsxdsp, 0x10, 0x1B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvuxdsp, 0x10, 0x1A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvsxwsp, 0x10, 0x0B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvuxwsp, 0x10, 0x0A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrspi, 0x12, 0x08, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrspic, 0x16, 0x0A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrspim, 0x12, 0x0B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrspip, 0x12, 0x0A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrspiz, 0x12, 0x09, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xvmuldp, 0x00, 0x0E, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xvdivdp, 0x00, 0x0F, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvredp, 0x14, 0x0D, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvsqrtdp, 0x16, 0x0C, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvrsqrtedp, 0x14, 0x0C, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2_AB(xvtdivdp, 0x14, 0x0F, 0, PPC2_VSX)
+GEN_VSX_HELPER_X1(xvtsqrtdp, 0x14, 0x0E, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xvmaxdp, 0x00, 0x1C, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xvmindp, 0x00, 0x1D, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvdpsp, 0x12, 0x18, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvdpsxds, 0x10, 0x1D, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvdpsxws, 0x10, 0x0D, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvdpuxds, 0x10, 0x1C, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvdpuxws, 0x10, 0x0C, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvsxddp, 0x10, 0x1F, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvuxddp, 0x10, 0x1E, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvsxwdp, 0x10, 0x0F, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvuxwdp, 0x10, 0x0E, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvrdpi, 0x12, 0x0C, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvrdpic, 0x16, 0x0E, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvrdpim, 0x12, 0x0F, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvrdpip, 0x12, 0x0E, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvrdpiz, 0x12, 0x0D, 0, PPC2_VSX)
+
+GEN_VSX_HELPER_X3(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xvmulsp, 0x00, 0x0A, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xvdivsp, 0x00, 0x0B, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvresp, 0x14, 0x09, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvsqrtsp, 0x16, 0x08, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvrsqrtesp, 0x14, 0x08, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2_AB(xvtdivsp, 0x14, 0x0B, 0, PPC2_VSX)
+GEN_VSX_HELPER_X1(xvtsqrtsp, 0x14, 0x0A, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xvmaxsp, 0x00, 0x18, 0, PPC2_VSX)
+GEN_VSX_HELPER_X3(xvminsp, 0x00, 0x19, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvspdp, 0x12, 0x1C, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvhpsp, 0x16, 0x1D, 0x18, PPC2_ISA300)
+GEN_VSX_HELPER_X2(xvcvsphp, 0x16, 0x1D, 0x19, PPC2_ISA300)
+GEN_VSX_HELPER_X2(xvcvspsxds, 0x10, 0x19, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvspsxws, 0x10, 0x09, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvspuxds, 0x10, 0x18, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvspuxws, 0x10, 0x08, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvsxdsp, 0x10, 0x1B, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvuxdsp, 0x10, 0x1A, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvsxwsp, 0x10, 0x0B, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvcvuxwsp, 0x10, 0x0A, 0, PPC2_VSX)
+GEN_VSX_HELPER_X2(xvrspi, 0x12, 0x08, 0, PPC2_VSX)
+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)
-GEN_VSX_HELPER_2(xxperm, 0x08, 0x03, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xxpermr, 0x08, 0x07, 0, PPC2_ISA300)
+GEN_VSX_HELPER_X3(xxperm, 0x08, 0x03, 0, PPC2_ISA300)
+GEN_VSX_HELPER_X3(xxpermr, 0x08, 0x07, 0, PPC2_ISA300)
+
+#define GEN_VSX_HELPER_VSX_MADD(name, op1, aop, mop, inval, type) \
+static void gen_##name(DisasContext *ctx) \
+{ \
+ TCGv_ptr xt, xa, b, c; \
+ if (unlikely(!ctx->vsx_enabled)) { \
+ gen_exception(ctx, POWERPC_EXCP_VSXU); \
+ return; \
+ } \
+ xt = gen_vsr_ptr(xT(ctx->opcode)); \
+ xa = gen_vsr_ptr(xA(ctx->opcode)); \
+ if (ctx->opcode & PPC_BIT(25)) { \
+ /* \
+ * AxT + B \
+ */ \
+ b = gen_vsr_ptr(xT(ctx->opcode)); \
+ c = gen_vsr_ptr(xB(ctx->opcode)); \
+ } else { \
+ /* \
+ * AxB + T \
+ */ \
+ b = gen_vsr_ptr(xB(ctx->opcode)); \
+ c = gen_vsr_ptr(xT(ctx->opcode)); \
+ } \
+ gen_helper_##name(cpu_env, xt, xa, b, c); \
+ tcg_temp_free_ptr(xt); \
+ tcg_temp_free_ptr(xa); \
+ tcg_temp_free_ptr(b); \
+ tcg_temp_free_ptr(c); \
+}
+
+GEN_VSX_HELPER_VSX_MADD(xsmadddp, 0x04, 0x04, 0x05, 0, PPC2_VSX)
+GEN_VSX_HELPER_VSX_MADD(xsmsubdp, 0x04, 0x06, 0x07, 0, PPC2_VSX)
+GEN_VSX_HELPER_VSX_MADD(xsnmadddp, 0x04, 0x14, 0x15, 0, PPC2_VSX)
+GEN_VSX_HELPER_VSX_MADD(xsnmsubdp, 0x04, 0x16, 0x17, 0, PPC2_VSX)
+GEN_VSX_HELPER_VSX_MADD(xsmaddsp, 0x04, 0x00, 0x01, 0, PPC2_VSX207)
+GEN_VSX_HELPER_VSX_MADD(xsmsubsp, 0x04, 0x02, 0x03, 0, PPC2_VSX207)
+GEN_VSX_HELPER_VSX_MADD(xsnmaddsp, 0x04, 0x10, 0x11, 0, PPC2_VSX207)
+GEN_VSX_HELPER_VSX_MADD(xsnmsubsp, 0x04, 0x12, 0x13, 0, PPC2_VSX207)
+GEN_VSX_HELPER_VSX_MADD(xvmadddp, 0x04, 0x0C, 0x0D, 0, PPC2_VSX)
+GEN_VSX_HELPER_VSX_MADD(xvmsubdp, 0x04, 0x0E, 0x0F, 0, PPC2_VSX)
+GEN_VSX_HELPER_VSX_MADD(xvnmadddp, 0x04, 0x1C, 0x1D, 0, PPC2_VSX)
+GEN_VSX_HELPER_VSX_MADD(xvnmsubdp, 0x04, 0x1E, 0x1F, 0, PPC2_VSX)
+GEN_VSX_HELPER_VSX_MADD(xvmaddsp, 0x04, 0x08, 0x09, 0, PPC2_VSX)
+GEN_VSX_HELPER_VSX_MADD(xvmsubsp, 0x04, 0x0A, 0x0B, 0, PPC2_VSX)
+GEN_VSX_HELPER_VSX_MADD(xvnmaddsp, 0x04, 0x18, 0x19, 0, PPC2_VSX)
+GEN_VSX_HELPER_VSX_MADD(xvnmsubsp, 0x04, 0x1A, 0x1B, 0, PPC2_VSX)
static void gen_xxbrd(DisasContext *ctx)
{
#define VSX_EXTRACT_INSERT(name) \
static void gen_##name(DisasContext *ctx) \
{ \
- TCGv xt, xb; \
+ TCGv_ptr xt, xb; \
TCGv_i32 t0; \
TCGv_i64 t1; \
uint8_t uimm = UIMM4(ctx->opcode); \
gen_exception(ctx, POWERPC_EXCP_VSXU); \
return; \
} \
- xt = tcg_const_tl(xT(ctx->opcode)); \
- xb = tcg_const_tl(xB(ctx->opcode)); \
+ xt = gen_vsr_ptr(xT(ctx->opcode)); \
+ xb = gen_vsr_ptr(xB(ctx->opcode)); \
t0 = tcg_temp_new_i32(); \
t1 = tcg_temp_new_i64(); \
/* \
} \
tcg_gen_movi_i32(t0, uimm); \
gen_helper_##name(cpu_env, xt, xb, t0); \
- tcg_temp_free(xb); \
- tcg_temp_free(xt); \
+ tcg_temp_free_ptr(xb); \
+ tcg_temp_free_ptr(xt); \
tcg_temp_free_i32(t0); \
tcg_temp_free_i64(t1); \
}
tcg_temp_free_i64(xbl);
}
-GEN_VSX_HELPER_2(xvxsigsp, 0x00, 0x04, 0, PPC2_ISA300)
+GEN_VSX_HELPER_X2(xvxsigsp, 0x00, 0x04, 0, PPC2_ISA300)
static void gen_xvxsigdp(DisasContext *ctx)
{
GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 2, opc3, 0, PPC_NONE, fl2), \
GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 3, opc3, 0, PPC_NONE, fl2)
+#define GEN_XX3FORM_NAME(name, opcname, opc2, opc3, fl2) \
+GEN_HANDLER2_E(name, opcname, 0x3C, opc2 | 0, opc3, 0, PPC_NONE, fl2), \
+GEN_HANDLER2_E(name, opcname, 0x3C, opc2 | 1, opc3, 0, PPC_NONE, fl2), \
+GEN_HANDLER2_E(name, opcname, 0x3C, opc2 | 2, opc3, 0, PPC_NONE, fl2), \
+GEN_HANDLER2_E(name, opcname, 0x3C, opc2 | 3, opc3, 0, PPC_NONE, fl2)
+
#define GEN_XX2IFORM(name, opc2, opc3, fl2) \
GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 1, PPC_NONE, fl2), \
GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 1, PPC_NONE, fl2), \
GEN_XX2FORM(xsrsqrtedp, 0x14, 0x04, PPC2_VSX),
GEN_XX3FORM(xstdivdp, 0x14, 0x07, PPC2_VSX),
GEN_XX2FORM(xstsqrtdp, 0x14, 0x06, PPC2_VSX),
-GEN_XX3FORM(xsmaddadp, 0x04, 0x04, PPC2_VSX),
-GEN_XX3FORM(xsmaddmdp, 0x04, 0x05, PPC2_VSX),
-GEN_XX3FORM(xsmsubadp, 0x04, 0x06, PPC2_VSX),
-GEN_XX3FORM(xsmsubmdp, 0x04, 0x07, PPC2_VSX),
-GEN_XX3FORM(xsnmaddadp, 0x04, 0x14, PPC2_VSX),
-GEN_XX3FORM(xsnmaddmdp, 0x04, 0x15, PPC2_VSX),
-GEN_XX3FORM(xsnmsubadp, 0x04, 0x16, PPC2_VSX),
-GEN_XX3FORM(xsnmsubmdp, 0x04, 0x17, PPC2_VSX),
+GEN_XX3FORM_NAME(xsmadddp, "xsmaddadp", 0x04, 0x04, PPC2_VSX),
+GEN_XX3FORM_NAME(xsmadddp, "xsmaddmdp", 0x04, 0x05, PPC2_VSX),
+GEN_XX3FORM_NAME(xsmsubdp, "xsmsubadp", 0x04, 0x06, PPC2_VSX),
+GEN_XX3FORM_NAME(xsmsubdp, "xsmsubmdp", 0x04, 0x07, PPC2_VSX),
+GEN_XX3FORM_NAME(xsnmadddp, "xsnmaddadp", 0x04, 0x14, PPC2_VSX),
+GEN_XX3FORM_NAME(xsnmadddp, "xsnmaddmdp", 0x04, 0x15, PPC2_VSX),
+GEN_XX3FORM_NAME(xsnmsubdp, "xsnmsubadp", 0x04, 0x16, PPC2_VSX),
+GEN_XX3FORM_NAME(xsnmsubdp, "xsnmsubmdp", 0x04, 0x17, PPC2_VSX),
GEN_XX3FORM(xscmpeqdp, 0x0C, 0x00, PPC2_ISA300),
GEN_XX3FORM(xscmpgtdp, 0x0C, 0x01, PPC2_ISA300),
GEN_XX3FORM(xscmpgedp, 0x0C, 0x02, PPC2_ISA300),
GEN_XX2FORM(xsrsp, 0x12, 0x11, PPC2_VSX207),
GEN_XX2FORM(xssqrtsp, 0x16, 0x00, PPC2_VSX207),
GEN_XX2FORM(xsrsqrtesp, 0x14, 0x00, PPC2_VSX207),
-GEN_XX3FORM(xsmaddasp, 0x04, 0x00, PPC2_VSX207),
-GEN_XX3FORM(xsmaddmsp, 0x04, 0x01, PPC2_VSX207),
-GEN_XX3FORM(xsmsubasp, 0x04, 0x02, PPC2_VSX207),
-GEN_XX3FORM(xsmsubmsp, 0x04, 0x03, PPC2_VSX207),
-GEN_XX3FORM(xsnmaddasp, 0x04, 0x10, PPC2_VSX207),
-GEN_XX3FORM(xsnmaddmsp, 0x04, 0x11, PPC2_VSX207),
-GEN_XX3FORM(xsnmsubasp, 0x04, 0x12, PPC2_VSX207),
-GEN_XX3FORM(xsnmsubmsp, 0x04, 0x13, PPC2_VSX207),
+GEN_XX3FORM_NAME(xsmaddsp, "xsmaddasp", 0x04, 0x00, PPC2_VSX207),
+GEN_XX3FORM_NAME(xsmaddsp, "xsmaddmsp", 0x04, 0x01, PPC2_VSX207),
+GEN_XX3FORM_NAME(xsmsubsp, "xsmsubasp", 0x04, 0x02, PPC2_VSX207),
+GEN_XX3FORM_NAME(xsmsubsp, "xsmsubmsp", 0x04, 0x03, PPC2_VSX207),
+GEN_XX3FORM_NAME(xsnmaddsp, "xsnmaddasp", 0x04, 0x10, PPC2_VSX207),
+GEN_XX3FORM_NAME(xsnmaddsp, "xsnmaddmsp", 0x04, 0x11, PPC2_VSX207),
+GEN_XX3FORM_NAME(xsnmsubsp, "xsnmsubasp", 0x04, 0x12, PPC2_VSX207),
+GEN_XX3FORM_NAME(xsnmsubsp, "xsnmsubmsp", 0x04, 0x13, PPC2_VSX207),
GEN_XX2FORM(xscvsxdsp, 0x10, 0x13, PPC2_VSX207),
GEN_XX2FORM(xscvuxdsp, 0x10, 0x12, PPC2_VSX207),
GEN_XX2FORM(xvrsqrtedp, 0x14, 0x0C, PPC2_VSX),
GEN_XX3FORM(xvtdivdp, 0x14, 0x0F, PPC2_VSX),
GEN_XX2FORM(xvtsqrtdp, 0x14, 0x0E, PPC2_VSX),
-GEN_XX3FORM(xvmaddadp, 0x04, 0x0C, PPC2_VSX),
-GEN_XX3FORM(xvmaddmdp, 0x04, 0x0D, PPC2_VSX),
-GEN_XX3FORM(xvmsubadp, 0x04, 0x0E, PPC2_VSX),
-GEN_XX3FORM(xvmsubmdp, 0x04, 0x0F, PPC2_VSX),
-GEN_XX3FORM(xvnmaddadp, 0x04, 0x1C, PPC2_VSX),
-GEN_XX3FORM(xvnmaddmdp, 0x04, 0x1D, PPC2_VSX),
-GEN_XX3FORM(xvnmsubadp, 0x04, 0x1E, PPC2_VSX),
-GEN_XX3FORM(xvnmsubmdp, 0x04, 0x1F, PPC2_VSX),
+GEN_XX3FORM_NAME(xvmadddp, "xvmaddadp", 0x04, 0x0C, PPC2_VSX),
+GEN_XX3FORM_NAME(xvmadddp, "xvmaddmdp", 0x04, 0x0D, PPC2_VSX),
+GEN_XX3FORM_NAME(xvmsubdp, "xvmsubadp", 0x04, 0x0E, PPC2_VSX),
+GEN_XX3FORM_NAME(xvmsubdp, "xvmsubmdp", 0x04, 0x0F, PPC2_VSX),
+GEN_XX3FORM_NAME(xvnmadddp, "xvnmaddadp", 0x04, 0x1C, PPC2_VSX),
+GEN_XX3FORM_NAME(xvnmadddp, "xvnmaddmdp", 0x04, 0x1D, PPC2_VSX),
+GEN_XX3FORM_NAME(xvnmsubdp, "xvnmsubadp", 0x04, 0x1E, PPC2_VSX),
+GEN_XX3FORM_NAME(xvnmsubdp, "xvnmsubmdp", 0x04, 0x1F, PPC2_VSX),
GEN_XX3FORM(xvmaxdp, 0x00, 0x1C, PPC2_VSX),
GEN_XX3FORM(xvmindp, 0x00, 0x1D, PPC2_VSX),
GEN_XX3_RC_FORM(xvcmpeqdp, 0x0C, 0x0C, PPC2_VSX),
GEN_XX2FORM(xvrsqrtesp, 0x14, 0x08, PPC2_VSX),
GEN_XX3FORM(xvtdivsp, 0x14, 0x0B, PPC2_VSX),
GEN_XX2FORM(xvtsqrtsp, 0x14, 0x0A, PPC2_VSX),
-GEN_XX3FORM(xvmaddasp, 0x04, 0x08, PPC2_VSX),
-GEN_XX3FORM(xvmaddmsp, 0x04, 0x09, PPC2_VSX),
-GEN_XX3FORM(xvmsubasp, 0x04, 0x0A, PPC2_VSX),
-GEN_XX3FORM(xvmsubmsp, 0x04, 0x0B, PPC2_VSX),
-GEN_XX3FORM(xvnmaddasp, 0x04, 0x18, PPC2_VSX),
-GEN_XX3FORM(xvnmaddmsp, 0x04, 0x19, PPC2_VSX),
-GEN_XX3FORM(xvnmsubasp, 0x04, 0x1A, PPC2_VSX),
-GEN_XX3FORM(xvnmsubmsp, 0x04, 0x1B, PPC2_VSX),
+GEN_XX3FORM_NAME(xvmaddsp, "xvmaddasp", 0x04, 0x08, PPC2_VSX),
+GEN_XX3FORM_NAME(xvmaddsp, "xvmaddmsp", 0x04, 0x09, PPC2_VSX),
+GEN_XX3FORM_NAME(xvmsubsp, "xvmsubasp", 0x04, 0x0A, PPC2_VSX),
+GEN_XX3FORM_NAME(xvmsubsp, "xvmsubmsp", 0x04, 0x0B, PPC2_VSX),
+GEN_XX3FORM_NAME(xvnmaddsp, "xvnmaddasp", 0x04, 0x18, PPC2_VSX),
+GEN_XX3FORM_NAME(xvnmaddsp, "xvnmaddmsp", 0x04, 0x19, PPC2_VSX),
+GEN_XX3FORM_NAME(xvnmsubsp, "xvnmsubasp", 0x04, 0x1A, PPC2_VSX),
+GEN_XX3FORM_NAME(xvnmsubsp, "xvnmsubmsp", 0x04, 0x1B, PPC2_VSX),
GEN_XX3FORM(xvmaxsp, 0x00, 0x18, PPC2_VSX),
GEN_XX3FORM(xvminsp, 0x00, 0x19, PPC2_VSX),
GEN_XX3_RC_FORM(xvcmpeqsp, 0x0C, 0x08, PPC2_VSX),
#include "qemu/cutils.h"
#include "disas/capstone.h"
#include "fpu/softfloat.h"
-#include "qapi/qapi-commands-target.h"
+#include "qapi/qapi-commands-machine-target.h"
/* #define PPC_DUMP_CPU */
/* #define PPC_DEBUG_SPR */
#include "cpu.h"
#include "exec/exec-all.h"
#include "qapi/error.h"
+#include "qemu/error-report.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
env->misa_mask = env->misa = misa;
}
-static void set_versions(CPURISCVState *env, int user_ver, int priv_ver)
+static void set_priv_version(CPURISCVState *env, int priv_ver)
{
- env->user_ver = user_ver;
env->priv_ver = priv_ver;
}
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
- set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
+ set_priv_version(env, PRIV_VERSION_1_11_0);
set_resetvec(env, DEFAULT_RSTVEC);
}
static void riscv_base32_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
- set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+ /* We set this in the realise function */
+ set_misa(env, 0);
}
static void rv32gcsu_priv1_09_1_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
- set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_09_1);
+ set_priv_version(env, PRIV_VERSION_1_09_1);
set_resetvec(env, DEFAULT_RSTVEC);
set_feature(env, RISCV_FEATURE_MMU);
set_feature(env, RISCV_FEATURE_PMP);
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
- set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
+ set_priv_version(env, PRIV_VERSION_1_10_0);
set_resetvec(env, DEFAULT_RSTVEC);
set_feature(env, RISCV_FEATURE_MMU);
set_feature(env, RISCV_FEATURE_PMP);
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
- set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
+ set_priv_version(env, PRIV_VERSION_1_10_0);
set_resetvec(env, DEFAULT_RSTVEC);
set_feature(env, RISCV_FEATURE_PMP);
}
static void riscv_base64_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
- set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+ /* We set this in the realise function */
+ set_misa(env, 0);
}
static void rv64gcsu_priv1_09_1_cpu_init(Object *obj)
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
- set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_09_1);
+ set_priv_version(env, PRIV_VERSION_1_09_1);
set_resetvec(env, DEFAULT_RSTVEC);
set_feature(env, RISCV_FEATURE_MMU);
set_feature(env, RISCV_FEATURE_PMP);
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
- set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
+ set_priv_version(env, PRIV_VERSION_1_10_0);
set_resetvec(env, DEFAULT_RSTVEC);
set_feature(env, RISCV_FEATURE_MMU);
set_feature(env, RISCV_FEATURE_PMP);
{
CPURISCVState *env = &RISCV_CPU(obj)->env;
set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
- set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
+ set_priv_version(env, PRIV_VERSION_1_10_0);
set_resetvec(env, DEFAULT_RSTVEC);
set_feature(env, RISCV_FEATURE_PMP);
}
env->pc = env->resetvec;
#endif
cs->exception_index = EXCP_NONE;
+ env->load_res = -1;
set_default_nan_mode(1, &env->fp_status);
}
RISCVCPU *cpu = RISCV_CPU(dev);
CPURISCVState *env = &cpu->env;
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
- int priv_version = PRIV_VERSION_1_10_0;
- int user_version = USER_VERSION_2_02_0;
+ int priv_version = PRIV_VERSION_1_11_0;
+ target_ulong target_misa = 0;
Error *local_err = NULL;
cpu_exec_realizefn(cs, &local_err);
}
if (cpu->cfg.priv_spec) {
- if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
+ if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) {
+ priv_version = PRIV_VERSION_1_11_0;
+ } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) {
priv_version = PRIV_VERSION_1_10_0;
} else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.9.1")) {
priv_version = PRIV_VERSION_1_09_1;
}
}
- if (cpu->cfg.user_spec) {
- if (!g_strcmp0(cpu->cfg.user_spec, "v2.02.0")) {
- user_version = USER_VERSION_2_02_0;
- } else {
- error_setg(errp,
- "Unsupported user spec version '%s'",
- cpu->cfg.user_spec);
- return;
- }
- }
-
- set_versions(env, user_version, priv_version);
+ set_priv_version(env, priv_version);
set_resetvec(env, DEFAULT_RSTVEC);
if (cpu->cfg.mmu) {
set_feature(env, RISCV_FEATURE_PMP);
}
+ /* If misa isn't set (rv32 and rv64 machines) set it here */
+ if (!env->misa) {
+ /* Do some ISA extension error checking */
+ if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
+ error_setg(errp,
+ "I and E extensions are incompatible");
+ return;
+ }
+
+ if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) {
+ error_setg(errp,
+ "Either I or E extension must be set");
+ return;
+ }
+
+ if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m &
+ cpu->cfg.ext_a & cpu->cfg.ext_f &
+ cpu->cfg.ext_d)) {
+ warn_report("Setting G will also set IMAFD");
+ cpu->cfg.ext_i = true;
+ cpu->cfg.ext_m = true;
+ cpu->cfg.ext_a = true;
+ cpu->cfg.ext_f = true;
+ cpu->cfg.ext_d = true;
+ }
+
+ /* Set the ISA extensions, checks should have happened above */
+ if (cpu->cfg.ext_i) {
+ target_misa |= RVI;
+ }
+ if (cpu->cfg.ext_e) {
+ target_misa |= RVE;
+ }
+ if (cpu->cfg.ext_m) {
+ target_misa |= RVM;
+ }
+ if (cpu->cfg.ext_a) {
+ target_misa |= RVA;
+ }
+ if (cpu->cfg.ext_f) {
+ target_misa |= RVF;
+ }
+ if (cpu->cfg.ext_d) {
+ target_misa |= RVD;
+ }
+ if (cpu->cfg.ext_c) {
+ target_misa |= RVC;
+ }
+ if (cpu->cfg.ext_s) {
+ target_misa |= RVS;
+ }
+ if (cpu->cfg.ext_u) {
+ target_misa |= RVU;
+ }
+
+ set_misa(env, RVXLEN | target_misa);
+ }
+
riscv_cpu_register_gdb_regs_for_features(cs);
qemu_init_vcpu(cs);
};
static Property riscv_cpu_properties[] = {
+ DEFINE_PROP_BOOL("i", RISCVCPU, cfg.ext_i, true),
+ DEFINE_PROP_BOOL("e", RISCVCPU, cfg.ext_e, false),
+ DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, true),
+ DEFINE_PROP_BOOL("m", RISCVCPU, cfg.ext_m, true),
+ DEFINE_PROP_BOOL("a", RISCVCPU, cfg.ext_a, true),
+ DEFINE_PROP_BOOL("f", RISCVCPU, cfg.ext_f, true),
+ DEFINE_PROP_BOOL("d", RISCVCPU, cfg.ext_d, true),
+ DEFINE_PROP_BOOL("c", RISCVCPU, cfg.ext_c, true),
+ DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true),
+ DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
+ DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
+ DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
+ DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
- DEFINE_PROP_STRING("user_spec", RISCVCPU, cfg.user_spec),
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
DEFINE_PROP_END_OF_LIST(),
cc->gdb_stop_before_watchpoint = true;
cc->disas_set_info = riscv_cpu_disas_set_info;
#ifndef CONFIG_USER_ONLY
+ cc->do_unassigned_access = riscv_cpu_unassigned_access;
cc->do_unaligned_access = riscv_cpu_do_unaligned_access;
cc->get_phys_page_debug = riscv_cpu_get_phys_page_debug;
#endif
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
#if defined(TARGET_RISCV32)
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base32_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_09_1, rv32gcsu_priv1_09_1_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_10_0, rv32gcsu_priv1_10_0_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_RV32IMACU_NOMMU, rv32imacu_nommu_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init)
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init),
+ /* Depreacted */
+ DEFINE_CPU(TYPE_RISCV_CPU_RV32IMACU_NOMMU, rv32imacu_nommu_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_09_1, rv32gcsu_priv1_09_1_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_RV32GCSU_V1_10_0, rv32gcsu_priv1_10_0_cpu_init)
#elif defined(TARGET_RISCV64)
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base64_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_09_1, rv64gcsu_priv1_09_1_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_10_0, rv64gcsu_priv1_10_0_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_RV64IMACU_NOMMU, rv64imacu_nommu_cpu_init),
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init)
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init),
+ /* Deprecated */
+ DEFINE_CPU(TYPE_RISCV_CPU_RV64IMACU_NOMMU, rv64imacu_nommu_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_09_1, rv64gcsu_priv1_09_1_cpu_init),
+ DEFINE_CPU(TYPE_RISCV_CPU_RV64GCSU_V1_10_0, rv64gcsu_priv1_10_0_cpu_init)
#endif
};
#define TYPE_RISCV_CPU_ANY RISCV_CPU_TYPE_NAME("any")
#define TYPE_RISCV_CPU_BASE32 RISCV_CPU_TYPE_NAME("rv32")
#define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64")
-#define TYPE_RISCV_CPU_RV32GCSU_V1_09_1 RISCV_CPU_TYPE_NAME("rv32gcsu-v1.9.1")
-#define TYPE_RISCV_CPU_RV32GCSU_V1_10_0 RISCV_CPU_TYPE_NAME("rv32gcsu-v1.10.0")
-#define TYPE_RISCV_CPU_RV32IMACU_NOMMU RISCV_CPU_TYPE_NAME("rv32imacu-nommu")
-#define TYPE_RISCV_CPU_RV64GCSU_V1_09_1 RISCV_CPU_TYPE_NAME("rv64gcsu-v1.9.1")
-#define TYPE_RISCV_CPU_RV64GCSU_V1_10_0 RISCV_CPU_TYPE_NAME("rv64gcsu-v1.10.0")
-#define TYPE_RISCV_CPU_RV64IMACU_NOMMU RISCV_CPU_TYPE_NAME("rv64imacu-nommu")
#define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31")
#define TYPE_RISCV_CPU_SIFIVE_E51 RISCV_CPU_TYPE_NAME("sifive-e51")
#define TYPE_RISCV_CPU_SIFIVE_U34 RISCV_CPU_TYPE_NAME("sifive-u34")
#define TYPE_RISCV_CPU_SIFIVE_U54 RISCV_CPU_TYPE_NAME("sifive-u54")
+/* Deprecated */
+#define TYPE_RISCV_CPU_RV32IMACU_NOMMU RISCV_CPU_TYPE_NAME("rv32imacu-nommu")
+#define TYPE_RISCV_CPU_RV32GCSU_V1_09_1 RISCV_CPU_TYPE_NAME("rv32gcsu-v1.9.1")
+#define TYPE_RISCV_CPU_RV32GCSU_V1_10_0 RISCV_CPU_TYPE_NAME("rv32gcsu-v1.10.0")
+#define TYPE_RISCV_CPU_RV64IMACU_NOMMU RISCV_CPU_TYPE_NAME("rv64imacu-nommu")
+#define TYPE_RISCV_CPU_RV64GCSU_V1_09_1 RISCV_CPU_TYPE_NAME("rv64gcsu-v1.9.1")
+#define TYPE_RISCV_CPU_RV64GCSU_V1_10_0 RISCV_CPU_TYPE_NAME("rv64gcsu-v1.10.0")
#define RV32 ((target_ulong)1 << (TARGET_LONG_BITS - 2))
#define RV64 ((target_ulong)2 << (TARGET_LONG_BITS - 2))
RISCV_FEATURE_MISA
};
-#define USER_VERSION_2_02_0 0x00020200
#define PRIV_VERSION_1_09_1 0x00010901
#define PRIV_VERSION_1_10_0 0x00011000
+#define PRIV_VERSION_1_11_0 0x00011100
+#define TRANSLATE_PMP_FAIL 2
#define TRANSLATE_FAIL 1
#define TRANSLATE_SUCCESS 0
#define MMU_USER_IDX 3
target_ulong badaddr;
- target_ulong user_ver;
target_ulong priv_ver;
target_ulong misa;
target_ulong misa_mask;
/* Configuration Settings */
struct {
+ bool ext_i;
+ bool ext_e;
+ bool ext_g;
+ bool ext_m;
+ bool ext_a;
+ bool ext_f;
+ bool ext_d;
+ bool ext_c;
+ bool ext_s;
+ bool ext_u;
+ bool ext_counters;
+ bool ext_ifencei;
+ bool ext_icsr;
+
char *priv_spec;
char *user_spec;
bool mmu;
bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
+void riscv_cpu_unassigned_access(CPUState *cpu, hwaddr addr, bool is_write,
+ bool is_exec, int unused, unsigned size);
char *riscv_isa_string(RISCVCPU *cpu);
void riscv_cpu_list(void);
#define CSR_MCOUNTEREN 0x306
/* Legacy Counter Setup (priv v1.9.1) */
+/* Update to #define CSR_MCOUNTINHIBIT 0x320 for 1.11.0 */
#define CSR_MUCOUNTEREN 0x320
#define CSR_MSCOUNTEREN 0x321
#define CSR_MHCOUNTEREN 0x322
}
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
env->priv = newpriv;
+
+ /*
+ * Clear the load reservation - otherwise a reservation placed in one
+ * context/process can be used by another, resulting in an SC succeeding
+ * incorrectly. Version 2.2 of the ISA specification explicitly requires
+ * this behaviour, while later revisions say that the kernel "should" use
+ * an SC instruction to force the yielding of a load reservation on a
+ * preemptive context switch. As a result, do both.
+ */
+ env->load_res = -1;
}
/* get_physical_address - get the physical address for this virtual address
/* check that physical address of PTE is legal */
target_ulong pte_addr = base + idx * ptesize;
+
+ if (riscv_feature(env, RISCV_FEATURE_PMP) &&
+ !pmp_hart_has_privs(env, pte_addr, sizeof(target_ulong),
+ 1 << MMU_DATA_LOAD, PRV_S)) {
+ return TRANSLATE_PMP_FAIL;
+ }
#if defined(TARGET_RISCV32)
target_ulong pte = ldl_phys(cs->as, pte_addr);
#elif defined(TARGET_RISCV64)
}
static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
- MMUAccessType access_type)
+ MMUAccessType access_type, bool pmp_violation)
{
CPUState *cs = env_cpu(env);
int page_fault_exceptions =
(env->priv_ver >= PRIV_VERSION_1_10_0) &&
- get_field(env->satp, SATP_MODE) != VM_1_10_MBARE;
+ get_field(env->satp, SATP_MODE) != VM_1_10_MBARE &&
+ !pmp_violation;
switch (access_type) {
case MMU_INST_FETCH:
cs->exception_index = page_fault_exceptions ?
return phys_addr;
}
+void riscv_cpu_unassigned_access(CPUState *cs, hwaddr addr, bool is_write,
+ bool is_exec, int unused, unsigned size)
+{
+ RISCVCPU *cpu = RISCV_CPU(cs);
+ CPURISCVState *env = &cpu->env;
+
+ if (is_write) {
+ cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
+ } else {
+ cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT;
+ }
+
+ env->badaddr = addr;
+ riscv_raise_exception(&cpu->env, cs->exception_index, GETPC());
+}
+
void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type, int mmu_idx,
uintptr_t retaddr)
CPURISCVState *env = &cpu->env;
hwaddr pa = 0;
int prot;
+ bool pmp_violation = false;
int ret = TRANSLATE_FAIL;
+ int mode = mmu_idx;
qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
__func__, address, access_type, mmu_idx);
ret = get_physical_address(env, &pa, &prot, address, access_type, mmu_idx);
+ if (mode == PRV_M && access_type != MMU_INST_FETCH) {
+ if (get_field(env->mstatus, MSTATUS_MPRV)) {
+ mode = get_field(env->mstatus, MSTATUS_MPP);
+ }
+ }
+
qemu_log_mask(CPU_LOG_MMU,
"%s address=%" VADDR_PRIx " ret %d physical " TARGET_FMT_plx
" prot %d\n", __func__, address, ret, pa, prot);
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
- !pmp_hart_has_privs(env, pa, TARGET_PAGE_SIZE, 1 << access_type)) {
- ret = TRANSLATE_FAIL;
+ (ret == TRANSLATE_SUCCESS) &&
+ !pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
+ ret = TRANSLATE_PMP_FAIL;
+ }
+ if (ret == TRANSLATE_PMP_FAIL) {
+ pmp_violation = true;
}
if (ret == TRANSLATE_SUCCESS) {
tlb_set_page(cs, address & TARGET_PAGE_MASK, pa & TARGET_PAGE_MASK,
} else if (probe) {
return false;
} else {
- raise_mmu_exception(env, address, access_type);
+ raise_mmu_exception(env, address, access_type, pmp_violation);
riscv_raise_exception(env, cs->exception_index, retaddr);
}
#else
static int ctr(CPURISCVState *env, int csrno)
{
#if !defined(CONFIG_USER_ONLY)
+ CPUState *cs = env_cpu(env);
+ RISCVCPU *cpu = RISCV_CPU(cs);
uint32_t ctr_en = ~0u;
+ if (!cpu->cfg.ext_counters) {
+ /* The Counters extensions is not enabled */
+ return -1;
+ }
+
+ /*
+ * The counters are always enabled at run time on newer priv specs, as the
+ * CSR has changed from controlling that the counters can be read to
+ * controlling that the counters increment.
+ */
+ if (env->priv_ver > PRIV_VERSION_1_09_1) {
+ return 0;
+ }
+
if (env->priv < PRV_M) {
ctr_en &= env->mcounteren;
}
return 0;
}
+/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
static int read_mscounteren(CPURISCVState *env, int csrno, target_ulong *val)
{
- if (env->priv_ver > PRIV_VERSION_1_09_1) {
+ if (env->priv_ver > PRIV_VERSION_1_09_1
+ && env->priv_ver < PRIV_VERSION_1_11_0) {
return -1;
}
*val = env->mcounteren;
return 0;
}
+/* This regiser is replaced with CSR_MCOUNTINHIBIT in 1.11.0 */
static int write_mscounteren(CPURISCVState *env, int csrno, target_ulong val)
{
- if (env->priv_ver > PRIV_VERSION_1_09_1) {
+ if (env->priv_ver > PRIV_VERSION_1_09_1
+ && env->priv_ver < PRIV_VERSION_1_11_0) {
return -1;
}
env->mcounteren = val;
{
int ret;
target_ulong old_value;
+ RISCVCPU *cpu = env_archcpu(env);
/* check privileges and return -1 if check fails */
#if !defined(CONFIG_USER_ONLY)
}
#endif
+ /* ensure the CSR extension is enabled. */
+ if (!cpu->cfg.ext_icsr) {
+ return -1;
+ }
+
/* check predicate */
if (!csr_ops[csrno].predicate || csr_ops[csrno].predicate(env, csrno) < 0) {
return -1;
static bool trans_sfence_vma(DisasContext *ctx, arg_sfence_vma *a)
{
#ifndef CONFIG_USER_ONLY
- if (ctx->priv_ver == PRIV_VERSION_1_10_0) {
+ if (ctx->priv_ver >= PRIV_VERSION_1_10_0) {
gen_helper_tlb_flush(cpu_env);
return true;
}
gen_set_label(l1);
/*
- * Address comparion failure. However, we still need to
+ * Address comparison failure. However, we still need to
* provide the memory barrier implied by AQ/RL.
*/
tcg_gen_mb(TCG_MO_ALL + a->aq * TCG_BAR_LDAQ + a->rl * TCG_BAR_STRL);
gen_set_gpr(a->rd, dat);
gen_set_label(l2);
+ /*
+ * Clear the load reservation, since an SC must fail if there is
+ * an SC to any address, in between an LR and SC pair.
+ */
+ tcg_gen_movi_tl(load_res, -1);
+
tcg_temp_free(dat);
tcg_temp_free(src1);
tcg_temp_free(src2);
static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
{
+ if (!ctx->ext_ifencei) {
+ return false;
+ }
+
/*
* FENCE_I is a no-op in QEMU,
* however we need to end the translation block
* Check if the address has required RWX privs to complete desired operation
*/
bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
- target_ulong size, pmp_priv_t privs)
+ target_ulong size, pmp_priv_t privs, target_ulong mode)
{
int i = 0;
int ret = -1;
from low to high */
for (i = 0; i < MAX_RISCV_PMPS; i++) {
s = pmp_is_in_range(env, i, addr);
- e = pmp_is_in_range(env, i, addr + size);
+ e = pmp_is_in_range(env, i, addr + size - 1);
/* partially inside */
if ((s + e) == 1) {
/* fully inside */
const uint8_t a_field =
pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
- if ((s + e) == 2) {
- if (PMP_AMATCH_OFF == a_field) {
- return 1;
- }
+ /*
+ * If the PMP entry is not off and the address is in range, do the priv
+ * check
+ */
+ if (((s + e) == 2) && (PMP_AMATCH_OFF != a_field)) {
allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
- if ((env->priv != PRV_M) || pmp_is_locked(env, i)) {
+ if ((mode != PRV_M) || pmp_is_locked(env, i)) {
allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
}
/* No rule matched */
if (ret == -1) {
- if (env->priv == PRV_M) {
+ if (mode == PRV_M) {
ret = 1; /* Privileged spec v1.10 states if no PMP entry matches an
* M-Mode access, the access succeeds */
} else {
target_ulong val);
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
- target_ulong size, pmp_priv_t priv);
+ target_ulong size, pmp_priv_t priv, target_ulong mode);
#endif
to any system register, which includes CSR_FRM, so we do not have
to reset this known value. */
int frm;
+ bool ext_ifencei;
} DisasContext;
#ifdef TARGET_RISCV64
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
CPURISCVState *env = cs->env_ptr;
+ RISCVCPU *cpu = RISCV_CPU(cs);
ctx->pc_succ_insn = ctx->base.pc_first;
ctx->mem_idx = ctx->base.tb->flags & TB_FLAGS_MMU_MASK;
ctx->priv_ver = env->priv_ver;
ctx->misa = env->misa;
ctx->frm = -1; /* unknown rounding mode */
+ ctx->ext_ifencei = cpu->cfg.ext_ifencei;
}
static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
#include "qemu/module.h"
#include "trace.h"
#include "qapi/visitor.h"
-#include "qapi/qapi-visit-misc.h"
+#include "qapi/qapi-types-machine.h"
#include "qapi/qapi-visit-run-state.h"
#include "sysemu/hw_accel.h"
#include "hw/qdev-properties.h"
* CPU features/facilities for s390x
*
* Copyright IBM Corp. 2016, 2018
+ * Copyright Red Hat, Inc. 2019
*
- * Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com>
+ * Author(s): David Hildenbrand <david@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at
* your option) any later version. See the COPYING file in the top-level
#include "qemu/module.h"
#include "cpu_features.h"
-#define FEAT_INIT(_name, _type, _bit, _desc) \
- { \
- .name = _name, \
- .type = _type, \
- .bit = _bit, \
- .desc = _desc, \
- }
-
-/* S390FeatDef.bit is not applicable as there is no feature block. */
-#define FEAT_INIT_MISC(_name, _desc) \
- FEAT_INIT(_name, S390_FEAT_TYPE_MISC, 0, _desc)
-
-/* indexed by feature number for easy lookup */
-static const S390FeatDef s390_features[] = {
- FEAT_INIT("esan3", S390_FEAT_TYPE_STFL, 0, "Instructions marked as n3"),
- FEAT_INIT("zarch", S390_FEAT_TYPE_STFL, 1, "z/Architecture architectural mode"),
- FEAT_INIT("dateh", S390_FEAT_TYPE_STFL, 3, "DAT-enhancement facility"),
- FEAT_INIT("idtes", S390_FEAT_TYPE_STFL, 4, "IDTE selective TLB segment-table clearing"),
- FEAT_INIT("idter", S390_FEAT_TYPE_STFL, 5, "IDTE selective TLB region-table clearing"),
- FEAT_INIT("asnlxr", S390_FEAT_TYPE_STFL, 6, "ASN-and-LX reuse facility"),
- FEAT_INIT("stfle", S390_FEAT_TYPE_STFL, 7, "Store-facility-list-extended facility"),
- FEAT_INIT("edat", S390_FEAT_TYPE_STFL, 8, "Enhanced-DAT facility"),
- FEAT_INIT("srs", S390_FEAT_TYPE_STFL, 9, "Sense-running-status facility"),
- FEAT_INIT("csske", S390_FEAT_TYPE_STFL, 10, "Conditional-SSKE facility"),
- FEAT_INIT("ctop", S390_FEAT_TYPE_STFL, 11, "Configuration-topology facility"),
- FEAT_INIT("apqci", S390_FEAT_TYPE_STFL, 12, "Query AP Configuration Information facility"),
- FEAT_INIT("ipter", S390_FEAT_TYPE_STFL, 13, "IPTE-range facility"),
- FEAT_INIT("nonqks", S390_FEAT_TYPE_STFL, 14, "Nonquiescing key-setting facility"),
- FEAT_INIT("apft", S390_FEAT_TYPE_STFL, 15, "AP Facilities Test facility"),
- FEAT_INIT("etf2", S390_FEAT_TYPE_STFL, 16, "Extended-translation facility 2"),
- FEAT_INIT("msa-base", S390_FEAT_TYPE_STFL, 17, "Message-security-assist facility (excluding subfunctions)"),
- FEAT_INIT("ldisp", S390_FEAT_TYPE_STFL, 18, "Long-displacement facility"),
- FEAT_INIT("ldisphp", S390_FEAT_TYPE_STFL, 19, "Long-displacement facility has high performance"),
- FEAT_INIT("hfpm", S390_FEAT_TYPE_STFL, 20, "HFP-multiply-add/subtract facility"),
- FEAT_INIT("eimm", S390_FEAT_TYPE_STFL, 21, "Extended-immediate facility"),
- FEAT_INIT("etf3", S390_FEAT_TYPE_STFL, 22, "Extended-translation facility 3"),
- FEAT_INIT("hfpue", S390_FEAT_TYPE_STFL, 23, "HFP-unnormalized-extension facility"),
- FEAT_INIT("etf2eh", S390_FEAT_TYPE_STFL, 24, "ETF2-enhancement facility"),
- FEAT_INIT("stckf", S390_FEAT_TYPE_STFL, 25, "Store-clock-fast facility"),
- FEAT_INIT("parseh", S390_FEAT_TYPE_STFL, 26, "Parsing-enhancement facility"),
- FEAT_INIT("mvcos", S390_FEAT_TYPE_STFL, 27, "Move-with-optional-specification facility"),
- FEAT_INIT("tods-base", S390_FEAT_TYPE_STFL, 28, "TOD-clock-steering facility (excluding subfunctions)"),
- FEAT_INIT("etf3eh", S390_FEAT_TYPE_STFL, 30, "ETF3-enhancement facility"),
- FEAT_INIT("ectg", S390_FEAT_TYPE_STFL, 31, "Extract-CPU-time facility"),
- FEAT_INIT("csst", S390_FEAT_TYPE_STFL, 32, "Compare-and-swap-and-store facility"),
- FEAT_INIT("csst2", S390_FEAT_TYPE_STFL, 33, "Compare-and-swap-and-store facility 2"),
- FEAT_INIT("ginste", S390_FEAT_TYPE_STFL, 34, "General-instructions-extension facility"),
- FEAT_INIT("exrl", S390_FEAT_TYPE_STFL, 35, "Execute-extensions facility"),
- FEAT_INIT("emon", S390_FEAT_TYPE_STFL, 36, "Enhanced-monitor facility"),
- FEAT_INIT("fpe", S390_FEAT_TYPE_STFL, 37, "Floating-point extension facility"),
- FEAT_INIT("opc", S390_FEAT_TYPE_STFL, 38, "Order Preserving Compression facility"),
- FEAT_INIT("sprogp", S390_FEAT_TYPE_STFL, 40, "Set-program-parameters facility"),
- FEAT_INIT("fpseh", S390_FEAT_TYPE_STFL, 41, "Floating-point-support-enhancement facilities"),
- FEAT_INIT("dfp", S390_FEAT_TYPE_STFL, 42, "DFP (decimal-floating-point) facility"),
- FEAT_INIT("dfphp", S390_FEAT_TYPE_STFL, 43, "DFP (decimal-floating-point) facility has high performance"),
- FEAT_INIT("pfpo", S390_FEAT_TYPE_STFL, 44, "PFPO instruction"),
- FEAT_INIT("stfle45", S390_FEAT_TYPE_STFL, 45, "Various facilities introduced with z196"),
- FEAT_INIT("cmpsceh", S390_FEAT_TYPE_STFL, 47, "CMPSC-enhancement facility"),
- FEAT_INIT("dfpzc", S390_FEAT_TYPE_STFL, 48, "Decimal-floating-point zoned-conversion facility"),
- FEAT_INIT("stfle49", S390_FEAT_TYPE_STFL, 49, "Various facilities introduced with zEC12"),
- FEAT_INIT("cte", S390_FEAT_TYPE_STFL, 50, "Constrained transactional-execution facility"),
- FEAT_INIT("ltlbc", S390_FEAT_TYPE_STFL, 51, "Local-TLB-clearing facility"),
- FEAT_INIT("iacc2", S390_FEAT_TYPE_STFL, 52, "Interlocked-access facility 2"),
- FEAT_INIT("stfle53", S390_FEAT_TYPE_STFL, 53, "Various facilities introduced with z13"),
- FEAT_INIT("eec", S390_FEAT_TYPE_STFL, 54, "Entropy encoding compression facility"),
- FEAT_INIT("msa5-base", S390_FEAT_TYPE_STFL, 57, "Message-security-assist-extension-5 facility (excluding subfunctions)"),
- FEAT_INIT("minste2", S390_FEAT_TYPE_STFL, 58, "Miscellaneous-instruction-extensions facility 2"),
- FEAT_INIT("sema", S390_FEAT_TYPE_STFL, 59, "Semaphore-assist facility"),
- FEAT_INIT("tsi", S390_FEAT_TYPE_STFL, 60, "Time-slice Instrumentation facility"),
- FEAT_INIT("minste3", S390_FEAT_TYPE_STFL, 61, "Miscellaneous-Instruction-Extensions Facility 3"),
- FEAT_INIT("ri", S390_FEAT_TYPE_STFL, 64, "CPU runtime-instrumentation facility"),
- FEAT_INIT("zpci", S390_FEAT_TYPE_STFL, 69, "z/PCI facility"),
- FEAT_INIT("aen", S390_FEAT_TYPE_STFL, 71, "General-purpose-adapter-event-notification facility"),
- FEAT_INIT("ais", S390_FEAT_TYPE_STFL, 72, "General-purpose-adapter-interruption-suppression facility"),
- FEAT_INIT("te", S390_FEAT_TYPE_STFL, 73, "Transactional-execution facility"),
- FEAT_INIT("sthyi", S390_FEAT_TYPE_STFL, 74, "Store-hypervisor-information facility"),
- FEAT_INIT("aefsi", S390_FEAT_TYPE_STFL, 75, "Access-exception-fetch/store-indication facility"),
- FEAT_INIT("msa3-base", S390_FEAT_TYPE_STFL, 76, "Message-security-assist-extension-3 facility (excluding subfunctions)"),
- FEAT_INIT("msa4-base", S390_FEAT_TYPE_STFL, 77, "Message-security-assist-extension-4 facility (excluding subfunctions)"),
- FEAT_INIT("edat2", S390_FEAT_TYPE_STFL, 78, "Enhanced-DAT facility 2"),
- FEAT_INIT("dfppc", S390_FEAT_TYPE_STFL, 80, "Decimal-floating-point packed-conversion facility"),
- FEAT_INIT("ppa15", S390_FEAT_TYPE_STFL, 81, "PPA15 is installed"),
- FEAT_INIT("bpb", S390_FEAT_TYPE_STFL, 82, "Branch prediction blocking"),
- FEAT_INIT("vx", S390_FEAT_TYPE_STFL, 129, "Vector facility"),
- FEAT_INIT("iep", S390_FEAT_TYPE_STFL, 130, "Instruction-execution-protection facility"),
- FEAT_INIT("sea_esop2", S390_FEAT_TYPE_STFL, 131, "Side-effect-access facility and Enhanced-suppression-on-protection facility 2"),
- FEAT_INIT("gs", S390_FEAT_TYPE_STFL, 133, "Guarded-storage facility"),
- FEAT_INIT("vxpd", S390_FEAT_TYPE_STFL, 134, "Vector packed decimal facility"),
- FEAT_INIT("vxeh", S390_FEAT_TYPE_STFL, 135, "Vector enhancements facility"),
- FEAT_INIT("mepoch", S390_FEAT_TYPE_STFL, 139, "Multiple-epoch facility"),
- FEAT_INIT("tpei", S390_FEAT_TYPE_STFL, 144, "Test-pending-external-interruption facility"),
- FEAT_INIT("irbm", S390_FEAT_TYPE_STFL, 145, "Insert-reference-bits-multiple facility"),
- FEAT_INIT("msa8-base", S390_FEAT_TYPE_STFL, 146, "Message-security-assist-extension-8 facility (excluding subfunctions)"),
- FEAT_INIT("cmmnt", S390_FEAT_TYPE_STFL, 147, "CMM: ESSA-enhancement (no translate) facility"),
- FEAT_INIT("vxeh2", S390_FEAT_TYPE_STFL, 148, "Vector Enhancements facility 2"),
- FEAT_INIT("esort-base", S390_FEAT_TYPE_STFL, 150, "Enhanced-sort facility (excluding subfunctions)"),
- FEAT_INIT("deflate-base", S390_FEAT_TYPE_STFL, 151, "Deflate-conversion facility (excluding subfunctions)"),
- FEAT_INIT("vxbeh", S390_FEAT_TYPE_STFL, 152, "Vector BCD enhancements facility 1"),
- FEAT_INIT("msa9-base", S390_FEAT_TYPE_STFL, 155, "Message-security-assist-extension-9 facility (excluding subfunctions)"),
- FEAT_INIT("etoken", S390_FEAT_TYPE_STFL, 156, "Etoken facility"),
-
- /* SCLP SCCB Byte 80 - 98 (bit numbers relative to byte-80) */
- FEAT_INIT("gsls", S390_FEAT_TYPE_SCLP_CONF_CHAR, 40, "SIE: Guest-storage-limit-suppression facility"),
- FEAT_INIT("esop", S390_FEAT_TYPE_SCLP_CONF_CHAR, 46, "Enhanced-suppression-on-protection facility"),
- FEAT_INIT("hpma2", S390_FEAT_TYPE_SCLP_CONF_CHAR, 90, "Host page management assist 2 Facility"), /* 91-2 */
- FEAT_INIT("kss", S390_FEAT_TYPE_SCLP_CONF_CHAR, 151, "SIE: Keyless-subset facility"), /* 98-7 */
-
- /* SCLP SCCB Byte 116 - 119 (bit numbers relative to byte-116) */
- FEAT_INIT("64bscao", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 0, "SIE: 64-bit-SCAO facility"),
- FEAT_INIT("cmma", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 1, "SIE: Collaborative-memory-management assist"),
- FEAT_INIT("pfmfi", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF interpretation facility"),
- FEAT_INIT("ibs", S390_FEAT_TYPE_SCLP_CONF_CHAR_EXT, 10, "SIE: Interlock-and-broadcast-suppression facility"),
-
- FEAT_INIT("sief2", S390_FEAT_TYPE_SCLP_CPU, 4, "SIE: interception format 2 (Virtual SIE)"),
- FEAT_INIT("skey", S390_FEAT_TYPE_SCLP_CPU, 5, "SIE: Storage-key facility"),
- FEAT_INIT("gpereh", S390_FEAT_TYPE_SCLP_CPU, 10, "SIE: Guest-PER enhancement facility"),
- FEAT_INIT("siif", S390_FEAT_TYPE_SCLP_CPU, 11, "SIE: Shared IPTE-interlock facility"),
- FEAT_INIT("sigpif", S390_FEAT_TYPE_SCLP_CPU, 12, "SIE: SIGP interpretation facility"),
- FEAT_INIT("ib", S390_FEAT_TYPE_SCLP_CPU, 42, "SIE: Intervention bypass facility"),
- FEAT_INIT("cei", S390_FEAT_TYPE_SCLP_CPU, 43, "SIE: Conditional-external-interception facility"),
-
- FEAT_INIT_MISC("dateh2", "DAT-enhancement facility 2"),
- FEAT_INIT_MISC("cmm", "Collaborative-memory-management facility"),
- FEAT_INIT_MISC("ap", "AP instructions installed"),
-
- FEAT_INIT("plo-cl", S390_FEAT_TYPE_PLO, 0, "PLO Compare and load (32 bit in general registers)"),
- FEAT_INIT("plo-clg", S390_FEAT_TYPE_PLO, 1, "PLO Compare and load (64 bit in parameter list)"),
- FEAT_INIT("plo-clgr", S390_FEAT_TYPE_PLO, 2, "PLO Compare and load (32 bit in general registers)"),
- FEAT_INIT("plo-clx", S390_FEAT_TYPE_PLO, 3, "PLO Compare and load (128 bit in parameter list)"),
- FEAT_INIT("plo-cs", S390_FEAT_TYPE_PLO, 4, "PLO Compare and swap (32 bit in general registers)"),
- FEAT_INIT("plo-csg", S390_FEAT_TYPE_PLO, 5, "PLO Compare and swap (64 bit in parameter list)"),
- FEAT_INIT("plo-csgr", S390_FEAT_TYPE_PLO, 6, "PLO Compare and swap (32 bit in general registers)"),
- FEAT_INIT("plo-csx", S390_FEAT_TYPE_PLO, 7, "PLO Compare and swap (128 bit in parameter list)"),
- FEAT_INIT("plo-dcs", S390_FEAT_TYPE_PLO, 8, "PLO Double compare and swap (32 bit in general registers)"),
- FEAT_INIT("plo-dcsg", S390_FEAT_TYPE_PLO, 9, "PLO Double compare and swap (64 bit in parameter list)"),
- FEAT_INIT("plo-dcsgr", S390_FEAT_TYPE_PLO, 10, "PLO Double compare and swap (32 bit in general registers)"),
- FEAT_INIT("plo-dcsx", S390_FEAT_TYPE_PLO, 11, "PLO Double compare and swap (128 bit in parameter list)"),
- FEAT_INIT("plo-csst", S390_FEAT_TYPE_PLO, 12, "PLO Compare and swap and store (32 bit in general registers)"),
- FEAT_INIT("plo-csstg", S390_FEAT_TYPE_PLO, 13, "PLO Compare and swap and store (64 bit in parameter list)"),
- FEAT_INIT("plo-csstgr", S390_FEAT_TYPE_PLO, 14, "PLO Compare and swap and store (32 bit in general registers)"),
- FEAT_INIT("plo-csstx", S390_FEAT_TYPE_PLO, 15, "PLO Compare and swap and store (128 bit in parameter list)"),
- FEAT_INIT("plo-csdst", S390_FEAT_TYPE_PLO, 16, "PLO Compare and swap and double store (32 bit in general registers)"),
- FEAT_INIT("plo-csdstg", S390_FEAT_TYPE_PLO, 17, "PLO Compare and swap and double store (64 bit in parameter list)"),
- FEAT_INIT("plo-csdstgr", S390_FEAT_TYPE_PLO, 18, "PLO Compare and swap and double store (32 bit in general registers)"),
- FEAT_INIT("plo-csdstx", S390_FEAT_TYPE_PLO, 19, "PLO Compare and swap and double store (128 bit in parameter list)"),
- FEAT_INIT("plo-cstst", S390_FEAT_TYPE_PLO, 20, "PLO Compare and swap and triple store (32 bit in general registers)"),
- FEAT_INIT("plo-cststg", S390_FEAT_TYPE_PLO, 21, "PLO Compare and swap and triple store (64 bit in parameter list)"),
- FEAT_INIT("plo-cststgr", S390_FEAT_TYPE_PLO, 22, "PLO Compare and swap and triple store (32 bit in general registers)"),
- FEAT_INIT("plo-cststx", S390_FEAT_TYPE_PLO, 23, "PLO Compare and swap and triple store (128 bit in parameter list)"),
-
- FEAT_INIT("ptff-qto", S390_FEAT_TYPE_PTFF, 1, "PTFF Query TOD Offset"),
- FEAT_INIT("ptff-qsi", S390_FEAT_TYPE_PTFF, 2, "PTFF Query Steering Information"),
- FEAT_INIT("ptff-qpc", S390_FEAT_TYPE_PTFF, 3, "PTFF Query Physical Clock"),
- FEAT_INIT("ptff-qui", S390_FEAT_TYPE_PTFF, 4, "PTFF Query UTC Information"),
- FEAT_INIT("ptff-qtou", S390_FEAT_TYPE_PTFF, 5, "PTFF Query TOD Offset User"),
- FEAT_INIT("ptff-qsie", S390_FEAT_TYPE_PTFF, 10, "PTFF Query Steering Information Extended"),
- FEAT_INIT("ptff-qtoue", S390_FEAT_TYPE_PTFF, 13, "PTFF Query TOD Offset User Extended"),
- FEAT_INIT("ptff-sto", S390_FEAT_TYPE_PTFF, 65, "PTFF Set TOD Offset"),
- FEAT_INIT("ptff-stou", S390_FEAT_TYPE_PTFF, 69, "PTFF Set TOD Offset User"),
- FEAT_INIT("ptff-stoe", S390_FEAT_TYPE_PTFF, 73, "PTFF Set TOD Offset Extended"),
- FEAT_INIT("ptff-stoue", S390_FEAT_TYPE_PTFF, 77, "PTFF Set TOD Offset User Extended"),
-
- FEAT_INIT("kmac-dea", S390_FEAT_TYPE_KMAC, 1, "KMAC DEA"),
- FEAT_INIT("kmac-tdea-128", S390_FEAT_TYPE_KMAC, 2, "KMAC TDEA-128"),
- FEAT_INIT("kmac-tdea-192", S390_FEAT_TYPE_KMAC, 3, "KMAC TDEA-192"),
- FEAT_INIT("kmac-edea", S390_FEAT_TYPE_KMAC, 9, "KMAC Encrypted-DEA"),
- FEAT_INIT("kmac-etdea-128", S390_FEAT_TYPE_KMAC, 10, "KMAC Encrypted-TDEA-128"),
- FEAT_INIT("kmac-etdea-192", S390_FEAT_TYPE_KMAC, 11, "KMAC Encrypted-TDEA-192"),
- FEAT_INIT("kmac-aes-128", S390_FEAT_TYPE_KMAC, 18, "KMAC AES-128"),
- FEAT_INIT("kmac-aes-192", S390_FEAT_TYPE_KMAC, 19, "KMAC AES-192"),
- FEAT_INIT("kmac-aes-256", S390_FEAT_TYPE_KMAC, 20, "KMAC AES-256"),
- FEAT_INIT("kmac-eaes-128", S390_FEAT_TYPE_KMAC, 26, "KMAC Encrypted-AES-128"),
- FEAT_INIT("kmac-eaes-192", S390_FEAT_TYPE_KMAC, 27, "KMAC Encrypted-AES-192"),
- FEAT_INIT("kmac-eaes-256", S390_FEAT_TYPE_KMAC, 28, "KMAC Encrypted-AES-256"),
-
- FEAT_INIT("kmc-dea", S390_FEAT_TYPE_KMC, 1, "KMC DEA"),
- FEAT_INIT("kmc-tdea-128", S390_FEAT_TYPE_KMC, 2, "KMC TDEA-128"),
- FEAT_INIT("kmc-tdea-192", S390_FEAT_TYPE_KMC, 3, "KMC TDEA-192"),
- FEAT_INIT("kmc-edea", S390_FEAT_TYPE_KMC, 9, "KMC Encrypted-DEA"),
- FEAT_INIT("kmc-etdea-128", S390_FEAT_TYPE_KMC, 10, "KMC Encrypted-TDEA-128"),
- FEAT_INIT("kmc-etdea-192", S390_FEAT_TYPE_KMC, 11, "KMC Encrypted-TDEA-192"),
- FEAT_INIT("kmc-aes-128", S390_FEAT_TYPE_KMC, 18, "KMC AES-128"),
- FEAT_INIT("kmc-aes-192", S390_FEAT_TYPE_KMC, 19, "KMC AES-192"),
- FEAT_INIT("kmc-aes-256", S390_FEAT_TYPE_KMC, 20, "KMC AES-256"),
- FEAT_INIT("kmc-eaes-128", S390_FEAT_TYPE_KMC, 26, "KMC Encrypted-AES-128"),
- FEAT_INIT("kmc-eaes-192", S390_FEAT_TYPE_KMC, 27, "KMC Encrypted-AES-192"),
- FEAT_INIT("kmc-eaes-256", S390_FEAT_TYPE_KMC, 28, "KMC Encrypted-AES-256"),
- FEAT_INIT("kmc-prng", S390_FEAT_TYPE_KMC, 67, "KMC PRNG"),
-
- FEAT_INIT("km-dea", S390_FEAT_TYPE_KM, 1, "KM DEA"),
- FEAT_INIT("km-tdea-128", S390_FEAT_TYPE_KM, 2, "KM TDEA-128"),
- FEAT_INIT("km-tdea-192", S390_FEAT_TYPE_KM, 3, "KM TDEA-192"),
- FEAT_INIT("km-edea", S390_FEAT_TYPE_KM, 9, "KM Encrypted-DEA"),
- FEAT_INIT("km-etdea-128", S390_FEAT_TYPE_KM, 10, "KM Encrypted-TDEA-128"),
- FEAT_INIT("km-etdea-192", S390_FEAT_TYPE_KM, 11, "KM Encrypted-TDEA-192"),
- FEAT_INIT("km-aes-128", S390_FEAT_TYPE_KM, 18, "KM AES-128"),
- FEAT_INIT("km-aes-192", S390_FEAT_TYPE_KM, 19, "KM AES-192"),
- FEAT_INIT("km-aes-256", S390_FEAT_TYPE_KM, 20, "KM AES-256"),
- FEAT_INIT("km-eaes-128", S390_FEAT_TYPE_KM, 26, "KM Encrypted-AES-128"),
- FEAT_INIT("km-eaes-192", S390_FEAT_TYPE_KM, 27, "KM Encrypted-AES-192"),
- FEAT_INIT("km-eaes-256", S390_FEAT_TYPE_KM, 28, "KM Encrypted-AES-256"),
- FEAT_INIT("km-xts-aes-128", S390_FEAT_TYPE_KM, 50, "KM XTS-AES-128"),
- FEAT_INIT("km-xts-aes-256", S390_FEAT_TYPE_KM, 52, "KM XTS-AES-256"),
- FEAT_INIT("km-xts-eaes-128", S390_FEAT_TYPE_KM, 58, "KM XTS-Encrypted-AES-128"),
- FEAT_INIT("km-xts-eaes-256", S390_FEAT_TYPE_KM, 60, "KM XTS-Encrypted-AES-256"),
-
- FEAT_INIT("kimd-sha-1", S390_FEAT_TYPE_KIMD, 1, "KIMD SHA-1"),
- FEAT_INIT("kimd-sha-256", S390_FEAT_TYPE_KIMD, 2, "KIMD SHA-256"),
- FEAT_INIT("kimd-sha-512", S390_FEAT_TYPE_KIMD, 3, "KIMD SHA-512"),
- FEAT_INIT("kimd-sha3-224", S390_FEAT_TYPE_KIMD, 32, "KIMD SHA3-224"),
- FEAT_INIT("kimd-sha3-256", S390_FEAT_TYPE_KIMD, 33, "KIMD SHA3-256"),
- FEAT_INIT("kimd-sha3-384", S390_FEAT_TYPE_KIMD, 34, "KIMD SHA3-384"),
- FEAT_INIT("kimd-sha3-512", S390_FEAT_TYPE_KIMD, 35, "KIMD SHA3-512"),
- FEAT_INIT("kimd-shake-128", S390_FEAT_TYPE_KIMD, 36, "KIMD SHAKE-128"),
- FEAT_INIT("kimd-shake-256", S390_FEAT_TYPE_KIMD, 37, "KIMD SHAKE-256"),
- FEAT_INIT("kimd-ghash", S390_FEAT_TYPE_KIMD, 65, "KIMD GHASH"),
-
- FEAT_INIT("klmd-sha-1", S390_FEAT_TYPE_KLMD, 1, "KLMD SHA-1"),
- FEAT_INIT("klmd-sha-256", S390_FEAT_TYPE_KLMD, 2, "KLMD SHA-256"),
- FEAT_INIT("klmd-sha-512", S390_FEAT_TYPE_KLMD, 3, "KLMD SHA-512"),
- FEAT_INIT("klmd-sha3-224", S390_FEAT_TYPE_KLMD, 32, "KLMD SHA3-224"),
- FEAT_INIT("klmd-sha3-256", S390_FEAT_TYPE_KLMD, 33, "KLMD SHA3-256"),
- FEAT_INIT("klmd-sha3-384", S390_FEAT_TYPE_KLMD, 34, "KLMD SHA3-384"),
- FEAT_INIT("klmd-sha3-512", S390_FEAT_TYPE_KLMD, 35, "KLMD SHA3-512"),
- FEAT_INIT("klmd-shake-128", S390_FEAT_TYPE_KLMD, 36, "KLMD SHAKE-128"),
- FEAT_INIT("klmd-shake-256", S390_FEAT_TYPE_KLMD, 37, "KLMD SHAKE-256"),
-
- FEAT_INIT("pckmo-edea", S390_FEAT_TYPE_PCKMO, 1, "PCKMO Encrypted-DEA-Key"),
- FEAT_INIT("pckmo-etdea-128", S390_FEAT_TYPE_PCKMO, 2, "PCKMO Encrypted-TDEA-128-Key"),
- FEAT_INIT("pckmo-etdea-192", S390_FEAT_TYPE_PCKMO, 3, "PCKMO Encrypted-TDEA-192-Key"),
- FEAT_INIT("pckmo-aes-128", S390_FEAT_TYPE_PCKMO, 18, "PCKMO Encrypted-AES-128-Key"),
- FEAT_INIT("pckmo-aes-192", S390_FEAT_TYPE_PCKMO, 19, "PCKMO Encrypted-AES-192-Key"),
- FEAT_INIT("pckmo-aes-256", S390_FEAT_TYPE_PCKMO, 20, "PCKMO Encrypted-AES-256-Key"),
- FEAT_INIT("pckmo-ecc-p256", S390_FEAT_TYPE_PCKMO, 32, "PCKMO Encrypt-ECC-P256-Key"),
- FEAT_INIT("pckmo-ecc-p384", S390_FEAT_TYPE_PCKMO, 33, "PCKMO Encrypt-ECC-P384-Key"),
- FEAT_INIT("pckmo-ecc-p521", S390_FEAT_TYPE_PCKMO, 34, "PCKMO Encrypt-ECC-P521-Key"),
- FEAT_INIT("pckmo-ecc-ed25519", S390_FEAT_TYPE_PCKMO, 40 , "PCKMO Encrypt-ECC-Ed25519-Key"),
- FEAT_INIT("pckmo-ecc-ed448", S390_FEAT_TYPE_PCKMO, 41 , "PCKMO Encrypt-ECC-Ed448-Key"),
-
- FEAT_INIT("kmctr-dea", S390_FEAT_TYPE_KMCTR, 1, "KMCTR DEA"),
- FEAT_INIT("kmctr-tdea-128", S390_FEAT_TYPE_KMCTR, 2, "KMCTR TDEA-128"),
- FEAT_INIT("kmctr-tdea-192", S390_FEAT_TYPE_KMCTR, 3, "KMCTR TDEA-192"),
- FEAT_INIT("kmctr-edea", S390_FEAT_TYPE_KMCTR, 9, "KMCTR Encrypted-DEA"),
- FEAT_INIT("kmctr-etdea-128", S390_FEAT_TYPE_KMCTR, 10, "KMCTR Encrypted-TDEA-128"),
- FEAT_INIT("kmctr-etdea-192", S390_FEAT_TYPE_KMCTR, 11, "KMCTR Encrypted-TDEA-192"),
- FEAT_INIT("kmctr-aes-128", S390_FEAT_TYPE_KMCTR, 18, "KMCTR AES-128"),
- FEAT_INIT("kmctr-aes-192", S390_FEAT_TYPE_KMCTR, 19, "KMCTR AES-192"),
- FEAT_INIT("kmctr-aes-256", S390_FEAT_TYPE_KMCTR, 20, "KMCTR AES-256"),
- FEAT_INIT("kmctr-eaes-128", S390_FEAT_TYPE_KMCTR, 26, "KMCTR Encrypted-AES-128"),
- FEAT_INIT("kmctr-eaes-192", S390_FEAT_TYPE_KMCTR, 27, "KMCTR Encrypted-AES-192"),
- FEAT_INIT("kmctr-eaes-256", S390_FEAT_TYPE_KMCTR, 28, "KMCTR Encrypted-AES-256"),
-
- FEAT_INIT("kmf-dea", S390_FEAT_TYPE_KMF, 1, "KMF DEA"),
- FEAT_INIT("kmf-tdea-128", S390_FEAT_TYPE_KMF, 2, "KMF TDEA-128"),
- FEAT_INIT("kmf-tdea-192", S390_FEAT_TYPE_KMF, 3, "KMF TDEA-192"),
- FEAT_INIT("kmf-edea", S390_FEAT_TYPE_KMF, 9, "KMF Encrypted-DEA"),
- FEAT_INIT("kmf-etdea-128", S390_FEAT_TYPE_KMF, 10, "KMF Encrypted-TDEA-128"),
- FEAT_INIT("kmf-etdea-192", S390_FEAT_TYPE_KMF, 11, "KMF Encrypted-TDEA-192"),
- FEAT_INIT("kmf-aes-128", S390_FEAT_TYPE_KMF, 18, "KMF AES-128"),
- FEAT_INIT("kmf-aes-192", S390_FEAT_TYPE_KMF, 19, "KMF AES-192"),
- FEAT_INIT("kmf-aes-256", S390_FEAT_TYPE_KMF, 20, "KMF AES-256"),
- FEAT_INIT("kmf-eaes-128", S390_FEAT_TYPE_KMF, 26, "KMF Encrypted-AES-128"),
- FEAT_INIT("kmf-eaes-192", S390_FEAT_TYPE_KMF, 27, "KMF Encrypted-AES-192"),
- FEAT_INIT("kmf-eaes-256", S390_FEAT_TYPE_KMF, 28, "KMF Encrypted-AES-256"),
-
- FEAT_INIT("kmo-dea", S390_FEAT_TYPE_KMO, 1, "KMO DEA"),
- FEAT_INIT("kmo-tdea-128", S390_FEAT_TYPE_KMO, 2, "KMO TDEA-128"),
- FEAT_INIT("kmo-tdea-192", S390_FEAT_TYPE_KMO, 3, "KMO TDEA-192"),
- FEAT_INIT("kmo-edea", S390_FEAT_TYPE_KMO, 9, "KMO Encrypted-DEA"),
- FEAT_INIT("kmo-etdea-128", S390_FEAT_TYPE_KMO, 10, "KMO Encrypted-TDEA-128"),
- FEAT_INIT("kmo-etdea-192", S390_FEAT_TYPE_KMO, 11, "KMO Encrypted-TDEA-192"),
- FEAT_INIT("kmo-aes-128", S390_FEAT_TYPE_KMO, 18, "KMO AES-128"),
- FEAT_INIT("kmo-aes-192", S390_FEAT_TYPE_KMO, 19, "KMO AES-192"),
- FEAT_INIT("kmo-aes-256", S390_FEAT_TYPE_KMO, 20, "KMO AES-256"),
- FEAT_INIT("kmo-eaes-128", S390_FEAT_TYPE_KMO, 26, "KMO Encrypted-AES-128"),
- FEAT_INIT("kmo-eaes-192", S390_FEAT_TYPE_KMO, 27, "KMO Encrypted-AES-192"),
- FEAT_INIT("kmo-eaes-256", S390_FEAT_TYPE_KMO, 28, "KMO Encrypted-AES-256"),
-
- FEAT_INIT("pcc-cmac-dea", S390_FEAT_TYPE_PCC, 1, "PCC Compute-Last-Block-CMAC-Using-DEA"),
- FEAT_INIT("pcc-cmac-tdea-128", S390_FEAT_TYPE_PCC, 2, "PCC Compute-Last-Block-CMAC-Using-TDEA-128"),
- FEAT_INIT("pcc-cmac-tdea-192", S390_FEAT_TYPE_PCC, 3, "PCC Compute-Last-Block-CMAC-Using-TDEA-192"),
- FEAT_INIT("pcc-cmac-edea", S390_FEAT_TYPE_PCC, 9, "PCC Compute-Last-Block-CMAC-Using-Encrypted-DEA"),
- FEAT_INIT("pcc-cmac-etdea-128", S390_FEAT_TYPE_PCC, 10, "PCC Compute-Last-Block-CMAC-Using-Encrypted-TDEA-128"),
- FEAT_INIT("pcc-cmac-etdea-192", S390_FEAT_TYPE_PCC, 11, "PCC Compute-Last-Block-CMAC-Using-EncryptedTDEA-192"),
- FEAT_INIT("pcc-cmac-aes-128", S390_FEAT_TYPE_PCC, 18, "PCC Compute-Last-Block-CMAC-Using-AES-128"),
- FEAT_INIT("pcc-cmac-aes-192", S390_FEAT_TYPE_PCC, 19, "PCC Compute-Last-Block-CMAC-Using-AES-192"),
- FEAT_INIT("pcc-cmac-eaes-256", S390_FEAT_TYPE_PCC, 20, "PCC Compute-Last-Block-CMAC-Using-AES-256"),
- FEAT_INIT("pcc-cmac-eaes-128", S390_FEAT_TYPE_PCC, 26, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-128"),
- FEAT_INIT("pcc-cmac-eaes-192", S390_FEAT_TYPE_PCC, 27, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-192"),
- FEAT_INIT("pcc-cmac-eaes-256", S390_FEAT_TYPE_PCC, 28, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-256"),
- FEAT_INIT("pcc-xts-aes-128", S390_FEAT_TYPE_PCC, 50, "PCC Compute-XTS-Parameter-Using-AES-128"),
- FEAT_INIT("pcc-xts-aes-256", S390_FEAT_TYPE_PCC, 52, "PCC Compute-XTS-Parameter-Using-AES-256"),
- FEAT_INIT("pcc-xts-eaes-128", S390_FEAT_TYPE_PCC, 58, "PCC Compute-XTS-Parameter-Using-Encrypted-AES-128"),
- FEAT_INIT("pcc-xts-eaes-256", S390_FEAT_TYPE_PCC, 60, "PCC Compute-XTS-Parameter-Using-Encrypted-AES-256"),
- FEAT_INIT("pcc-scalar-mult-p256", S390_FEAT_TYPE_PCC, 64, "PCC Scalar-Multiply-P256"),
- FEAT_INIT("pcc-scalar-mult-p384", S390_FEAT_TYPE_PCC, 65, "PCC Scalar-Multiply-P384"),
- FEAT_INIT("pcc-scalar-mult-p521", S390_FEAT_TYPE_PCC, 66, "PCC Scalar-Multiply-P521"),
- FEAT_INIT("pcc-scalar-mult-ed25519", S390_FEAT_TYPE_PCC, 72, "PCC Scalar-Multiply-Ed25519"),
- FEAT_INIT("pcc-scalar-mult-ed448", S390_FEAT_TYPE_PCC, 73, "PCC Scalar-Multiply-Ed448"),
- FEAT_INIT("pcc-scalar-mult-x25519", S390_FEAT_TYPE_PCC, 80, "PCC Scalar-Multiply-X25519"),
- FEAT_INIT("pcc-scalar-mult-x448", S390_FEAT_TYPE_PCC, 81, "PCC Scalar-Multiply-X448"),
-
- FEAT_INIT("ppno-sha-512-drng", S390_FEAT_TYPE_PPNO, 3, "PPNO SHA-512-DRNG"),
- FEAT_INIT("prno-trng-qrtcr", S390_FEAT_TYPE_PPNO, 112, "PRNO TRNG-Query-Raw-to-Conditioned-Ratio"),
- FEAT_INIT("prno-trng", S390_FEAT_TYPE_PPNO, 114, "PRNO TRNG"),
-
- FEAT_INIT("kma-gcm-aes-128", S390_FEAT_TYPE_KMA, 18, "KMA GCM-AES-128"),
- FEAT_INIT("kma-gcm-aes-192", S390_FEAT_TYPE_KMA, 19, "KMA GCM-AES-192"),
- FEAT_INIT("kma-gcm-aes-256", S390_FEAT_TYPE_KMA, 20, "KMA GCM-AES-256"),
- FEAT_INIT("kma-gcm-eaes-128", S390_FEAT_TYPE_KMA, 26, "KMA GCM-Encrypted-AES-128"),
- FEAT_INIT("kma-gcm-eaes-192", S390_FEAT_TYPE_KMA, 27, "KMA GCM-Encrypted-AES-192"),
- FEAT_INIT("kma-gcm-eaes-256", S390_FEAT_TYPE_KMA, 28, "KMA GCM-Encrypted-AES-256"),
-
- FEAT_INIT("kdsa-ecdsa-verify-p256", S390_FEAT_TYPE_KDSA, 1, "KDSA ECDSA-Verify-P256"),
- FEAT_INIT("kdsa-ecdsa-verify-p384", S390_FEAT_TYPE_KDSA, 2, "KDSA ECDSA-Verify-P384"),
- FEAT_INIT("kdsa-ecdsa-verify-p521", S390_FEAT_TYPE_KDSA, 3, "KDSA ECDSA-Verify-P521"),
- FEAT_INIT("kdsa-ecdsa-sign-p256", S390_FEAT_TYPE_KDSA, 9, "KDSA ECDSA-Sign-P256"),
- FEAT_INIT("kdsa-ecdsa-sign-p384", S390_FEAT_TYPE_KDSA, 10, "KDSA ECDSA-Sign-P384"),
- FEAT_INIT("kdsa-ecdsa-sign-p521", S390_FEAT_TYPE_KDSA, 11, "KDSA ECDSA-Sign-P521"),
- FEAT_INIT("kdsa-eecdsa-sign-p256", S390_FEAT_TYPE_KDSA, 17, "KDSA Encrypted-ECDSA-Sign-P256"),
- FEAT_INIT("kdsa-eecdsa-sign-p384", S390_FEAT_TYPE_KDSA, 18, "KDSA Encrypted-ECDSA-Sign-P384"),
- FEAT_INIT("kdsa-eecdsa-sign-p521", S390_FEAT_TYPE_KDSA, 19, "KDSA Encrypted-ECDSA-Sign-P521"),
- FEAT_INIT("kdsa-eddsa-verify-ed25519", S390_FEAT_TYPE_KDSA, 32, "KDSA EdDSA-Verify-Ed25519"),
- FEAT_INIT("kdsa-eddsa-verify-ed448", S390_FEAT_TYPE_KDSA, 36, "KDSA EdDSA-Verify-Ed448"),
- FEAT_INIT("kdsa-eddsa-sign-ed25519", S390_FEAT_TYPE_KDSA, 40, "KDSA EdDSA-Sign-Ed25519"),
- FEAT_INIT("kdsa-eddsa-sign-ed448", S390_FEAT_TYPE_KDSA, 44, "KDSA EdDSA-Sign-Ed448"),
- FEAT_INIT("kdsa-eeddsa-sign-ed25519", S390_FEAT_TYPE_KDSA, 48, "KDSA Encrypted-EdDSA-Sign-Ed25519"),
- FEAT_INIT("kdsa-eeddsa-sign-ed448", S390_FEAT_TYPE_KDSA, 52, "KDSA Encrypted-EdDSA-Sign-Ed448"),
-
- FEAT_INIT("sortl-sflr", S390_FEAT_TYPE_SORTL, 1, "SORTL SFLR"),
- FEAT_INIT("sortl-svlr", S390_FEAT_TYPE_SORTL, 2, "SORTL SVLR"),
- FEAT_INIT("sortl-32", S390_FEAT_TYPE_SORTL, 130, "SORTL 32 input lists"),
- FEAT_INIT("sortl-128", S390_FEAT_TYPE_SORTL, 132, "SORTL 128 input lists"),
- FEAT_INIT("sortl-f0", S390_FEAT_TYPE_SORTL, 192, "SORTL format 0 parameter-block"),
-
- FEAT_INIT("dfltcc-gdht", S390_FEAT_TYPE_DFLTCC, 1, "DFLTCC GDHT"),
- FEAT_INIT("dfltcc-cmpr", S390_FEAT_TYPE_DFLTCC, 2, "DFLTCC CMPR"),
- FEAT_INIT("dfltcc-xpnd", S390_FEAT_TYPE_DFLTCC, 4, "DFLTCC XPND"),
- FEAT_INIT("dfltcc-f0", S390_FEAT_TYPE_DFLTCC, 192, "DFLTCC format 0 parameter-block"),
+#define DEF_FEAT(_FEAT, _NAME, _TYPE, _BIT, _DESC) \
+ [S390_FEAT_##_FEAT] = { \
+ .name = _NAME, \
+ .type = S390_FEAT_TYPE_##_TYPE, \
+ .bit = _BIT, \
+ .desc = _DESC, \
+ },
+static const S390FeatDef s390_features[S390_FEAT_MAX] = {
+ #include "cpu_features_def.inc.h"
};
+#undef DEF_FEAT
const S390FeatDef *s390_feat_def(S390Feat feat)
{
* CPU features/facilities for s390
*
* Copyright IBM Corp. 2016, 2018
+ * Copyright Red Hat, Inc. 2019
*
* Author(s): Michael Mueller <mimu@linux.vnet.ibm.com>
- * David Hildenbrand <dahi@linux.vnet.ibm.com>
+ * David Hildenbrand <david@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at
* your option) any later version. See the COPYING file in the top-level
#ifndef TARGET_S390X_CPU_FEATURES_DEF_H
#define TARGET_S390X_CPU_FEATURES_DEF_H
+#define DEF_FEAT(_FEAT, ...) S390_FEAT_##_FEAT,
typedef enum {
- /* Stfle */
- S390_FEAT_ESAN3 = 0,
- S390_FEAT_ZARCH,
- S390_FEAT_DAT_ENH,
- S390_FEAT_IDTE_SEGMENT,
- S390_FEAT_IDTE_REGION,
- S390_FEAT_ASN_LX_REUSE,
- S390_FEAT_STFLE,
- S390_FEAT_EDAT,
- S390_FEAT_SENSE_RUNNING_STATUS,
- S390_FEAT_CONDITIONAL_SSKE,
- S390_FEAT_CONFIGURATION_TOPOLOGY,
- S390_FEAT_AP_QUERY_CONFIG_INFO,
- S390_FEAT_IPTE_RANGE,
- S390_FEAT_NONQ_KEY_SETTING,
- S390_FEAT_AP_FACILITIES_TEST,
- S390_FEAT_EXTENDED_TRANSLATION_2,
- S390_FEAT_MSA,
- S390_FEAT_LONG_DISPLACEMENT,
- S390_FEAT_LONG_DISPLACEMENT_FAST,
- S390_FEAT_HFP_MADDSUB,
- S390_FEAT_EXTENDED_IMMEDIATE,
- S390_FEAT_EXTENDED_TRANSLATION_3,
- S390_FEAT_HFP_UNNORMALIZED_EXT,
- S390_FEAT_ETF2_ENH,
- S390_FEAT_STORE_CLOCK_FAST,
- S390_FEAT_PARSING_ENH,
- S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
- S390_FEAT_TOD_CLOCK_STEERING,
- S390_FEAT_ETF3_ENH,
- S390_FEAT_EXTRACT_CPU_TIME,
- S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
- S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2,
- S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
- S390_FEAT_EXECUTE_EXT,
- S390_FEAT_ENHANCED_MONITOR,
- S390_FEAT_FLOATING_POINT_EXT,
- S390_FEAT_ORDER_PRESERVING_COMPRESSION,
- S390_FEAT_SET_PROGRAM_PARAMETERS,
- S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
- S390_FEAT_DFP,
- S390_FEAT_DFP_FAST,
- S390_FEAT_PFPO,
- S390_FEAT_STFLE_45,
- S390_FEAT_CMPSC_ENH,
- S390_FEAT_DFP_ZONED_CONVERSION,
- S390_FEAT_STFLE_49,
- S390_FEAT_CONSTRAINT_TRANSACTIONAL_EXE,
- S390_FEAT_LOCAL_TLB_CLEARING,
- S390_FEAT_INTERLOCKED_ACCESS_2,
- S390_FEAT_STFLE_53,
- S390_FEAT_ENTROPY_ENC_COMP,
- S390_FEAT_MSA_EXT_5,
- S390_FEAT_MISC_INSTRUCTION_EXT,
- S390_FEAT_SEMAPHORE_ASSIST,
- S390_FEAT_TIME_SLICE_INSTRUMENTATION,
- S390_FEAT_MISC_INSTRUCTION_EXT3,
- S390_FEAT_RUNTIME_INSTRUMENTATION,
- S390_FEAT_ZPCI,
- S390_FEAT_ADAPTER_EVENT_NOTIFICATION,
- S390_FEAT_ADAPTER_INT_SUPPRESSION,
- S390_FEAT_TRANSACTIONAL_EXE,
- S390_FEAT_STORE_HYPERVISOR_INFO,
- S390_FEAT_ACCESS_EXCEPTION_FS_INDICATION,
- S390_FEAT_MSA_EXT_3,
- S390_FEAT_MSA_EXT_4,
- S390_FEAT_EDAT_2,
- S390_FEAT_DFP_PACKED_CONVERSION,
- S390_FEAT_PPA15,
- S390_FEAT_BPB,
- S390_FEAT_VECTOR,
- S390_FEAT_INSTRUCTION_EXEC_PROT,
- S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2,
- S390_FEAT_GUARDED_STORAGE,
- S390_FEAT_VECTOR_PACKED_DECIMAL,
- S390_FEAT_VECTOR_ENH,
- S390_FEAT_MULTIPLE_EPOCH,
- S390_FEAT_TEST_PENDING_EXT_INTERRUPTION,
- S390_FEAT_INSERT_REFERENCE_BITS_MULT,
- S390_FEAT_MSA_EXT_8,
- S390_FEAT_CMM_NT,
- S390_FEAT_VECTOR_ENH2,
- S390_FEAT_ESORT_BASE,
- S390_FEAT_DEFLATE_BASE,
- S390_FEAT_VECTOR_BCD_ENH,
- S390_FEAT_MSA_EXT_9,
- S390_FEAT_ETOKEN,
-
- /* Sclp Conf Char */
- S390_FEAT_SIE_GSLS,
- S390_FEAT_ESOP,
- S390_FEAT_HPMA2,
- S390_FEAT_SIE_KSS,
-
- /* Sclp Conf Char Ext */
- S390_FEAT_SIE_64BSCAO,
- S390_FEAT_SIE_CMMA,
- S390_FEAT_SIE_PFMFI,
- S390_FEAT_SIE_IBS,
-
- /* Sclp Cpu */
- S390_FEAT_SIE_F2,
- S390_FEAT_SIE_SKEY,
- S390_FEAT_SIE_GPERE,
- S390_FEAT_SIE_SIIF,
- S390_FEAT_SIE_SIGPIF,
- S390_FEAT_SIE_IB,
- S390_FEAT_SIE_CEI,
-
- /* Misc */
- S390_FEAT_DAT_ENH_2,
- S390_FEAT_CMM,
- S390_FEAT_AP,
-
- /* PLO */
- S390_FEAT_PLO_CL,
- S390_FEAT_PLO_CLG,
- S390_FEAT_PLO_CLGR,
- S390_FEAT_PLO_CLX,
- S390_FEAT_PLO_CS,
- S390_FEAT_PLO_CSG,
- S390_FEAT_PLO_CSGR,
- S390_FEAT_PLO_CSX,
- S390_FEAT_PLO_DCS,
- S390_FEAT_PLO_DCSG,
- S390_FEAT_PLO_DCSGR,
- S390_FEAT_PLO_DCSX,
- S390_FEAT_PLO_CSST,
- S390_FEAT_PLO_CSSTG,
- S390_FEAT_PLO_CSSTGR,
- S390_FEAT_PLO_CSSTX,
- S390_FEAT_PLO_CSDST,
- S390_FEAT_PLO_CSDSTG,
- S390_FEAT_PLO_CSDSTGR,
- S390_FEAT_PLO_CSDSTX,
- S390_FEAT_PLO_CSTST,
- S390_FEAT_PLO_CSTSTG,
- S390_FEAT_PLO_CSTSTGR,
- S390_FEAT_PLO_CSTSTX,
-
- /* PTFF */
- S390_FEAT_PTFF_QTO,
- S390_FEAT_PTFF_QSI,
- S390_FEAT_PTFF_QPT,
- S390_FEAT_PTFF_QUI,
- S390_FEAT_PTFF_QTOU,
- S390_FEAT_PTFF_QSIE,
- S390_FEAT_PTFF_QTOUE,
- S390_FEAT_PTFF_STO,
- S390_FEAT_PTFF_STOU,
- S390_FEAT_PTFF_STOE,
- S390_FEAT_PTFF_STOUE,
-
- /* KMAC */
- S390_FEAT_KMAC_DEA,
- S390_FEAT_KMAC_TDEA_128,
- S390_FEAT_KMAC_TDEA_192,
- S390_FEAT_KMAC_EDEA,
- S390_FEAT_KMAC_ETDEA_128,
- S390_FEAT_KMAC_ETDEA_192,
- S390_FEAT_KMAC_AES_128,
- S390_FEAT_KMAC_AES_192,
- S390_FEAT_KMAC_AES_256,
- S390_FEAT_KMAC_EAES_128,
- S390_FEAT_KMAC_EAES_192,
- S390_FEAT_KMAC_EAES_256,
-
- /* KMC */
- S390_FEAT_KMC_DEA,
- S390_FEAT_KMC_TDEA_128,
- S390_FEAT_KMC_TDEA_192,
- S390_FEAT_KMC_EDEA,
- S390_FEAT_KMC_ETDEA_128,
- S390_FEAT_KMC_ETDEA_192,
- S390_FEAT_KMC_AES_128,
- S390_FEAT_KMC_AES_192,
- S390_FEAT_KMC_AES_256,
- S390_FEAT_KMC_EAES_128,
- S390_FEAT_KMC_EAES_192,
- S390_FEAT_KMC_EAES_256,
- S390_FEAT_KMC_PRNG,
-
- /* KM */
- S390_FEAT_KM_DEA,
- S390_FEAT_KM_TDEA_128,
- S390_FEAT_KM_TDEA_192,
- S390_FEAT_KM_EDEA,
- S390_FEAT_KM_ETDEA_128,
- S390_FEAT_KM_ETDEA_192,
- S390_FEAT_KM_AES_128,
- S390_FEAT_KM_AES_192,
- S390_FEAT_KM_AES_256,
- S390_FEAT_KM_EAES_128,
- S390_FEAT_KM_EAES_192,
- S390_FEAT_KM_EAES_256,
- S390_FEAT_KM_XTS_AES_128,
- S390_FEAT_KM_XTS_AES_256,
- S390_FEAT_KM_XTS_EAES_128,
- S390_FEAT_KM_XTS_EAES_256,
-
- /* KIMD */
- S390_FEAT_KIMD_SHA_1,
- S390_FEAT_KIMD_SHA_256,
- S390_FEAT_KIMD_SHA_512,
- S390_FEAT_KIMD_SHA3_224,
- S390_FEAT_KIMD_SHA3_256,
- S390_FEAT_KIMD_SHA3_384,
- S390_FEAT_KIMD_SHA3_512,
- S390_FEAT_KIMD_SHAKE_128,
- S390_FEAT_KIMD_SHAKE_256,
- S390_FEAT_KIMD_GHASH,
-
- /* KLMD */
- S390_FEAT_KLMD_SHA_1,
- S390_FEAT_KLMD_SHA_256,
- S390_FEAT_KLMD_SHA_512,
- S390_FEAT_KLMD_SHA3_224,
- S390_FEAT_KLMD_SHA3_256,
- S390_FEAT_KLMD_SHA3_384,
- S390_FEAT_KLMD_SHA3_512,
- S390_FEAT_KLMD_SHAKE_128,
- S390_FEAT_KLMD_SHAKE_256,
-
- /* PCKMO */
- S390_FEAT_PCKMO_EDEA,
- S390_FEAT_PCKMO_ETDEA_128,
- S390_FEAT_PCKMO_ETDEA_256,
- S390_FEAT_PCKMO_AES_128,
- S390_FEAT_PCKMO_AES_192,
- S390_FEAT_PCKMO_AES_256,
- S390_FEAT_PCKMO_ECC_P256,
- S390_FEAT_PCKMO_ECC_P384,
- S390_FEAT_PCKMO_ECC_P521,
- S390_FEAT_PCKMO_ECC_ED25519,
- S390_FEAT_PCKMO_ECC_ED448,
-
- /* KMCTR */
- S390_FEAT_KMCTR_DEA,
- S390_FEAT_KMCTR_TDEA_128,
- S390_FEAT_KMCTR_TDEA_192,
- S390_FEAT_KMCTR_EDEA,
- S390_FEAT_KMCTR_ETDEA_128,
- S390_FEAT_KMCTR_ETDEA_192,
- S390_FEAT_KMCTR_AES_128,
- S390_FEAT_KMCTR_AES_192,
- S390_FEAT_KMCTR_AES_256,
- S390_FEAT_KMCTR_EAES_128,
- S390_FEAT_KMCTR_EAES_192,
- S390_FEAT_KMCTR_EAES_256,
-
- /* KMF */
- S390_FEAT_KMF_DEA,
- S390_FEAT_KMF_TDEA_128,
- S390_FEAT_KMF_TDEA_192,
- S390_FEAT_KMF_EDEA,
- S390_FEAT_KMF_ETDEA_128,
- S390_FEAT_KMF_ETDEA_192,
- S390_FEAT_KMF_AES_128,
- S390_FEAT_KMF_AES_192,
- S390_FEAT_KMF_AES_256,
- S390_FEAT_KMF_EAES_128,
- S390_FEAT_KMF_EAES_192,
- S390_FEAT_KMF_EAES_256,
-
- /* KMO */
- S390_FEAT_KMO_DEA,
- S390_FEAT_KMO_TDEA_128,
- S390_FEAT_KMO_TDEA_192,
- S390_FEAT_KMO_EDEA,
- S390_FEAT_KMO_ETDEA_128,
- S390_FEAT_KMO_ETDEA_192,
- S390_FEAT_KMO_AES_128,
- S390_FEAT_KMO_AES_192,
- S390_FEAT_KMO_AES_256,
- S390_FEAT_KMO_EAES_128,
- S390_FEAT_KMO_EAES_192,
- S390_FEAT_KMO_EAES_256,
-
- /* PCC */
- S390_FEAT_PCC_CMAC_DEA,
- S390_FEAT_PCC_CMAC_TDEA_128,
- S390_FEAT_PCC_CMAC_TDEA_192,
- S390_FEAT_PCC_CMAC_ETDEA_128,
- S390_FEAT_PCC_CMAC_ETDEA_192,
- S390_FEAT_PCC_CMAC_TDEA,
- S390_FEAT_PCC_CMAC_AES_128,
- S390_FEAT_PCC_CMAC_AES_192,
- S390_FEAT_PCC_CMAC_AES_256,
- S390_FEAT_PCC_CMAC_EAES_128,
- S390_FEAT_PCC_CMAC_EAES_192,
- S390_FEAT_PCC_CMAC_EAES_256,
- S390_FEAT_PCC_XTS_AES_128,
- S390_FEAT_PCC_XTS_AES_256,
- S390_FEAT_PCC_XTS_EAES_128,
- S390_FEAT_PCC_XTS_EAES_256,
- S390_FEAT_PCC_SCALAR_MULT_P256,
- S390_FEAT_PCC_SCALAR_MULT_P384,
- S390_FEAT_PCC_SCALAR_MULT_P512,
- S390_FEAT_PCC_SCALAR_MULT_ED25519,
- S390_FEAT_PCC_SCALAR_MULT_ED448,
- S390_FEAT_PCC_SCALAR_MULT_X25519,
- S390_FEAT_PCC_SCALAR_MULT_X448,
-
- /* PPNO/PRNO */
- S390_FEAT_PPNO_SHA_512_DRNG,
- S390_FEAT_PRNO_TRNG_QRTCR,
- S390_FEAT_PRNO_TRNG,
-
- /* KMA */
- S390_FEAT_KMA_GCM_AES_128,
- S390_FEAT_KMA_GCM_AES_192,
- S390_FEAT_KMA_GCM_AES_256 ,
- S390_FEAT_KMA_GCM_EAES_128,
- S390_FEAT_KMA_GCM_EAES_192,
- S390_FEAT_KMA_GCM_EAES_256,
-
- /* KDSA */
- S390_FEAT_ECDSA_VERIFY_P256,
- S390_FEAT_ECDSA_VERIFY_P384,
- S390_FEAT_ECDSA_VERIFY_P512,
- S390_FEAT_ECDSA_SIGN_P256,
- S390_FEAT_ECDSA_SIGN_P384,
- S390_FEAT_ECDSA_SIGN_P512,
- S390_FEAT_EECDSA_SIGN_P256,
- S390_FEAT_EECDSA_SIGN_P384,
- S390_FEAT_EECDSA_SIGN_P512,
- S390_FEAT_EDDSA_VERIFY_ED25519,
- S390_FEAT_EDDSA_VERIFY_ED448,
- S390_FEAT_EDDSA_SIGN_ED25519,
- S390_FEAT_EDDSA_SIGN_ED448,
- S390_FEAT_EEDDSA_SIGN_ED25519,
- S390_FEAT_EEDDSA_SIGN_ED448,
-
- /* SORTL */
- S390_FEAT_SORTL_SFLR,
- S390_FEAT_SORTL_SVLR,
- S390_FEAT_SORTL_32,
- S390_FEAT_SORTL_128,
- S390_FEAT_SORTL_F0,
-
- /* DEFLATE */
- S390_FEAT_DEFLATE_GHDT,
- S390_FEAT_DEFLATE_CMPR,
- S390_FEAT_DEFLATE_XPND,
- S390_FEAT_DEFLATE_F0,
-
+ #include "cpu_features_def.inc.h"
S390_FEAT_MAX,
} S390Feat;
+#undef DEF_FEAT
#endif /* TARGET_S390X_CPU_FEATURES_DEF_H */
--- /dev/null
+/*
+ * RAW s390x CPU feature definitions:
+ *
+ * DEF_FEAT(_FEAT, _NAME, _TYPE, _BIT, _DESC):
+ * - _FEAT: Feature (enum) name used internally (S390_FEAT_##_FEAT)
+ * - _NAME: Feature name exposed to the user.
+ * - _TYPE: Feature type (S390_FEAT_TYPE_##_TYPE).
+ * - _BIT: Feature bit number within feature type block (unused for MISC).
+ * - _DESC: Feature description, exposed to the user.
+ *
+ * Copyright IBM Corp. 2016, 2018
+ * Copyright Red Hat, Inc. 2019
+ *
+ * Author(s): Michael Mueller <mimu@linux.vnet.ibm.com>
+ * David Hildenbrand <david@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at
+ * your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+
+/* Features exposed via the STFL(E) instruction. */
+DEF_FEAT(ESAN3, "esan3", STFL, 0, "Instructions marked as n3")
+DEF_FEAT(ZARCH, "zarch", STFL, 1, "z/Architecture architectural mode")
+DEF_FEAT(DAT_ENH, "dateh", STFL, 3, "DAT-enhancement facility")
+DEF_FEAT(IDTE_SEGMENT, "idtes", STFL, 4, "IDTE selective TLB segment-table clearing")
+DEF_FEAT(IDTE_REGION, "idter", STFL, 5, "IDTE selective TLB region-table clearing")
+DEF_FEAT(ASN_LX_REUSE, "asnlxr", STFL, 6, "ASN-and-LX reuse facility")
+DEF_FEAT(STFLE, "stfle", STFL, 7, "Store-facility-list-extended facility")
+DEF_FEAT(EDAT, "edat", STFL, 8, "Enhanced-DAT facility")
+DEF_FEAT(SENSE_RUNNING_STATUS, "srs", STFL, 9, "Sense-running-status facility")
+DEF_FEAT(CONDITIONAL_SSKE, "csske", STFL, 10, "Conditional-SSKE facility")
+DEF_FEAT(CONFIGURATION_TOPOLOGY, "ctop", STFL, 11, "Configuration-topology facility")
+DEF_FEAT(AP_QUERY_CONFIG_INFO, "apqci", STFL, 12, "Query AP Configuration Information facility")
+DEF_FEAT(IPTE_RANGE, "ipter", STFL, 13, "IPTE-range facility")
+DEF_FEAT(NONQ_KEY_SETTING, "nonqks", STFL, 14, "Nonquiescing key-setting facility")
+DEF_FEAT(AP_FACILITIES_TEST, "apft", STFL, 15, "AP Facilities Test facility")
+DEF_FEAT(EXTENDED_TRANSLATION_2, "etf2", STFL, 16, "Extended-translation facility 2")
+DEF_FEAT(MSA, "msa-base", STFL, 17, "Message-security-assist facility (excluding subfunctions)")
+DEF_FEAT(LONG_DISPLACEMENT, "ldisp", STFL, 18, "Long-displacement facility")
+DEF_FEAT(LONG_DISPLACEMENT_FAST, "ldisphp", STFL, 19, "Long-displacement facility has high performance")
+DEF_FEAT(HFP_MADDSUB, "hfpm", STFL, 20, "HFP-multiply-add/subtract facility")
+DEF_FEAT(EXTENDED_IMMEDIATE, "eimm", STFL, 21, "Extended-immediate facility")
+DEF_FEAT(EXTENDED_TRANSLATION_3, "etf3", STFL, 22, "Extended-translation facility 3")
+DEF_FEAT(HFP_UNNORMALIZED_EXT, "hfpue", STFL, 23, "HFP-unnormalized-extension facility")
+DEF_FEAT(ETF2_ENH, "etf2eh", STFL, 24, "ETF2-enhancement facility")
+DEF_FEAT(STORE_CLOCK_FAST, "stckf", STFL, 25, "Store-clock-fast facility")
+DEF_FEAT(PARSING_ENH, "parseh", STFL, 26, "Parsing-enhancement facility")
+DEF_FEAT(MOVE_WITH_OPTIONAL_SPEC, "mvcos", STFL, 27, "Move-with-optional-specification facility")
+DEF_FEAT(TOD_CLOCK_STEERING, "tods-base", STFL, 28, "TOD-clock-steering facility (excluding subfunctions)")
+DEF_FEAT(ETF3_ENH, "etf3eh", STFL, 30, "ETF3-enhancement facility")
+DEF_FEAT(EXTRACT_CPU_TIME, "ectg", STFL, 31, "Extract-CPU-time facility")
+DEF_FEAT(COMPARE_AND_SWAP_AND_STORE, "csst", STFL, 32, "Compare-and-swap-and-store facility")
+DEF_FEAT(COMPARE_AND_SWAP_AND_STORE_2, "csst2", STFL, 33, "Compare-and-swap-and-store facility 2")
+DEF_FEAT(GENERAL_INSTRUCTIONS_EXT, "ginste", STFL, 34, "General-instructions-extension facility")
+DEF_FEAT(EXECUTE_EXT, "exrl", STFL, 35, "Execute-extensions facility")
+DEF_FEAT(ENHANCED_MONITOR, "emon", STFL, 36, "Enhanced-monitor facility")
+DEF_FEAT(FLOATING_POINT_EXT, "fpe", STFL, 37, "Floating-point extension facility")
+DEF_FEAT(ORDER_PRESERVING_COMPRESSION, "opc", STFL, 38, "Order Preserving Compression facility")
+DEF_FEAT(SET_PROGRAM_PARAMETERS, "sprogp", STFL, 40, "Set-program-parameters facility")
+DEF_FEAT(FLOATING_POINT_SUPPPORT_ENH, "fpseh", STFL, 41, "Floating-point-support-enhancement facilities")
+DEF_FEAT(DFP, "dfp", STFL, 42, "DFP (decimal-floating-point) facility")
+DEF_FEAT(DFP_FAST, "dfphp", STFL, 43, "DFP (decimal-floating-point) facility has high performance")
+DEF_FEAT(PFPO, "pfpo", STFL, 44, "PFPO instruction")
+DEF_FEAT(STFLE_45, "stfle45", STFL, 45, "Various facilities introduced with z196")
+DEF_FEAT(CMPSC_ENH, "cmpsceh", STFL, 47, "CMPSC-enhancement facility")
+DEF_FEAT(DFP_ZONED_CONVERSION, "dfpzc", STFL, 48, "Decimal-floating-point zoned-conversion facility")
+DEF_FEAT(STFLE_49, "stfle49", STFL, 49, "Various facilities introduced with zEC12")
+DEF_FEAT(CONSTRAINT_TRANSACTIONAL_EXE, "cte", STFL, 50, "Constrained transactional-execution facility")
+DEF_FEAT(LOCAL_TLB_CLEARING, "ltlbc", STFL, 51, "Local-TLB-clearing facility")
+DEF_FEAT(INTERLOCKED_ACCESS_2, "iacc2", STFL, 52, "Interlocked-access facility 2")
+DEF_FEAT(STFLE_53, "stfle53", STFL, 53, "Various facilities introduced with z13")
+DEF_FEAT(ENTROPY_ENC_COMP, "eec", STFL, 54, "Entropy encoding compression facility")
+DEF_FEAT(MSA_EXT_5, "msa5-base", STFL, 57, "Message-security-assist-extension-5 facility (excluding subfunctions)")
+DEF_FEAT(MISC_INSTRUCTION_EXT, "minste2", STFL, 58, "Miscellaneous-instruction-extensions facility 2")
+DEF_FEAT(SEMAPHORE_ASSIST, "sema", STFL, 59, "Semaphore-assist facility")
+DEF_FEAT(TIME_SLICE_INSTRUMENTATION, "tsi", STFL, 60, "Time-slice Instrumentation facility")
+DEF_FEAT(MISC_INSTRUCTION_EXT3, "minste3", STFL, 61, "Miscellaneous-Instruction-Extensions Facility 3")
+DEF_FEAT(RUNTIME_INSTRUMENTATION, "ri", STFL, 64, "CPU runtime-instrumentation facility")
+DEF_FEAT(ZPCI, "zpci", STFL, 69, "z/PCI facility")
+DEF_FEAT(ADAPTER_EVENT_NOTIFICATION, "aen", STFL, 71, "General-purpose-adapter-event-notification facility")
+DEF_FEAT(ADAPTER_INT_SUPPRESSION, "ais", STFL, 72, "General-purpose-adapter-interruption-suppression facility")
+DEF_FEAT(TRANSACTIONAL_EXE, "te", STFL, 73, "Transactional-execution facility")
+DEF_FEAT(STORE_HYPERVISOR_INFO, "sthyi", STFL, 74, "Store-hypervisor-information facility")
+DEF_FEAT(ACCESS_EXCEPTION_FS_INDICATION, "aefsi", STFL, 75, "Access-exception-fetch/store-indication facility")
+DEF_FEAT(MSA_EXT_3, "msa3-base", STFL, 76, "Message-security-assist-extension-3 facility (excluding subfunctions)")
+DEF_FEAT(MSA_EXT_4, "msa4-base", STFL, 77, "Message-security-assist-extension-4 facility (excluding subfunctions)")
+DEF_FEAT(EDAT_2, "edat2", STFL, 78, "Enhanced-DAT facility 2")
+DEF_FEAT(DFP_PACKED_CONVERSION, "dfppc", STFL, 80, "Decimal-floating-point packed-conversion facility")
+DEF_FEAT(PPA15, "ppa15", STFL, 81, "PPA15 is installed")
+DEF_FEAT(BPB, "bpb", STFL, 82, "Branch prediction blocking")
+DEF_FEAT(VECTOR, "vx", STFL, 129, "Vector facility")
+DEF_FEAT(INSTRUCTION_EXEC_PROT, "iep", STFL, 130, "Instruction-execution-protection facility")
+DEF_FEAT(SIDE_EFFECT_ACCESS_ESOP2, "sea_esop2", STFL, 131, "Side-effect-access facility and Enhanced-suppression-on-protection facility 2")
+DEF_FEAT(GUARDED_STORAGE, "gs", STFL, 133, "Guarded-storage facility")
+DEF_FEAT(VECTOR_PACKED_DECIMAL, "vxpd", STFL, 134, "Vector packed decimal facility")
+DEF_FEAT(VECTOR_ENH, "vxeh", STFL, 135, "Vector enhancements facility")
+DEF_FEAT(MULTIPLE_EPOCH, "mepoch", STFL, 139, "Multiple-epoch facility")
+DEF_FEAT(TEST_PENDING_EXT_INTERRUPTION, "tpei", STFL, 144, "Test-pending-external-interruption facility")
+DEF_FEAT(INSERT_REFERENCE_BITS_MULT, "irbm", STFL, 145, "Insert-reference-bits-multiple facility")
+DEF_FEAT(MSA_EXT_8, "msa8-base", STFL, 146, "Message-security-assist-extension-8 facility (excluding subfunctions)")
+DEF_FEAT(CMM_NT, "cmmnt", STFL, 147, "CMM: ESSA-enhancement (no translate) facility")
+DEF_FEAT(VECTOR_ENH2, "vxeh2", STFL, 148, "Vector Enhancements facility 2")
+DEF_FEAT(ESORT_BASE, "esort-base", STFL, 150, "Enhanced-sort facility (excluding subfunctions)")
+DEF_FEAT(DEFLATE_BASE, "deflate-base", STFL, 151, "Deflate-conversion facility (excluding subfunctions)")
+DEF_FEAT(VECTOR_BCD_ENH, "vxbeh", STFL, 152, "Vector BCD enhancements facility 1")
+DEF_FEAT(MSA_EXT_9, "msa9-base", STFL, 155, "Message-security-assist-extension-9 facility (excluding subfunctions)")
+DEF_FEAT(ETOKEN, "etoken", STFL, 156, "Etoken facility")
+
+/* Features exposed via SCLP SCCB Byte 80 - 98 (bit numbers relative to byte-80) */
+DEF_FEAT(SIE_GSLS, "gsls", SCLP_CONF_CHAR, 40, "SIE: Guest-storage-limit-suppression facility")
+DEF_FEAT(ESOP, "esop", SCLP_CONF_CHAR, 46, "Enhanced-suppression-on-protection facility")
+DEF_FEAT(HPMA2, "hpma2", SCLP_CONF_CHAR, 90, "Host page management assist 2 Facility") /* 91-2 */
+DEF_FEAT(SIE_KSS, "kss", SCLP_CONF_CHAR, 151, "SIE: Keyless-subset facility") /* 98-7 */
+
+/* Features exposed via SCLP SCCB Byte 116 - 119 (bit numbers relative to byte-116) */
+DEF_FEAT(SIE_64BSCAO, "64bscao", SCLP_CONF_CHAR_EXT, 0, "SIE: 64-bit-SCAO facility")
+DEF_FEAT(SIE_CMMA, "cmma", SCLP_CONF_CHAR_EXT, 1, "SIE: Collaborative-memory-management assist")
+DEF_FEAT(SIE_PFMFI, "pfmfi", SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF interpretation facility")
+DEF_FEAT(SIE_IBS, "ibs", SCLP_CONF_CHAR_EXT, 10, "SIE: Interlock-and-broadcast-suppression facility")
+
+/* Features exposed via SCLP CPU info. */
+DEF_FEAT(SIE_F2, "sief2", SCLP_CPU, 4, "SIE: interception format 2 (Virtual SIE)")
+DEF_FEAT(SIE_SKEY, "skey", SCLP_CPU, 5, "SIE: Storage-key facility")
+DEF_FEAT(SIE_GPERE, "gpereh", SCLP_CPU, 10, "SIE: Guest-PER enhancement facility")
+DEF_FEAT(SIE_SIIF, "siif", SCLP_CPU, 11, "SIE: Shared IPTE-interlock facility")
+DEF_FEAT(SIE_SIGPIF, "sigpif", SCLP_CPU, 12, "SIE: SIGP interpretation facility")
+DEF_FEAT(SIE_IB, "ib", SCLP_CPU, 42, "SIE: Intervention bypass facility")
+DEF_FEAT(SIE_CEI, "cei", SCLP_CPU, 43, "SIE: Conditional-external-interception facility")
+
+/*
+ * Features exposed via no feature bit (but e.g., instruction sensing)
+ * -> the feature bit number is irrelavant
+ */
+DEF_FEAT(DAT_ENH_2, "dateh2", MISC, 0, "DAT-enhancement facility 2")
+DEF_FEAT(CMM, "cmm", MISC, 0, "Collaborative-memory-management facility")
+DEF_FEAT(AP, "ap", MISC, 0, "AP instructions installed")
+
+/* Features exposed via the PLO instruction. */
+DEF_FEAT(PLO_CL, "plo-cl", PLO, 0, "PLO Compare and load (32 bit in general registers)")
+DEF_FEAT(PLO_CLG, "plo-clg", PLO, 1, "PLO Compare and load (64 bit in parameter list)")
+DEF_FEAT(PLO_CLGR, "plo-clgr", PLO, 2, "PLO Compare and load (32 bit in general registers)")
+DEF_FEAT(PLO_CLX, "plo-clx", PLO, 3, "PLO Compare and load (128 bit in parameter list)")
+DEF_FEAT(PLO_CS, "plo-cs", PLO, 4, "PLO Compare and swap (32 bit in general registers)")
+DEF_FEAT(PLO_CSG, "plo-csg", PLO, 5, "PLO Compare and swap (64 bit in parameter list)")
+DEF_FEAT(PLO_CSGR, "plo-csgr", PLO, 6, "PLO Compare and swap (32 bit in general registers)")
+DEF_FEAT(PLO_CSX, "plo-csx", PLO, 7, "PLO Compare and swap (128 bit in parameter list)")
+DEF_FEAT(PLO_DCS, "plo-dcs", PLO, 8, "PLO Double compare and swap (32 bit in general registers)")
+DEF_FEAT(PLO_DCSG, "plo-dcsg", PLO, 9, "PLO Double compare and swap (64 bit in parameter list)")
+DEF_FEAT(PLO_DCSGR, "plo-dcsgr", PLO, 10, "PLO Double compare and swap (32 bit in general registers)")
+DEF_FEAT(PLO_DCSX, "plo-dcsx", PLO, 11, "PLO Double compare and swap (128 bit in parameter list)")
+DEF_FEAT(PLO_CSST, "plo-csst", PLO, 12, "PLO Compare and swap and store (32 bit in general registers)")
+DEF_FEAT(PLO_CSSTG, "plo-csstg", PLO, 13, "PLO Compare and swap and store (64 bit in parameter list)")
+DEF_FEAT(PLO_CSSTGR, "plo-csstgr", PLO, 14, "PLO Compare and swap and store (32 bit in general registers)")
+DEF_FEAT(PLO_CSSTX, "plo-csstx", PLO, 15, "PLO Compare and swap and store (128 bit in parameter list)")
+DEF_FEAT(PLO_CSDST, "plo-csdst", PLO, 16, "PLO Compare and swap and double store (32 bit in general registers)")
+DEF_FEAT(PLO_CSDSTG, "plo-csdstg", PLO, 17, "PLO Compare and swap and double store (64 bit in parameter list)")
+DEF_FEAT(PLO_CSDSTGR, "plo-csdstgr", PLO, 18, "PLO Compare and swap and double store (32 bit in general registers)")
+DEF_FEAT(PLO_CSDSTX, "plo-csdstx", PLO, 19, "PLO Compare and swap and double store (128 bit in parameter list)")
+DEF_FEAT(PLO_CSTST, "plo-cstst", PLO, 20, "PLO Compare and swap and triple store (32 bit in general registers)")
+DEF_FEAT(PLO_CSTSTG, "plo-cststg", PLO, 21, "PLO Compare and swap and triple store (64 bit in parameter list)")
+DEF_FEAT(PLO_CSTSTGR, "plo-cststgr", PLO, 22, "PLO Compare and swap and triple store (32 bit in general registers)")
+DEF_FEAT(PLO_CSTSTX, "plo-cststx", PLO, 23, "PLO Compare and swap and triple store (128 bit in parameter list)")
+
+/* Features exposed via the PTFF instruction. */
+DEF_FEAT(PTFF_QTO, "ptff-qto", PTFF, 1, "PTFF Query TOD Offset")
+DEF_FEAT(PTFF_QSI, "ptff-qsi", PTFF, 2, "PTFF Query Steering Information")
+DEF_FEAT(PTFF_QPT, "ptff-qpc", PTFF, 3, "PTFF Query Physical Clock")
+DEF_FEAT(PTFF_QUI, "ptff-qui", PTFF, 4, "PTFF Query UTC Information")
+DEF_FEAT(PTFF_QTOU, "ptff-qtou", PTFF, 5, "PTFF Query TOD Offset User")
+DEF_FEAT(PTFF_QSIE, "ptff-qsie", PTFF, 10, "PTFF Query Steering Information Extended")
+DEF_FEAT(PTFF_QTOUE, "ptff-qtoue", PTFF, 13, "PTFF Query TOD Offset User Extended")
+DEF_FEAT(PTFF_STO, "ptff-sto", PTFF, 65, "PTFF Set TOD Offset")
+DEF_FEAT(PTFF_STOU, "ptff-stou", PTFF, 69, "PTFF Set TOD Offset User")
+DEF_FEAT(PTFF_STOE, "ptff-stoe", PTFF, 73, "PTFF Set TOD Offset Extended")
+DEF_FEAT(PTFF_STOUE, "ptff-stoue", PTFF, 77, "PTFF Set TOD Offset User Extended")
+
+/* Features exposed via the KMAC instruction. */
+DEF_FEAT(KMAC_DEA, "kmac-dea", KMAC, 1, "KMAC DEA")
+DEF_FEAT(KMAC_TDEA_128, "kmac-tdea-128", KMAC, 2, "KMAC TDEA-128")
+DEF_FEAT(KMAC_TDEA_192, "kmac-tdea-192", KMAC, 3, "KMAC TDEA-192")
+DEF_FEAT(KMAC_EDEA, "kmac-edea", KMAC, 9, "KMAC Encrypted-DEA")
+DEF_FEAT(KMAC_ETDEA_128, "kmac-etdea-128", KMAC, 10, "KMAC Encrypted-TDEA-128")
+DEF_FEAT(KMAC_ETDEA_192, "kmac-etdea-192", KMAC, 11, "KMAC Encrypted-TDEA-192")
+DEF_FEAT(KMAC_AES_128, "kmac-aes-128", KMAC, 18, "KMAC AES-128")
+DEF_FEAT(KMAC_AES_192, "kmac-aes-192", KMAC, 19, "KMAC AES-192")
+DEF_FEAT(KMAC_AES_256, "kmac-aes-256", KMAC, 20, "KMAC AES-256")
+DEF_FEAT(KMAC_EAES_128, "kmac-eaes-128", KMAC, 26, "KMAC Encrypted-AES-128")
+DEF_FEAT(KMAC_EAES_192, "kmac-eaes-192", KMAC, 27, "KMAC Encrypted-AES-192")
+DEF_FEAT(KMAC_EAES_256, "kmac-eaes-256", KMAC, 28, "KMAC Encrypted-AES-256")
+
+/* Features exposed via the KMC instruction. */
+DEF_FEAT(KMC_DEA, "kmc-dea", KMC, 1, "KMC DEA")
+DEF_FEAT(KMC_TDEA_128, "kmc-tdea-128", KMC, 2, "KMC TDEA-128")
+DEF_FEAT(KMC_TDEA_192, "kmc-tdea-192", KMC, 3, "KMC TDEA-192")
+DEF_FEAT(KMC_EDEA, "kmc-edea", KMC, 9, "KMC Encrypted-DEA")
+DEF_FEAT(KMC_ETDEA_128, "kmc-etdea-128", KMC, 10, "KMC Encrypted-TDEA-128")
+DEF_FEAT(KMC_ETDEA_192, "kmc-etdea-192", KMC, 11, "KMC Encrypted-TDEA-192")
+DEF_FEAT(KMC_AES_128, "kmc-aes-128", KMC, 18, "KMC AES-128")
+DEF_FEAT(KMC_AES_192, "kmc-aes-192", KMC, 19, "KMC AES-192")
+DEF_FEAT(KMC_AES_256, "kmc-aes-256", KMC, 20, "KMC AES-256")
+DEF_FEAT(KMC_EAES_128, "kmc-eaes-128", KMC, 26, "KMC Encrypted-AES-128")
+DEF_FEAT(KMC_EAES_192, "kmc-eaes-192", KMC, 27, "KMC Encrypted-AES-192")
+DEF_FEAT(KMC_EAES_256, "kmc-eaes-256", KMC, 28, "KMC Encrypted-AES-256")
+DEF_FEAT(KMC_PRNG, "kmc-prng", KMC, 67, "KMC PRNG")
+
+/* Features exposed via the KM instruction. */
+DEF_FEAT(KM_DEA, "km-dea", KM, 1, "KM DEA")
+DEF_FEAT(KM_TDEA_128, "km-tdea-128", KM, 2, "KM TDEA-128")
+DEF_FEAT(KM_TDEA_192, "km-tdea-192", KM, 3, "KM TDEA-192")
+DEF_FEAT(KM_EDEA, "km-edea", KM, 9, "KM Encrypted-DEA")
+DEF_FEAT(KM_ETDEA_128, "km-etdea-128", KM, 10, "KM Encrypted-TDEA-128")
+DEF_FEAT(KM_ETDEA_192, "km-etdea-192", KM, 11, "KM Encrypted-TDEA-192")
+DEF_FEAT(KM_AES_128, "km-aes-128", KM, 18, "KM AES-128")
+DEF_FEAT(KM_AES_192, "km-aes-192", KM, 19, "KM AES-192")
+DEF_FEAT(KM_AES_256, "km-aes-256", KM, 20, "KM AES-256")
+DEF_FEAT(KM_EAES_128, "km-eaes-128", KM, 26, "KM Encrypted-AES-128")
+DEF_FEAT(KM_EAES_192, "km-eaes-192", KM, 27, "KM Encrypted-AES-192")
+DEF_FEAT(KM_EAES_256, "km-eaes-256", KM, 28, "KM Encrypted-AES-256")
+DEF_FEAT(KM_XTS_AES_128, "km-xts-aes-128", KM, 50, "KM XTS-AES-128")
+DEF_FEAT(KM_XTS_AES_256, "km-xts-aes-256", KM, 52, "KM XTS-AES-256")
+DEF_FEAT(KM_XTS_EAES_128, "km-xts-eaes-128", KM, 58, "KM XTS-Encrypted-AES-128")
+DEF_FEAT(KM_XTS_EAES_256, "km-xts-eaes-256", KM, 60, "KM XTS-Encrypted-AES-256")
+
+/* Features exposed via the KIMD instruction. */
+DEF_FEAT(KIMD_SHA_1, "kimd-sha-1", KIMD, 1, "KIMD SHA-1")
+DEF_FEAT(KIMD_SHA_256, "kimd-sha-256", KIMD, 2, "KIMD SHA-256")
+DEF_FEAT(KIMD_SHA_512, "kimd-sha-512", KIMD, 3, "KIMD SHA-512")
+DEF_FEAT(KIMD_SHA3_224, "kimd-sha3-224", KIMD, 32, "KIMD SHA3-224")
+DEF_FEAT(KIMD_SHA3_256, "kimd-sha3-256", KIMD, 33, "KIMD SHA3-256")
+DEF_FEAT(KIMD_SHA3_384, "kimd-sha3-384", KIMD, 34, "KIMD SHA3-384")
+DEF_FEAT(KIMD_SHA3_512, "kimd-sha3-512", KIMD, 35, "KIMD SHA3-512")
+DEF_FEAT(KIMD_SHAKE_128, "kimd-shake-128", KIMD, 36, "KIMD SHAKE-128")
+DEF_FEAT(KIMD_SHAKE_256, "kimd-shake-256", KIMD, 37, "KIMD SHAKE-256")
+DEF_FEAT(KIMD_GHASH, "kimd-ghash", KIMD, 65, "KIMD GHASH")
+
+/* Features exposed via the KLMD instruction. */
+DEF_FEAT(KLMD_SHA_1, "klmd-sha-1", KLMD, 1, "KLMD SHA-1")
+DEF_FEAT(KLMD_SHA_256, "klmd-sha-256", KLMD, 2, "KLMD SHA-256")
+DEF_FEAT(KLMD_SHA_512, "klmd-sha-512", KLMD, 3, "KLMD SHA-512")
+DEF_FEAT(KLMD_SHA3_224, "klmd-sha3-224", KLMD, 32, "KLMD SHA3-224")
+DEF_FEAT(KLMD_SHA3_256, "klmd-sha3-256", KLMD, 33, "KLMD SHA3-256")
+DEF_FEAT(KLMD_SHA3_384, "klmd-sha3-384", KLMD, 34, "KLMD SHA3-384")
+DEF_FEAT(KLMD_SHA3_512, "klmd-sha3-512", KLMD, 35, "KLMD SHA3-512")
+DEF_FEAT(KLMD_SHAKE_128, "klmd-shake-128", KLMD, 36, "KLMD SHAKE-128")
+DEF_FEAT(KLMD_SHAKE_256, "klmd-shake-256", KLMD, 37, "KLMD SHAKE-256")
+
+/* Features exposed via the PCKMO instruction. */
+DEF_FEAT(PCKMO_EDEA, "pckmo-edea", PCKMO, 1, "PCKMO Encrypted-DEA-Key")
+DEF_FEAT(PCKMO_ETDEA_128, "pckmo-etdea-128", PCKMO, 2, "PCKMO Encrypted-TDEA-128-Key")
+DEF_FEAT(PCKMO_ETDEA_256, "pckmo-etdea-192", PCKMO, 3, "PCKMO Encrypted-TDEA-192-Key")
+DEF_FEAT(PCKMO_AES_128, "pckmo-aes-128", PCKMO, 18, "PCKMO Encrypted-AES-128-Key")
+DEF_FEAT(PCKMO_AES_192, "pckmo-aes-192", PCKMO, 19, "PCKMO Encrypted-AES-192-Key")
+DEF_FEAT(PCKMO_AES_256, "pckmo-aes-256", PCKMO, 20, "PCKMO Encrypted-AES-256-Key")
+DEF_FEAT(PCKMO_ECC_P256, "pckmo-ecc-p256", PCKMO, 32, "PCKMO Encrypt-ECC-P256-Key")
+DEF_FEAT(PCKMO_ECC_P384, "pckmo-ecc-p384", PCKMO, 33, "PCKMO Encrypt-ECC-P384-Key")
+DEF_FEAT(PCKMO_ECC_P521, "pckmo-ecc-p521", PCKMO, 34, "PCKMO Encrypt-ECC-P521-Key")
+DEF_FEAT(PCKMO_ECC_ED25519, "pckmo-ecc-ed25519", PCKMO, 40 , "PCKMO Encrypt-ECC-Ed25519-Key")
+DEF_FEAT(PCKMO_ECC_ED448, "pckmo-ecc-ed448", PCKMO, 41 , "PCKMO Encrypt-ECC-Ed448-Key")
+
+/* Features exposed via the KMCTR instruction. */
+DEF_FEAT(KMCTR_DEA, "kmctr-dea", KMCTR, 1, "KMCTR DEA")
+DEF_FEAT(KMCTR_TDEA_128, "kmctr-tdea-128", KMCTR, 2, "KMCTR TDEA-128")
+DEF_FEAT(KMCTR_TDEA_192, "kmctr-tdea-192", KMCTR, 3, "KMCTR TDEA-192")
+DEF_FEAT(KMCTR_EDEA, "kmctr-edea", KMCTR, 9, "KMCTR Encrypted-DEA")
+DEF_FEAT(KMCTR_ETDEA_128, "kmctr-etdea-128", KMCTR, 10, "KMCTR Encrypted-TDEA-128")
+DEF_FEAT(KMCTR_ETDEA_192, "kmctr-etdea-192", KMCTR, 11, "KMCTR Encrypted-TDEA-192")
+DEF_FEAT(KMCTR_AES_128, "kmctr-aes-128", KMCTR, 18, "KMCTR AES-128")
+DEF_FEAT(KMCTR_AES_192, "kmctr-aes-192", KMCTR, 19, "KMCTR AES-192")
+DEF_FEAT(KMCTR_AES_256, "kmctr-aes-256", KMCTR, 20, "KMCTR AES-256")
+DEF_FEAT(KMCTR_EAES_128, "kmctr-eaes-128", KMCTR, 26, "KMCTR Encrypted-AES-128")
+DEF_FEAT(KMCTR_EAES_192, "kmctr-eaes-192", KMCTR, 27, "KMCTR Encrypted-AES-192")
+DEF_FEAT(KMCTR_EAES_256, "kmctr-eaes-256", KMCTR, 28, "KMCTR Encrypted-AES-256")
+
+/* Features exposed via the KMF instruction. */
+DEF_FEAT(KMF_DEA, "kmf-dea", KMF, 1, "KMF DEA")
+DEF_FEAT(KMF_TDEA_128, "kmf-tdea-128", KMF, 2, "KMF TDEA-128")
+DEF_FEAT(KMF_TDEA_192, "kmf-tdea-192", KMF, 3, "KMF TDEA-192")
+DEF_FEAT(KMF_EDEA, "kmf-edea", KMF, 9, "KMF Encrypted-DEA")
+DEF_FEAT(KMF_ETDEA_128, "kmf-etdea-128", KMF, 10, "KMF Encrypted-TDEA-128")
+DEF_FEAT(KMF_ETDEA_192, "kmf-etdea-192", KMF, 11, "KMF Encrypted-TDEA-192")
+DEF_FEAT(KMF_AES_128, "kmf-aes-128", KMF, 18, "KMF AES-128")
+DEF_FEAT(KMF_AES_192, "kmf-aes-192", KMF, 19, "KMF AES-192")
+DEF_FEAT(KMF_AES_256, "kmf-aes-256", KMF, 20, "KMF AES-256")
+DEF_FEAT(KMF_EAES_128, "kmf-eaes-128", KMF, 26, "KMF Encrypted-AES-128")
+DEF_FEAT(KMF_EAES_192, "kmf-eaes-192", KMF, 27, "KMF Encrypted-AES-192")
+DEF_FEAT(KMF_EAES_256, "kmf-eaes-256", KMF, 28, "KMF Encrypted-AES-256")
+
+/* Features exposed via the KMO instruction. */
+DEF_FEAT(KMO_DEA, "kmo-dea", KMO, 1, "KMO DEA")
+DEF_FEAT(KMO_TDEA_128, "kmo-tdea-128", KMO, 2, "KMO TDEA-128")
+DEF_FEAT(KMO_TDEA_192, "kmo-tdea-192", KMO, 3, "KMO TDEA-192")
+DEF_FEAT(KMO_EDEA, "kmo-edea", KMO, 9, "KMO Encrypted-DEA")
+DEF_FEAT(KMO_ETDEA_128, "kmo-etdea-128", KMO, 10, "KMO Encrypted-TDEA-128")
+DEF_FEAT(KMO_ETDEA_192, "kmo-etdea-192", KMO, 11, "KMO Encrypted-TDEA-192")
+DEF_FEAT(KMO_AES_128, "kmo-aes-128", KMO, 18, "KMO AES-128")
+DEF_FEAT(KMO_AES_192, "kmo-aes-192", KMO, 19, "KMO AES-192")
+DEF_FEAT(KMO_AES_256, "kmo-aes-256", KMO, 20, "KMO AES-256")
+DEF_FEAT(KMO_EAES_128, "kmo-eaes-128", KMO, 26, "KMO Encrypted-AES-128")
+DEF_FEAT(KMO_EAES_192, "kmo-eaes-192", KMO, 27, "KMO Encrypted-AES-192")
+DEF_FEAT(KMO_EAES_256, "kmo-eaes-256", KMO, 28, "KMO Encrypted-AES-256")
+
+/* Features exposed via the PCC instruction. */
+DEF_FEAT(PCC_CMAC_DEA, "pcc-cmac-dea", PCC, 1, "PCC Compute-Last-Block-CMAC-Using-DEA")
+DEF_FEAT(PCC_CMAC_TDEA_128, "pcc-cmac-tdea-128", PCC, 2, "PCC Compute-Last-Block-CMAC-Using-TDEA-128")
+DEF_FEAT(PCC_CMAC_TDEA_192, "pcc-cmac-tdea-192", PCC, 3, "PCC Compute-Last-Block-CMAC-Using-TDEA-192")
+DEF_FEAT(PCC_CMAC_ETDEA_128, "pcc-cmac-edea", PCC, 9, "PCC Compute-Last-Block-CMAC-Using-Encrypted-DEA")
+DEF_FEAT(PCC_CMAC_ETDEA_192, "pcc-cmac-etdea-128", PCC, 10, "PCC Compute-Last-Block-CMAC-Using-Encrypted-TDEA-128")
+DEF_FEAT(PCC_CMAC_TDEA, "pcc-cmac-etdea-192", PCC, 11, "PCC Compute-Last-Block-CMAC-Using-EncryptedTDEA-192")
+DEF_FEAT(PCC_CMAC_AES_128, "pcc-cmac-aes-128", PCC, 18, "PCC Compute-Last-Block-CMAC-Using-AES-128")
+DEF_FEAT(PCC_CMAC_AES_192, "pcc-cmac-aes-192", PCC, 19, "PCC Compute-Last-Block-CMAC-Using-AES-192")
+DEF_FEAT(PCC_CMAC_AES_256, "pcc-cmac-eaes-256", PCC, 20, "PCC Compute-Last-Block-CMAC-Using-AES-256")
+DEF_FEAT(PCC_CMAC_EAES_128, "pcc-cmac-eaes-128", PCC, 26, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-128")
+DEF_FEAT(PCC_CMAC_EAES_192, "pcc-cmac-eaes-192", PCC, 27, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-192")
+DEF_FEAT(PCC_CMAC_EAES_256, "pcc-cmac-eaes-256", PCC, 28, "PCC Compute-Last-Block-CMAC-Using-Encrypted-AES-256")
+DEF_FEAT(PCC_XTS_AES_128, "pcc-xts-aes-128", PCC, 50, "PCC Compute-XTS-Parameter-Using-AES-128")
+DEF_FEAT(PCC_XTS_AES_256, "pcc-xts-aes-256", PCC, 52, "PCC Compute-XTS-Parameter-Using-AES-256")
+DEF_FEAT(PCC_XTS_EAES_128, "pcc-xts-eaes-128", PCC, 58, "PCC Compute-XTS-Parameter-Using-Encrypted-AES-128")
+DEF_FEAT(PCC_XTS_EAES_256, "pcc-xts-eaes-256", PCC, 60, "PCC Compute-XTS-Parameter-Using-Encrypted-AES-256")
+DEF_FEAT(PCC_SCALAR_MULT_P256, "pcc-scalar-mult-p256", PCC, 64, "PCC Scalar-Multiply-P256")
+DEF_FEAT(PCC_SCALAR_MULT_P384, "pcc-scalar-mult-p384", PCC, 65, "PCC Scalar-Multiply-P384")
+DEF_FEAT(PCC_SCALAR_MULT_P512, "pcc-scalar-mult-p521", PCC, 66, "PCC Scalar-Multiply-P521")
+DEF_FEAT(PCC_SCALAR_MULT_ED25519, "pcc-scalar-mult-ed25519", PCC, 72, "PCC Scalar-Multiply-Ed25519")
+DEF_FEAT(PCC_SCALAR_MULT_ED448, "pcc-scalar-mult-ed448", PCC, 73, "PCC Scalar-Multiply-Ed448")
+DEF_FEAT(PCC_SCALAR_MULT_X25519, "pcc-scalar-mult-x25519", PCC, 80, "PCC Scalar-Multiply-X25519")
+DEF_FEAT(PCC_SCALAR_MULT_X448, "pcc-scalar-mult-x448", PCC, 81, "PCC Scalar-Multiply-X448")
+
+/* Features exposed via the PPNO/PRNO instruction. */
+DEF_FEAT(PPNO_SHA_512_DRNG, "ppno-sha-512-drng", PPNO, 3, "PPNO SHA-512-DRNG")
+DEF_FEAT(PRNO_TRNG_QRTCR, "prno-trng-qrtcr", PPNO, 112, "PRNO TRNG-Query-Raw-to-Conditioned-Ratio")
+DEF_FEAT(PRNO_TRNG, "prno-trng", PPNO, 114, "PRNO TRNG")
+
+/* Features exposed via the KMA instruction. */
+DEF_FEAT(KMA_GCM_AES_128, "kma-gcm-aes-128", KMA, 18, "KMA GCM-AES-128")
+DEF_FEAT(KMA_GCM_AES_192, "kma-gcm-aes-192", KMA, 19, "KMA GCM-AES-192")
+DEF_FEAT(KMA_GCM_AES_256, "kma-gcm-aes-256", KMA, 20, "KMA GCM-AES-256")
+DEF_FEAT(KMA_GCM_EAES_128, "kma-gcm-eaes-128", KMA, 26, "KMA GCM-Encrypted-AES-128")
+DEF_FEAT(KMA_GCM_EAES_192, "kma-gcm-eaes-192", KMA, 27, "KMA GCM-Encrypted-AES-192")
+DEF_FEAT(KMA_GCM_EAES_256, "kma-gcm-eaes-256", KMA, 28, "KMA GCM-Encrypted-AES-256")
+
+/* Features exposed via the KDSA instruction. */
+DEF_FEAT(KDSA_ECDSA_VERIFY_P256, "kdsa-ecdsa-verify-p256", KDSA, 1, "KDSA ECDSA-Verify-P256")
+DEF_FEAT(KDSA_ECDSA_VERIFY_P384, "kdsa-ecdsa-verify-p384", KDSA, 2, "KDSA ECDSA-Verify-P384")
+DEF_FEAT(KDSA_ECDSA_VERIFY_P512, "kdsa-ecdsa-verify-p521", KDSA, 3, "KDSA ECDSA-Verify-P521")
+DEF_FEAT(KDSA_ECDSA_SIGN_P256, "kdsa-ecdsa-sign-p256", KDSA, 9, "KDSA ECDSA-Sign-P256")
+DEF_FEAT(KDSA_ECDSA_SIGN_P384, "kdsa-ecdsa-sign-p384", KDSA, 10, "KDSA ECDSA-Sign-P384")
+DEF_FEAT(KDSA_ECDSA_SIGN_P512, "kdsa-ecdsa-sign-p521", KDSA, 11, "KDSA ECDSA-Sign-P521")
+DEF_FEAT(KDSA_EECDSA_SIGN_P256, "kdsa-eecdsa-sign-p256", KDSA, 17, "KDSA Encrypted-ECDSA-Sign-P256")
+DEF_FEAT(KDSA_EECDSA_SIGN_P384, "kdsa-eecdsa-sign-p384", KDSA, 18, "KDSA Encrypted-ECDSA-Sign-P384")
+DEF_FEAT(KDSA_EECDSA_SIGN_P512, "kdsa-eecdsa-sign-p521", KDSA, 19, "KDSA Encrypted-ECDSA-Sign-P521")
+DEF_FEAT(KDSA_EDDSA_VERIFY_ED25519, "kdsa-eddsa-verify-ed25519", KDSA, 32, "KDSA EdDSA-Verify-Ed25519")
+DEF_FEAT(KDSA_EDDSA_VERIFY_ED448, "kdsa-eddsa-verify-ed448", KDSA, 36, "KDSA EdDSA-Verify-Ed448")
+DEF_FEAT(KDSA_EDDSA_SIGN_ED25519, "kdsa-eddsa-sign-ed25519", KDSA, 40, "KDSA EdDSA-Sign-Ed25519")
+DEF_FEAT(KDSA_EDDSA_SIGN_ED448, "kdsa-eddsa-sign-ed448", KDSA, 44, "KDSA EdDSA-Sign-Ed448")
+DEF_FEAT(KDSA_EEDDSA_SIGN_ED25519, "kdsa-eeddsa-sign-ed25519", KDSA, 48, "KDSA Encrypted-EdDSA-Sign-Ed25519")
+DEF_FEAT(KDSA_EEDDSA_SIGN_ED448, "kdsa-eeddsa-sign-ed448", KDSA, 52, "KDSA Encrypted-EdDSA-Sign-Ed448")
+
+/* Features exposed via the SORTL instruction. */
+DEF_FEAT(SORTL_SFLR, "sortl-sflr", SORTL, 1, "SORTL SFLR")
+DEF_FEAT(SORTL_SVLR, "sortl-svlr", SORTL, 2, "SORTL SVLR")
+DEF_FEAT(SORTL_32, "sortl-32", SORTL, 130, "SORTL 32 input lists")
+DEF_FEAT(SORTL_128, "sortl-128", SORTL, 132, "SORTL 128 input lists")
+DEF_FEAT(SORTL_F0, "sortl-f0", SORTL, 192, "SORTL format 0 parameter-block")
+
+/* Features exposed via the DEFLATE instruction. */
+DEF_FEAT(DEFLATE_GHDT, "dfltcc-gdht", DFLTCC, 1, "DFLTCC GDHT")
+DEF_FEAT(DEFLATE_CMPR, "dfltcc-cmpr", DFLTCC, 2, "DFLTCC CMPR")
+DEF_FEAT(DEFLATE_XPND, "dfltcc-xpnd", DFLTCC, 4, "DFLTCC XPND")
+DEF_FEAT(DEFLATE_F0, "dfltcc-f0", DFLTCC, 192, "DFLTCC format 0 parameter-block")
#include "sysemu/arch_init.h"
#include "hw/pci/pci.h"
#endif
-#include "qapi/qapi-commands-target.h"
+#include "qapi/qapi-commands-machine-target.h"
#define CPUDEF_INIT(_type, _gen, _ec_ga, _mha_pow, _hmfai, _name, _desc) \
{ \
#define S390_FEAT_GROUP_MSA_EXT_9 \
S390_FEAT_MSA_EXT_9, \
- S390_FEAT_ECDSA_VERIFY_P256, \
- S390_FEAT_ECDSA_VERIFY_P384, \
- S390_FEAT_ECDSA_VERIFY_P512, \
- S390_FEAT_ECDSA_SIGN_P256, \
- S390_FEAT_ECDSA_SIGN_P384, \
- S390_FEAT_ECDSA_SIGN_P512, \
- S390_FEAT_EECDSA_SIGN_P256, \
- S390_FEAT_EECDSA_SIGN_P384, \
- S390_FEAT_EECDSA_SIGN_P512, \
- S390_FEAT_EDDSA_VERIFY_ED25519, \
- S390_FEAT_EDDSA_VERIFY_ED448, \
- S390_FEAT_EDDSA_SIGN_ED25519, \
- S390_FEAT_EDDSA_SIGN_ED448, \
- S390_FEAT_EEDDSA_SIGN_ED25519, \
- S390_FEAT_EEDDSA_SIGN_ED448, \
+ S390_FEAT_KDSA_ECDSA_VERIFY_P256, \
+ S390_FEAT_KDSA_ECDSA_VERIFY_P384, \
+ S390_FEAT_KDSA_ECDSA_VERIFY_P512, \
+ S390_FEAT_KDSA_ECDSA_SIGN_P256, \
+ S390_FEAT_KDSA_ECDSA_SIGN_P384, \
+ S390_FEAT_KDSA_ECDSA_SIGN_P512, \
+ S390_FEAT_KDSA_EECDSA_SIGN_P256, \
+ S390_FEAT_KDSA_EECDSA_SIGN_P384, \
+ S390_FEAT_KDSA_EECDSA_SIGN_P512, \
+ S390_FEAT_KDSA_EDDSA_VERIFY_ED25519, \
+ S390_FEAT_KDSA_EDDSA_VERIFY_ED448, \
+ S390_FEAT_KDSA_EDDSA_SIGN_ED25519, \
+ S390_FEAT_KDSA_EDDSA_SIGN_ED448, \
+ S390_FEAT_KDSA_EEDDSA_SIGN_ED25519, \
+ S390_FEAT_KDSA_EEDDSA_SIGN_ED448, \
S390_FEAT_PCC_SCALAR_MULT_P256, \
S390_FEAT_PCC_SCALAR_MULT_P384, \
S390_FEAT_PCC_SCALAR_MULT_P512, \
#include "sysemu/sysemu.h"
#include "sysemu/tcg.h"
#include "trace.h"
-#include "qapi/qapi-types-misc.h"
+#include "qapi/qapi-types-machine.h"
QemuMutex qemu_sigp_mutex;
#include "cpu.h"
#include "monitor/monitor.h"
#include "monitor/hmp-target.h"
-#include "hmp.h"
+#include "monitor/hmp.h"
static void print_tlb(Monitor *mon, int idx, tlb_t *tlb)
{
#include "cpu.h"
#include "monitor/monitor.h"
#include "monitor/hmp-target.h"
-#include "hmp.h"
+#include "monitor/hmp.h"
void hmp_info_tlb(Monitor *mon, const QDict *qdict)
#define QUIET_NAN 0x7fc00000
#define ADD_NAN 0x7fc00001
+#define SQRT_NAN 0x7fc00004
#define DIV_NAN 0x7fc00008
#define MUL_NAN 0x7fc00002
#define FPU_FS PSW_USB_C
#define FPU_FZ PSW_USB_AV
#define FPU_FU PSW_USB_SAV
+#define float32_sqrt_nan make_float32(SQRT_NAN)
+#define float32_quiet_nan make_float32(QUIET_NAN)
+
/* we don't care about input_denormal */
static inline uint8_t f_get_excp_flags(CPUTriCoreState *env)
{
}
+/*
+ * Target TriCore QSEED.F significand Lookup Table
+ *
+ * The QSEED.F output significand depends on the least-significant
+ * exponent bit and the 6 most-significant significand bits.
+ *
+ * IEEE 754 float datatype
+ * partitioned into Sign (S), Exponent (E) and Significand (M):
+ *
+ * S E E E E E E E E M M M M M M ...
+ * | | |
+ * +------+------+-------+-------+
+ * | |
+ * for lookup table
+ * calculating index for
+ * output E output M
+ *
+ * This lookup table was extracted by analyzing QSEED output
+ * from the real hardware
+ */
+static const uint8_t target_qseed_significand_table[128] = {
+ 253, 252, 245, 244, 239, 238, 231, 230, 225, 224, 217, 216,
+ 211, 210, 205, 204, 201, 200, 195, 194, 189, 188, 185, 184,
+ 179, 178, 175, 174, 169, 168, 165, 164, 161, 160, 157, 156,
+ 153, 152, 149, 148, 145, 144, 141, 140, 137, 136, 133, 132,
+ 131, 130, 127, 126, 123, 122, 121, 120, 117, 116, 115, 114,
+ 111, 110, 109, 108, 103, 102, 99, 98, 93, 92, 89, 88, 83,
+ 82, 79, 78, 75, 74, 71, 70, 67, 66, 63, 62, 59, 58, 55,
+ 54, 53, 52, 49, 48, 45, 44, 43, 42, 39, 38, 37, 36, 33,
+ 32, 31, 30, 27, 26, 25, 24, 23, 22, 19, 18, 17, 16, 15,
+ 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2
+};
+
+uint32_t helper_qseed(CPUTriCoreState *env, uint32_t r1)
+{
+ uint32_t arg1, S, E, M, E_minus_one, m_idx;
+ uint32_t new_E, new_M, new_S, result;
+
+ arg1 = make_float32(r1);
+
+ /* fetch IEEE-754 fields S, E and the uppermost 6-bit of M */
+ S = extract32(arg1, 31, 1);
+ E = extract32(arg1, 23, 8);
+ M = extract32(arg1, 17, 6);
+
+ if (float32_is_any_nan(arg1)) {
+ result = float32_quiet_nan;
+ } else if (float32_is_zero_or_denormal(arg1)) {
+ if (float32_is_neg(arg1)) {
+ result = float32_infinity | (1 << 31);
+ } else {
+ result = float32_infinity;
+ }
+ } else if (float32_is_neg(arg1)) {
+ result = float32_sqrt_nan;
+ } else if (float32_is_infinity(arg1)) {
+ result = float32_zero;
+ } else {
+ E_minus_one = E - 1;
+ m_idx = ((E_minus_one & 1) << 6) | M;
+ new_S = S;
+ new_E = 0xBD - E_minus_one / 2;
+ new_M = target_qseed_significand_table[m_idx];
+
+ result = 0;
+ result = deposit32(result, 31, 1, new_S);
+ result = deposit32(result, 23, 8, new_E);
+ result = deposit32(result, 15, 8, new_M);
+ }
+
+ if (float32_is_signaling_nan(arg1, &env->fp_status)
+ || result == float32_sqrt_nan) {
+ env->FPU_FI = 1 << 31;
+ env->FPU_FS = 1;
+ } else {
+ env->FPU_FS = 0;
+ }
+
+ return (uint32_t) result;
+}
+
uint32_t helper_fdiv(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
{
uint32_t flags;
return (uint32_t)f_result;
}
+uint32_t helper_utof(CPUTriCoreState *env, uint32_t arg)
+{
+ float32 f_result;
+ uint32_t flags;
+
+ f_result = uint32_to_float32(arg, &env->fp_status);
+
+ flags = f_get_excp_flags(env);
+ if (flags) {
+ f_update_psw_flags(env, flags);
+ } else {
+ env->FPU_FS = 0;
+ }
+ return (uint32_t)f_result;
+}
+
+uint32_t helper_ftoiz(CPUTriCoreState *env, uint32_t arg)
+{
+ float32 f_arg = make_float32(arg);
+ uint32_t result;
+ int32_t flags;
+
+ result = float32_to_int32_round_to_zero(f_arg, &env->fp_status);
+
+ flags = f_get_excp_flags(env);
+ if (flags & float_flag_invalid) {
+ flags &= ~float_flag_inexact;
+ if (float32_is_any_nan(f_arg)) {
+ result = 0;
+ }
+ }
+
+ if (flags) {
+ f_update_psw_flags(env, flags);
+ } else {
+ env->FPU_FS = 0;
+ }
+
+ return result;
+}
+
uint32_t helper_ftouz(CPUTriCoreState *env, uint32_t arg)
{
float32 f_arg = make_float32(arg);
DEF_HELPER_4(fmadd, i32, env, i32, i32, i32)
DEF_HELPER_4(fmsub, i32, env, i32, i32, i32)
DEF_HELPER_3(fcmp, i32, env, i32, i32)
+DEF_HELPER_2(qseed, i32, env, i32)
DEF_HELPER_2(ftoi, i32, env, i32)
DEF_HELPER_2(itof, i32, env, i32)
+DEF_HELPER_2(utof, i32, env, i32)
+DEF_HELPER_2(ftoiz, i32, env, i32)
DEF_HELPER_2(ftouz, i32, env, i32)
DEF_HELPER_2(updfl, void, env, i32)
/* dvinit */
case OPC2_32_RR_UPDFL:
gen_helper_updfl(cpu_env, cpu_gpr_d[r1]);
break;
+ case OPC2_32_RR_UTOF:
+ gen_helper_utof(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
+ break;
+ case OPC2_32_RR_FTOIZ:
+ gen_helper_ftoiz(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
+ break;
+ case OPC2_32_RR_QSEED_F:
+ gen_helper_qseed(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1]);
+ break;
default:
generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
}
}
break;
case OPC2_32_RRPW_INSERT:
- if (pos + width <= 31) {
+ if (pos + width <= 32) {
tcg_gen_deposit_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
- width, pos);
+ pos, width);
}
break;
default:
ctx.singlestep_enabled = cs->singlestep_enabled;
ctx.bstate = BS_NONE;
ctx.mem_idx = cpu_mmu_index(env, false);
+ ctx.hflags = (uint32_t)tb->flags;
tcg_clear_temp_count();
gen_tb_start(tb);
#include "cpu.h"
#include "monitor/monitor.h"
#include "monitor/hmp-target.h"
-#include "hmp.h"
+#include "monitor/hmp.h"
void hmp_info_tlb(Monitor *mon, const QDict *qdict)
{
check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
check-qtest-arm-y += tests/boot-serial-test$(EXESUF)
check-qtest-arm-y += tests/hexloader-test$(EXESUF)
+check-qtest-arm-$(CONFIG_PFLASH_CFI02) += tests/pflash-cfi02-test$(EXESUF)
check-qtest-aarch64-y = tests/numa-test$(EXESUF)
check-qtest-aarch64-y += tests/boot-serial-test$(EXESUF)
tests/rtc-test$(EXESUF): tests/rtc-test.o
tests/m48t59-test$(EXESUF): tests/m48t59-test.o
tests/hexloader-test$(EXESUF): tests/hexloader-test.o
+tests/pflash-cfi02$(EXESUF): tests/pflash-cfi02-test.o
tests/endianness-test$(EXESUF): tests/endianness-test.o
tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y)
tests/rtas-test$(EXESUF): tests/rtas-test.o $(libqos-spapr-obj-y)
SRC_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..', '..', '..')
sys.path.append(os.path.join(SRC_ROOT_DIR, 'python'))
-from qemu import QEMUMachine
+from qemu.machine import QEMUMachine
def is_readable_executable_file(path):
return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK)
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu import QEMUMachine
+from qemu.machine import QEMUMachine
from avocado_qemu import Test
# Virtio Device IDs:
mxe-$TARGET-w64-mingw32.shared-curl \
mxe-$TARGET-w64-mingw32.shared-glib \
mxe-$TARGET-w64-mingw32.shared-libgcrypt \
- mxe-$TARGET-w64-mingw32.shared-libssh2 \
mxe-$TARGET-w64-mingw32.shared-libusb1 \
mxe-$TARGET-w64-mingw32.shared-lzo \
mxe-$TARGET-w64-mingw32.shared-nettle \
mxe-$TARGET-w64-mingw32.shared-curl \
mxe-$TARGET-w64-mingw32.shared-glib \
mxe-$TARGET-w64-mingw32.shared-libgcrypt \
- mxe-$TARGET-w64-mingw32.shared-libssh2 \
mxe-$TARGET-w64-mingw32.shared-libusb1 \
mxe-$TARGET-w64-mingw32.shared-lzo \
mxe-$TARGET-w64-mingw32.shared-nettle \
libpng-devel \
librbd-devel \
libseccomp-devel \
- libssh2-devel \
+ libssh-devel \
libubsan \
libusbx-devel \
libxml2-devel \
mingw32-gtk3 \
mingw32-libjpeg-turbo \
mingw32-libpng \
- mingw32-libssh2 \
mingw32-libtasn1 \
mingw32-nettle \
mingw32-pixman \
mingw64-gtk3 \
mingw64-libjpeg-turbo \
mingw64-libpng \
- mingw64-libssh2 \
mingw64-libtasn1 \
mingw64-nettle \
mingw64-pixman \
libsnappy-dev \
libspice-protocol-dev \
libspice-server-dev \
- libssh2-1-dev \
+ libssh-dev \
libusb-1.0-0-dev \
libusbredirhost-dev \
libvdeplug-dev \
libsnappy-dev \
libspice-protocol-dev \
libspice-server-dev \
- libssh2-1-dev \
+ libssh-dev \
libusb-1.0-0-dev \
libusbredirhost-dev \
libvdeplug-dev \
/* FIXME: { "microblaze", "any" }, doesn't work with -M none -cpu any */
/* FIXME: { "microblazeel", "any" }, doesn't work with -M none -cpu any */
{ "mips", "4Kc" },
- { "mipsel", "4Kc" },
+ { "mipsel", "I7200" },
{ "mips64", "20Kc" },
- { "mips64el", "20Kc" },
+ { "mips64el", "I6500" },
{ "moxie", "MoxieLite" },
{ "nios2", "FIXME" },
{ "or1k", "or1200" },
sys.path.append(os.path.join(os.path.dirname(__file__),
'..', '..', '..', 'python'))
-import qemu
+from qemu.machine import QEMUMachine
class Engine(object):
dstmonaddr = "/var/tmp/qemu-dst-%d-monitor.sock" % os.getpid()
srcmonaddr = "/var/tmp/qemu-src-%d-monitor.sock" % os.getpid()
- src = qemu.QEMUMachine(self._binary,
- args=self._get_src_args(hardware),
- wrapper=self._get_src_wrapper(hardware),
- name="qemu-src-%d" % os.getpid(),
- monitor_address=srcmonaddr)
-
- dst = qemu.QEMUMachine(self._binary,
- args=self._get_dst_args(hardware, uri),
- wrapper=self._get_dst_wrapper(hardware),
- name="qemu-dst-%d" % os.getpid(),
- monitor_address=dstmonaddr)
+ src = QEMUMachine(self._binary,
+ args=self._get_src_args(hardware),
+ wrapper=self._get_src_wrapper(hardware),
+ name="qemu-src-%d" % os.getpid(),
+ monitor_address=srcmonaddr)
+
+ dst = QEMUMachine(self._binary,
+ args=self._get_dst_args(hardware, uri),
+ wrapper=self._get_dst_wrapper(hardware),
+ name="qemu-dst-%d" % os.getpid(),
+ monitor_address=dstmonaddr)
try:
src.launch()
--- /dev/null
+/*
+ * QTest testcase for parallel flash with AMD command set
+ *
+ * Copyright (c) 2019 Stephen Checkoway
+ *
+ * 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 "libqtest.h"
+
+/*
+ * To test the pflash_cfi02 device, we run QEMU with the musicpal machine with
+ * a pflash drive. This enables us to test some flash configurations, but not
+ * all. In particular, we're limited to a 16-bit wide flash device.
+ */
+
+#define MP_FLASH_SIZE_MAX (32 * 1024 * 1024)
+#define BASE_ADDR (0x100000000ULL - MP_FLASH_SIZE_MAX)
+
+#define UNIFORM_FLASH_SIZE (8 * 1024 * 1024)
+#define UNIFORM_FLASH_SECTOR_SIZE (64 * 1024)
+
+/* Use a newtype to keep flash addresses separate from byte addresses. */
+typedef struct {
+ uint64_t addr;
+} faddr;
+#define FLASH_ADDR(x) ((faddr) { .addr = (x) })
+
+#define CFI_ADDR FLASH_ADDR(0x55)
+#define UNLOCK0_ADDR FLASH_ADDR(0x555)
+#define UNLOCK1_ADDR FLASH_ADDR(0x2AA)
+
+#define CFI_CMD 0x98
+#define UNLOCK0_CMD 0xAA
+#define UNLOCK1_CMD 0x55
+#define SECOND_UNLOCK_CMD 0x80
+#define AUTOSELECT_CMD 0x90
+#define RESET_CMD 0xF0
+#define PROGRAM_CMD 0xA0
+#define SECTOR_ERASE_CMD 0x30
+#define CHIP_ERASE_CMD 0x10
+#define UNLOCK_BYPASS_CMD 0x20
+#define UNLOCK_BYPASS_RESET_CMD 0x00
+#define ERASE_SUSPEND_CMD 0xB0
+#define ERASE_RESUME_CMD SECTOR_ERASE_CMD
+
+typedef struct {
+ int bank_width;
+
+ /* Nonuniform block size. */
+ int nb_blocs[4];
+ int sector_len[4];
+
+ QTestState *qtest;
+} FlashConfig;
+
+static char image_path[] = "/tmp/qtest.XXXXXX";
+
+/*
+ * The pflash implementation allows some parameters to be unspecified. We want
+ * to test those configurations but we also need to know the real values in
+ * our testing code. So after we launch qemu, we'll need a new FlashConfig
+ * with the correct values filled in.
+ */
+static FlashConfig expand_config_defaults(const FlashConfig *c)
+{
+ FlashConfig ret = *c;
+
+ if (ret.bank_width == 0) {
+ ret.bank_width = 2;
+ }
+ if (ret.nb_blocs[0] == 0 && ret.sector_len[0] == 0) {
+ ret.sector_len[0] = UNIFORM_FLASH_SECTOR_SIZE;
+ ret.nb_blocs[0] = UNIFORM_FLASH_SIZE / UNIFORM_FLASH_SECTOR_SIZE;
+ }
+
+ /* XXX: Limitations of test harness. */
+ assert(ret.bank_width == 2);
+ return ret;
+}
+
+/*
+ * Return a bit mask suitable for extracting the least significant
+ * status/query response from an interleaved response.
+ */
+static inline uint64_t device_mask(const FlashConfig *c)
+{
+ return (uint64_t)-1;
+}
+
+/*
+ * Return a bit mask exactly as long as the bank_width.
+ */
+static inline uint64_t bank_mask(const FlashConfig *c)
+{
+ if (c->bank_width == 8) {
+ return (uint64_t)-1;
+ }
+ return (1ULL << (c->bank_width * 8)) - 1ULL;
+}
+
+static inline void flash_write(const FlashConfig *c, uint64_t byte_addr,
+ uint64_t data)
+{
+ /* Sanity check our tests. */
+ assert((data & ~bank_mask(c)) == 0);
+ uint64_t addr = BASE_ADDR + byte_addr;
+ switch (c->bank_width) {
+ case 1:
+ qtest_writeb(c->qtest, addr, data);
+ break;
+ case 2:
+ qtest_writew(c->qtest, addr, data);
+ break;
+ case 4:
+ qtest_writel(c->qtest, addr, data);
+ break;
+ case 8:
+ qtest_writeq(c->qtest, addr, data);
+ break;
+ default:
+ abort();
+ }
+}
+
+static inline uint64_t flash_read(const FlashConfig *c, uint64_t byte_addr)
+{
+ uint64_t addr = BASE_ADDR + byte_addr;
+ switch (c->bank_width) {
+ case 1:
+ return qtest_readb(c->qtest, addr);
+ case 2:
+ return qtest_readw(c->qtest, addr);
+ case 4:
+ return qtest_readl(c->qtest, addr);
+ case 8:
+ return qtest_readq(c->qtest, addr);
+ default:
+ abort();
+ }
+}
+
+/*
+ * Convert a flash address expressed in the maximum width of the device as a
+ * byte address.
+ */
+static inline uint64_t as_byte_addr(const FlashConfig *c, faddr flash_addr)
+{
+ /*
+ * Command addresses are always given as addresses in the maximum
+ * supported bus size for the flash chip. So an x8/x16 chip in x8 mode
+ * uses addresses 0xAAA and 0x555 to unlock because the least significant
+ * bit is ignored. (0x555 rather than 0x554 is traditional.)
+ *
+ * In general we need to multiply by the maximum device width.
+ */
+ return flash_addr.addr * c->bank_width;
+}
+
+/*
+ * Return the command value or expected status replicated across all devices.
+ */
+static inline uint64_t replicate(const FlashConfig *c, uint64_t data)
+{
+ /* Sanity check our tests. */
+ assert((data & ~device_mask(c)) == 0);
+ return data;
+}
+
+static inline void flash_cmd(const FlashConfig *c, faddr cmd_addr,
+ uint8_t cmd)
+{
+ flash_write(c, as_byte_addr(c, cmd_addr), replicate(c, cmd));
+}
+
+static inline uint64_t flash_query(const FlashConfig *c, faddr query_addr)
+{
+ return flash_read(c, as_byte_addr(c, query_addr));
+}
+
+static inline uint64_t flash_query_1(const FlashConfig *c, faddr query_addr)
+{
+ return flash_query(c, query_addr) & device_mask(c);
+}
+
+static void unlock(const FlashConfig *c)
+{
+ flash_cmd(c, UNLOCK0_ADDR, UNLOCK0_CMD);
+ flash_cmd(c, UNLOCK1_ADDR, UNLOCK1_CMD);
+}
+
+static void reset(const FlashConfig *c)
+{
+ flash_cmd(c, FLASH_ADDR(0), RESET_CMD);
+}
+
+static void sector_erase(const FlashConfig *c, uint64_t byte_addr)
+{
+ unlock(c);
+ flash_cmd(c, UNLOCK0_ADDR, SECOND_UNLOCK_CMD);
+ unlock(c);
+ flash_write(c, byte_addr, replicate(c, SECTOR_ERASE_CMD));
+}
+
+static void wait_for_completion(const FlashConfig *c, uint64_t byte_addr)
+{
+ /* If DQ6 is toggling, step the clock and ensure the toggle stops. */
+ const uint64_t dq6 = replicate(c, 0x40);
+ if ((flash_read(c, byte_addr) & dq6) ^ (flash_read(c, byte_addr) & dq6)) {
+ /* Wait for erase or program to finish. */
+ qtest_clock_step_next(c->qtest);
+ /* Ensure that DQ6 has stopped toggling. */
+ g_assert_cmphex(flash_read(c, byte_addr), ==, flash_read(c, byte_addr));
+ }
+}
+
+static void bypass_program(const FlashConfig *c, uint64_t byte_addr,
+ uint16_t data)
+{
+ flash_cmd(c, UNLOCK0_ADDR, PROGRAM_CMD);
+ flash_write(c, byte_addr, data);
+ /*
+ * Data isn't valid until DQ6 stops toggling. We don't model this as
+ * writes are immediate, but if this changes in the future, we can wait
+ * until the program is complete.
+ */
+ wait_for_completion(c, byte_addr);
+}
+
+static void program(const FlashConfig *c, uint64_t byte_addr, uint16_t data)
+{
+ unlock(c);
+ bypass_program(c, byte_addr, data);
+}
+
+static void chip_erase(const FlashConfig *c)
+{
+ unlock(c);
+ flash_cmd(c, UNLOCK0_ADDR, SECOND_UNLOCK_CMD);
+ unlock(c);
+ flash_cmd(c, UNLOCK0_ADDR, CHIP_ERASE_CMD);
+}
+
+static void erase_suspend(const FlashConfig *c)
+{
+ flash_cmd(c, FLASH_ADDR(0), ERASE_SUSPEND_CMD);
+}
+
+static void erase_resume(const FlashConfig *c)
+{
+ flash_cmd(c, FLASH_ADDR(0), ERASE_RESUME_CMD);
+}
+
+/*
+ * Test flash commands with a variety of device geometry.
+ */
+static void test_geometry(const void *opaque)
+{
+ const FlashConfig *config = opaque;
+ QTestState *qtest;
+ qtest = qtest_initf("-M musicpal,accel=qtest"
+ " -drive if=pflash,file=%s,format=raw,copy-on-read"
+ /* Device geometry properties. */
+ " -global driver=cfi.pflash02,"
+ "property=num-blocks0,value=%d"
+ " -global driver=cfi.pflash02,"
+ "property=sector-length0,value=%d"
+ " -global driver=cfi.pflash02,"
+ "property=num-blocks1,value=%d"
+ " -global driver=cfi.pflash02,"
+ "property=sector-length1,value=%d"
+ " -global driver=cfi.pflash02,"
+ "property=num-blocks2,value=%d"
+ " -global driver=cfi.pflash02,"
+ "property=sector-length2,value=%d"
+ " -global driver=cfi.pflash02,"
+ "property=num-blocks3,value=%d"
+ " -global driver=cfi.pflash02,"
+ "property=sector-length3,value=%d",
+ image_path,
+ config->nb_blocs[0],
+ config->sector_len[0],
+ config->nb_blocs[1],
+ config->sector_len[1],
+ config->nb_blocs[2],
+ config->sector_len[2],
+ config->nb_blocs[3],
+ config->sector_len[3]);
+ FlashConfig explicit_config = expand_config_defaults(config);
+ explicit_config.qtest = qtest;
+ const FlashConfig *c = &explicit_config;
+
+ /* Check the IDs. */
+ unlock(c);
+ flash_cmd(c, UNLOCK0_ADDR, AUTOSELECT_CMD);
+ g_assert_cmphex(flash_query(c, FLASH_ADDR(0)), ==, replicate(c, 0xBF));
+ if (c->bank_width >= 2) {
+ /*
+ * XXX: The ID returned by the musicpal flash chip is 16 bits which
+ * wouldn't happen with an 8-bit device. It would probably be best to
+ * prohibit addresses larger than the device width in pflash_cfi02.c,
+ * but then we couldn't test smaller device widths at all.
+ */
+ g_assert_cmphex(flash_query(c, FLASH_ADDR(1)), ==,
+ replicate(c, 0x236D));
+ }
+ reset(c);
+
+ /* Check the erase blocks. */
+ flash_cmd(c, CFI_ADDR, CFI_CMD);
+ g_assert_cmphex(flash_query(c, FLASH_ADDR(0x10)), ==, replicate(c, 'Q'));
+ g_assert_cmphex(flash_query(c, FLASH_ADDR(0x11)), ==, replicate(c, 'R'));
+ g_assert_cmphex(flash_query(c, FLASH_ADDR(0x12)), ==, replicate(c, 'Y'));
+
+ /* Num erase regions. */
+ int nb_erase_regions = flash_query_1(c, FLASH_ADDR(0x2C));
+ g_assert_cmphex(nb_erase_regions, ==,
+ !!c->nb_blocs[0] + !!c->nb_blocs[1] + !!c->nb_blocs[2] +
+ !!c->nb_blocs[3]);
+
+ /* Check device length. */
+ uint32_t device_len = 1 << flash_query_1(c, FLASH_ADDR(0x27));
+ g_assert_cmphex(device_len, ==, UNIFORM_FLASH_SIZE);
+
+ /* Check that erase suspend to read/write is supported. */
+ uint16_t pri = flash_query_1(c, FLASH_ADDR(0x15)) +
+ (flash_query_1(c, FLASH_ADDR(0x16)) << 8);
+ g_assert_cmpint(pri, >=, 0x2D + 4 * nb_erase_regions);
+ g_assert_cmpint(flash_query(c, FLASH_ADDR(pri + 0)), ==, replicate(c, 'P'));
+ g_assert_cmpint(flash_query(c, FLASH_ADDR(pri + 1)), ==, replicate(c, 'R'));
+ g_assert_cmpint(flash_query(c, FLASH_ADDR(pri + 2)), ==, replicate(c, 'I'));
+ g_assert_cmpint(flash_query_1(c, FLASH_ADDR(pri + 6)), ==, 2); /* R/W */
+ reset(c);
+
+ const uint64_t dq7 = replicate(c, 0x80);
+ const uint64_t dq6 = replicate(c, 0x40);
+ const uint64_t dq3 = replicate(c, 0x08);
+ const uint64_t dq2 = replicate(c, 0x04);
+
+ uint64_t byte_addr = 0;
+ for (int region = 0; region < nb_erase_regions; ++region) {
+ uint64_t base = 0x2D + 4 * region;
+ flash_cmd(c, CFI_ADDR, CFI_CMD);
+ uint32_t nb_sectors = flash_query_1(c, FLASH_ADDR(base + 0)) +
+ (flash_query_1(c, FLASH_ADDR(base + 1)) << 8) + 1;
+ uint32_t sector_len = (flash_query_1(c, FLASH_ADDR(base + 2)) << 8) +
+ (flash_query_1(c, FLASH_ADDR(base + 3)) << 16);
+ g_assert_cmphex(nb_sectors, ==, c->nb_blocs[region]);
+ g_assert_cmphex(sector_len, ==, c->sector_len[region]);
+ reset(c);
+
+ /* Erase and program sector. */
+ for (uint32_t i = 0; i < nb_sectors; ++i) {
+ sector_erase(c, byte_addr);
+
+ /* Check that DQ3 is 0. */
+ g_assert_cmphex(flash_read(c, byte_addr) & dq3, ==, 0);
+ qtest_clock_step_next(c->qtest); /* Step over the 50 us timeout. */
+
+ /* Check that DQ3 is 1. */
+ uint64_t status0 = flash_read(c, byte_addr);
+ g_assert_cmphex(status0 & dq3, ==, dq3);
+
+ /* DQ7 is 0 during an erase. */
+ g_assert_cmphex(status0 & dq7, ==, 0);
+ uint64_t status1 = flash_read(c, byte_addr);
+
+ /* DQ6 toggles during an erase. */
+ g_assert_cmphex(status0 & dq6, ==, ~status1 & dq6);
+
+ /* Wait for erase to complete. */
+ wait_for_completion(c, byte_addr);
+
+ /* Ensure DQ6 has stopped toggling. */
+ g_assert_cmphex(flash_read(c, byte_addr), ==,
+ flash_read(c, byte_addr));
+
+ /* Now the data should be valid. */
+ g_assert_cmphex(flash_read(c, byte_addr), ==, bank_mask(c));
+
+ /* Program a bit pattern. */
+ program(c, byte_addr, 0x55);
+ g_assert_cmphex(flash_read(c, byte_addr) & 0xFF, ==, 0x55);
+ program(c, byte_addr, 0xA5);
+ g_assert_cmphex(flash_read(c, byte_addr) & 0xFF, ==, 0x05);
+ byte_addr += sector_len;
+ }
+ }
+
+ /* Erase the chip. */
+ chip_erase(c);
+ /* Read toggle. */
+ uint64_t status0 = flash_read(c, 0);
+ /* DQ7 is 0 during an erase. */
+ g_assert_cmphex(status0 & dq7, ==, 0);
+ uint64_t status1 = flash_read(c, 0);
+ /* DQ6 toggles during an erase. */
+ g_assert_cmphex(status0 & dq6, ==, ~status1 & dq6);
+ /* Wait for erase to complete. */
+ qtest_clock_step_next(c->qtest);
+ /* Ensure DQ6 has stopped toggling. */
+ g_assert_cmphex(flash_read(c, 0), ==, flash_read(c, 0));
+ /* Now the data should be valid. */
+
+ for (int region = 0; region < nb_erase_regions; ++region) {
+ for (uint32_t i = 0; i < c->nb_blocs[region]; ++i) {
+ uint64_t byte_addr = i * c->sector_len[region];
+ g_assert_cmphex(flash_read(c, byte_addr), ==, bank_mask(c));
+ }
+ }
+
+ /* Unlock bypass */
+ unlock(c);
+ flash_cmd(c, UNLOCK0_ADDR, UNLOCK_BYPASS_CMD);
+ bypass_program(c, 0 * c->bank_width, 0x01);
+ bypass_program(c, 1 * c->bank_width, 0x23);
+ bypass_program(c, 2 * c->bank_width, 0x45);
+ /*
+ * Test that bypass programming, unlike normal programming can use any
+ * address for the PROGRAM_CMD.
+ */
+ flash_cmd(c, FLASH_ADDR(3 * c->bank_width), PROGRAM_CMD);
+ flash_write(c, 3 * c->bank_width, 0x67);
+ wait_for_completion(c, 3 * c->bank_width);
+ flash_cmd(c, FLASH_ADDR(0), UNLOCK_BYPASS_RESET_CMD);
+ bypass_program(c, 4 * c->bank_width, 0x89); /* Should fail. */
+ g_assert_cmphex(flash_read(c, 0 * c->bank_width), ==, 0x01);
+ g_assert_cmphex(flash_read(c, 1 * c->bank_width), ==, 0x23);
+ g_assert_cmphex(flash_read(c, 2 * c->bank_width), ==, 0x45);
+ g_assert_cmphex(flash_read(c, 3 * c->bank_width), ==, 0x67);
+ g_assert_cmphex(flash_read(c, 4 * c->bank_width), ==, bank_mask(c));
+
+ /* Test ignored high order bits of address. */
+ flash_cmd(c, FLASH_ADDR(0x5555), UNLOCK0_CMD);
+ flash_cmd(c, FLASH_ADDR(0x2AAA), UNLOCK1_CMD);
+ flash_cmd(c, FLASH_ADDR(0x5555), AUTOSELECT_CMD);
+ g_assert_cmphex(flash_query(c, FLASH_ADDR(0)), ==, replicate(c, 0xBF));
+ reset(c);
+
+ /*
+ * Program a word on each sector, erase one or two sectors per region, and
+ * verify that all of those, and only those, are erased.
+ */
+ byte_addr = 0;
+ for (int region = 0; region < nb_erase_regions; ++region) {
+ for (int i = 0; i < config->nb_blocs[region]; ++i) {
+ program(c, byte_addr, 0);
+ byte_addr += config->sector_len[region];
+ }
+ }
+ unlock(c);
+ flash_cmd(c, UNLOCK0_ADDR, SECOND_UNLOCK_CMD);
+ unlock(c);
+ byte_addr = 0;
+ const uint64_t erase_cmd = replicate(c, SECTOR_ERASE_CMD);
+ for (int region = 0; region < nb_erase_regions; ++region) {
+ flash_write(c, byte_addr, erase_cmd);
+ if (c->nb_blocs[region] > 1) {
+ flash_write(c, byte_addr + c->sector_len[region], erase_cmd);
+ }
+ byte_addr += c->sector_len[region] * c->nb_blocs[region];
+ }
+
+ qtest_clock_step_next(c->qtest); /* Step over the 50 us timeout. */
+ wait_for_completion(c, 0);
+ byte_addr = 0;
+ for (int region = 0; region < nb_erase_regions; ++region) {
+ for (int i = 0; i < config->nb_blocs[region]; ++i) {
+ if (i < 2) {
+ g_assert_cmphex(flash_read(c, byte_addr), ==, bank_mask(c));
+ } else {
+ g_assert_cmphex(flash_read(c, byte_addr), ==, 0);
+ }
+ byte_addr += config->sector_len[region];
+ }
+ }
+
+ /* Test erase suspend/resume during erase timeout. */
+ sector_erase(c, 0);
+ /*
+ * Check that DQ 3 is 0 and DQ6 and DQ2 are toggling in the sector being
+ * erased as well as in a sector not being erased.
+ */
+ byte_addr = c->sector_len[0];
+ status0 = flash_read(c, 0);
+ status1 = flash_read(c, 0);
+ g_assert_cmpint(status0 & dq3, ==, 0);
+ g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
+ g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
+ status0 = flash_read(c, byte_addr);
+ status1 = flash_read(c, byte_addr);
+ g_assert_cmpint(status0 & dq3, ==, 0);
+ g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
+ g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
+
+ /*
+ * Check that after suspending, DQ6 does not toggle but DQ2 does toggle in
+ * an erase suspended sector but that neither toggle (we should be
+ * getting data) in a sector not being erased.
+ */
+ erase_suspend(c);
+ status0 = flash_read(c, 0);
+ status1 = flash_read(c, 0);
+ g_assert_cmpint(status0 & dq6, ==, status1 & dq6);
+ g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
+ g_assert_cmpint(flash_read(c, byte_addr), ==, flash_read(c, byte_addr));
+
+ /* Check that after resuming, DQ3 is 1 and DQ6 and DQ2 toggle. */
+ erase_resume(c);
+ status0 = flash_read(c, 0);
+ status1 = flash_read(c, 0);
+ g_assert_cmpint(status0 & dq3, ==, dq3);
+ g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
+ g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
+ status0 = flash_read(c, byte_addr);
+ status1 = flash_read(c, byte_addr);
+ g_assert_cmpint(status0 & dq3, ==, dq3);
+ g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
+ g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
+ wait_for_completion(c, 0);
+
+ /* Repeat this process but this time suspend after the timeout. */
+ sector_erase(c, 0);
+ qtest_clock_step_next(c->qtest);
+ /*
+ * Check that DQ 3 is 1 and DQ6 and DQ2 are toggling in the sector being
+ * erased as well as in a sector not being erased.
+ */
+ byte_addr = c->sector_len[0];
+ status0 = flash_read(c, 0);
+ status1 = flash_read(c, 0);
+ g_assert_cmpint(status0 & dq3, ==, dq3);
+ g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
+ g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
+ status0 = flash_read(c, byte_addr);
+ status1 = flash_read(c, byte_addr);
+ g_assert_cmpint(status0 & dq3, ==, dq3);
+ g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
+ g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
+
+ /*
+ * Check that after suspending, DQ6 does not toggle but DQ2 does toggle in
+ * an erase suspended sector but that neither toggle (we should be
+ * getting data) in a sector not being erased.
+ */
+ erase_suspend(c);
+ status0 = flash_read(c, 0);
+ status1 = flash_read(c, 0);
+ g_assert_cmpint(status0 & dq6, ==, status1 & dq6);
+ g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
+ g_assert_cmpint(flash_read(c, byte_addr), ==, flash_read(c, byte_addr));
+
+ /* Check that after resuming, DQ3 is 1 and DQ6 and DQ2 toggle. */
+ erase_resume(c);
+ status0 = flash_read(c, 0);
+ status1 = flash_read(c, 0);
+ g_assert_cmpint(status0 & dq3, ==, dq3);
+ g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
+ g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
+ status0 = flash_read(c, byte_addr);
+ status1 = flash_read(c, byte_addr);
+ g_assert_cmpint(status0 & dq3, ==, dq3);
+ g_assert_cmpint(status0 & dq6, ==, ~status1 & dq6);
+ g_assert_cmpint(status0 & dq2, ==, ~status1 & dq2);
+ wait_for_completion(c, 0);
+
+ qtest_quit(qtest);
+}
+
+/*
+ * Test that
+ * 1. enter autoselect mode;
+ * 2. enter CFI mode; and then
+ * 3. exit CFI mode
+ * leaves the flash device in autoselect mode.
+ */
+static void test_cfi_in_autoselect(const void *opaque)
+{
+ const FlashConfig *config = opaque;
+ QTestState *qtest;
+ qtest = qtest_initf("-M musicpal,accel=qtest"
+ " -drive if=pflash,file=%s,format=raw,copy-on-read",
+ image_path);
+ FlashConfig explicit_config = expand_config_defaults(config);
+ explicit_config.qtest = qtest;
+ const FlashConfig *c = &explicit_config;
+
+ /* 1. Enter autoselect. */
+ unlock(c);
+ flash_cmd(c, UNLOCK0_ADDR, AUTOSELECT_CMD);
+ g_assert_cmphex(flash_query(c, FLASH_ADDR(0)), ==, replicate(c, 0xBF));
+
+ /* 2. Enter CFI. */
+ flash_cmd(c, CFI_ADDR, CFI_CMD);
+ g_assert_cmphex(flash_query(c, FLASH_ADDR(0x10)), ==, replicate(c, 'Q'));
+ g_assert_cmphex(flash_query(c, FLASH_ADDR(0x11)), ==, replicate(c, 'R'));
+ g_assert_cmphex(flash_query(c, FLASH_ADDR(0x12)), ==, replicate(c, 'Y'));
+
+ /* 3. Exit CFI. */
+ reset(c);
+ g_assert_cmphex(flash_query(c, FLASH_ADDR(0)), ==, replicate(c, 0xBF));
+
+ qtest_quit(qtest);
+}
+
+static void cleanup(void *opaque)
+{
+ unlink(image_path);
+}
+
+/*
+ * XXX: Tests are limited to bank_width = 2 for now because that's what
+ * hw/arm/musicpal.c has.
+ */
+static const FlashConfig configuration[] = {
+ /* One x16 device. */
+ {
+ .bank_width = 2,
+ },
+ /* Nonuniform sectors (top boot). */
+ {
+ .bank_width = 2,
+ .nb_blocs = { 127, 1, 2, 1 },
+ .sector_len = { 0x10000, 0x08000, 0x02000, 0x04000 },
+ },
+ /* Nonuniform sectors (bottom boot). */
+ {
+ .bank_width = 2,
+ .nb_blocs = { 1, 2, 1, 127 },
+ .sector_len = { 0x04000, 0x02000, 0x08000, 0x10000 },
+ },
+};
+
+int main(int argc, char **argv)
+{
+ int fd = mkstemp(image_path);
+ if (fd == -1) {
+ g_printerr("Failed to create temporary file %s: %s\n", image_path,
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ if (ftruncate(fd, UNIFORM_FLASH_SIZE) < 0) {
+ int error_code = errno;
+ close(fd);
+ unlink(image_path);
+ g_printerr("Failed to truncate file %s to %u MB: %s\n", image_path,
+ UNIFORM_FLASH_SIZE, strerror(error_code));
+ exit(EXIT_FAILURE);
+ }
+ close(fd);
+
+ qtest_add_abrt_handler(cleanup, NULL);
+ g_test_init(&argc, &argv, NULL);
+
+ size_t nb_configurations = sizeof configuration / sizeof configuration[0];
+ for (size_t i = 0; i < nb_configurations; ++i) {
+ const FlashConfig *config = &configuration[i];
+ char *path = g_strdup_printf("pflash-cfi02"
+ "/geometry/%dx%x-%dx%x-%dx%x-%dx%x"
+ "/%d",
+ config->nb_blocs[0],
+ config->sector_len[0],
+ config->nb_blocs[1],
+ config->sector_len[1],
+ config->nb_blocs[2],
+ config->sector_len[2],
+ config->nb_blocs[3],
+ config->sector_len[3],
+ config->bank_width);
+ qtest_add_data_func(path, config, test_geometry);
+ g_free(path);
+ }
+
+ qtest_add_data_func("pflash-cfi02/cfi-in-autoselect", &configuration[0],
+ test_cfi_in_autoselect);
+ int result = g_test_run();
+ cleanup(NULL);
+ return result;
+}
0x140000000 0x10000 0x50000 TEST_DIR/t-s003.vmdk
=== Testing afl image with a very large capacity ===
-qemu-img: Can't get image size 'TEST_DIR/afl9.IMGFMT': File too large
+qemu-img: Could not open 'TEST_DIR/afl9.IMGFMT': L1 size too big
*** done
echo "== reading whole image =="
$QEMU_IO --object $SECRET -c "read 0 $size" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir
+echo
+echo "== rewriting cluster part =="
+$QEMU_IO --object $SECRET -c "write -P 0xb 512 512" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir
+
+echo
+echo "== verify pattern =="
+$QEMU_IO --object $SECRET -c "read -P 0 0 512" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir
+$QEMU_IO --object $SECRET -c "read -P 0xb 512 512" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir
+
echo
echo "== rewriting whole image =="
$QEMU_IO --object $SECRET -c "write -P 0xa 0 $size" --image-opts $IMGSPEC | _filter_qemu_io | _filter_testdir
read 134217728/134217728 bytes at offset 0
128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+== rewriting cluster part ==
+wrote 512/512 bytes at offset 512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verify pattern ==
+read 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 512/512 bytes at offset 512
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
== rewriting whole image ==
wrote 134217728/134217728 bytes at offset 0
128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
import time
from iotests import qemu_img_create, qemu_io, filter_qemu_io, QemuIoInteractive
-nbd_sock = 'nbd_sock'
+nbd_sock = os.path.join(iotests.test_dir, 'nbd_sock')
nbd_uri = 'nbd+unix:///exp?socket=' + nbd_sock
disk = os.path.join(iotests.test_dir, 'disk')
iotests.img_info_log(remote_path)
- md5_key = subprocess.check_output(
- 'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' +
- 'cut -d" " -f3 | base64 -d | md5sum -b | cut -d" " -f1',
- shell=True).rstrip().decode('ascii')
+ keys = subprocess.check_output(
+ 'ssh-keyscan 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' +
+ 'cut -d" " -f3',
+ shell=True).rstrip().decode('ascii').split('\n')
+
+ # Mappings of base64 representations to digests
+ md5_keys = {}
+ sha1_keys = {}
+
+ for key in keys:
+ md5_keys[key] = subprocess.check_output(
+ 'echo %s | base64 -d | md5sum -b | cut -d" " -f1' % key,
+ shell=True).rstrip().decode('ascii')
+
+ sha1_keys[key] = subprocess.check_output(
+ 'echo %s | base64 -d | sha1sum -b | cut -d" " -f1' % key,
+ shell=True).rstrip().decode('ascii')
vm.launch()
+
+ # Find correct key first
+ matching_key = None
+ for key in keys:
+ result = vm.qmp('blockdev-add',
+ driver='ssh', node_name='node0', path=disk_path,
+ server={
+ 'host': '127.0.0.1',
+ 'port': '22',
+ }, host_key_check={
+ 'mode': 'hash',
+ 'type': 'md5',
+ 'hash': md5_keys[key],
+ })
+
+ if 'error' not in result:
+ vm.qmp('blockdev-del', node_name='node0')
+ matching_key = key
+ break
+
+ if matching_key is None:
+ vm.shutdown()
+ iotests.notrun('Did not find a key that fits 127.0.0.1')
+
blockdev_create(vm, { 'driver': 'ssh',
'location': {
'path': disk_path,
'host-key-check': {
'mode': 'hash',
'type': 'md5',
- 'hash': md5_key,
+ 'hash': md5_keys[matching_key],
}
},
'size': 8388608 })
iotests.img_info_log(remote_path)
- sha1_key = subprocess.check_output(
- 'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' +
- 'cut -d" " -f3 | base64 -d | sha1sum -b | cut -d" " -f1',
- shell=True).rstrip().decode('ascii')
-
vm.launch()
blockdev_create(vm, { 'driver': 'ssh',
'location': {
'host-key-check': {
'mode': 'hash',
'type': 'sha1',
- 'hash': sha1_key,
+ 'hash': sha1_keys[matching_key],
}
},
'size': 4194304 })
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"mode": "none"}, "path": "/this/is/not/an/existing/path", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 4194304}}}
{"return": {}}
-Job failed: failed to open remote file '/this/is/not/an/existing/path': Failed opening remote file (libssh2 error code: -31)
+Job failed: failed to open remote file '/this/is/not/an/existing/path': SFTP server: No such file (libssh error code: 1, sftp error code: 2)
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu import QEMUMachine
+from qemu.machine import QEMUMachine
# Note:
# This test was added to check that mirror dead-lock was fixed (see previous
auto_finalize = False)
self.assert_qmp(result, 'return', {})
- # We can't remove hd2 while the stream job is ongoing
+ # We can remove hd2 while the stream job is ongoing
opts['backing']['backing'] = None
- self.reopen(opts, {}, "Cannot change 'backing' link from 'hd1' to 'hd2'")
+ self.reopen(opts, {})
# We can't remove hd1 while the stream job is ongoing
opts['backing'] = None
}
#define DO_MSA__WD__WD_WT(suffix, mnemonic) \
-static inline void do_msa_##suffix(void *input1, void *input2, \
- void *output) \
+static inline void do_msa_##suffix(const void *input1, \
+ const void *input2, \
+ const void *output) \
{ \
__asm__ volatile ( \
"move $t0, %0\n\t" \
}
#define DO_MSA__WD__WS_WD(suffix, mnemonic) \
-static inline void do_msa_##suffix(void *input1, void *input2, \
- void *output) \
+static inline void do_msa_##suffix(const void *input1, \
+ const void *input2, \
+ const void *output) \
{ \
__asm__ volatile ( \
"move $t0, %0\n\t" \
*/
DO_MSA__WD__WS_WT(BINSL_B, binsl.b)
+DO_MSA__WD__WD_WT(BINSL_B__DDT, binsl.b)
+DO_MSA__WD__WS_WD(BINSL_B__DSD, binsl.b)
DO_MSA__WD__WS_WT(BINSL_H, binsl.h)
+DO_MSA__WD__WD_WT(BINSL_H__DDT, binsl.h)
+DO_MSA__WD__WS_WD(BINSL_H__DSD, binsl.h)
DO_MSA__WD__WS_WT(BINSL_W, binsl.w)
+DO_MSA__WD__WD_WT(BINSL_W__DDT, binsl.w)
+DO_MSA__WD__WS_WD(BINSL_W__DSD, binsl.w)
DO_MSA__WD__WS_WT(BINSL_D, binsl.d)
+DO_MSA__WD__WD_WT(BINSL_D__DDT, binsl.d)
+DO_MSA__WD__WS_WD(BINSL_D__DSD, binsl.d)
DO_MSA__WD__WS_WT(BINSR_B, binsr.b)
+DO_MSA__WD__WD_WT(BINSR_B__DDT, binsr.b)
+DO_MSA__WD__WS_WD(BINSR_B__DSD, binsr.b)
DO_MSA__WD__WS_WT(BINSR_H, binsr.h)
+DO_MSA__WD__WD_WT(BINSR_H__DDT, binsr.h)
+DO_MSA__WD__WS_WD(BINSR_H__DSD, binsr.h)
DO_MSA__WD__WS_WT(BINSR_W, binsr.w)
+DO_MSA__WD__WD_WT(BINSR_W__DDT, binsr.w)
+DO_MSA__WD__WS_WD(BINSR_W__DSD, binsr.w)
DO_MSA__WD__WS_WT(BINSR_D, binsr.d)
+DO_MSA__WD__WD_WT(BINSR_D__DDT, binsr.d)
+DO_MSA__WD__WS_WD(BINSR_D__DSD, binsr.d)
DO_MSA__WD__WS_WT(BMNZ_V, bmnz.v)
+DO_MSA__WD__WD_WT(BMNZ_V__DDT, bmnz.v)
+DO_MSA__WD__WS_WD(BMNZ_V__DSD, bmnz.v)
DO_MSA__WD__WS_WT(BMZ_V, bmz.v)
+DO_MSA__WD__WD_WT(BMZ_V__DDT, bmz.v)
+DO_MSA__WD__WS_WD(BMZ_V__DSD, bmz.v)
DO_MSA__WD__WS_WT(BSEL_V, bsel.v)
+DO_MSA__WD__WD_WT(BSEL_V__DDT, bsel.v)
+DO_MSA__WD__WS_WD(BSEL_V__DSD, bsel.v)
/*
*/
DO_MSA__WD__WS_WT(MADD_Q_H, madd_q.h)
+DO_MSA__WD__WD_WT(MADD_Q_H__DDT, madd_q.h)
+DO_MSA__WD__WS_WD(MADD_Q_H__DSD, madd_q.h)
DO_MSA__WD__WS_WT(MADD_Q_W, madd_q.w)
+DO_MSA__WD__WD_WT(MADD_Q_W__DDT, madd_q.w)
+DO_MSA__WD__WS_WD(MADD_Q_W__DSD, madd_q.w)
DO_MSA__WD__WS_WT(MADDR_Q_H, maddr_q.h)
+DO_MSA__WD__WD_WT(MADDR_Q_H__DDT, maddr_q.h)
+DO_MSA__WD__WS_WD(MADDR_Q_H__DSD, maddr_q.h)
DO_MSA__WD__WS_WT(MADDR_Q_W, maddr_q.w)
+DO_MSA__WD__WD_WT(MADDR_Q_W__DDT, maddr_q.w)
+DO_MSA__WD__WS_WD(MADDR_Q_W__DSD, maddr_q.w)
DO_MSA__WD__WS_WT(MSUB_Q_H, msub_q.h)
+DO_MSA__WD__WD_WT(MSUB_Q_H__DDT, msub_q.h)
+DO_MSA__WD__WS_WD(MSUB_Q_H__DSD, msub_q.h)
DO_MSA__WD__WS_WT(MSUB_Q_W, msub_q.w)
+DO_MSA__WD__WD_WT(MSUB_Q_W__DDT, msub_q.w)
+DO_MSA__WD__WS_WD(MSUB_Q_W__DSD, msub_q.w)
DO_MSA__WD__WS_WT(MSUBR_Q_H, msubr_q.h)
+DO_MSA__WD__WD_WT(MSUBR_Q_H__DDT, msubr_q.h)
+DO_MSA__WD__WS_WD(MSUBR_Q_H__DSD, msubr_q.h)
DO_MSA__WD__WS_WT(MSUBR_Q_W, msubr_q.w)
+DO_MSA__WD__WD_WT(MSUBR_Q_W__DDT, msubr_q.w)
+DO_MSA__WD__WS_WD(MSUBR_Q_W__DSD, msubr_q.w)
DO_MSA__WD__WS_WT(MUL_Q_H, mul_q.h)
DO_MSA__WD__WS_WT(MUL_Q_W, mul_q.w)
DO_MSA__WD__WS_WT(DOTP_U_W, dotp_u.w)
DO_MSA__WD__WS_WT(DOTP_U_D, dotp_u.d)
+DO_MSA__WD__WS_WT(DPADD_S_H, dpadd_s.h)
+DO_MSA__WD__WD_WT(DPADD_S_H__DDT, dpadd_s.h)
+DO_MSA__WD__WS_WD(DPADD_S_H__DSD, dpadd_s.h)
+DO_MSA__WD__WS_WT(DPADD_S_W, dpadd_s.w)
+DO_MSA__WD__WD_WT(DPADD_S_W__DDT, dpadd_s.w)
+DO_MSA__WD__WS_WD(DPADD_S_W__DSD, dpadd_s.w)
+DO_MSA__WD__WS_WT(DPADD_S_D, dpadd_s.d)
+DO_MSA__WD__WD_WT(DPADD_S_D__DDT, dpadd_s.d)
+DO_MSA__WD__WS_WD(DPADD_S_D__DSD, dpadd_s.d)
+
+DO_MSA__WD__WS_WT(DPADD_U_H, dpadd_u.h)
+DO_MSA__WD__WD_WT(DPADD_U_H__DDT, dpadd_u.h)
+DO_MSA__WD__WS_WD(DPADD_U_H__DSD, dpadd_u.h)
+DO_MSA__WD__WS_WT(DPADD_U_W, dpadd_u.w)
+DO_MSA__WD__WD_WT(DPADD_U_W__DDT, dpadd_u.w)
+DO_MSA__WD__WS_WD(DPADD_U_W__DSD, dpadd_u.w)
+DO_MSA__WD__WS_WT(DPADD_U_D, dpadd_u.d)
+DO_MSA__WD__WD_WT(DPADD_U_D__DDT, dpadd_u.d)
+DO_MSA__WD__WS_WD(DPADD_U_D__DSD, dpadd_u.d)
+
+DO_MSA__WD__WS_WT(DPSUB_S_H, dpsub_s.h)
+DO_MSA__WD__WD_WT(DPSUB_S_H__DDT, dpsub_s.h)
+DO_MSA__WD__WS_WD(DPSUB_S_H__DSD, dpsub_s.h)
+DO_MSA__WD__WS_WT(DPSUB_S_W, dpsub_s.w)
+DO_MSA__WD__WD_WT(DPSUB_S_W__DDT, dpsub_s.w)
+DO_MSA__WD__WS_WD(DPSUB_S_W__DSD, dpsub_s.w)
+DO_MSA__WD__WS_WT(DPSUB_S_D, dpsub_s.d)
+DO_MSA__WD__WD_WT(DPSUB_S_D__DDT, dpsub_s.d)
+DO_MSA__WD__WS_WD(DPSUB_S_D__DSD, dpsub_s.d)
+
+DO_MSA__WD__WS_WT(DPSUB_U_H, dpsub_u.h)
+DO_MSA__WD__WD_WT(DPSUB_U_H__DDT, dpsub_u.h)
+DO_MSA__WD__WS_WD(DPSUB_U_H__DSD, dpsub_u.h)
+DO_MSA__WD__WS_WT(DPSUB_U_W, dpsub_u.w)
+DO_MSA__WD__WD_WT(DPSUB_U_W__DDT, dpsub_u.w)
+DO_MSA__WD__WS_WD(DPSUB_U_W__DSD, dpsub_u.w)
+DO_MSA__WD__WS_WT(DPSUB_U_D, dpsub_u.d)
+DO_MSA__WD__WD_WT(DPSUB_U_D__DDT, dpsub_u.d)
+DO_MSA__WD__WS_WD(DPSUB_U_D__DSD, dpsub_u.d)
+
/*
* Int Max Min
*/
DO_MSA__WD__WS_WT(MADDV_B, maddv.b)
+DO_MSA__WD__WD_WT(MADDV_B__DDT, maddv.b)
+DO_MSA__WD__WS_WD(MADDV_B__DSD, maddv.b)
DO_MSA__WD__WS_WT(MADDV_H, maddv.h)
+DO_MSA__WD__WD_WT(MADDV_H__DDT, maddv.h)
+DO_MSA__WD__WS_WD(MADDV_H__DSD, maddv.h)
DO_MSA__WD__WS_WT(MADDV_W, maddv.w)
+DO_MSA__WD__WD_WT(MADDV_W__DDT, maddv.w)
+DO_MSA__WD__WS_WD(MADDV_W__DSD, maddv.w)
DO_MSA__WD__WS_WT(MADDV_D, maddv.d)
+DO_MSA__WD__WD_WT(MADDV_D__DDT, maddv.d)
+DO_MSA__WD__WS_WD(MADDV_D__DSD, maddv.d)
DO_MSA__WD__WS_WT(MSUBV_B, msubv.b)
+DO_MSA__WD__WD_WT(MSUBV_B__DDT, msubv.b)
+DO_MSA__WD__WS_WD(MSUBV_B__DSD, msubv.b)
DO_MSA__WD__WS_WT(MSUBV_H, msubv.h)
+DO_MSA__WD__WD_WT(MSUBV_H__DDT, msubv.h)
+DO_MSA__WD__WS_WD(MSUBV_H__DSD, msubv.h)
DO_MSA__WD__WS_WT(MSUBV_W, msubv.w)
+DO_MSA__WD__WD_WT(MSUBV_W__DDT, msubv.w)
+DO_MSA__WD__WS_WD(MSUBV_W__DSD, msubv.w)
DO_MSA__WD__WS_WT(MSUBV_D, msubv.d)
+DO_MSA__WD__WD_WT(MSUBV_D__DDT, msubv.d)
+DO_MSA__WD__WS_WD(MSUBV_D__DSD, msubv.d)
DO_MSA__WD__WS_WT(MULV_B, mulv.b)
DO_MSA__WD__WS_WT(MULV_H, mulv.h)
DO_MSA__WD__WS_WT(XOR_V, xor.v)
+/*
+ * Move
+ * ----
+ */
+
+DO_MSA__WD__WS(MOVE_V, move.v)
+
+
/*
* Pack
* ----
--- /dev/null
+/*
+ * Test program for MSA instruction BINSL.B
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Bit Move";
+ char *instruction_name = "BINSL.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x9c71e7cc71675471ULL, 0x4767015ffe71c70cULL, }, /* 64 */
+ { 0x8c6be7cc29675571ULL, 0x4767015ffe7ba70cULL, },
+ { 0x8c6be7cc29625571ULL, 0x4b670b5efe7bb30cULL, },
+ { 0x8c6ae7cc29625541ULL, 0x4b670b5efe7bb30cULL, },
+ { 0x8caa01642982c541ULL, 0x1bf7bb1a143b33fcULL, },
+ { 0xfcbe01644d92c741ULL, 0x1bf7bb1a143f53fcULL, },
+ { 0xfcbe01644d93c741ULL, 0x12f7bb1a143f53fcULL, },
+ { 0xfcbe01604d93c709ULL, 0x12f7bb1a143f53fcULL, },
+ { 0xfc5eafa8cdd38b89ULL, 0x22d8cbfeaa2f5314ULL, }, /* 72 */
+ { 0xac5aafa8b9c38b89ULL, 0x22d8cbfeaa2b3314ULL, },
+ { 0xac5aafa8b9cf8b89ULL, 0x27d8c7ffaa2b2714ULL, },
+ { 0xac5aafa8b9cf8b81ULL, 0x27d8c7ffaa2b2714ULL, },
+ { 0x2c5a1748392fe301ULL, 0x87f187d9a84ba7a4ULL, },
+ { 0x7c4e17485d3fe201ULL, 0x87f187d9a842e7a4ULL, },
+ { 0x744e17485d31e201ULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, }, /* 80 */
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, }, /* 88 */
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x744f174c5f31e24fULL, 0x8df189d8a842e3a4ULL, },
+ { 0x8c6ae6cc28714240ULL, 0x49710958a862b30cULL, }, /* 96 */
+ { 0x8c6ae6cc28714240ULL, 0x49710958a862b30cULL, },
+ { 0x8c6ae6cc28714240ULL, 0x49710958a862b30cULL, },
+ { 0x8c6ae6cc28714240ULL, 0x49710958a862b30cULL, },
+ { 0xfcaa006428b1c240ULL, 0x09f18958282253fcULL, },
+ { 0xfcaa006428b1c240ULL, 0x09f18958282253fcULL, },
+ { 0xfcaa006428b1c240ULL, 0x09f18958282253fcULL, },
+ { 0xfcaa006428b1c240ULL, 0x09f18958282253fcULL, },
+ { 0xac4a80aca8f182c0ULL, 0x09f1c9d8a8222314ULL, }, /* 104 */
+ { 0xac4a80aca8f182c0ULL, 0x09f1c9d8a8222314ULL, },
+ { 0xac4a80aca8f182c0ULL, 0x09f1c9d8a8222314ULL, },
+ { 0xac4a80aca8f182c0ULL, 0x09f1c9d8a8222314ULL, },
+ { 0x744a004c2831e240ULL, 0x89f189d8a842e3a4ULL, },
+ { 0x744a004c2831e240ULL, 0x89f189d8a842e3a4ULL, },
+ { 0x744a004c2831e240ULL, 0x89f189d8a842e3a4ULL, },
+ { 0x744a004c2831e240ULL, 0x89f189d8a842e3a4ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_B__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_B__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction BINSL.D
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Bit Move";
+ char *instruction_name = "BINSL.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x9c71c71c71c71c71ULL, 0x4b6471c71c71c71cULL, }, /* 64 */
+ { 0x8871c71c71c71c71ULL, 0x4b670b5efe7bb00cULL, },
+ { 0x8871c71c71c71c71ULL, 0x4b670b5efe7bb00cULL, },
+ { 0x886bc71c71c71c71ULL, 0x4b670b5efe7bb00cULL, },
+ { 0x886bc71c71c71c71ULL, 0x12f70b5efe7bb00cULL, },
+ { 0xfbebc71c71c71c71ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xfbebc71c71c71c71ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xfbbfc71c71c71c71ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xfbbfc71c71c71c71ULL, 0x27dfbb1a153f52fcULL, }, /* 72 */
+ { 0xac3fc71c71c71c71ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0xac3fc71c71c71c71ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0xac5bc71c71c71c71ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x2c5bc71c71c71c71ULL, 0x8df0c6ffab2b2514ULL, },
+ { 0x705bc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x705bc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, }, /* 80 */
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, }, /* 88 */
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704fc71c71c71c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x886ae6cc28625c71ULL, 0x4b670b5ef942e2a4ULL, }, /* 96 */
+ { 0x886ae6cc28625c71ULL, 0x4b670b5ef942e2a4ULL, },
+ { 0x886ae6cc28625c71ULL, 0x4b670b5ef942e2a4ULL, },
+ { 0x886ae6cc28625c71ULL, 0x4b670b5ef942e2a4ULL, },
+ { 0xfbbe00634d93dc71ULL, 0x12f7bb1a1142e2a4ULL, },
+ { 0xfbbe00634d93dc71ULL, 0x12f7bb1a1142e2a4ULL, },
+ { 0xfbbe00634d93dc71ULL, 0x12f7bb1a1142e2a4ULL, },
+ { 0xfbbe00634d93dc71ULL, 0x12f7bb1a1142e2a4ULL, },
+ { 0xac5aaeaab9cf9c71ULL, 0x27d8c6ffa942e2a4ULL, }, /* 104 */
+ { 0xac5aaeaab9cf9c71ULL, 0x27d8c6ffa942e2a4ULL, },
+ { 0xac5aaeaab9cf9c71ULL, 0x27d8c6ffa942e2a4ULL, },
+ { 0xac5aaeaab9cf9c71ULL, 0x27d8c6ffa942e2a4ULL, },
+ { 0x704f164d5e31dc71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704f164d5e31dc71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704f164d5e31dc71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704f164d5e31dc71ULL, 0x8df188d8a942e2a4ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_D__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_D__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction BINSL.H
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Bit Move";
+ char *instruction_name = "BINSL.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x8871e6cc31c71c71ULL, 0x4b1c0b5ffe71b00cULL, }, /* 64 */
+ { 0x886be6cc21c75571ULL, 0x4b1c0b5ffe7bb00cULL, },
+ { 0x886be6cc28625571ULL, 0x4b1c0b5efe7bb00cULL, },
+ { 0x886ae6cc28625541ULL, 0x4b1c0b5efe7bb00cULL, },
+ { 0xfbaa00644862d541ULL, 0x121cbb1a153b52fcULL, },
+ { 0xfbbe00644862c741ULL, 0x121cbb1a153f52fcULL, },
+ { 0xfbbe00644d93c741ULL, 0x129cbb1a153f52fcULL, },
+ { 0xfbbe00604d93c709ULL, 0x129cbb1a153f52fcULL, },
+ { 0xac5eaea8ad93c709ULL, 0x279cc6feab2f2514ULL, }, /* 72 */
+ { 0xac5aaea8bd938b89ULL, 0x279cc6feab2b2514ULL, },
+ { 0xac5aaea8b9cf8b89ULL, 0x279cc6ffab2b2514ULL, },
+ { 0xac5aaea8b9cf8b81ULL, 0x279cc6ffab2b2514ULL, },
+ { 0x705a164859cf8b81ULL, 0x8d9c88d9a94be2a4ULL, },
+ { 0x704e164859cfe201ULL, 0x8d9c88d9a942e2a4ULL, },
+ { 0x704e16485e31e201ULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, }, /* 80 */
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, }, /* 88 */
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x704f164c5e31e24fULL, 0x8d9c88d8a942e2a4ULL, },
+ { 0x886ae6cc1e315540ULL, 0x4b640b58e942b2a4ULL, }, /* 96 */
+ { 0x886ae6cc1e315540ULL, 0x4b640b58e942b2a4ULL, },
+ { 0x886ae6cc1e315540ULL, 0x4b640b58e942b2a4ULL, },
+ { 0x886ae6cc1e315540ULL, 0x4b640b58e942b2a4ULL, },
+ { 0xfbaa00645e31d540ULL, 0x1364bb58094252a4ULL, },
+ { 0xfbaa00645e31d540ULL, 0x1364bb58094252a4ULL, },
+ { 0xfbaa00645e31d540ULL, 0x1364bb58094252a4ULL, },
+ { 0xfbaa00645e31d540ULL, 0x1364bb58094252a4ULL, },
+ { 0xac4aa8649e31d540ULL, 0x2364c6d8a94222a4ULL, }, /* 104 */
+ { 0xac4aa8649e31d540ULL, 0x2364c6d8a94222a4ULL, },
+ { 0xac4aa8649e31d540ULL, 0x2364c6d8a94222a4ULL, },
+ { 0xac4aa8649e31d540ULL, 0x2364c6d8a94222a4ULL, },
+ { 0x704a10645e31d540ULL, 0x8b6488d8a942e2a4ULL, },
+ { 0x704a10645e31d540ULL, 0x8b6488d8a942e2a4ULL, },
+ { 0x704a10645e31d540ULL, 0x8b6488d8a942e2a4ULL, },
+ { 0x704a10645e31d540ULL, 0x8b6488d8a942e2a4ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_H__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_H__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction BINSL.W
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Bit Move";
+ char *instruction_name = "BINSL.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x8869c71c71c71c71ULL, 0x4b670b5ffe79c71cULL, }, /* 64 */
+ { 0x8869c71c28471c71ULL, 0x4b670b5ffe7bb00cULL, },
+ { 0x8869c71c28471c71ULL, 0x4b670b5efe7bb00cULL, },
+ { 0x8869c71c28631c71ULL, 0x4b670b5efe7bb00cULL, },
+ { 0xfbb9c71c28631c71ULL, 0x12f7bb1a153bb00cULL, },
+ { 0xfbb9c71c4de31c71ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xfbb9c71c4de31c71ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xfbbdc71c4d931c71ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xac5dc71ccd931c71ULL, 0x27d8c6feab2f52fcULL, }, /* 72 */
+ { 0xac5dc71cb9931c71ULL, 0x27d8c6feab2b2514ULL, },
+ { 0xac5dc71cb9931c71ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0xac59c71cb9cf1c71ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x7049c71c39cf1c71ULL, 0x8df188d9a9432514ULL, },
+ { 0x7049c71c5e4f1c71ULL, 0x8df188d9a942e2a4ULL, },
+ { 0x7049c71c5e4f1c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, }, /* 80 */
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, }, /* 88 */
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704dc71c5e311c71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x886ae6cc28625c71ULL, 0x4b670b58f942e2a4ULL, }, /* 96 */
+ { 0x886ae6cc28625c71ULL, 0x4b670b58f942e2a4ULL, },
+ { 0x886ae6cc28625c71ULL, 0x4b670b58f942e2a4ULL, },
+ { 0x886ae6cc28625c71ULL, 0x4b670b58f942e2a4ULL, },
+ { 0xfbbae6cc4d93dc71ULL, 0x12f7bb581142e2a4ULL, },
+ { 0xfbbae6cc4d93dc71ULL, 0x12f7bb581142e2a4ULL, },
+ { 0xfbbae6cc4d93dc71ULL, 0x12f7bb581142e2a4ULL, },
+ { 0xfbbae6cc4d93dc71ULL, 0x12f7bb581142e2a4ULL, },
+ { 0xac5ae6ccb9cf9c71ULL, 0x27d8c6d8a942e2a4ULL, }, /* 104 */
+ { 0xac5ae6ccb9cf9c71ULL, 0x27d8c6d8a942e2a4ULL, },
+ { 0xac5ae6ccb9cf9c71ULL, 0x27d8c6d8a942e2a4ULL, },
+ { 0xac5ae6ccb9cf9c71ULL, 0x27d8c6d8a942e2a4ULL, },
+ { 0x704ae6cc5e31dc71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704ae6cc5e31dc71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704ae6cc5e31dc71ULL, 0x8df188d8a942e2a4ULL, },
+ { 0x704ae6cc5e31dc71ULL, 0x8df188d8a942e2a4ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_W__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSL_W__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction BINSR.B
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Bit Move";
+ char *instruction_name = "BINSR.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c72e60c70c21570ULL, 0xcb677bde7e7bc60cULL, }, /* 64 */
+ { 0x186ae60c68c25570ULL, 0xcb677bde7e7bc00cULL, },
+ { 0x086ae60c68625570ULL, 0x4b670b5e7e7bf00cULL, },
+ { 0x086ae60c28625540ULL, 0x4b670b5e7e7bf00cULL, },
+ { 0x096e800329634740ULL, 0x42f70b1a157ff01cULL, },
+ { 0x0b3e80030d63c740ULL, 0x42f70b1a153ff21cULL, },
+ { 0x1b3e80030d93c740ULL, 0x12f73b1a153fd21cULL, },
+ { 0x1bbe80234d93c708ULL, 0x12f73b1a153fd21cULL, },
+ { 0x1abaae2a4d97cb08ULL, 0x17d8367f2b3bd314ULL, }, /* 72 */
+ { 0x1cdaae2a799f8b08ULL, 0x17d8367f2b2bd514ULL, },
+ { 0x0cdaae2a79cf8b08ULL, 0x27d846ff2b2be514ULL, },
+ { 0x0c5aae2a39cf8b00ULL, 0x27d846ff2b2be514ULL, },
+ { 0x0c5f962d38c9a200ULL, 0x2df148d82922e400ULL, },
+ { 0x004f962d1ec1e200ULL, 0x2df148d82942e200ULL, },
+ { 0x104f962d1e31e200ULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, }, /* 80 */
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, }, /* 88 */
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x104f960d5e31e24eULL, 0x8df108d82942e200ULL, },
+ { 0x106ae60c2832e540ULL, 0x8bf309d82a43e000ULL, }, /* 96 */
+ { 0x106ae60c2832d540ULL, 0x8bf70bd82e4be000ULL, },
+ { 0x106ae60c2832d540ULL, 0x8b670bd87e4be000ULL, },
+ { 0x106ae60c2832d540ULL, 0x8b670bd87e4be000ULL, },
+ { 0x116e80032933c740ULL, 0x82f70bd8154fe000ULL, },
+ { 0x133e80032933c740ULL, 0x82f70bd8153fe000ULL, },
+ { 0x1b3e80032933c740ULL, 0x82f70bd8153fe000ULL, },
+ { 0x1b3e80032933c740ULL, 0x82f70bd8153fe000ULL, },
+ { 0x1c5a800a293f8b40ULL, 0x87d806d92b2be100ULL, }, /* 104 */
+ { 0x0c5a800a29cf8b40ULL, 0x27d846db2b2be100ULL, },
+ { 0x0c5a800a29cf8b40ULL, 0x27d846df2b2be100ULL, },
+ { 0x0c5a800a29cf8b40ULL, 0x27d846ff2b2be100ULL, },
+ { 0x105f800d2a318240ULL, 0x8dd908d82922e200ULL, },
+ { 0x104f800d2e318240ULL, 0x8dd908d82922e200ULL, },
+ { 0x104f800d5e318240ULL, 0x8dd908d82922e200ULL, },
+ { 0x104f800d5e318240ULL, 0x8dd908d82922e200ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_B__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_B__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction BINSR.D
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Bit Move";
+ char *instruction_name = "BINSR.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c70ULL, 0xc71c71c71c71d00cULL, }, /* 64 */
+ { 0x1c71c71c71c71d40ULL, 0xcb670b5efe7bb00cULL, },
+ { 0x1c71c71c71c71d40ULL, 0xcb670b5efe7bb00cULL, },
+ { 0x1c71c71c71c75540ULL, 0xcb670b5efe7bb00cULL, },
+ { 0x1c71c71c71c75540ULL, 0xcb670b5efe7bb2fcULL, },
+ { 0x1c71c71c71c75508ULL, 0xd2f7bb1a153f52fcULL, },
+ { 0x1c71c71c71c75508ULL, 0xd2f7bb1a153f52fcULL, },
+ { 0x1c71c71c71c74708ULL, 0xd2f7bb1a153f52fcULL, },
+ { 0x1c71c71c71c74708ULL, 0xd2f7bb1a153f4514ULL, }, /* 72 */
+ { 0x1c71c71c71c74780ULL, 0xc7d8c6ffab2b2514ULL, },
+ { 0x1c71c71c71c74780ULL, 0xc7d8c6ffab2b2514ULL, },
+ { 0x1c71c71c71c70b80ULL, 0xc7d8c6ffab2b2514ULL, },
+ { 0x1c71c71c71c70b80ULL, 0xc7d8c6ffab2b22a0ULL, },
+ { 0x1c71c71c71c70a4eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c70a4eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, }, /* 80 */
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, }, /* 88 */
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c7624eULL, 0xcdf188d8a942e2a0ULL, },
+ { 0x1c71c71c71c75540ULL, 0xcdf188d8fe7bb00cULL, }, /* 96 */
+ { 0x1c71c71c71c75540ULL, 0xcdf188d8fe7bb00cULL, },
+ { 0x1c71c71c71c75540ULL, 0xcdf188d8fe7bb00cULL, },
+ { 0x1c71c71c71c75540ULL, 0xcdf188d8fe7bb00cULL, },
+ { 0x1c71c71c71c75540ULL, 0xcdf188d8fe7bb2fcULL, },
+ { 0x1c71c71c71c75540ULL, 0xd2f7bb1a153f52fcULL, },
+ { 0x1c71c71c71c75540ULL, 0xd2f7bb1a153f52fcULL, },
+ { 0x1c71c71c71c75540ULL, 0xd2f7bb1a153f52fcULL, },
+ { 0x1c71c71c71c75540ULL, 0xc7d8c6ffab2b2514ULL, }, /* 104 */
+ { 0x1c71c71c71c75540ULL, 0xc7d8c6ffab2b2514ULL, },
+ { 0x1c71c71c71c75540ULL, 0xc7d8c6ffab2b2514ULL, },
+ { 0x1c71c71c71c75540ULL, 0xc7d8c6ffab2b2514ULL, },
+ { 0x1c71c71c71c75540ULL, 0xc7d8c6ffab22e2a0ULL, },
+ { 0x1c71c71c71c75540ULL, 0xc7d8c6fea942e2a0ULL, },
+ { 0x1c71c71c71c75540ULL, 0xc7d8c6fea942e2a0ULL, },
+ { 0x1c71c71c71c75540ULL, 0xc7d8c6fea942e2a0ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_D__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_D__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction BINSR.H
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Bit Move";
+ char *instruction_name = "BINSR.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x186ac6cc71c21c70ULL, 0xc7670b5e1e7bd00cULL, }, /* 64 */
+ { 0x086ac6cc71c21d40ULL, 0xc7670b5efe7bd00cULL, },
+ { 0x086ac6cc28621d40ULL, 0xc7670b5efe7bd00cULL, },
+ { 0x886ae6cc28625540ULL, 0xc7670b5efe7bd00cULL, },
+ { 0x8bbee06328635540ULL, 0xc7f73b1af53fd2fcULL, },
+ { 0xfbbee06328635508ULL, 0xc7f73b1a153fd2fcULL, },
+ { 0xfbbee0634d935508ULL, 0xc6f7bb1a153fd2fcULL, },
+ { 0xfbbec0634d934708ULL, 0xc6f7bb1a153fd2fcULL, },
+ { 0xfc5aceaa4d974708ULL, 0xc6d8c6ff1b2bc514ULL, }, /* 72 */
+ { 0xac5aceaa4d9f4780ULL, 0xc6d8c6ffab2bc514ULL, },
+ { 0xac5aceaab9cf4780ULL, 0xc7d8c6ffab2bc514ULL, },
+ { 0xac5aeeaab9cf0b80ULL, 0xc7d8c6ffab2bc514ULL, },
+ { 0xa84ff64db9c90b80ULL, 0xc7f188d8a942c2a0ULL, },
+ { 0xf04ff64db9c10a4eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0xf04ff64d5e310a4eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, }, /* 80 */
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, }, /* 88 */
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e31624eULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x886ae6cc5e325540ULL, 0xc7f3895ea943c2a0ULL, }, /* 96 */
+ { 0x886ae6cc5e325540ULL, 0xc7f78b5ea94bc2a0ULL, },
+ { 0x886ae6cc5e325540ULL, 0xc7678b5eae7bc2a0ULL, },
+ { 0x886ae6cc5e325540ULL, 0xc7678b5eae7bc2a0ULL, },
+ { 0x8bbee0635e335540ULL, 0xc7f7bb1aa53fc2a0ULL, },
+ { 0xfbbee0635e335540ULL, 0xc7f7bb1a153fc2a0ULL, },
+ { 0xfbbee0635e335540ULL, 0xc7f7bb1a153fc2a0ULL, },
+ { 0xfbbee0635e335540ULL, 0xc7f7bb1a153fc2a0ULL, },
+ { 0xac5ae06a5e3f5540ULL, 0xc7d8beffab2bc2a0ULL, }, /* 104 */
+ { 0xac5ae6aab9cf5540ULL, 0xc7d8c6ffab2bc2a0ULL, },
+ { 0xac5ae6aab9cf5540ULL, 0xc7d8c6ffab2bc2a0ULL, },
+ { 0xac5ae6aab9cf5540ULL, 0xc7d8c6ffab2bc2a0ULL, },
+ { 0xa84fe64d5e315540ULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e315540ULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e315540ULL, 0xc7f188d8a942c2a0ULL, },
+ { 0x704fd64d5e315540ULL, 0xc7f188d8a942c2a0ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_H__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_H__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction BINSR.W
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Bit Move";
+ char *instruction_name = "BINSR.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c6cc71c71c70ULL, 0xcb670b5e1c71d00cULL, }, /* 64 */
+ { 0x1c71c6cc71c71d40ULL, 0xcb670b5e1e7bb00cULL, },
+ { 0x1c71c6cc71c71d40ULL, 0x4b670b5e1e7bb00cULL, },
+ { 0x1c71e6cc71c75540ULL, 0x4b670b5e1e7bb00cULL, },
+ { 0x1c71e06371c75540ULL, 0x12f7bb1a1e7bb2fcULL, },
+ { 0x1c71e06371c75508ULL, 0x12f7bb1a153f52fcULL, },
+ { 0x1c71e06371c75508ULL, 0x12f7bb1a153f52fcULL, },
+ { 0x1c71c06371c74708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0x1c71ceaa71c74708ULL, 0x27d8c6ff153f4514ULL, }, /* 72 */
+ { 0x1c71ceaa71c74780ULL, 0x27d8c6ff0b2b2514ULL, },
+ { 0x1c71ceaa71c74780ULL, 0x27d8c6ff0b2b2514ULL, },
+ { 0x1c71eeaa71c70b80ULL, 0x27d8c6ff0b2b2514ULL, },
+ { 0x1c71f64d71c70b80ULL, 0x0df188d80b2b22a0ULL, },
+ { 0x1c71f64d71c70a4eULL, 0x0df188d80942e2a0ULL, },
+ { 0x1c71f64d71c70a4eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, }, /* 80 */
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, }, /* 88 */
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c7624eULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71e6cc71c75540ULL, 0x8d670b5e0942e2a0ULL, }, /* 96 */
+ { 0x1c71e6cc71c75540ULL, 0xcb670b5e0942e2a0ULL, },
+ { 0x1c71e6cc71c75540ULL, 0xcb670b5e0942e2a0ULL, },
+ { 0x1c71e6cc71c75540ULL, 0xcb670b5e0942e2a0ULL, },
+ { 0x1c71e06371c75540ULL, 0x92f7bb1a0942e2a0ULL, },
+ { 0x1c71e06371c75540ULL, 0x92f7bb1a0942e2a0ULL, },
+ { 0x1c71e06371c75540ULL, 0x92f7bb1a0942e2a0ULL, },
+ { 0x1c71e06371c75540ULL, 0x92f7bb1a0942e2a0ULL, },
+ { 0x1c71e06a71c75540ULL, 0x97d8c6ff0942e2a0ULL, }, /* 104 */
+ { 0x1c71e6aa71c75540ULL, 0x27d8c6ff0942e2a0ULL, },
+ { 0x1c71e6aa71c75540ULL, 0x27d8c6ff0942e2a0ULL, },
+ { 0x1c71e6aa71c75540ULL, 0x27d8c6ff0942e2a0ULL, },
+ { 0x1c71e64d71c75540ULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c75540ULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c75540ULL, 0x8df188d80942e2a0ULL, },
+ { 0x1c71d64d71c75540ULL, 0x8df188d80942e2a0ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_W__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BINSR_W__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction BMNZ.V
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Bit Move";
+ char *instruction_name = "BMNZ.V";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x9c7be7dc79e75d71ULL, 0xcf7f7bdffe7bf71cULL, }, /* 64 */
+ { 0x8c6be7dc38665d71ULL, 0xcf6f4bdffe7bb50cULL, },
+ { 0x886be7dc28625571ULL, 0xcb670b5efe7bb00cULL, },
+ { 0x886ae7dc28625571ULL, 0x4b670b5efe7bb00cULL, },
+ { 0x882a015008024531ULL, 0x02670b1a143b100cULL, },
+ { 0xfbbe01734d93c739ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xfbbe01734d93c739ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xfbbe01734d93c739ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xfbdea7bb6dd38339ULL, 0x13d0b25eab2f62f4ULL, }, /* 72 */
+ { 0xa85aa7ba29c38331ULL, 0x03d0825eab2b2014ULL, },
+ { 0xac5aafbab9cf8bb1ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0xac5aafbab9cf8bb1ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x245a0f7e99adcaf1ULL, 0x2df9ccf9a942a510ULL, },
+ { 0x744e0f5ddc3dcaf9ULL, 0x2df9ccf9a942e7a0ULL, },
+ { 0x704e075d5c31c279ULL, 0x0df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, }, /* 80 */
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, }, /* 88 */
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x704f175d5e31e27fULL, 0x8df188d8a942e2a0ULL, },
+ { 0x004a064c08204040ULL, 0x09610858a842a000ULL, }, /* 96 */
+ { 0x004a064c08204040ULL, 0x09610858a842a000ULL, },
+ { 0x004a064c08204040ULL, 0x09610858a842a000ULL, },
+ { 0x004a064c08204040ULL, 0x09610858a842a000ULL, },
+ { 0x000a004008004000ULL, 0x0061081800020000ULL, },
+ { 0x000a004008004000ULL, 0x0061081800020000ULL, },
+ { 0x000a004008004000ULL, 0x0061081800020000ULL, },
+ { 0x000a004008004000ULL, 0x0061081800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, }, /* 104 */
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BMNZ_V(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BMNZ_V(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BMNZ_V__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BMNZ_V__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction BMZ.V
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Bit Move";
+ char *instruction_name = "BMZ.V";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 24 */
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, }, /* 32 */
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, }, /* 40 */
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, }, /* 48 */
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, }, /* 56 */
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x0860c60c20421440ULL, 0x430401461c71800cULL, }, /* 64 */
+ { 0x0860e68c20621440ULL, 0x4b040146fe71a00cULL, },
+ { 0x0860e6cc20625440ULL, 0x4b270946fe71b00cULL, },
+ { 0x8860e6cc20625540ULL, 0x4b270b46fe79b00cULL, },
+ { 0xfbf4e6ef65f3d748ULL, 0x5bb7bb46ff7df2fcULL, },
+ { 0xfbb400634593c708ULL, 0x12b7bb02153d52fcULL, },
+ { 0xfbb400634593c708ULL, 0x12b7bb02153d52fcULL, },
+ { 0xfbb400634593c708ULL, 0x12b7bb02153d52fcULL, },
+ { 0xac300862918fcf80ULL, 0x26bfcfa31539151cULL, }, /* 72 */
+ { 0xac70aeeab1cfcf80ULL, 0x27bfcfe7bf39351cULL, },
+ { 0xac50aeaab1cf8b80ULL, 0x2798c6e7ab292514ULL, },
+ { 0xac50aeaab1cf8b80ULL, 0x2798c6e7ab292514ULL, },
+ { 0xf845b6897653a30eULL, 0x879082c6ab2962a4ULL, },
+ { 0xf845160d5633a34eULL, 0x8f9082c2a969e2a4ULL, },
+ { 0xf845164d5633e34eULL, 0x8fb18ac2a969e2a4ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, }, /* 80 */
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, }, /* 88 */
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0x7045164d5631e24eULL, 0x8db188c0a940e2a0ULL, },
+ { 0xf86ff6cd7e73f74eULL, 0xcff78bdeff7bf2acULL, }, /* 96 */
+ { 0xf86ff6cd7e73f74eULL, 0xcff78bdeff7bf2acULL, },
+ { 0xf86ff6cd7e73f74eULL, 0xcff78bdeff7bf2acULL, },
+ { 0xf86ff6cd7e73f74eULL, 0xcff78bdeff7bf2acULL, },
+ { 0xfbfff6ef7ff3f74eULL, 0xdff7bbdeff7ff2fcULL, },
+ { 0xfbfff6ef7ff3f74eULL, 0xdff7bbdeff7ff2fcULL, },
+ { 0xfbfff6ef7ff3f74eULL, 0xdff7bbdeff7ff2fcULL, },
+ { 0xfbfff6ef7ff3f74eULL, 0xdff7bbdeff7ff2fcULL, },
+ { 0xfffffeefffffffceULL, 0xffffffffff7ff7fcULL, }, /* 104 */
+ { 0xfffffeefffffffceULL, 0xffffffffff7ff7fcULL, },
+ { 0xfffffeefffffffceULL, 0xffffffffff7ff7fcULL, },
+ { 0xfffffeefffffffceULL, 0xffffffffff7ff7fcULL, },
+ { 0xfffffeefffffffceULL, 0xffffffffff7ff7fcULL, },
+ { 0xfffffeefffffffceULL, 0xffffffffff7ff7fcULL, },
+ { 0xfffffeefffffffceULL, 0xffffffffff7ff7fcULL, },
+ { 0xfffffeefffffffceULL, 0xffffffffff7ff7fcULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BMZ_V(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BMZ_V(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BMZ_V__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BMZ_V__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction BSEL.V
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Bit Move";
+ char *instruction_name = "BSEL.V";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xeeeeeeeeeeeeeeeeULL, 0xeeeeeeeeeeeeeeeeULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xefcefcefcefcefceULL, 0xfcefcefcefcefcefULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, }, /* 16 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0xaa8aa8aa8aa8aa8aULL, 0xa8aa8aa8aa8aa8aaULL, },
+ { 0x0820820820820820ULL, 0x8208208208208208ULL, },
+ { 0x5d75d75d75d75d75ULL, 0xd75d75d75d75d75dULL, }, /* 24 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0x1111111111111111ULL, 0x1111111111111111ULL, },
+ { 0x4544544544544544ULL, 0x5445445445445445ULL, },
+ { 0x1451451451451451ULL, 0x4514514514514514ULL, },
+ { 0xdcddcddcddcddcddULL, 0xcddcddcddcddcddcULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x4444444444444444ULL, 0x4444444444444444ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x0c40c40c40c40c40ULL, 0xc40c40c40c40c40cULL, },
+ { 0x3f73f73f73f73f73ULL, 0xf73f73f73f73f73fULL, }, /* 40 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x1111111111111111ULL, 0x1111111111111111ULL, },
+ { 0x2222222222222222ULL, 0x2222222222222222ULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0x2302302302302302ULL, 0x3023023023023023ULL, },
+ { 0x1031031031031031ULL, 0x0310310310310310ULL, },
+ { 0xf3bf3bf3bf3bf3bfULL, 0x3bf3bf3bf3bf3bf3ULL, }, /* 48 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x4104104104104104ULL, 0x1041041041041041ULL, },
+ { 0xe28e28e28e28e28eULL, 0x28e28e28e28e28e2ULL, },
+ { 0x2302302302302302ULL, 0x3023023023023023ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, }, /* 56 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x1451451451451451ULL, 0x4514514514514514ULL, },
+ { 0x0c60c60c60c60c60ULL, 0xc60c60c60c60c60cULL, },
+ { 0x1031031031031031ULL, 0x0310310310310310ULL, },
+ { 0x0c40c40c40c40c40ULL, 0xc40c40c40c40c40cULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0x882a004008024500ULL, 0x02670b1a143b100cULL, },
+ { 0x884ae68c28621140ULL, 0x4b40025eea6ba004ULL, },
+ { 0x006a064c08204440ULL, 0x09670958bc52b008ULL, },
+ { 0xfbfe066f4db3c748ULL, 0x1bf7bb5abd7ff2fcULL, },
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xa81a002209838300ULL, 0x02d0821a012b0014ULL, },
+ { 0x73ae00414c11c608ULL, 0x10f7b918151652e8ULL, },
+ { 0x8c7aaeeab9ce4d80ULL, 0x276f4fffbe3b351cULL, }, /* 72 */
+ { 0xa83a00620983c700ULL, 0x02f78b1a153b101cULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x204a060818018200ULL, 0x05d080d8a9022000ULL, },
+ { 0x504f164d4e30604eULL, 0x89610858a842e2a0ULL, },
+ { 0x700e00415c11c208ULL, 0x04f18898010242a0ULL, },
+ { 0x204b160c1a21a246ULL, 0x8dd080d8a942a000ULL, },
+ { 0x704f164d5e31e24eULL, 0x8df188d8a942e2a0ULL, },
+ { 0x004a064c08204040ULL, 0x09610858a842a000ULL, }, /* 80 */
+ { 0x000a004008004000ULL, 0x0061081800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, }, /* 88 */
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x000a000008000000ULL, 0x0040001800020000ULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 96 */
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, },
+ { 0xfbfee6ef6df3d748ULL, 0x5bf7bb5eff7ff2fcULL, },
+ { 0xfbfee6ef6df3d748ULL, 0x5bf7bb5eff7ff2fcULL, },
+ { 0xfbfee6ef6df3d748ULL, 0x5bf7bb5eff7ff2fcULL, },
+ { 0xfbfee6ef6df3d748ULL, 0x5bf7bb5eff7ff2fcULL, },
+ { 0xfffeeeeffdffdfc8ULL, 0x7fffffffff7ff7fcULL, }, /* 104 */
+ { 0xfffeeeeffdffdfc8ULL, 0x7fffffffff7ff7fcULL, },
+ { 0xfffeeeeffdffdfc8ULL, 0x7fffffffff7ff7fcULL, },
+ { 0xfffeeeeffdffdfc8ULL, 0x7fffffffff7ff7fcULL, },
+ { 0xfffffeefffffffceULL, 0xffffffffff7ff7fcULL, },
+ { 0xfffffeefffffffceULL, 0xffffffffff7ff7fcULL, },
+ { 0xfffffeefffffffceULL, 0xffffffffff7ff7fcULL, },
+ { 0xfffffeefffffffceULL, 0xffffffffff7ff7fcULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BSEL_V(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BSEL_V(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BSEL_V__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_BSEL_V__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MADD_Q.H
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
+ * Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Fixed Multiply";
+ char *instruction_name = "MADD_Q.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xfffefffefffefffeULL, 0xfffefffefffefffeULL, },
+ { 0xfffefffdfffefffeULL, 0xfffdfffefffefffdULL, },
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, },
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, }, /* 8 */
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, },
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, },
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, },
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, },
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, },
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, },
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, },
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, }, /* 16 */
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, },
+ { 0x38e138e138e138e1ULL, 0x38e138e138e138e1ULL, },
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, },
+ { 0x221f221f221f221fULL, 0x221f221f221f221fULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0x12f2da0f4bd712f2ULL, 0xda0f4bd712f2da0fULL, },
+ { 0xfffbfffcfffcfffbULL, 0xfffcfffcfffbfffcULL, },
+ { 0xfffafffbfffbfffaULL, 0xfffbfffbfffafffbULL, }, /* 24 */
+ { 0xfffafffbfffbfffaULL, 0xfffbfffbfffafffbULL, },
+ { 0xc716c717c717c716ULL, 0xc717c717c716c717ULL, },
+ { 0xfff9fffafffafff9ULL, 0xfffafffafff9fffaULL, },
+ { 0xddd6ddd7ddd7ddd6ULL, 0xddd7ddd7ddd6ddd7ULL, },
+ { 0xfff7fff8fff8fff7ULL, 0xfff8fff8fff7fff8ULL, },
+ { 0xed0025e4b41ded00ULL, 0x25e4b41ded0025e4ULL, },
+ { 0xfff5fff6fff6fff5ULL, 0xfff6fff6fff5fff6ULL, },
+ { 0xfff5fff6fff6fff5ULL, 0xfff6fff6fff5fff6ULL, }, /* 32 */
+ { 0xfff5fff6fff6fff5ULL, 0xfff6fff6fff5fff6ULL, },
+ { 0x2217221822182217ULL, 0x2218221822172218ULL, },
+ { 0xfff4fff5fff5fff4ULL, 0xfff5fff5fff4fff5ULL, },
+ { 0x146f14701470146fULL, 0x14701470146f1470ULL, },
+ { 0xfff3fff4fff4fff3ULL, 0xfff4fff4fff3fff4ULL, },
+ { 0x0b53e9322d770b53ULL, 0xe9322d770b53e932ULL, },
+ { 0xfff2fff3fff3fff2ULL, 0xfff3fff3fff2fff3ULL, },
+ { 0xfff1fff2fff2fff1ULL, 0xfff2fff2fff1fff2ULL, }, /* 40 */
+ { 0xfff1fff2fff2fff1ULL, 0xfff2fff2fff1fff2ULL, },
+ { 0xddceddcfddcfddceULL, 0xddcfddcfddceddcfULL, },
+ { 0xffeffff0fff0ffefULL, 0xfff0fff0ffeffff0ULL, },
+ { 0xeb73eb74eb74eb73ULL, 0xeb74eb74eb73eb74ULL, },
+ { 0xffedffeeffeeffedULL, 0xffeeffeeffedffeeULL, },
+ { 0xf48c16afd26af48cULL, 0x16afd26af48c16afULL, },
+ { 0xffecffedffecffecULL, 0xffedffecffecffedULL, },
+ { 0xffecffecffecffecULL, 0xffecffecffecffecULL, }, /* 48 */
+ { 0xffecffecffecffecULL, 0xffecffecffecffecULL, },
+ { 0x12e2d9ff4bc712e2ULL, 0xd9ff4bc712e2d9ffULL, },
+ { 0xffebffebffecffebULL, 0xffebffecffebffebULL, },
+ { 0x0b4be9292d6f0b4bULL, 0xe9292d6f0b4be929ULL, },
+ { 0xffeaffeaffebffeaULL, 0xffeaffebffeaffeaULL, },
+ { 0x063c1932650f063cULL, 0x1932650f063c1932ULL, },
+ { 0xffe9ffe9ffebffe9ULL, 0xffe9ffebffe9ffe9ULL, },
+ { 0xffe8ffe9ffeaffe8ULL, 0xffe9ffeaffe8ffe9ULL, }, /* 56 */
+ { 0xffe8ffe9ffeaffe8ULL, 0xffe9ffeaffe8ffe9ULL, },
+ { 0xecf125d6b40fecf1ULL, 0x25d6b40fecf125d6ULL, },
+ { 0xffe6ffe8ffe8ffe6ULL, 0xffe8ffe8ffe6ffe8ULL, },
+ { 0xf48516a9d264f485ULL, 0x16a9d264f48516a9ULL, },
+ { 0xffe5ffe7ffe6ffe5ULL, 0xffe7ffe6ffe5ffe7ULL, },
+ { 0xf992e69e9ac2f992ULL, 0xe69e9ac2f992e69eULL, },
+ { 0xffe3ffe7ffe4ffe3ULL, 0xffe7ffe4ffe3ffe7ULL, },
+ { 0x6f9c04dd0ca138aaULL, 0x2c5200e6ffe731d8ULL, }, /* 64 */
+ { 0x739604c9251a12b8ULL, 0x377dfac7ffa6fe02ULL, },
+ { 0x7fff14cc0ef4c520ULL, 0x4ef5f5b700a7e6d8ULL, },
+ { 0x171110672cabb158ULL, 0x0bc4eb2201aef931ULL, },
+ { 0x1b0b105345248b66ULL, 0x16efe503016dc55bULL, },
+ { 0x1b2f10537427a4c0ULL, 0x19be0a1804f3fb27ULL, },
+ { 0x1df71014499cd899ULL, 0x1fa528c6f6de1330ULL, },
+ { 0x1a3a10257fffe5d0ULL, 0x0ebe68e9e8780024ULL, },
+ { 0x6860202869d99838ULL, 0x263663d9e979e8faULL, }, /* 72 */
+ { 0x6b281fe93f4ecc11ULL, 0x2c1d7fffdb640103ULL, },
+ { 0x7fff539865cb3619ULL, 0x38847fff139c0bc0ULL, },
+ { 0x369a456c32245120ULL, 0x15027fff4d19033dULL, },
+ { 0xcdac41074fdb3d58ULL, 0xd1d1756a4e201596ULL, },
+ { 0xc9ef41187fff4a8fULL, 0xc0ea7fff3fba028aULL, },
+ { 0x808a32ec4c586596ULL, 0x9d687fff7937fa07ULL, },
+ { 0xe31436ce7fff6c79ULL, 0x030a7fff7fff00c4ULL, },
+ { 0xfe192c037fff7fffULL, 0x04d47fff7e7a0049ULL, }, /* 80 */
+ { 0xfe292c257fff4707ULL, 0x058b3b197fff0078ULL, },
+ { 0xff5c101739ce0661ULL, 0x074420c72b2a009aULL, },
+ { 0xfecc12e4645704e6ULL, 0x00ca02430de90076ULL, },
+ { 0xffeb0f2b7fff0829ULL, 0x014002760dbe002cULL, },
+ { 0xffeb0f367fff0487ULL, 0x016f012210050048ULL, },
+ { 0xfff8058b39ce0068ULL, 0x01e100a00567005cULL, },
+ { 0xfff006826457004fULL, 0x0034000b01bd0046ULL, },
+ { 0xfffe05397fff0083ULL, 0x0052000b01b7001aULL, }, /* 88 */
+ { 0xfffe053d7fff0048ULL, 0x005e000501ff002aULL, },
+ { 0xffff01e839ce0006ULL, 0x007b000200ac0036ULL, },
+ { 0xfffe023d64570004ULL, 0x000d000000370029ULL, },
+ { 0xffff01cc7fff0006ULL, 0x001400000036000fULL, },
+ { 0xffff01cd7fff0003ULL, 0x00160000003e0018ULL, },
+ { 0xffff00a839ce0000ULL, 0x001c00000014001eULL, },
+ { 0xfffe00c564570000ULL, 0x0003000000060017ULL, },
+ { 0xffff009e7fff0000ULL, 0x0004000000050008ULL, }, /* 96 */
+ { 0xffff007e7fff0000ULL, 0x0006000000040003ULL, },
+ { 0xffff00657fff0000ULL, 0x0009000000030001ULL, },
+ { 0xffff00517fff0000ULL, 0x000e000000020000ULL, },
+ { 0xffff00517fff0000ULL, 0x0010000000020000ULL, },
+ { 0xffff00517fff0000ULL, 0x0012000000020000ULL, },
+ { 0xffff00517fff0000ULL, 0x0014000000020000ULL, },
+ { 0xffff00517fff0000ULL, 0x0016000000020000ULL, },
+ { 0xffff001d39ce0000ULL, 0x001c000000000000ULL, }, /* 104 */
+ { 0xffff000a1a1b0000ULL, 0x0024000000000000ULL, },
+ { 0xffff00030bca0000ULL, 0x002f000000000000ULL, },
+ { 0xffff000105530000ULL, 0x003d000000000000ULL, },
+ { 0xfffe0001093d0000ULL, 0x0006000000000000ULL, },
+ { 0xfffc000110090000ULL, 0x0000000000000000ULL, },
+ { 0xfff800011bd50000ULL, 0x0000000000000000ULL, },
+ { 0xfff0000130500000ULL, 0x0000000000000000ULL, },
+};
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADD_Q_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADD_Q_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADD_Q_H__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADD_Q_H__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MADD_Q.W
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
+ * Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Fixed Multiply";
+ char *instruction_name = "MADD_Q.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xfffffffefffffffeULL, 0xfffffffefffffffeULL, },
+ { 0xfffffffefffffffeULL, 0xfffffffdfffffffeULL, },
+ { 0xfffffffdfffffffdULL, 0xfffffffdfffffffdULL, },
+ { 0xfffffffdfffffffdULL, 0xfffffffdfffffffdULL, }, /* 8 */
+ { 0xfffffffdfffffffdULL, 0xfffffffdfffffffdULL, },
+ { 0xfffffffdfffffffdULL, 0xfffffffdfffffffdULL, },
+ { 0xfffffffdfffffffdULL, 0xfffffffdfffffffdULL, },
+ { 0xfffffffdfffffffdULL, 0xfffffffdfffffffdULL, },
+ { 0xfffffffdfffffffdULL, 0xfffffffdfffffffdULL, },
+ { 0xfffffffdfffffffdULL, 0xfffffffdfffffffdULL, },
+ { 0xfffffffdfffffffdULL, 0xfffffffdfffffffdULL, },
+ { 0xfffffffdfffffffdULL, 0xfffffffdfffffffdULL, }, /* 16 */
+ { 0xfffffffdfffffffdULL, 0xfffffffdfffffffdULL, },
+ { 0x38e38e3638e38e36ULL, 0x38e38e3638e38e36ULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0x2222221e2222221eULL, 0x2222221e2222221eULL, },
+ { 0xfffffffbfffffffbULL, 0xfffffffbfffffffbULL, },
+ { 0x12f684b94bda12f2ULL, 0xda12f68012f684b9ULL, },
+ { 0xfffffffbfffffffbULL, 0xfffffffbfffffffbULL, },
+ { 0xfffffffafffffffaULL, 0xfffffffafffffffaULL, }, /* 24 */
+ { 0xfffffffafffffffaULL, 0xfffffffafffffffaULL, },
+ { 0xc71c71c0c71c71c0ULL, 0xc71c71c0c71c71c0ULL, },
+ { 0xfffffff8fffffff8ULL, 0xfffffff8fffffff8ULL, },
+ { 0xddddddd5ddddddd5ULL, 0xddddddd5ddddddd5ULL, },
+ { 0xfffffff6fffffff6ULL, 0xfffffff6fffffff6ULL, },
+ { 0xed097b38b425ecffULL, 0x25ed0970ed097b38ULL, },
+ { 0xfffffff5fffffff4ULL, 0xfffffff4fffffff5ULL, },
+ { 0xfffffff5fffffff4ULL, 0xfffffff4fffffff5ULL, }, /* 32 */
+ { 0xfffffff5fffffff4ULL, 0xfffffff4fffffff5ULL, },
+ { 0x2222221722222216ULL, 0x2222221622222217ULL, },
+ { 0xfffffff4fffffff3ULL, 0xfffffff3fffffff4ULL, },
+ { 0x147ae13c147ae13bULL, 0x147ae13b147ae13cULL, },
+ { 0xfffffff4fffffff3ULL, 0xfffffff3fffffff4ULL, },
+ { 0x0b60b5ff2d82d821ULL, 0xe93e93dc0b60b5ffULL, },
+ { 0xfffffff3fffffff3ULL, 0xfffffff3fffffff3ULL, },
+ { 0xfffffff2fffffff2ULL, 0xfffffff2fffffff2ULL, }, /* 40 */
+ { 0xfffffff2fffffff2ULL, 0xfffffff2fffffff2ULL, },
+ { 0xddddddcfddddddcfULL, 0xddddddcfddddddcfULL, },
+ { 0xfffffff0fffffff0ULL, 0xfffffff0fffffff0ULL, },
+ { 0xeb851ea8eb851ea8ULL, 0xeb851ea8eb851ea8ULL, },
+ { 0xffffffefffffffefULL, 0xffffffefffffffefULL, },
+ { 0xf49f49e3d27d27c1ULL, 0x16c16c05f49f49e3ULL, },
+ { 0xffffffeeffffffeeULL, 0xffffffeeffffffeeULL, },
+ { 0xffffffeeffffffeeULL, 0xffffffedffffffeeULL, }, /* 48 */
+ { 0xffffffeeffffffeeULL, 0xffffffedffffffeeULL, },
+ { 0x12f684ac4bda12e5ULL, 0xda12f67212f684acULL, },
+ { 0xffffffeeffffffeeULL, 0xffffffecffffffeeULL, },
+ { 0x0b60b5f92d82d81cULL, 0xe93e93d50b60b5f9ULL, },
+ { 0xffffffedffffffeeULL, 0xffffffebffffffedULL, },
+ { 0x06522c2c6522c3e1ULL, 0x1948b0e706522c2cULL, },
+ { 0xffffffecffffffeeULL, 0xffffffeaffffffecULL, },
+ { 0xffffffebffffffedULL, 0xffffffeaffffffebULL, }, /* 56 */
+ { 0xffffffebffffffedULL, 0xffffffeaffffffebULL, },
+ { 0xed097b2db425ecf6ULL, 0x25ed0965ed097b2dULL, },
+ { 0xffffffeaffffffebULL, 0xffffffe9ffffffeaULL, },
+ { 0xf49f49ded27d27bdULL, 0x16c16c00f49f49deULL, },
+ { 0xffffffe9ffffffeaULL, 0xffffffe9ffffffe9ULL, },
+ { 0xf9add3a99add3bf7ULL, 0xe6b74eecf9add3a9ULL, },
+ { 0xffffffe8ffffffe8ULL, 0xffffffe8ffffffe8ULL, },
+ { 0x6fb7e8710cbdc0baULL, 0x2c6b142e000499ecULL, }, /* 64 */
+ { 0x73b239bf253787bbULL, 0x379780d7ffc424b2ULL, },
+ { 0x7fffffff0f12777aULL, 0x4f10996a00c57ee6ULL, },
+ { 0x1713a7162cca6b1fULL, 0x0be04dd301cca255ULL, },
+ { 0x1b0df86445443220ULL, 0x170cba7c018c2d1bULL, },
+ { 0x1b323a657448a831ULL, 0x19dc4690051313a9ULL, },
+ { 0x1dfa85ec49be7952ULL, 0x1fc3e11af6fe2ffbULL, },
+ { 0x1a3e24c87fffffffULL, 0x0edd19b6e8983fd8ULL, },
+ { 0x6863454e69daefbeULL, 0x26563249e9999a0cULL, }, /* 72 */
+ { 0x6b2b90d53f50c0dfULL, 0x2c3dccd3db84b65eULL, },
+ { 0x7fffffff65cdd2a2ULL, 0x38a5553713bd77aaULL, },
+ { 0x369baa383226e26fULL, 0x1523c32e4d39d083ULL, },
+ { 0xcdaf514f4fded614ULL, 0xd1f377974e40f3f2ULL, },
+ { 0xc9f2f02b7fffffffULL, 0xc10cb0333fdb03cfULL, },
+ { 0x808e9a644c590fccULL, 0x9d8b1e2a79575ca8ULL, },
+ { 0xe31932487fffffffULL, 0x032ce40b7fffffffULL, },
+ { 0xfe196fe57fffffffULL, 0x050bc0117e7bb00bULL, }, /* 80 */
+ { 0xfe299f467fffffffULL, 0x05cb2b207fffffffULL, },
+ { 0xff5d018239cf8b7fULL, 0x0798e21e2b2b2513ULL, },
+ { 0xfecdfe1e645a7d99ULL, 0x00d3dcf00dea608dULL, },
+ { 0xffebe0507fffffffULL, 0x0150aaf30dc02967ULL, },
+ { 0xffec8bad7fffffffULL, 0x01828e9310087db0ULL, },
+ { 0xfff9423b39cf8b7fULL, 0x01fae4ad056841b8ULL, },
+ { 0xfff35804645a7d99ULL, 0x003737ba01be3861ULL, },
+ { 0xffff2aee7fffffffULL, 0x0057bed401b8eeafULL, }, /* 88 */
+ { 0xffff32047fffffffULL, 0x0064bf7c02021ffbULL, },
+ { 0xffffb89f39cf8b7fULL, 0x00841c7300ad6409ULL, },
+ { 0xffff79fe645a7d99ULL, 0x000e642e0037e4a5ULL, },
+ { 0xfffff72f7fffffffULL, 0x0016de7600373b15ULL, },
+ { 0xfffff77a7fffffffULL, 0x001a420100406619ULL, },
+ { 0xfffffd0b39cf8b7fULL, 0x00226e950015b801ULL, },
+ { 0xfffffa72645a7d99ULL, 0x0003c03400070049ULL, },
+ { 0xffffffa27fffffffULL, 0x0005f5d70006eb0bULL, }, /* 96 */
+ { 0xfffffff97fffffffULL, 0x000978af0006d60eULL, },
+ { 0xffffffff7fffffffULL, 0x000f0d050006c150ULL, },
+ { 0xffffffff7fffffffULL, 0x0017eac30006acd1ULL, },
+ { 0xffffffff7fffffffULL, 0x001b76100007c878ULL, },
+ { 0xffffffff7fffffffULL, 0x001f87d000091335ULL, },
+ { 0xffffffff7fffffffULL, 0x002433ef000a94d9ULL, },
+ { 0xffffffff7fffffffULL, 0x0029914d000c5680ULL, },
+ { 0xffffffff39cf8b7fULL, 0x003681f800042937ULL, }, /* 104 */
+ { 0xffffffff1a1c28c3ULL, 0x004779e10001673fULL, },
+ { 0xffffffff0bcae025ULL, 0x005dba1000007928ULL, },
+ { 0xffffffff055376c1ULL, 0x007ae77c000028dcULL, },
+ { 0xfffffffe093ed554ULL, 0x000d636d00000d2bULL, },
+ { 0xfffffffc100c9463ULL, 0x0001755c0000043eULL, },
+ { 0xfffffff81bdc128cULL, 0x000028ab0000015eULL, },
+ { 0xfffffff0305c8babULL, 0x0000046e00000070ULL, },
+};
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADD_Q_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADD_Q_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADD_Q_W__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADD_Q_W__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MADDR_Q.H
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
+ * Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Fixed Multiply";
+ char *instruction_name = "MADDR_Q.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000010000ULL, 0x0000000100000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, }, /* 16 */
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x38e538e538e538e5ULL, 0x38e538e538e538e5ULL, },
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x2224222422242224ULL, 0x2224222422242224ULL, },
+ { 0x0002000200020002ULL, 0x0002000200020002ULL, },
+ { 0x12f9da154bdd12f9ULL, 0xda154bdd12f9da15ULL, },
+ { 0x0003000300020003ULL, 0x0003000200030003ULL, },
+ { 0x0002000200010002ULL, 0x0002000100020002ULL, }, /* 24 */
+ { 0x0002000200010002ULL, 0x0002000100020002ULL, },
+ { 0xc71ec71ec71dc71eULL, 0xc71ec71dc71ec71eULL, },
+ { 0x0001000100000001ULL, 0x0001000000010001ULL, },
+ { 0xdddedddedddddddeULL, 0xdddedddddddedddeULL, },
+ { 0x00000000ffff0000ULL, 0x0000ffff00000000ULL, },
+ { 0xed0925edb425ed09ULL, 0x25edb425ed0925edULL, },
+ { 0xffff0000ffffffffULL, 0x0000ffffffff0000ULL, },
+ { 0xffff0000ffffffffULL, 0x0000ffffffff0000ULL, }, /* 32 */
+ { 0xffff0000ffffffffULL, 0x0000ffffffff0000ULL, },
+ { 0x2222222322222222ULL, 0x2223222222222223ULL, },
+ { 0xffff0000ffffffffULL, 0x0000ffffffff0000ULL, },
+ { 0x147b147c147b147bULL, 0x147c147b147b147cULL, },
+ { 0x0000000100000000ULL, 0x0001000000000001ULL, },
+ { 0x0b61e93f2d840b61ULL, 0xe93f2d840b61e93fULL, },
+ { 0x0000000100000000ULL, 0x0001000000000001ULL, },
+ { 0x0000000100000000ULL, 0x0001000000000001ULL, }, /* 40 */
+ { 0x0000000100000000ULL, 0x0001000000000001ULL, },
+ { 0xdddedddfdddedddeULL, 0xdddfdddedddedddfULL, },
+ { 0x0000000100000000ULL, 0x0001000000000001ULL, },
+ { 0xeb85eb86eb85eb85ULL, 0xeb86eb85eb85eb86ULL, },
+ { 0x0000000100000000ULL, 0x0001000000000001ULL, },
+ { 0xf49f16c2d27df49fULL, 0x16c2d27df49f16c2ULL, },
+ { 0xffff00000000ffffULL, 0x00000000ffff0000ULL, },
+ { 0xffff00000001ffffULL, 0x00000001ffff0000ULL, }, /* 48 */
+ { 0xffff00000001ffffULL, 0x00000001ffff0000ULL, },
+ { 0x12f6da134bdc12f6ULL, 0xda134bdc12f6da13ULL, },
+ { 0xffff00000002ffffULL, 0x00000002ffff0000ULL, },
+ { 0x0b60e93e2d860b60ULL, 0xe93e2d860b60e93eULL, },
+ { 0xffffffff0003ffffULL, 0xffff0003ffffffffULL, },
+ { 0x0651194765270651ULL, 0x1947652706511947ULL, },
+ { 0xfffffffe0004ffffULL, 0xfffe0004fffffffeULL, },
+ { 0xfffffffe0003ffffULL, 0xfffe0003fffffffeULL, }, /* 56 */
+ { 0xfffffffe0003ffffULL, 0xfffe0003fffffffeULL, },
+ { 0xed0925ecb428ed09ULL, 0x25ecb428ed0925ecULL, },
+ { 0xffffffff0002ffffULL, 0xffff0002ffffffffULL, },
+ { 0xf49e16c1d27ef49eULL, 0x16c1d27ef49e16c1ULL, },
+ { 0xfffeffff0001fffeULL, 0xffff0001fffeffffULL, },
+ { 0xf9ace6b69adef9acULL, 0xe6b69adef9ace6b6ULL, },
+ { 0xfffeffff0001fffeULL, 0xffff0001fffeffffULL, },
+ { 0x6fb804f50cbf38c5ULL, 0x2c6a0103000331f0ULL, }, /* 64 */
+ { 0x73b204e2253812d4ULL, 0x3796fae5ffc2fe1aULL, },
+ { 0x7fff14e60f13c53dULL, 0x4f0ff5d500c4e6f1ULL, },
+ { 0x171210822ccab176ULL, 0x0bdeeb4001ccf94aULL, },
+ { 0x1b0c106f45438b85ULL, 0x170ae522018bc574ULL, },
+ { 0x1b30106f7447a4e0ULL, 0x19d90a380512fb41ULL, },
+ { 0x1df8103049bdd8baULL, 0x1fc028e7f6fd134bULL, },
+ { 0x1a3c10417fffe5f1ULL, 0x0eda690ae8970040ULL, },
+ { 0x6862204569da985aULL, 0x265363fae999e917ULL, }, /* 72 */
+ { 0x6b2a20063f50cc34ULL, 0x2c3a7fffdb840121ULL, },
+ { 0x7fff53b565ce363dULL, 0x38a17fff13bd0bdfULL, },
+ { 0x369a458932275144ULL, 0x15207fff4d3a035dULL, },
+ { 0xcdad41254fde3d7dULL, 0xd1ef756a4e4215b6ULL, },
+ { 0xc9f141367fff4ab4ULL, 0xc1097fff3fdc02abULL, },
+ { 0x808c330a4c5865bbULL, 0x9d887fff7959fa29ULL, },
+ { 0xe31636ed7fff6c9fULL, 0x032b7fff7fff00e7ULL, },
+ { 0xfe192c1c7fff7fffULL, 0x05097fff7e7a0057ULL, }, /* 80 */
+ { 0xfe292c3e7fff4707ULL, 0x05c83b1a7fff008fULL, },
+ { 0xff5d102139cf0662ULL, 0x079520c82b2b00b8ULL, },
+ { 0xfece12f0645904e7ULL, 0x00d302440dea008eULL, },
+ { 0xffec0f357fff082bULL, 0x014f02780dc00035ULL, },
+ { 0xffed0f417fff0488ULL, 0x0181012410080057ULL, },
+ { 0xfff9059039cf0068ULL, 0x01f900a205680070ULL, },
+ { 0xfff3068864590050ULL, 0x0037000b01be0056ULL, },
+ { 0xffff053f7fff0085ULL, 0x0057000c01b90020ULL, }, /* 88 */
+ { 0xffff05437fff004aULL, 0x0064000602020035ULL, },
+ { 0x000001eb39cf0007ULL, 0x0083000300ad0044ULL, },
+ { 0x0000024164590005ULL, 0x000e000000380034ULL, },
+ { 0x000001cf7fff0008ULL, 0x0016000000370014ULL, },
+ { 0x000001d07fff0004ULL, 0x0019000000400021ULL, },
+ { 0x000000a939cf0000ULL, 0x002100000016002bULL, },
+ { 0x000000c664590000ULL, 0x0004000000070021ULL, },
+ { 0x0000009f7fff0000ULL, 0x000600000007000cULL, }, /* 96 */
+ { 0x000000807fff0000ULL, 0x000a000000070005ULL, },
+ { 0x000000677fff0000ULL, 0x0010000000070002ULL, },
+ { 0x000000537fff0000ULL, 0x0019000000070001ULL, },
+ { 0x000000537fff0000ULL, 0x001d000000080002ULL, },
+ { 0x000000537fff0000ULL, 0x0021000000090003ULL, },
+ { 0x000000537fff0000ULL, 0x00260000000a0005ULL, },
+ { 0x000000537fff0000ULL, 0x002c0000000c0008ULL, },
+ { 0x0000001e39cf0000ULL, 0x003a00000004000aULL, }, /* 104 */
+ { 0x0000000b1a1c0000ULL, 0x004c00000001000dULL, },
+ { 0x000000040bcb0000ULL, 0x0064000000000011ULL, },
+ { 0x0000000105530000ULL, 0x0083000000000016ULL, },
+ { 0x00000001093e0000ULL, 0x000e000000000011ULL, },
+ { 0x00000001100b0000ULL, 0x000200000000000dULL, },
+ { 0x000000011bd90000ULL, 0x000000000000000aULL, },
+ { 0x0000000130570000ULL, 0x0000000000000008ULL, },
+};
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDR_Q_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDR_Q_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDR_Q_H__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDR_Q_H__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MADDR_Q.W
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
+ * Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Fixed Multiply";
+ char *instruction_name = "MADDR_Q.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, }, /* 16 */
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x38e38e3b38e38e3bULL, 0x38e38e3b38e38e3bULL, },
+ { 0x0000000200000002ULL, 0x0000000200000002ULL, },
+ { 0x2222222522222225ULL, 0x2222222522222225ULL, },
+ { 0x0000000300000003ULL, 0x0000000300000003ULL, },
+ { 0x12f684c14bda12faULL, 0xda12f68812f684c1ULL, },
+ { 0x0000000400000003ULL, 0x0000000400000004ULL, },
+ { 0x0000000300000002ULL, 0x0000000300000003ULL, }, /* 24 */
+ { 0x0000000300000002ULL, 0x0000000300000003ULL, },
+ { 0xc71c71cac71c71c9ULL, 0xc71c71cac71c71caULL, },
+ { 0x0000000200000001ULL, 0x0000000200000002ULL, },
+ { 0xdddddddfdddddddeULL, 0xdddddddfdddddddfULL, },
+ { 0x0000000100000000ULL, 0x0000000100000001ULL, },
+ { 0xed097b43b425ed0aULL, 0x25ed097ced097b43ULL, },
+ { 0x0000000000000000ULL, 0x0000000100000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000100000000ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000100000000ULL, },
+ { 0x2222222322222223ULL, 0x2222222422222223ULL, },
+ { 0x0000000000000000ULL, 0x0000000100000000ULL, },
+ { 0x147ae148147ae148ULL, 0x147ae149147ae148ULL, },
+ { 0x0000000000000000ULL, 0x0000000100000000ULL, },
+ { 0x0b60b60c2d82d82eULL, 0xe93e93ea0b60b60cULL, },
+ { 0x0000000100000000ULL, 0x0000000100000001ULL, },
+ { 0x0000000100000000ULL, 0x0000000100000001ULL, }, /* 40 */
+ { 0x0000000100000000ULL, 0x0000000100000001ULL, },
+ { 0xdddddddfdddddddeULL, 0xdddddddfdddddddfULL, },
+ { 0x0000000100000000ULL, 0x0000000100000001ULL, },
+ { 0xeb851eb9eb851eb8ULL, 0xeb851eb9eb851eb9ULL, },
+ { 0x0000000100000000ULL, 0x0000000100000001ULL, },
+ { 0xf49f49f5d27d27d3ULL, 0x16c16c17f49f49f5ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, }, /* 48 */
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x12f684be4bda12f8ULL, 0xda12f68512f684beULL, },
+ { 0x0000000000000002ULL, 0x0000000000000000ULL, },
+ { 0x0b60b60c2d82d830ULL, 0xe93e93e90b60b60cULL, },
+ { 0x0000000000000003ULL, 0xffffffff00000000ULL, },
+ { 0x06522c3f6522c3f7ULL, 0x1948b0fb06522c3fULL, },
+ { 0x0000000000000004ULL, 0xffffffff00000000ULL, },
+ { 0x0000000000000003ULL, 0xffffffff00000000ULL, }, /* 56 */
+ { 0x0000000000000003ULL, 0xffffffff00000000ULL, },
+ { 0xed097b43b425ed0cULL, 0x25ed097bed097b43ULL, },
+ { 0x0000000000000002ULL, 0x0000000000000000ULL, },
+ { 0xf49f49f5d27d27d4ULL, 0x16c16c17f49f49f5ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0xf9add3c19add3c0eULL, 0xe6b74f04f9add3c1ULL, },
+ { 0x0000000000000000ULL, 0x0000000100000000ULL, },
+ { 0x6fb7e8890cbdc0d3ULL, 0x2c6b144700049a05ULL, }, /* 64 */
+ { 0x73b239d7253787d5ULL, 0x379780f0ffc424ccULL, },
+ { 0x7fffffff0f127795ULL, 0x4f10998300c57f01ULL, },
+ { 0x1713a7162cca6b3bULL, 0x0be04ded01cca270ULL, },
+ { 0x1b0df8644544323dULL, 0x170cba96018c2d37ULL, },
+ { 0x1b323a657448a84fULL, 0x19dc46aa051313c6ULL, },
+ { 0x1dfa85ed49be7970ULL, 0x1fc3e135f6fe3018ULL, },
+ { 0x1a3e24ca7fffffffULL, 0x0edd19d1e8983ff6ULL, },
+ { 0x6863455169daefbfULL, 0x26563264e9999a2bULL, }, /* 72 */
+ { 0x6b2b90d93f50c0e0ULL, 0x2c3dccefdb84b67dULL, },
+ { 0x7fffffff65cdd2a4ULL, 0x38a5555313bd77c9ULL, },
+ { 0x369baa393226e271ULL, 0x1523c34a4d39d0a3ULL, },
+ { 0xcdaf51504fded617ULL, 0xd1f377b44e40f412ULL, },
+ { 0xc9f2f02d7fffffffULL, 0xc10cb0503fdb03f0ULL, },
+ { 0x808e9a674c590fccULL, 0x9d8b1e4779575ccaULL, },
+ { 0xe319324b7fffffffULL, 0x032ce4297fffffffULL, },
+ { 0xfe196fe67fffffffULL, 0x050bc0417e7bb00bULL, }, /* 80 */
+ { 0xfe299f487fffffffULL, 0x05cb2b577fffffffULL, },
+ { 0xff5d018339cf8b80ULL, 0x0798e2662b2b2514ULL, },
+ { 0xfecdfe20645a7d9bULL, 0x00d3dcf80dea608eULL, },
+ { 0xffebe0517fffffffULL, 0x0150ab000dc02968ULL, },
+ { 0xffec8baf7fffffffULL, 0x01828ea210087db2ULL, },
+ { 0xfff9423c39cf8b80ULL, 0x01fae4c1056841b9ULL, },
+ { 0xfff35806645a7d9bULL, 0x003737bc01be3862ULL, },
+ { 0xffff2aee7fffffffULL, 0x0057bed801b8eeb0ULL, }, /* 88 */
+ { 0xffff32047fffffffULL, 0x0064bf8102021ffcULL, },
+ { 0xffffb89f39cf8b80ULL, 0x00841c7a00ad640aULL, },
+ { 0xffff79fe645a7d9bULL, 0x000e642f0037e4a6ULL, },
+ { 0xfffff7307fffffffULL, 0x0016de7800373b16ULL, },
+ { 0xfffff77b7fffffffULL, 0x001a42040040661aULL, },
+ { 0xfffffd0c39cf8b80ULL, 0x00226e990015b802ULL, },
+ { 0xfffffa75645a7d9bULL, 0x0003c0350007004aULL, },
+ { 0xffffffa37fffffffULL, 0x0005f5d90006eb0dULL, }, /* 96 */
+ { 0xfffffffa7fffffffULL, 0x000978b30006d610ULL, },
+ { 0x000000007fffffffULL, 0x000f0d0c0006c153ULL, },
+ { 0x000000007fffffffULL, 0x0017eacf0006acd5ULL, },
+ { 0x000000007fffffffULL, 0x001b761e0007c87dULL, },
+ { 0x000000007fffffffULL, 0x001f87e00009133bULL, },
+ { 0x000000007fffffffULL, 0x00243402000a94e0ULL, },
+ { 0x000000007fffffffULL, 0x00299164000c5689ULL, },
+ { 0x0000000039cf8b80ULL, 0x003682160004293bULL, }, /* 104 */
+ { 0x000000001a1c28c4ULL, 0x00477a0900016741ULL, },
+ { 0x000000000bcae026ULL, 0x005dba4500007929ULL, },
+ { 0x00000000055376c2ULL, 0x007ae7c2000028ddULL, },
+ { 0x00000000093ed557ULL, 0x000d637500000d2cULL, },
+ { 0x00000000100c9469ULL, 0x0001755d0000043fULL, },
+ { 0x000000001bdc1297ULL, 0x000028ac0000015eULL, },
+ { 0x00000000305c8bbfULL, 0x0000046e00000071ULL, },
+};
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDR_Q_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDR_Q_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDR_Q_W__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDR_Q_W__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MSUB_Q.H
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
+ * Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Fixed Multiply";
+ char *instruction_name = "MSUB_Q.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xfffefffefffefffeULL, 0xfffefffefffefffeULL, },
+ { 0xfffefffefffefffeULL, 0xfffefffefffefffeULL, },
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, },
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, },
+ { 0xfffcfffdfffcfffcULL, 0xfffdfffcfffcfffdULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, }, /* 8 */
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffbfffbfffbfffbULL, 0xfffbfffbfffbfffbULL, }, /* 16 */
+ { 0xfffbfffbfffbfffbULL, 0xfffbfffbfffbfffbULL, },
+ { 0xc716c716c716c716ULL, 0xc716c716c716c716ULL, },
+ { 0xfff9fff9fff9fff9ULL, 0xfff9fff9fff9fff9ULL, },
+ { 0xddd6ddd6ddd6ddd6ULL, 0xddd6ddd6ddd6ddd6ULL, },
+ { 0xfff8fff8fff8fff8ULL, 0xfff8fff8fff8fff8ULL, },
+ { 0xed0125e4b41ced01ULL, 0x25e4b41ced0125e4ULL, },
+ { 0xfff7fff6fff6fff7ULL, 0xfff6fff6fff7fff6ULL, },
+ { 0xfff7fff6fff6fff7ULL, 0xfff6fff6fff7fff6ULL, }, /* 24 */
+ { 0xfff7fff6fff6fff7ULL, 0xfff6fff6fff7fff6ULL, },
+ { 0x38da38d938d938daULL, 0x38d938d938da38d9ULL, },
+ { 0xfff6fff5fff5fff6ULL, 0xfff5fff5fff6fff5ULL, },
+ { 0x2218221722172218ULL, 0x2217221722182217ULL, },
+ { 0xfff6fff5fff5fff6ULL, 0xfff5fff5fff6fff5ULL, },
+ { 0x12ecda084bcf12ecULL, 0xda084bcf12ecda08ULL, },
+ { 0xfff6fff5fff5fff6ULL, 0xfff5fff5fff6fff5ULL, },
+ { 0xfff5fff4fff4fff5ULL, 0xfff4fff4fff5fff4ULL, }, /* 32 */
+ { 0xfff5fff4fff4fff5ULL, 0xfff4fff4fff5fff4ULL, },
+ { 0xddd2ddd1ddd1ddd2ULL, 0xddd1ddd1ddd2ddd1ULL, },
+ { 0xfff4fff3fff3fff4ULL, 0xfff3fff3fff4fff3ULL, },
+ { 0xeb78eb77eb77eb78ULL, 0xeb77eb77eb78eb77ULL, },
+ { 0xfff3fff2fff2fff3ULL, 0xfff2fff2fff3fff2ULL, },
+ { 0xf49216b3d26ef492ULL, 0x16b3d26ef49216b3ULL, },
+ { 0xfff2fff1fff1fff2ULL, 0xfff1fff1fff2fff1ULL, },
+ { 0xfff2fff1fff1fff2ULL, 0xfff1fff1fff2fff1ULL, }, /* 40 */
+ { 0xfff2fff1fff1fff2ULL, 0xfff1fff1fff2fff1ULL, },
+ { 0x2214221322132214ULL, 0x2213221322142213ULL, },
+ { 0xfff2fff1fff1fff2ULL, 0xfff1fff1fff2fff1ULL, },
+ { 0x146d146c146c146dULL, 0x146c146c146d146cULL, },
+ { 0xfff2fff1fff1fff2ULL, 0xfff1fff1fff2fff1ULL, },
+ { 0x0b52e92f2d740b52ULL, 0xe92f2d740b52e92fULL, },
+ { 0xfff1fff0fff1fff1ULL, 0xfff0fff1fff1fff0ULL, },
+ { 0xfff0fff0fff0fff0ULL, 0xfff0fff0fff0fff0ULL, }, /* 48 */
+ { 0xfff0fff0fff0fff0ULL, 0xfff0fff0fff0fff0ULL, },
+ { 0xecf925dcb414ecf9ULL, 0x25dcb414ecf925dcULL, },
+ { 0xffefffefffeeffefULL, 0xffefffeeffefffefULL, },
+ { 0xf48e16b0d26af48eULL, 0x16b0d26af48e16b0ULL, },
+ { 0xffeeffeeffedffeeULL, 0xffeeffedffeeffeeULL, },
+ { 0xf99be6a59ac8f99bULL, 0xe6a59ac8f99be6a5ULL, },
+ { 0xffedffedffebffedULL, 0xffedffebffedffedULL, },
+ { 0xffedffecffebffedULL, 0xffecffebffedffecULL, }, /* 56 */
+ { 0xffedffecffebffedULL, 0xffecffebffedffecULL, },
+ { 0x12e3d9fe4bc512e3ULL, 0xd9fe4bc512e3d9feULL, },
+ { 0xffedffebffebffedULL, 0xffebffebffedffebULL, },
+ { 0x0b4de9292d6e0b4dULL, 0xe9292d6e0b4de929ULL, },
+ { 0xffecffeaffebffecULL, 0xffeaffebffecffeaULL, },
+ { 0x063e1932650e063eULL, 0x1932650e063e1932ULL, },
+ { 0xffecffe8ffebffecULL, 0xffe8ffebffecffe8ULL, },
+ { 0x9032faf1f32dc724ULL, 0xd37cfee8ffe7cdf6ULL, }, /* 64 */
+ { 0x8c37fb04dab3ed15ULL, 0xc8500506002701cbULL, },
+ { 0x8000eb00f0d83aacULL, 0xb0d70a15ff2518f4ULL, },
+ { 0xe8edef64d3204e73ULL, 0xf40714a9fe1d069aULL, },
+ { 0xe4f2ef77baa67464ULL, 0xe8db1ac7fe5d3a6fULL, },
+ { 0xe4cdef768ba25b09ULL, 0xe60bf5b1fad604a2ULL, },
+ { 0xe204efb4b62c272fULL, 0xe023d70208eaec98ULL, },
+ { 0xe5c0efa2800019f7ULL, 0xf10996de174fffa3ULL, },
+ { 0x9799df9e9625678eULL, 0xd9909bed164d16ccULL, }, /* 72 */
+ { 0x94d0dfdcc0af33b4ULL, 0xd3a880002461fec2ULL, },
+ { 0x8000ac2c9a31c9abULL, 0xc7408000ec28f404ULL, },
+ { 0xc964ba57cdd7aea3ULL, 0xeac18000b2aafc86ULL, },
+ { 0x3251bebbb01fc26aULL, 0x2df18a94b1a2ea2cULL, },
+ { 0x360dbea98000b532ULL, 0x3ed78000c007fd37ULL, },
+ { 0x7f71ccd4b3a69a2aULL, 0x62588000868905b9ULL, },
+ { 0x1ce6c8f180009346ULL, 0xfcb580008000fefbULL, },
+ { 0x37e5be19a862dbafULL, 0xfea58b5e8000fe57ULL, }, /* 80 */
+ { 0x39c0be4bdd7bcb85ULL, 0xfed88000953fff6aULL, },
+ { 0x5f7d948aca8d9bc1ULL, 0xff3480008000ff95ULL, },
+ { 0x0bb4a742f1e1847fULL, 0xfe7e80008000ff7cULL, },
+ { 0x16a395c8f655d6c0ULL, 0xff618b5e8000ff29ULL, },
+ { 0x1763961afc30c464ULL, 0xff788000953fffb4ULL, },
+ { 0x26ab8000fa188e23ULL, 0xffa280008000ffcaULL, },
+ { 0x04bd964dfe708000ULL, 0xff4e80008000ffbdULL, },
+ { 0x092a817dfeeed540ULL, 0xffb68b5e8000ff93ULL, }, /* 88 */
+ { 0x097881deff94c239ULL, 0xffc08000953fffd9ULL, },
+ { 0x0fa88000ff5889feULL, 0xffd380008000ffe4ULL, },
+ { 0x01eb964dffd38000ULL, 0xffaa80008000ffddULL, },
+ { 0x03b5817dffe1d540ULL, 0xffdc8b5e8000ffc7ULL, },
+ { 0x03d481defff3c239ULL, 0xffe18000953fffebULL, },
+ { 0x06548000ffeb89feULL, 0xffea80008000fff1ULL, },
+ { 0x00c6964dfffa8000ULL, 0xffd680008000ffedULL, },
+ { 0x017e817dfffbd540ULL, 0xffee8b5e8000ffe1ULL, }, /* 96 */
+ { 0x02e28000fffcf1b8ULL, 0xfff895b98000ffcdULL, },
+ { 0x05938000fffdfb3aULL, 0xfffc9f298000ffadULL, },
+ { 0x0ac88000fffdfe67ULL, 0xfffea7c28000ff79ULL, },
+ { 0x0b238063fffefdb0ULL, 0xfffe8000953fffd0ULL, },
+ { 0x0b8180c5fffffca8ULL, 0xfffe8000a6f7ffefULL, },
+ { 0x0be28127fffffb2bULL, 0xfffe8000b5befffaULL, },
+ { 0x0c478189fffff904ULL, 0xfffe8000c211fffdULL, },
+ { 0x144c8000fffef2a8ULL, 0xfffe80009905fffdULL, }, /* 104 */
+ { 0x218f8000fffce682ULL, 0xfffe80008000fffdULL, },
+ { 0x377d8000fff9cf4eULL, 0xfffe80008000fffdULL, },
+ { 0x5bc08000fff5a2fbULL, 0xfffe80008000fffdULL, },
+ { 0x0b3f964dfffd8d66ULL, 0xfffc80008000fffcULL, },
+ { 0x0160a8b7ffff8000ULL, 0xfff880008000fffbULL, },
+ { 0x002bb7ecffff8000ULL, 0xfff080008000fff9ULL, },
+ { 0x0005c47affff8000ULL, 0xffe180008000fff7ULL, },
+};
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUB_Q_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUB_Q_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUB_Q_H__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUB_Q_H__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MSUB_Q.W
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
+ * Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Fixed Multiply";
+ char *instruction_name = "MSUB_Q.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xfffffffefffffffeULL, 0xfffffffefffffffeULL, },
+ { 0xfffffffefffffffeULL, 0xfffffffefffffffeULL, },
+ { 0xfffffffdfffffffdULL, 0xfffffffdfffffffdULL, },
+ { 0xfffffffdfffffffdULL, 0xfffffffdfffffffdULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffdfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, }, /* 8 */
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffbfffffffbULL, 0xfffffffbfffffffbULL, }, /* 16 */
+ { 0xfffffffbfffffffbULL, 0xfffffffbfffffffbULL, },
+ { 0xc71c71c1c71c71c1ULL, 0xc71c71c1c71c71c1ULL, },
+ { 0xfffffffafffffffaULL, 0xfffffffafffffffaULL, },
+ { 0xddddddd7ddddddd7ULL, 0xddddddd7ddddddd7ULL, },
+ { 0xfffffff9fffffff9ULL, 0xfffffff9fffffff9ULL, },
+ { 0xed097b3ab425ed01ULL, 0x25ed0973ed097b3aULL, },
+ { 0xfffffff7fffffff7ULL, 0xfffffff7fffffff7ULL, },
+ { 0xfffffff7fffffff7ULL, 0xfffffff7fffffff7ULL, }, /* 24 */
+ { 0xfffffff7fffffff7ULL, 0xfffffff7fffffff7ULL, },
+ { 0x38e38e3038e38e30ULL, 0x38e38e3038e38e30ULL, },
+ { 0xfffffff7fffffff7ULL, 0xfffffff7fffffff7ULL, },
+ { 0x2222221922222219ULL, 0x2222221922222219ULL, },
+ { 0xfffffff7fffffff7ULL, 0xfffffff7fffffff7ULL, },
+ { 0x12f684b44bda12edULL, 0xda12f67c12f684b4ULL, },
+ { 0xfffffff6fffffff7ULL, 0xfffffff7fffffff6ULL, },
+ { 0xfffffff5fffffff6ULL, 0xfffffff6fffffff5ULL, }, /* 32 */
+ { 0xfffffff5fffffff6ULL, 0xfffffff6fffffff5ULL, },
+ { 0xddddddd2ddddddd3ULL, 0xddddddd3ddddddd2ULL, },
+ { 0xfffffff4fffffff5ULL, 0xfffffff5fffffff4ULL, },
+ { 0xeb851eabeb851eacULL, 0xeb851eaceb851eabULL, },
+ { 0xfffffff2fffffff3ULL, 0xfffffff3fffffff2ULL, },
+ { 0xf49f49e6d27d27c4ULL, 0x16c16c09f49f49e6ULL, },
+ { 0xfffffff1fffffff1ULL, 0xfffffff1fffffff1ULL, },
+ { 0xfffffff1fffffff1ULL, 0xfffffff1fffffff1ULL, }, /* 40 */
+ { 0xfffffff1fffffff1ULL, 0xfffffff1fffffff1ULL, },
+ { 0x2222221322222213ULL, 0x2222221322222213ULL, },
+ { 0xfffffff1fffffff1ULL, 0xfffffff1fffffff1ULL, },
+ { 0x147ae138147ae138ULL, 0x147ae138147ae138ULL, },
+ { 0xfffffff0fffffff0ULL, 0xfffffff0fffffff0ULL, },
+ { 0x0b60b5fb2d82d81dULL, 0xe93e93d90b60b5fbULL, },
+ { 0xffffffefffffffefULL, 0xffffffefffffffefULL, },
+ { 0xffffffeeffffffeeULL, 0xffffffefffffffeeULL, }, /* 48 */
+ { 0xffffffeeffffffeeULL, 0xffffffefffffffeeULL, },
+ { 0xed097b2fb425ecf6ULL, 0x25ed0969ed097b2fULL, },
+ { 0xffffffecffffffecULL, 0xffffffeeffffffecULL, },
+ { 0xf49f49e0d27d27bdULL, 0x16c16c04f49f49e0ULL, },
+ { 0xffffffebffffffeaULL, 0xffffffedffffffebULL, },
+ { 0xf9add3ab9add3bf6ULL, 0xe6b74ef0f9add3abULL, },
+ { 0xffffffeaffffffe8ULL, 0xffffffecffffffeaULL, },
+ { 0xffffffeaffffffe8ULL, 0xffffffebffffffeaULL, }, /* 56 */
+ { 0xffffffeaffffffe8ULL, 0xffffffebffffffeaULL, },
+ { 0x12f684a74bda12deULL, 0xda12f66f12f684a7ULL, },
+ { 0xffffffe9ffffffe8ULL, 0xffffffeaffffffe9ULL, },
+ { 0x0b60b5f42d82d815ULL, 0xe93e93d20b60b5f4ULL, },
+ { 0xffffffe8ffffffe7ULL, 0xffffffe8ffffffe8ULL, },
+ { 0x06522c276522c3d9ULL, 0x1948b0e406522c27ULL, },
+ { 0xffffffe7ffffffe7ULL, 0xffffffe7ffffffe7ULL, },
+ { 0x9048175df3423f14ULL, 0xd394eba0fffb65e2ULL, }, /* 64 */
+ { 0x8c4dc60edac87812ULL, 0xc8687ef6003bdb1bULL, },
+ { 0x80000000f0ed8852ULL, 0xb0ef6662ff3a80e6ULL, },
+ { 0xe8ec58e8d33594acULL, 0xf41fb1f8fe335d76ULL, },
+ { 0xe4f20799babbcdaaULL, 0xe8f3454efe73d2afULL, },
+ { 0xe4cdc5978bb75798ULL, 0xe623b939faecec20ULL, },
+ { 0xe2057a0fb6418676ULL, 0xe03c1eae0901cfcdULL, },
+ { 0xe5c1db3280000000ULL, 0xf122e6111767bfefULL, },
+ { 0x979cbaab96251040ULL, 0xd9a9cd7d166665baULL, }, /* 72 */
+ { 0x94d46f23c0af3f1eULL, 0xd3c232f2247b4967ULL, },
+ { 0x800000009a322d5aULL, 0xc75aaa8dec42881aULL, },
+ { 0xc96455c6cdd91d8cULL, 0xeadc3c95b2c62f40ULL, },
+ { 0x3250aeaeb02129e6ULL, 0x2e0c882bb1bf0bd0ULL, },
+ { 0x360d0fd180000000ULL, 0x3ef34f8ec024fbf2ULL, },
+ { 0x7f716597b3a6f032ULL, 0x6274e19686a8a318ULL, },
+ { 0x1ce6cdb280000000ULL, 0xfcd31bb480000000ULL, },
+ { 0x37e70b49a8625540ULL, 0xfeb1f7e080000000ULL, }, /* 80 */
+ { 0x39c31699dd7c5546ULL, 0xfee37780953f52fcULL, },
+ { 0x5f82316fca8f431eULL, 0xff3c0af780000000ULL, },
+ { 0x0bb5432ff1e2e177ULL, 0xfe8d6e9580000000ULL, },
+ { 0x16a56af3f656d2b3ULL, 0xff67ba1b80000000ULL, },
+ { 0x17664384fc31bf42ULL, 0xff7e4aa4953f52fcULL, },
+ { 0x26b0cbfdfa1b830bULL, 0xffa6ab9180000000ULL, },
+ { 0x04be31a4fe719ab1ULL, 0xff57124580000000ULL, },
+ { 0x092c8a1ffeef4c68ULL, 0xffba958e80000000ULL, }, /* 88 */
+ { 0x097aa960ff949347ULL, 0xffc4dede953f52fcULL, },
+ { 0x0fac7158ff59ab27ULL, 0xffd7471a80000000ULL, },
+ { 0x01ebdf01ffd41248ULL, 0xffb2fdd380000000ULL, },
+ { 0x03b76546ffe1ee50ULL, 0xffe05b1780000000ULL, },
+ { 0x03d70afdfff427aaULL, 0xffe50b86953f52fcULL, },
+ { 0x065971c1ffeda8dfULL, 0xffed6fa980000000ULL, },
+ { 0x00c741e8fffb2801ULL, 0xffdce50280000000ULL, },
+ { 0x01816947fffcaf39ULL, 0xfff1931580000000ULL, }, /* 96 */
+ { 0x02e97a17fffdbb03ULL, 0xfffa128380000000ULL, },
+ { 0x05a1edf3fffe7250ULL, 0xfffd906f80000000ULL, },
+ { 0x0ae508c5fffeefc8ULL, 0xfffeffc380000000ULL, },
+ { 0x0b41cf1bffff94c3ULL, 0xffff25bb953f52fcULL, },
+ { 0x0ba1ab79ffffd5c1ULL, 0xffff4613a6f7bf69ULL, },
+ { 0x0c04b828ffffef5bULL, 0xffff61a0b5bf25caULL, },
+ { 0x0c6b104efffff971ULL, 0xffff7918c21285a5ULL, },
+ { 0x148886c7fffff5d8ULL, 0xffffa3179907b21bULL, }, /* 104 */
+ { 0x21f39335fffff046ULL, 0xffffc00380000000ULL, },
+ { 0x38235e38ffffe7a6ULL, 0xffffd3ee80000000ULL, },
+ { 0x5cd2ce93ffffda4bULL, 0xffffe1a680000000ULL, },
+ { 0x0b60ff8afffff60aULL, 0xffffc69a80000000ULL, },
+ { 0x01651818fffffd5eULL, 0xffff937480000000ULL, },
+ { 0x002bc65fffffff4dULL, 0xffff32bb80000000ULL, },
+ { 0x00055dbfffffffd0ULL, 0xfffe7bd280000000ULL, },
+};
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUB_Q_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUB_Q_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUB_Q_W__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUB_Q_W__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MSUBR_Q.H
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
+ * Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Fixed Multiply";
+ char *instruction_name = "MSUBR_Q.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x00000000ffff0000ULL, 0x0000ffff00000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 16 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xc71bc71bc71bc71bULL, 0xc71bc71bc71bc71bULL, },
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xdddcdddcdddcdddcULL, 0xdddcdddcdddcdddcULL, },
+ { 0xfffefffefffefffeULL, 0xfffefffefffefffeULL, },
+ { 0xed0725ebb423ed07ULL, 0x25ebb423ed0725ebULL, },
+ { 0xfffdfffdfffefffdULL, 0xfffdfffefffdfffdULL, },
+ { 0xfffefffefffffffeULL, 0xfffefffffffefffeULL, }, /* 24 */
+ { 0xfffefffefffffffeULL, 0xfffefffffffefffeULL, },
+ { 0x38e238e238e338e2ULL, 0x38e238e338e238e2ULL, },
+ { 0xffffffff0000ffffULL, 0xffff0000ffffffffULL, },
+ { 0x2222222222232222ULL, 0x2222222322222222ULL, },
+ { 0x0000000000010000ULL, 0x0000000100000000ULL, },
+ { 0x12f7da134bdb12f7ULL, 0xda134bdb12f7da13ULL, },
+ { 0x0001000000010001ULL, 0x0000000100010000ULL, },
+ { 0x0001000000010001ULL, 0x0000000100010000ULL, }, /* 32 */
+ { 0x0001000000010001ULL, 0x0000000100010000ULL, },
+ { 0xdddedddddddedddeULL, 0xdddddddedddeddddULL, },
+ { 0x0001000000010001ULL, 0x0000000100010000ULL, },
+ { 0xeb85eb84eb85eb85ULL, 0xeb84eb85eb85eb84ULL, },
+ { 0x0000ffff00000000ULL, 0xffff00000000ffffULL, },
+ { 0xf49f16c1d27cf49fULL, 0x16c1d27cf49f16c1ULL, },
+ { 0x0000ffff00000000ULL, 0xffff00000000ffffULL, },
+ { 0x0000ffff00000000ULL, 0xffff00000000ffffULL, }, /* 40 */
+ { 0x0000ffff00000000ULL, 0xffff00000000ffffULL, },
+ { 0x2222222122222222ULL, 0x2221222222222221ULL, },
+ { 0x0000ffff00000000ULL, 0xffff00000000ffffULL, },
+ { 0x147b147a147b147bULL, 0x147a147b147b147aULL, },
+ { 0x0000ffff00000000ULL, 0xffff00000000ffffULL, },
+ { 0x0b61e93e2d830b61ULL, 0xe93e2d830b61e93eULL, },
+ { 0x0001000000000001ULL, 0x0000000000010000ULL, },
+ { 0x00010000ffff0001ULL, 0x0000ffff00010000ULL, }, /* 48 */
+ { 0x00010000ffff0001ULL, 0x0000ffff00010000ULL, },
+ { 0xed0a25edb424ed0aULL, 0x25edb424ed0a25edULL, },
+ { 0x00010000fffe0001ULL, 0x0000fffe00010000ULL, },
+ { 0xf4a016c2d27af4a0ULL, 0x16c2d27af4a016c2ULL, },
+ { 0x00010001fffd0001ULL, 0x0001fffd00010001ULL, },
+ { 0xf9afe6b99ad9f9afULL, 0xe6b99ad9f9afe6b9ULL, },
+ { 0x00010002fffc0001ULL, 0x0002fffc00010002ULL, },
+ { 0x00010002fffd0001ULL, 0x0002fffd00010002ULL, }, /* 56 */
+ { 0x00010002fffd0001ULL, 0x0002fffd00010002ULL, },
+ { 0x12f7da144bd812f7ULL, 0xda144bd812f7da14ULL, },
+ { 0x00010001fffe0001ULL, 0x0001fffe00010001ULL, },
+ { 0x0b62e93f2d820b62ULL, 0xe93f2d820b62e93fULL, },
+ { 0x00020001ffff0002ULL, 0x0001ffff00020001ULL, },
+ { 0x0654194a65220654ULL, 0x194a65220654194aULL, },
+ { 0x00020001ffff0002ULL, 0x0001ffff00020001ULL, },
+ { 0x9048fb0bf341c73bULL, 0xd396fefdfffdce10ULL, }, /* 64 */
+ { 0x8c4efb1edac8ed2cULL, 0xc86a051b003e01e6ULL, },
+ { 0x8000eb1af0ed3ac3ULL, 0xb0f10a2bff3c190fULL, },
+ { 0xe8edef7ed3364e8aULL, 0xf42214c0fe3406b6ULL, },
+ { 0xe4f3ef91babd747bULL, 0xe8f61adefe753a8cULL, },
+ { 0xe4cfef918bb95b20ULL, 0xe627f5c8faee04bfULL, },
+ { 0xe207efd0b6432746ULL, 0xe040d7190903ecb5ULL, },
+ { 0xe5c3efbf80001a0fULL, 0xf12696f61769ffc0ULL, },
+ { 0x979ddfbb962567a6ULL, 0xd9ad9c06166716e9ULL, }, /* 72 */
+ { 0x94d5dffac0af33ccULL, 0xd3c68000247cfedfULL, },
+ { 0x8000ac4b9a31c9c4ULL, 0xc75f8000ec43f421ULL, },
+ { 0xc965ba77cdd8aebdULL, 0xeae08000b2c6fca3ULL, },
+ { 0x3252bedbb021c284ULL, 0x2e118a95b1beea4aULL, },
+ { 0x360ebeca8000b54dULL, 0x3ef78000c024fd55ULL, },
+ { 0x7f73ccf6b3a79a46ULL, 0x6278800086a705d7ULL, },
+ { 0x1ce9c91380009362ULL, 0xfcd580008000ff19ULL, },
+ { 0x37ebbe42a862dbb9ULL, 0xfeb38b5e8000fe89ULL, }, /* 80 */
+ { 0x39c7be75dd7ccb94ULL, 0xfee48000953fff7cULL, },
+ { 0x5f8994cfca8f9bdeULL, 0xff3c80008000ffa2ULL, },
+ { 0x0bb6a77cf1e284a3ULL, 0xfe8d80008000ff8cULL, },
+ { 0x16a7960ef656d6ccULL, 0xff688b5e8000ff44ULL, },
+ { 0x17689660fc31c475ULL, 0xff7f8000953fffbeULL, },
+ { 0x26b48000fa1a8e43ULL, 0xffa780008000ffd1ULL, },
+ { 0x04bf964dfe718000ULL, 0xff5880008000ffc6ULL, },
+ { 0x092e817dfeefd540ULL, 0xffbb8b5e8000ffa2ULL, }, /* 88 */
+ { 0x097c81dfff94c239ULL, 0xffc58000953fffdfULL, },
+ { 0x0faf8000ff5989ffULL, 0xffd780008000ffe9ULL, },
+ { 0x01ec964dffd48000ULL, 0xffb280008000ffe4ULL, },
+ { 0x03b8817dffe2d540ULL, 0xffe08b5e8000ffd3ULL, },
+ { 0x03d881dffff4c239ULL, 0xffe58000953ffff0ULL, },
+ { 0x065b8000ffed89ffULL, 0xffed80008000fff5ULL, },
+ { 0x00c7964dfffb8000ULL, 0xffdc80008000fff2ULL, },
+ { 0x0181817dfffdd540ULL, 0xfff18b5e8000ffe9ULL, }, /* 96 */
+ { 0x02e98000fffef1b9ULL, 0xfffa95ba8000ffdbULL, },
+ { 0x05a18000fffffb3bULL, 0xfffe9f2a8000ffc4ULL, },
+ { 0x0ae38000fffffe68ULL, 0xffffa7c48000ff9fULL, },
+ { 0x0b4080630000fdb2ULL, 0xffff8000953fffdeULL, },
+ { 0x0ba080c60000fcabULL, 0xffff8000a6f7fff4ULL, },
+ { 0x0c0381280000fb2fULL, 0xffff8000b5befffcULL, },
+ { 0x0c69818a0000f90aULL, 0xffff8000c211ffffULL, },
+ { 0x148580000000f2b4ULL, 0xffff80009905ffffULL, }, /* 104 */
+ { 0x21ee80000000e69aULL, 0xffff80008000ffffULL, },
+ { 0x381a80000000cf7cULL, 0xffff80008000ffffULL, },
+ { 0x5cc480000000a354ULL, 0xffff80008000ffffULL, },
+ { 0x0b5f964d00008dd4ULL, 0xfffe80008000ffffULL, },
+ { 0x0165a8b700008000ULL, 0xfffc80008000ffffULL, },
+ { 0x002cb7ec00008000ULL, 0xfff880008000ffffULL, },
+ { 0x0005c47b00008000ULL, 0xfff180008000ffffULL, },
+};
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBR_Q_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBR_Q_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBR_Q_H__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBR_Q_H__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MSUBR_Q.W
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2019 RT-RK Computer Based Systems LLC
+ * Copyright (C) 2019 Mateja Marjanovic <mateja.marjanovic@rt-rk.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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Fixed Multiply";
+ char *instruction_name = "MSUBR_Q.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 8 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, }, /* 16 */
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x38e38e3b38e38e3bULL, 0x38e38e3b38e38e3bULL, },
+ { 0x0000000200000002ULL, 0x0000000200000002ULL, },
+ { 0x2222222522222225ULL, 0x2222222522222225ULL, },
+ { 0x0000000300000003ULL, 0x0000000300000003ULL, },
+ { 0x12f684c14bda12faULL, 0xda12f68812f684c1ULL, },
+ { 0x0000000400000003ULL, 0x0000000400000004ULL, },
+ { 0x0000000300000002ULL, 0x0000000300000003ULL, }, /* 24 */
+ { 0x0000000300000002ULL, 0x0000000300000003ULL, },
+ { 0xc71c71cac71c71c9ULL, 0xc71c71cac71c71caULL, },
+ { 0x0000000200000001ULL, 0x0000000200000002ULL, },
+ { 0xdddddddfdddddddeULL, 0xdddddddfdddddddfULL, },
+ { 0x0000000100000000ULL, 0x0000000100000001ULL, },
+ { 0xed097b43b425ed0aULL, 0x25ed097ced097b43ULL, },
+ { 0x0000000000000000ULL, 0x0000000100000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000100000000ULL, }, /* 32 */
+ { 0x0000000000000000ULL, 0x0000000100000000ULL, },
+ { 0x2222222322222223ULL, 0x2222222422222223ULL, },
+ { 0x0000000000000000ULL, 0x0000000100000000ULL, },
+ { 0x147ae148147ae148ULL, 0x147ae149147ae148ULL, },
+ { 0x0000000000000000ULL, 0x0000000100000000ULL, },
+ { 0x0b60b60c2d82d82eULL, 0xe93e93ea0b60b60cULL, },
+ { 0x0000000100000000ULL, 0x0000000100000001ULL, },
+ { 0x0000000100000000ULL, 0x0000000100000001ULL, }, /* 40 */
+ { 0x0000000100000000ULL, 0x0000000100000001ULL, },
+ { 0xdddddddfdddddddeULL, 0xdddddddfdddddddfULL, },
+ { 0x0000000100000000ULL, 0x0000000100000001ULL, },
+ { 0xeb851eb9eb851eb8ULL, 0xeb851eb9eb851eb9ULL, },
+ { 0x0000000100000000ULL, 0x0000000100000001ULL, },
+ { 0xf49f49f5d27d27d3ULL, 0x16c16c17f49f49f5ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, }, /* 48 */
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0x12f684be4bda12f8ULL, 0xda12f68512f684beULL, },
+ { 0x0000000000000002ULL, 0x0000000000000000ULL, },
+ { 0x0b60b60c2d82d830ULL, 0xe93e93e90b60b60cULL, },
+ { 0x0000000000000003ULL, 0xffffffff00000000ULL, },
+ { 0x06522c3f6522c3f7ULL, 0x1948b0fb06522c3fULL, },
+ { 0x0000000000000004ULL, 0xffffffff00000000ULL, },
+ { 0x0000000000000003ULL, 0xffffffff00000000ULL, }, /* 56 */
+ { 0x0000000000000003ULL, 0xffffffff00000000ULL, },
+ { 0xed097b43b425ed0cULL, 0x25ed097bed097b43ULL, },
+ { 0x0000000000000002ULL, 0x0000000000000000ULL, },
+ { 0xf49f49f5d27d27d4ULL, 0x16c16c17f49f49f5ULL, },
+ { 0x0000000000000001ULL, 0x0000000000000000ULL, },
+ { 0xf9add3c19add3c0eULL, 0xe6b74f04f9add3c1ULL, },
+ { 0x0000000000000000ULL, 0x0000000100000000ULL, },
+ { 0x6fb7e8890cbdc0d3ULL, 0x2c6b144700049a05ULL, }, /* 64 */
+ { 0x73b239d7253787d5ULL, 0x379780f0ffc424ccULL, },
+ { 0x7fffffff0f127795ULL, 0x4f10998300c57f01ULL, },
+ { 0x1713a7162cca6b3bULL, 0x0be04ded01cca270ULL, },
+ { 0x1b0df8644544323dULL, 0x170cba96018c2d37ULL, },
+ { 0x1b323a657448a84fULL, 0x19dc46aa051313c6ULL, },
+ { 0x1dfa85ed49be7970ULL, 0x1fc3e135f6fe3018ULL, },
+ { 0x1a3e24ca7fffffffULL, 0x0edd19d1e8983ff6ULL, },
+ { 0x6863455169daefbfULL, 0x26563264e9999a2bULL, }, /* 72 */
+ { 0x6b2b90d93f50c0e0ULL, 0x2c3dccefdb84b67dULL, },
+ { 0x7fffffff65cdd2a4ULL, 0x38a5555313bd77c9ULL, },
+ { 0x369baa393226e271ULL, 0x1523c34a4d39d0a3ULL, },
+ { 0xcdaf51504fded617ULL, 0xd1f377b44e40f412ULL, },
+ { 0xc9f2f02d7fffffffULL, 0xc10cb0503fdb03f0ULL, },
+ { 0x808e9a674c590fccULL, 0x9d8b1e4779575ccaULL, },
+ { 0xe319324b7fffffffULL, 0x032ce4297fffffffULL, },
+ { 0xfe196fe67fffffffULL, 0x050bc0417e7bb00bULL, }, /* 80 */
+ { 0xfe299f487fffffffULL, 0x05cb2b577fffffffULL, },
+ { 0xff5d018339cf8b80ULL, 0x0798e2662b2b2514ULL, },
+ { 0xfecdfe20645a7d9bULL, 0x00d3dcf80dea608eULL, },
+ { 0xffebe0517fffffffULL, 0x0150ab000dc02968ULL, },
+ { 0xffec8baf7fffffffULL, 0x01828ea210087db2ULL, },
+ { 0xfff9423c39cf8b80ULL, 0x01fae4c1056841b9ULL, },
+ { 0xfff35806645a7d9bULL, 0x003737bc01be3862ULL, },
+ { 0xffff2aee7fffffffULL, 0x0057bed801b8eeb0ULL, }, /* 88 */
+ { 0xffff32047fffffffULL, 0x0064bf8102021ffcULL, },
+ { 0xffffb89f39cf8b80ULL, 0x00841c7a00ad640aULL, },
+ { 0xffff79fe645a7d9bULL, 0x000e642f0037e4a6ULL, },
+ { 0xfffff7307fffffffULL, 0x0016de7800373b16ULL, },
+ { 0xfffff77b7fffffffULL, 0x001a42040040661aULL, },
+ { 0xfffffd0c39cf8b80ULL, 0x00226e990015b802ULL, },
+ { 0xfffffa75645a7d9bULL, 0x0003c0350007004aULL, },
+ { 0xffffffa37fffffffULL, 0x0005f5d90006eb0dULL, }, /* 96 */
+ { 0xfffffffa7fffffffULL, 0x000978b30006d610ULL, },
+ { 0x000000007fffffffULL, 0x000f0d0c0006c153ULL, },
+ { 0x000000007fffffffULL, 0x0017eacf0006acd5ULL, },
+ { 0x000000007fffffffULL, 0x001b761e0007c87dULL, },
+ { 0x000000007fffffffULL, 0x001f87e00009133bULL, },
+ { 0x000000007fffffffULL, 0x00243402000a94e0ULL, },
+ { 0x000000007fffffffULL, 0x00299164000c5689ULL, },
+ { 0x0000000039cf8b80ULL, 0x003682160004293bULL, }, /* 104 */
+ { 0x000000001a1c28c4ULL, 0x00477a0900016741ULL, },
+ { 0x000000000bcae026ULL, 0x005dba4500007929ULL, },
+ { 0x00000000055376c2ULL, 0x007ae7c2000028ddULL, },
+ { 0x00000000093ed557ULL, 0x000d637500000d2cULL, },
+ { 0x00000000100c9469ULL, 0x0001755d0000043fULL, },
+ { 0x000000001bdc1297ULL, 0x000028ac0000015eULL, },
+ { 0x00000000305c8bbfULL, 0x0000046e00000071ULL, },
+};
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDR_Q_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDR_Q_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDR_Q_W__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDR_Q_W__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction DPADD_S.D
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Dot Product";
+ char *instruction_name = "DPADD_S.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000002ULL, 0x0000000000000002ULL, }, /* 0 */
+ { 0x0000000000000002ULL, 0x0000000000000002ULL, },
+ { 0x00000000aaaaaaaeULL, 0x00000000aaaaaaaeULL, },
+ { 0x0000000000000004ULL, 0x0000000000000004ULL, },
+ { 0x000000006666666cULL, 0x000000006666666cULL, },
+ { 0x0000000000000006ULL, 0x0000000000000006ULL, },
+ { 0x000000008e38e395ULL, 0xffffffffe38e38ebULL, },
+ { 0x0000000000000008ULL, 0x0000000000000008ULL, },
+ { 0x0000000000000008ULL, 0x0000000000000008ULL, }, /* 8 */
+ { 0x0000000000000008ULL, 0x0000000000000008ULL, },
+ { 0x0000000000000008ULL, 0x0000000000000008ULL, },
+ { 0x0000000000000008ULL, 0x0000000000000008ULL, },
+ { 0x0000000000000008ULL, 0x0000000000000008ULL, },
+ { 0x0000000000000008ULL, 0x0000000000000008ULL, },
+ { 0x0000000000000008ULL, 0x0000000000000008ULL, },
+ { 0x0000000000000008ULL, 0x0000000000000008ULL, },
+ { 0x00000000aaaaaab4ULL, 0x00000000aaaaaab4ULL, }, /* 16 */
+ { 0x00000000aaaaaab4ULL, 0x00000000aaaaaab4ULL, },
+ { 0x38e38e3a71c71c7cULL, 0x38e38e3a71c71c7cULL, },
+ { 0x0000000155555560ULL, 0x0000000155555560ULL, },
+ { 0x2222222444444450ULL, 0x2222222444444450ULL, },
+ { 0x000000020000000cULL, 0x000000020000000cULL, },
+ { 0x2f684bdcb425ed16ULL, 0xf684bda397b425faULL, },
+ { 0x00000002aaaaaab8ULL, 0x00000002aaaaaab8ULL, },
+ { 0x000000020000000eULL, 0x000000020000000eULL, }, /* 24 */
+ { 0x000000020000000eULL, 0x000000020000000eULL, },
+ { 0xc71c71c8e38e38f2ULL, 0xc71c71c8e38e38f2ULL, },
+ { 0x0000000155555564ULL, 0x0000000155555564ULL, },
+ { 0xdddddddeccccccdcULL, 0xdddddddeccccccdcULL, },
+ { 0x00000000aaaaaabaULL, 0x00000000aaaaaabaULL, },
+ { 0xd097b42684bda13fULL, 0x097b425ef684bdb1ULL, },
+ { 0x0000000000000010ULL, 0x0000000000000010ULL, },
+ { 0x0000000066666678ULL, 0x0000000066666678ULL, }, /* 32 */
+ { 0x0000000066666678ULL, 0x0000000066666678ULL, },
+ { 0x2222222355555568ULL, 0x2222222355555568ULL, },
+ { 0x00000000cccccce0ULL, 0x00000000cccccce0ULL, },
+ { 0x147ae1491eb85200ULL, 0x147ae1491eb85200ULL, },
+ { 0x0000000133333348ULL, 0x0000000133333348ULL, },
+ { 0x1c71c71e3e93e954ULL, 0xfa4fa4fbb60b60ccULL, },
+ { 0x00000001999999b0ULL, 0x00000001999999b0ULL, },
+ { 0x000000013333334aULL, 0x000000013333334aULL, }, /* 40 */
+ { 0x000000013333334aULL, 0x000000013333334aULL, },
+ { 0xdddddddeeeeeef06ULL, 0xdddddddeeeeeef06ULL, },
+ { 0x00000000cccccce4ULL, 0x00000000cccccce4ULL, },
+ { 0xeb851eb8e147ae2cULL, 0xeb851eb8e147ae2cULL, },
+ { 0x000000006666667eULL, 0x000000006666667eULL, },
+ { 0xe38e38e3e93e9401ULL, 0x05b05b05c71c71dfULL, },
+ { 0x0000000000000018ULL, 0x0000000000000018ULL, },
+ { 0x000000008e38e3a7ULL, 0xffffffffe38e38fdULL, }, /* 48 */
+ { 0x000000008e38e3a7ULL, 0xffffffffe38e38fdULL, },
+ { 0x2f684bdb425ed0b1ULL, 0xf684bda17b425eebULL, },
+ { 0x000000011c71c736ULL, 0xffffffffc71c71e2ULL, },
+ { 0x1c71c71e27d27d42ULL, 0xfa4fa4fa49f49f66ULL, },
+ { 0x00000001aaaaaac5ULL, 0xffffffffaaaaaac7ULL, },
+ { 0x35ba781b4587e6d2ULL, 0x0fcd6e9d6b74f050ULL, },
+ { 0x0000000238e38e54ULL, 0xffffffff8e38e3acULL, },
+ { 0x00000001aaaaaac7ULL, 0xffffffffaaaaaac9ULL, }, /* 56 */
+ { 0x00000001aaaaaac7ULL, 0xffffffffaaaaaac9ULL, },
+ { 0xd097b427a12f6869ULL, 0x097b425ebda12f87ULL, },
+ { 0x000000011c71c73aULL, 0xffffffffc71c71e6ULL, },
+ { 0xe38e38e477777796ULL, 0x05b05b05aaaaaacaULL, },
+ { 0x000000008e38e3adULL, 0xffffffffe38e3903ULL, },
+ { 0xca4587e781948b2fULL, 0xf032916206522c5fULL, },
+ { 0x0000000000000020ULL, 0x0000000000000020ULL, },
+ { 0x3e3ad4ae1266c2b0ULL, 0x1637d725aebdb734ULL, }, /* 64 */
+ { 0x4c74e0d60a3d6d94ULL, 0x1badd2dd9f4dac90ULL, },
+ { 0x6874e8f94205b90cULL, 0x27eb0c41af2c3022ULL, },
+ { 0x42dab657e16f25e8ULL, 0x06d6782e137656f2ULL, },
+ { 0x5114c27fd945d0ccULL, 0x0c4c73e604064c4eULL, },
+ { 0x68a91e898c276755ULL, 0x0f77ad378bdfb302ULL, },
+ { 0x54c82cde41d1cf13ULL, 0x0b6108a5f38e1598ULL, },
+ { 0x6f755d3eddd1234aULL, 0xfbbaace2f5421908ULL, },
+ { 0x8b75656215996ec2ULL, 0x07f7e64705209c9aULL, }, /* 72 */
+ { 0x779473b6cb43d680ULL, 0x03e141b56cceff30ULL, },
+ { 0xa6279a1866fb9f64ULL, 0x2631668db9e53ac1ULL, },
+ { 0x67a1f71bd99e4586ULL, 0x312ec9f6206e6e69ULL, },
+ { 0x4207c47a7907b262ULL, 0x101a35e284b89539ULL, },
+ { 0x5cb4f4db15070699ULL, 0x0073da1f866c98a9ULL, },
+ { 0x1e2f51de87a9acbbULL, 0x0b713d87ecf5cc51ULL, },
+ { 0x721d49ba5f0acfa8ULL, 0x5ba5bbe9afeae691ULL, },
+ { 0x4bcd68690d995de0ULL, 0x771da6b4b6c967ebULL, }, /* 80 */
+ { 0x4ea9a2cfbb5acd7bULL, 0x79dd6a73439e6387ULL, },
+ { 0x47c800b999dd2371ULL, 0x766d25914ef7a7a0ULL, },
+ { 0x41b0fa10eb77cf84ULL, 0x26e85189458965f8ULL, },
+ { 0x1fc448ce062c2944ULL, 0x31f490a9422a80e6ULL, },
+ { 0x211bdfadfd79770eULL, 0x3b25f4cac5763378ULL, },
+ { 0x16fbb87edd87b6f0ULL, 0x57c0b65fabdda20eULL, },
+ { 0x14621091eac4a5f6ULL, 0x4d29a25d32fa9ef6ULL, },
+ { 0x07832ded1c464b02ULL, 0x6396905709e3cfa4ULL, }, /* 88 */
+ { 0x0ff4a84eab8df3b9ULL, 0x6bc9a7d8c6adf2eaULL, },
+ { 0x21e53326bfbd0b05ULL, 0x8f8f3b9c679dff5aULL, },
+ { 0x191ed6a24e1576f9ULL, 0x9e8c2e402760373aULL, },
+ { 0x19b438400fc27751ULL, 0x819c4bbfd3ee6972ULL, },
+ { 0x1e0d5dc1094ae999ULL, 0x7496a289f5eff010ULL, },
+ { 0x11af620b7bc03943ULL, 0x8a11f229836addc7ULL, },
+ { 0x46fa45d0e84440fcULL, 0xe8d2c0211fb042bfULL, },
+ { 0x22142516b5a8adbcULL, 0xe1cf1923e186aad1ULL, }, /* 96 */
+ { 0x066ebbbb4ff6da44ULL, 0xd918d7e6a7e61877ULL, },
+ { 0x100acc9d22839a48ULL, 0xce291932929e367fULL, },
+ { 0x0dfe419d62a62f64ULL, 0xc020fe45a8cf7acfULL, },
+ { 0x2ba79b6ffbf3c63bULL, 0xb428f52c49fce695ULL, },
+ { 0x29b3b85200bdf100ULL, 0xb4ae7ea2f52aa5b9ULL, },
+ { 0x293bb84d6360c0b6ULL, 0xae33b26e4c493c49ULL, },
+ { 0x46a99fdf54f4862dULL, 0xae790dc5055f6f51ULL, },
+ { 0x18480e0fd728c7c3ULL, 0xa000ad7b15f8ebe0ULL, }, /* 104 */
+ { 0x1b8b97aa205e1239ULL, 0x89c78b8909c4a8e5ULL, },
+ { 0x09abb26b05ef649dULL, 0x74242fa1bd49e740ULL, },
+ { 0x04e233bc861d272bULL, 0x9c5343ab30f62f9fULL, },
+ { 0xda2da0d0884dc3d1ULL, 0xb824f201640b4147ULL, },
+ { 0x9d8b22ee1b9a2e0fULL, 0xb642ddf1edb0747fULL, },
+ { 0x7c81956533686a37ULL, 0xdd5181781dc3ad37ULL, },
+ { 0xc60b1905717ff25aULL, 0xe2af726e71ad7ad7ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_S_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_S_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_S_D__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_S_D__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction DPADD_S.H
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Dot Product";
+ char *instruction_name = "DPADD_S.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0002000200020002ULL, 0x0002000200020002ULL, }, /* 0 */
+ { 0x0002000200020002ULL, 0x0002000200020002ULL, },
+ { 0x00ae00ae00ae00aeULL, 0x00ae00ae00ae00aeULL, },
+ { 0x0004000400040004ULL, 0x0004000400040004ULL, },
+ { 0x006c006c006c006cULL, 0x006c006c006c006cULL, },
+ { 0x0006000600060006ULL, 0x0006000600060006ULL, },
+ { 0x0095ffeb00400095ULL, 0xffeb00400095ffebULL, },
+ { 0x0008000800080008ULL, 0x0008000800080008ULL, },
+ { 0x0008000800080008ULL, 0x0008000800080008ULL, }, /* 8 */
+ { 0x0008000800080008ULL, 0x0008000800080008ULL, },
+ { 0x0008000800080008ULL, 0x0008000800080008ULL, },
+ { 0x0008000800080008ULL, 0x0008000800080008ULL, },
+ { 0x0008000800080008ULL, 0x0008000800080008ULL, },
+ { 0x0008000800080008ULL, 0x0008000800080008ULL, },
+ { 0x0008000800080008ULL, 0x0008000800080008ULL, },
+ { 0x0008000800080008ULL, 0x0008000800080008ULL, },
+ { 0x00b400b400b400b4ULL, 0x00b400b400b400b4ULL, }, /* 16 */
+ { 0x00b400b400b400b4ULL, 0x00b400b400b400b4ULL, },
+ { 0x3a7c3a7c3a7c3a7cULL, 0x3a7c3a7c3a7c3a7cULL, },
+ { 0x0160016001600160ULL, 0x0160016001600160ULL, },
+ { 0x2450245024502450ULL, 0x2450245024502450ULL, },
+ { 0x020c020c020c020cULL, 0x020c020c020c020cULL, },
+ { 0x3216f8fa15883216ULL, 0xf8fa15883216f8faULL, },
+ { 0x02b802b802b802b8ULL, 0x02b802b802b802b8ULL, },
+ { 0x020e020e020e020eULL, 0x020e020e020e020eULL, }, /* 24 */
+ { 0x020e020e020e020eULL, 0x020e020e020e020eULL, },
+ { 0xc8f2c8f2c8f2c8f2ULL, 0xc8f2c8f2c8f2c8f2ULL, },
+ { 0x0164016401640164ULL, 0x0164016401640164ULL, },
+ { 0xdedcdedcdedcdedcULL, 0xdedcdedcdedcdedcULL, },
+ { 0x00ba00ba00ba00baULL, 0x00ba00ba00ba00baULL, },
+ { 0xd13f09b1ed78d13fULL, 0x09b1ed78d13f09b1ULL, },
+ { 0x0010001000100010ULL, 0x0010001000100010ULL, },
+ { 0x0078007800780078ULL, 0x0078007800780078ULL, }, /* 32 */
+ { 0x0078007800780078ULL, 0x0078007800780078ULL, },
+ { 0x2368236823682368ULL, 0x2368236823682368ULL, },
+ { 0x00e000e000e000e0ULL, 0x00e000e000e000e0ULL, },
+ { 0x1600160016001600ULL, 0x1600160016001600ULL, },
+ { 0x0148014801480148ULL, 0x0148014801480148ULL, },
+ { 0x1e54fbcc0d101e54ULL, 0xfbcc0d101e54fbccULL, },
+ { 0x01b001b001b001b0ULL, 0x01b001b001b001b0ULL, },
+ { 0x014a014a014a014aULL, 0x014a014a014a014aULL, }, /* 40 */
+ { 0x014a014a014a014aULL, 0x014a014a014a014aULL, },
+ { 0xdf06df06df06df06ULL, 0xdf06df06df06df06ULL, },
+ { 0x00e400e400e400e4ULL, 0x00e400e400e400e4ULL, },
+ { 0xec2cec2cec2cec2cULL, 0xec2cec2cec2cec2cULL, },
+ { 0x007e007e007e007eULL, 0x007e007e007e007eULL, },
+ { 0xe40105dff4f0e401ULL, 0x05dff4f0e40105dfULL, },
+ { 0x0018001800180018ULL, 0x0018001800180018ULL, },
+ { 0x00a7fffd005200a7ULL, 0xfffd005200a7fffdULL, }, /* 48 */
+ { 0x00a7fffd005200a7ULL, 0xfffd005200a7fffdULL, },
+ { 0x30b1f6eb13ce30b1ULL, 0xf6eb13ce30b1f6ebULL, },
+ { 0x0136ffe2008c0136ULL, 0xffe2008c0136ffe2ULL, },
+ { 0x1e42fa660c541e42ULL, 0xfa660c541e42fa66ULL, },
+ { 0x01c5ffc700c601c5ULL, 0xffc700c601c5ffc7ULL, },
+ { 0x37d20f503fca37d2ULL, 0x0f503fca37d20f50ULL, },
+ { 0x0254ffac01000254ULL, 0xffac01000254ffacULL, },
+ { 0x01c7ffc900c801c7ULL, 0xffc900c801c7ffc9ULL, }, /* 56 */
+ { 0x01c7ffc900c801c7ULL, 0xffc900c801c7ffc9ULL, },
+ { 0xd2690987edf8d269ULL, 0x0987edf8d2690987ULL, },
+ { 0x013affe60090013aULL, 0xffe60090013affe6ULL, },
+ { 0xe49605caf530e496ULL, 0x05caf530e49605caULL, },
+ { 0x00ad0003005800adULL, 0x0003005800ad0003ULL, },
+ { 0xcb2ff05fc18ecb2fULL, 0xf05fc18ecb2ff05fULL, },
+ { 0x0020002000200020ULL, 0x0020002000200020ULL, },
+ { 0x64440d542be42c59ULL, 0x3f8a231d3b3d19b0ULL, }, /* 64 */
+ { 0x4b48f9380e321b6cULL, 0x413129b25958ffe0ULL, },
+ { 0x97ec1304f058d493ULL, 0x3c8626d66eabf540ULL, },
+ { 0x8422012411cade1dULL, 0x14cc12fe8f0ffa20ULL, },
+ { 0x6b26ed08f418cd30ULL, 0x16731993ad2ae050ULL, },
+ { 0x7c43135139aada21ULL, 0x18082ed0be64faa4ULL, },
+ { 0x66b3f20f392cf02eULL, 0x1c2e3e58c200062eULL, },
+ { 0x50250fd64095f94cULL, 0x149f5aa0cb1bfe12ULL, },
+ { 0x9cc929a222bbb273ULL, 0x0ff457c4e06ef372ULL, }, /* 72 */
+ { 0x87390860223dc880ULL, 0x141a674ce40afefcULL, },
+ { 0xc26d3f883f4f3df9ULL, 0x204b7471077c05e5ULL, },
+ { 0xb9731e9e1bdc24afULL, 0x111e8fc92f75fa0fULL, },
+ { 0xa5a90cbe3d4e2e39ULL, 0xe9647bf14fd9feefULL, },
+ { 0x8f1b2a8544b73757ULL, 0xe1d5983958f4f6d3ULL, },
+ { 0x8621099b21441e0dULL, 0xd2a8b39180edeafdULL, },
+ { 0xcf8222a84d293955ULL, 0x0732f211af821281ULL, },
+ { 0xb24e311468e36182ULL, 0x1d5df7b5739a06edULL, }, /* 80 */
+ { 0x9fb838d0948447f9ULL, 0x1c22f28463ef0925ULL, },
+ { 0xa63c3700ca342b06ULL, 0x1b16f62c40350d56ULL, },
+ { 0x91603bbac05427d0ULL, 0x0dabf3fc381feb90ULL, },
+ { 0xed2843f4d67c28c3ULL, 0xef47f1f54694ece0ULL, },
+ { 0xe3373f50950e1df3ULL, 0xeb96f4e231bee6f8ULL, },
+ { 0x00111042b00d1732ULL, 0xf8f3f7b81663e296ULL, },
+ { 0x0550257c952a23bcULL, 0xfd4e0730286f0ddaULL, },
+ { 0x2418088a94861e5bULL, 0x1bcf191d5d740802ULL, }, /* 88 */
+ { 0x1d34dae8a7fc1a85ULL, 0x1f6e155281a10a8aULL, },
+ { 0x25f8ef24c16f4c23ULL, 0x12f7103e9bd702c4ULL, },
+ { 0x33b0f882bf8c4de5ULL, 0x0b68ff0eb3981908ULL, },
+ { 0xfaa812ea88fc60b6ULL, 0x38790427823a1198ULL, },
+ { 0x11760a6866984906ULL, 0x38280709862a18aaULL, },
+ { 0x355ee4445e3624a9ULL, 0x3a70056ab5ba156aULL, },
+ { 0x6990f6508b1005efULL, 0x19d2f282bd2beb34ULL, },
+ { 0x09f8e7147ee80358ULL, 0x0ea3c3a4d25af434ULL, }, /* 96 */
+ { 0x0270e58e89681a57ULL, 0xed529f3dfdf4fa64ULL, },
+ { 0x2fe0ff749ea038b9ULL, 0x08bfb178f83600f4ULL, },
+ { 0x0c98e7fe6a903991ULL, 0xf0f0da2312380064ULL, },
+ { 0x272ce738ba222968ULL, 0xf060e7ef217afed4ULL, },
+ { 0x1b11fce0969a2387ULL, 0xebe0ecf24235fee0ULL, },
+ { 0x1628f080a22617f4ULL, 0xeb86f0ea54aafebcULL, },
+ { 0x0b6abf0075b21275ULL, 0xee56f2fe4664ff28ULL, },
+ { 0x2d12d3d2642dcfbbULL, 0xde28f62c3ff20223ULL, }, /* 104 */
+ { 0x24a2f1b03fd408a0ULL, 0xd2baf84428ad0529ULL, },
+ { 0xf7c6115e36c734f8ULL, 0xd6a8f9d00d740916ULL, },
+ { 0xe656ec5832b62134ULL, 0xde02fb961c9f0c1bULL, },
+ { 0xf580051836e82d2eULL, 0xed2a0e7efa190093ULL, },
+ { 0xc9300cbe462435ecULL, 0xf33df43e02952973ULL, },
+ { 0xbff0f9ec66bc299eULL, 0xf581f02ee651f985ULL, },
+ { 0x9e90f34e7f2c06f4ULL, 0x01e3f07e04092877ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_S_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_S_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_S_H__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_S_H__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction DPADD_S.W
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Dot Product";
+ char *instruction_name = "DPADD_S.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000200000002ULL, 0x0000000200000002ULL, }, /* 0 */
+ { 0x0000000200000002ULL, 0x0000000200000002ULL, },
+ { 0x0000aaae0000aaaeULL, 0x0000aaae0000aaaeULL, },
+ { 0x0000000400000004ULL, 0x0000000400000004ULL, },
+ { 0x0000666c0000666cULL, 0x0000666c0000666cULL, },
+ { 0x0000000600000006ULL, 0x0000000600000006ULL, },
+ { 0xffffe39500008e40ULL, 0x000038ebffffe395ULL, },
+ { 0x0000000800000008ULL, 0x0000000800000008ULL, },
+ { 0x0000000800000008ULL, 0x0000000800000008ULL, }, /* 8 */
+ { 0x0000000800000008ULL, 0x0000000800000008ULL, },
+ { 0x0000000800000008ULL, 0x0000000800000008ULL, },
+ { 0x0000000800000008ULL, 0x0000000800000008ULL, },
+ { 0x0000000800000008ULL, 0x0000000800000008ULL, },
+ { 0x0000000800000008ULL, 0x0000000800000008ULL, },
+ { 0x0000000800000008ULL, 0x0000000800000008ULL, },
+ { 0x0000000800000008ULL, 0x0000000800000008ULL, },
+ { 0x0000aab40000aab4ULL, 0x0000aab40000aab4ULL, }, /* 16 */
+ { 0x0000aab40000aab4ULL, 0x0000aab40000aab4ULL, },
+ { 0x38e51c7c38e51c7cULL, 0x38e51c7c38e51c7cULL, },
+ { 0x0001556000015560ULL, 0x0001556000015560ULL, },
+ { 0x2224445022244450ULL, 0x2224445022244450ULL, },
+ { 0x0002000c0002000cULL, 0x0002000c0002000cULL, },
+ { 0xf686ed162f6b0988ULL, 0x12f925faf686ed16ULL, },
+ { 0x0002aab80002aab8ULL, 0x0002aab80002aab8ULL, },
+ { 0x0002000e0002000eULL, 0x0002000e0002000eULL, }, /* 24 */
+ { 0x0002000e0002000eULL, 0x0002000e0002000eULL, },
+ { 0xc71e38f2c71e38f2ULL, 0xc71e38f2c71e38f2ULL, },
+ { 0x0001556400015564ULL, 0x0001556400015564ULL, },
+ { 0xdddeccdcdddeccdcULL, 0xdddeccdcdddeccdcULL, },
+ { 0x0000aaba0000aabaULL, 0x0000aaba0000aabaULL, },
+ { 0x097ba13fd0982f78ULL, 0xed09bdb1097ba13fULL, },
+ { 0x0000001000000010ULL, 0x0000001000000010ULL, },
+ { 0x0000667800006678ULL, 0x0000667800006678ULL, }, /* 32 */
+ { 0x0000667800006678ULL, 0x0000667800006678ULL, },
+ { 0x2223556822235568ULL, 0x2223556822235568ULL, },
+ { 0x0000cce00000cce0ULL, 0x0000cce00000cce0ULL, },
+ { 0x147c5200147c5200ULL, 0x147c5200147c5200ULL, },
+ { 0x0001334800013348ULL, 0x0001334800013348ULL, },
+ { 0xfa50e9541c73a510ULL, 0x0b6260ccfa50e954ULL, },
+ { 0x000199b0000199b0ULL, 0x000199b0000199b0ULL, },
+ { 0x0001334a0001334aULL, 0x0001334a0001334aULL, }, /* 40 */
+ { 0x0001334a0001334aULL, 0x0001334a0001334aULL, },
+ { 0xdddeef06dddeef06ULL, 0xdddeef06dddeef06ULL, },
+ { 0x0000cce40000cce4ULL, 0x0000cce40000cce4ULL, },
+ { 0xeb85ae2ceb85ae2cULL, 0xeb85ae2ceb85ae2cULL, },
+ { 0x0000667e0000667eULL, 0x0000667e0000667eULL, },
+ { 0x05b09401e38e82f0ULL, 0xf49f71df05b09401ULL, },
+ { 0x0000001800000018ULL, 0x0000001800000018ULL, },
+ { 0xffffe3a700008e52ULL, 0x000038fdffffe3a7ULL, }, /* 48 */
+ { 0xffffe3a700008e52ULL, 0x000038fdffffe3a7ULL, },
+ { 0xf684d0b12f6997ceULL, 0x12f75eebf684d0b1ULL, },
+ { 0xffffc73600011c8cULL, 0x000071e2ffffc736ULL, },
+ { 0xfa4f7d421c738e54ULL, 0x0b619f66fa4f7d42ULL, },
+ { 0xffffaac50001aac6ULL, 0x0000aac7ffffaac5ULL, },
+ { 0x0fcce6d235bcf9caULL, 0x3f36f0500fcce6d2ULL, },
+ { 0xffff8e5400023900ULL, 0x0000e3acffff8e54ULL, },
+ { 0xffffaac70001aac8ULL, 0x0000aac9ffffaac7ULL, }, /* 56 */
+ { 0xffffaac70001aac8ULL, 0x0000aac9ffffaac7ULL, },
+ { 0x097b6869d0994bf8ULL, 0xed0a2f87097b6869ULL, },
+ { 0xffffc73a00011c90ULL, 0x000071e6ffffc73aULL, },
+ { 0x05b07796e38f1130ULL, 0xf49faaca05b07796ULL, },
+ { 0xffffe3ad00008e58ULL, 0x00003903ffffe3adULL, },
+ { 0xf0328b2fca45cd8eULL, 0xc0ca2c5ff0328b2fULL, },
+ { 0x0000002000000020ULL, 0x0000002000000020ULL, },
+ { 0x3a57fe9422c255a4ULL, 0x16b6ba1518facfc9ULL, }, /* 64 */
+ { 0x3c4b6c241c0669eaULL, 0x193d8a02feefaadeULL, },
+ { 0x6b6084e0ea284328ULL, 0x2271e08cf3dc0f77ULL, },
+ { 0x34b7f0f2ef20736aULL, 0xfb8f1ed3fd8c7dadULL, },
+ { 0x36ab5e82e86487b0ULL, 0xfe15eec0e38158c2ULL, },
+ { 0x36bda5cf0c93ba59ULL, 0x120897b5002b2653ULL, },
+ { 0x38025a59113b8b36ULL, 0x2453b4030525b498ULL, },
+ { 0x362cc9c2346212c9ULL, 0x3bf2477af46d1b56ULL, },
+ { 0x6541e27e0283ec07ULL, 0x45269e04e9597fefULL, }, /* 72 */
+ { 0x66869708072bbce4ULL, 0x5771ba52ee540e34ULL, },
+ { 0x9bb32f904f6ed245ULL, 0x6a56b2930fcf50fdULL, },
+ { 0x6feae478431ee5e4ULL, 0x731e8c13284ca993ULL, },
+ { 0x3942508a48171626ULL, 0x4c3bca5a31fd17c9ULL, },
+ { 0x376cbff36b3d9db9ULL, 0x63da5dd121447e87ULL, },
+ { 0x0ba474db5eedb158ULL, 0x6ca2375139c1d71dULL, },
+ { 0x3edb00658507867dULL, 0xd6e9ca725a84f021ULL, },
+ { 0x21746d8f492aab6bULL, 0xc86ec10d5ef05719ULL, }, /* 80 */
+ { 0x21105bf47228d8e1ULL, 0xd541f981830d22c5ULL, },
+ { 0xf90ba39c64a9aab9ULL, 0xd00d1cd8b17e0558ULL, },
+ { 0xedf1ebed93975370ULL, 0xd7fd3855cb7afcd4ULL, },
+ { 0xf85b68939e46773eULL, 0xceb49456ccc86662ULL, },
+ { 0xf8a465f666205360ULL, 0xe8078ebee9b86012ULL, },
+ { 0xdaa6e8fa242ed740ULL, 0xfd8488e8ff04a562ULL, },
+ { 0xc84291663638bd8eULL, 0x360ea9ec09bfe9aaULL, },
+ { 0xed300e0228a5c87eULL, 0x42280c3610aaee67ULL, }, /* 88 */
+ { 0xed8592684150f62dULL, 0x43c5604a0c58a5a1ULL, },
+ { 0x1661583a33e11b5dULL, 0x38e0b738fb2ab5fdULL, },
+ { 0x27e2359b43cb17c4ULL, 0x4169f958054c48f1ULL, },
+ { 0x0ff9c2b35666c87aULL, 0x546263e7ee7c57c1ULL, },
+ { 0x0f9e0bba7cf02cdcULL, 0x3fbf94eb097a6841ULL, },
+ { 0x06c9e6ca464484ecULL, 0x61838f28157007d3ULL, },
+ { 0x0791b5936e65c7d8ULL, 0x6a978c3b0d46a893ULL, },
+ { 0x0b5ca2c16d1c8082ULL, 0x84d8b2a628807419ULL, }, /* 96 */
+ { 0x0f3c4ea553ddefbaULL, 0x5d23288204008ac5ULL, },
+ { 0x006066f95bad42d4ULL, 0x7a5e585328976801ULL, },
+ { 0xf610532580647c0eULL, 0xa2551d9f07de4a9aULL, },
+ { 0xf65aca543e1e0beaULL, 0x936bdec820b433d4ULL, },
+ { 0xf66f1d9c4e4a0274ULL, 0x945159553437f0d0ULL, },
+ { 0xf6a34c5265777892ULL, 0x744c4f1e33a0fa19ULL, },
+ { 0xf6e8ae026961c977ULL, 0x679ecf7e36000115ULL, },
+ { 0x13ee44e6654e7066ULL, 0x828c7150244331b9ULL, }, /* 104 */
+ { 0xf787434e16614d78ULL, 0x55caaa201f72a96eULL, },
+ { 0xe4e9b290ecfd62e7ULL, 0x76440870087d3a2cULL, },
+ { 0x065e2c1ac531b8faULL, 0x86cb35600e1a0d9bULL, },
+ { 0x0d00c2eeb7cb8587ULL, 0xa3f3f27b07c3312fULL, },
+ { 0x0d62db84ab6f1a84ULL, 0xd3421106ff7d27d5ULL, },
+ { 0x10143b76893e48fbULL, 0xdf44d938fb177a2fULL, },
+ { 0x1c4ff82055152453ULL, 0xffe7837ceebc407dULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_S_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_S_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_S_W__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_S_W__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction DPADD_U.D
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Dot Product";
+ char *instruction_name = "DPADD_U.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xfffffffc00000002ULL, 0xfffffffc00000002ULL, }, /* 0 */
+ { 0xfffffffc00000002ULL, 0xfffffffc00000002ULL, },
+ { 0x5555554eaaaaaaaeULL, 0x5555554eaaaaaaaeULL, },
+ { 0xfffffff800000004ULL, 0xfffffff800000004ULL, },
+ { 0x9999998e6666666cULL, 0x9999998e6666666cULL, },
+ { 0xfffffff400000006ULL, 0xfffffff400000006ULL, },
+ { 0x71c71c638e38e395ULL, 0x1c71c70de38e38ebULL, },
+ { 0xfffffff000000008ULL, 0xfffffff000000008ULL, },
+ { 0xfffffff000000008ULL, 0xfffffff000000008ULL, }, /* 8 */
+ { 0xfffffff000000008ULL, 0xfffffff000000008ULL, },
+ { 0xfffffff000000008ULL, 0xfffffff000000008ULL, },
+ { 0xfffffff000000008ULL, 0xfffffff000000008ULL, },
+ { 0xfffffff000000008ULL, 0xfffffff000000008ULL, },
+ { 0xfffffff000000008ULL, 0xfffffff000000008ULL, },
+ { 0xfffffff000000008ULL, 0xfffffff000000008ULL, },
+ { 0xfffffff000000008ULL, 0xfffffff000000008ULL, },
+ { 0x55555542aaaaaab4ULL, 0x55555542aaaaaab4ULL, }, /* 16 */
+ { 0x55555542aaaaaab4ULL, 0x55555542aaaaaab4ULL, },
+ { 0x38e38e2471c71c7cULL, 0x38e38e2471c71c7cULL, },
+ { 0xaaaaaa9555555560ULL, 0xaaaaaa9555555560ULL, },
+ { 0xbbbbbba444444450ULL, 0xbbbbbba444444450ULL, },
+ { 0xffffffe80000000cULL, 0xffffffe80000000cULL, },
+ { 0xf684bd87b425ed16ULL, 0xbda12f4e97b425faULL, },
+ { 0x5555553aaaaaaab8ULL, 0x5555553aaaaaaab8ULL, },
+ { 0xffffffe40000000eULL, 0xffffffe40000000eULL, }, /* 24 */
+ { 0xffffffe40000000eULL, 0xffffffe40000000eULL, },
+ { 0x71c71c54e38e38f2ULL, 0x71c71c54e38e38f2ULL, },
+ { 0xaaaaaa8d55555564ULL, 0xaaaaaa8d55555564ULL, },
+ { 0x33333314ccccccdcULL, 0x33333314ccccccdcULL, },
+ { 0x55555536aaaaaabaULL, 0x55555536aaaaaabaULL, },
+ { 0xd097b40684bda13fULL, 0xb425ece9f684bdb1ULL, },
+ { 0xffffffe000000010ULL, 0xffffffe000000010ULL, },
+ { 0x9999997666666678ULL, 0x9999997666666678ULL, }, /* 32 */
+ { 0x9999997666666678ULL, 0x9999997666666678ULL, },
+ { 0xaaaaaa8555555568ULL, 0xaaaaaa8555555568ULL, },
+ { 0x3333330ccccccce0ULL, 0x3333330ccccccce0ULL, },
+ { 0x7ae147851eb85200ULL, 0x7ae147851eb85200ULL, },
+ { 0xcccccca333333348ULL, 0xcccccca333333348ULL, },
+ { 0xf49f49c93e93e954ULL, 0xb05b0584b60b60ccULL, },
+ { 0x66666639999999b0ULL, 0x66666639999999b0ULL, },
+ { 0xcccccc9f3333334aULL, 0xcccccc9f3333334aULL, }, /* 40 */
+ { 0xcccccc9f3333334aULL, 0xcccccc9f3333334aULL, },
+ { 0x111110e2eeeeef06ULL, 0x111110e2eeeeef06ULL, },
+ { 0x33333304cccccce4ULL, 0x33333304cccccce4ULL, },
+ { 0x851eb822e147ae2cULL, 0x851eb822e147ae2cULL, },
+ { 0x9999996a6666667eULL, 0x9999996a6666667eULL, },
+ { 0xe38e38b3e93e9401ULL, 0xd27d27a2c71c71dfULL, },
+ { 0xffffffd000000018ULL, 0xffffffd000000018ULL, },
+ { 0x71c71c3f8e38e3a7ULL, 0x1c71c6e9e38e38fdULL, }, /* 48 */
+ { 0x71c71c3f8e38e3a7ULL, 0x1c71c6e9e38e38fdULL, },
+ { 0x684bd9df425ed0b1ULL, 0xda12f6507b425eebULL, },
+ { 0xe38e38af1c71c736ULL, 0x38e38e03c71c71e2ULL, },
+ { 0x0b60b5d527d27d42ULL, 0x1c71c6e549f49f66ULL, },
+ { 0x5555551eaaaaaac5ULL, 0x5555551daaaaaac7ULL, },
+ { 0x6e9e061a4587e6d2ULL, 0x2c3f35816b74f050ULL, },
+ { 0xc71c718e38e38e54ULL, 0x71c71c378e38e3acULL, },
+ { 0x5555551aaaaaaac7ULL, 0x55555519aaaaaac9ULL, }, /* 56 */
+ { 0x5555551aaaaaaac7ULL, 0x55555519aaaaaac9ULL, },
+ { 0xb425eccda12f6869ULL, 0xed097b05bda12f87ULL, },
+ { 0xe38e38a71c71c73aULL, 0x38e38dfbc71c71e6ULL, },
+ { 0x5555551777777796ULL, 0xeeeeeeb0aaaaaacaULL, },
+ { 0x71c71c338e38e3adULL, 0x1c71c6dde38e3903ULL, },
+ { 0xca4587a781948b2fULL, 0x61f9ad9406522c5fULL, },
+ { 0xffffffc000000020ULL, 0xffffffc000000020ULL, },
+ { 0x4f10a2061266c2b0ULL, 0x132f36fdaebdb734ULL, }, /* 64 */
+ { 0xe173955d0a3d6d94ULL, 0x2de485b19f4dac90ULL, },
+ { 0x5a9b88364205b90cULL, 0xe3c89435af2c3022ULL, },
+ { 0xa5506be1e16f25e8ULL, 0xb5d99e2c137656f2ULL, },
+ { 0x37b35f38d945d0ccULL, 0xd08eece004064c4eULL, },
+ { 0x46c3bc088c276755ULL, 0xd3ba26318bdfb302ULL, },
+ { 0x288f407241d1cf13ULL, 0xe4e2d49bf38e1598ULL, },
+ { 0xb38b871fddd1234aULL, 0xfd7386eef5421908ULL, },
+ { 0x2cb379f915996ec2ULL, 0xb357957305209c9aULL, }, /* 72 */
+ { 0x0e7efe62cb43d680ULL, 0xc48043dd6cceff30ULL, },
+ { 0x0966991866fb9f64ULL, 0x3d26b2ddb9e53ac1ULL, },
+ { 0x9961eeb6d99e4586ULL, 0xc46ae4f9206e6e69ULL, },
+ { 0xe416d2627907b262ULL, 0x967beeef84b89539ULL, },
+ { 0x6f13191015070699ULL, 0xaf0ca142866c98a9ULL, },
+ { 0xff0e6eae87a9acbbULL, 0x3650d35decf5cc51ULL, },
+ { 0x52fc668a5f0acfa8ULL, 0xf4ee28afafeae691ULL, },
+ { 0x8e335693216733a0ULL, 0xebf294e7e1b7da9fULL, }, /* 80 */
+ { 0x242889888a96ab79ULL, 0x1029e138e123d999ULL, },
+ { 0xa117d2200713df49ULL, 0xa936d669733f9d55ULL, },
+ { 0xea5eaf7c9d524d27ULL, 0x533cccdee6d6ad0dULL, },
+ { 0x8014252a44e6c8b7ULL, 0x5139a5a2ff917d2dULL, },
+ { 0x12e82535692eaeadULL, 0x6c74742f3b1a47edULL, },
+ { 0x6bfad303a455af5fULL, 0xa4da8c7753e03c42ULL, },
+ { 0xd7d1673544f2b638ULL, 0x37b76789ca48e5eaULL, },
+ { 0x55b32da89b1ab874ULL, 0x1136a063291c7430ULL, }, /* 88 */
+ { 0xd8fa08f2c6e9500cULL, 0x15e6a0cfa25fce7eULL, },
+ { 0xfb6ec0cb14ee46c0ULL, 0x85e0ab776ca06e87ULL, },
+ { 0x7170744f4e43c44fULL, 0x17ee0476d6f5954fULL, },
+ { 0xba3c379c6c72bc03ULL, 0xf4a9e78f41249a57ULL, },
+ { 0x923c97db1bf9726fULL, 0x0c32ba5fa7655f81ULL, },
+ { 0x08ff0c9a1b07a05dULL, 0x7e05b61db39e9936ULL, },
+ { 0x16e37ad7ce0b9d05ULL, 0x3aa86333e7ca176eULL, },
+ { 0x4396d885c2a89499ULL, 0x3259d55cbbd56e50ULL, }, /* 96 */
+ { 0x86505184e2848fd5ULL, 0xfbe6ef6acb48e5d8ULL, },
+ { 0xf19ecbd2f0d9cb45ULL, 0x102d8886fc3ba2e4ULL, },
+ { 0x985e99073ad19cddULL, 0x0fae6c4a600fe8c8ULL, },
+ { 0x40076fc7eafc7c7aULL, 0x18d0edce69b82b2cULL, },
+ { 0xc633d71b8943703fULL, 0x236de461c55a6368ULL, },
+ { 0xb2b44afd6be31aa8ULL, 0x366f22bc07569aa2ULL, },
+ { 0x832148e5fdab87bfULL, 0x3b138b90c7099132ULL, },
+ { 0x9388b611f0bd2a51ULL, 0xc95a7ba92714878aULL, }, /* 104 */
+ { 0xa598b2d7184dc31bULL, 0x02d31201c0d1f3a9ULL, },
+ { 0x26b9d9c7d27ede61ULL, 0x84305afc61d71edcULL, },
+ { 0xd994c5da2b819a07ULL, 0xda2ed7517c38dd10ULL, },
+ { 0x490b25198d55f4bbULL, 0xa54a7d332b34db68ULL, },
+ { 0x9d17b063519fea3aULL, 0x1d81a65b0c1f8770ULL, },
+ { 0x000b355286100badULL, 0x35e1e113d0b4c238ULL, },
+ { 0x316423fb99a16a0dULL, 0xddbffc10af9e9540ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_U_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_U_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_U_D__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_U_D__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction DPADD_U.H
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Dot Product";
+ char *instruction_name = "DPADD_U.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xfc02fc02fc02fc02ULL, 0xfc02fc02fc02fc02ULL, }, /* 0 */
+ { 0xfc02fc02fc02fc02ULL, 0xfc02fc02fc02fc02ULL, },
+ { 0x4eae4eae4eae4eaeULL, 0x4eae4eae4eae4eaeULL, },
+ { 0xf804f804f804f804ULL, 0xf804f804f804f804ULL, },
+ { 0x8e6c8e6c8e6c8e6cULL, 0x8e6c8e6c8e6c8e6cULL, },
+ { 0xf406f406f406f406ULL, 0xf406f406f406f406ULL, },
+ { 0x63950debb9406395ULL, 0x0debb94063950debULL, },
+ { 0xf008f008f008f008ULL, 0xf008f008f008f008ULL, },
+ { 0xf008f008f008f008ULL, 0xf008f008f008f008ULL, }, /* 8 */
+ { 0xf008f008f008f008ULL, 0xf008f008f008f008ULL, },
+ { 0xf008f008f008f008ULL, 0xf008f008f008f008ULL, },
+ { 0xf008f008f008f008ULL, 0xf008f008f008f008ULL, },
+ { 0xf008f008f008f008ULL, 0xf008f008f008f008ULL, },
+ { 0xf008f008f008f008ULL, 0xf008f008f008f008ULL, },
+ { 0xf008f008f008f008ULL, 0xf008f008f008f008ULL, },
+ { 0xf008f008f008f008ULL, 0xf008f008f008f008ULL, },
+ { 0x42b442b442b442b4ULL, 0x42b442b442b442b4ULL, }, /* 16 */
+ { 0x42b442b442b442b4ULL, 0x42b442b442b442b4ULL, },
+ { 0x247c247c247c247cULL, 0x247c247c247c247cULL, },
+ { 0x9560956095609560ULL, 0x9560956095609560ULL, },
+ { 0xa450a450a450a450ULL, 0xa450a450a450a450ULL, },
+ { 0xe80ce80ce80ce80cULL, 0xe80ce80ce80ce80cULL, },
+ { 0xdd16a3fa6b88dd16ULL, 0xa3fa6b88dd16a3faULL, },
+ { 0x3ab83ab83ab83ab8ULL, 0x3ab83ab83ab83ab8ULL, },
+ { 0xe40ee40ee40ee40eULL, 0xe40ee40ee40ee40eULL, }, /* 24 */
+ { 0xe40ee40ee40ee40eULL, 0xe40ee40ee40ee40eULL, },
+ { 0x54f254f254f254f2ULL, 0x54f254f254f254f2ULL, },
+ { 0x8d648d648d648d64ULL, 0x8d648d648d648d64ULL, },
+ { 0x14dc14dc14dc14dcULL, 0x14dc14dc14dc14dcULL, },
+ { 0x36ba36ba36ba36baULL, 0x36ba36ba36ba36baULL, },
+ { 0xb13f94b17878b13fULL, 0x94b17878b13f94b1ULL, },
+ { 0xe010e010e010e010ULL, 0xe010e010e010e010ULL, },
+ { 0x7678767876787678ULL, 0x7678767876787678ULL, }, /* 32 */
+ { 0x7678767876787678ULL, 0x7678767876787678ULL, },
+ { 0x8568856885688568ULL, 0x8568856885688568ULL, },
+ { 0x0ce00ce00ce00ce0ULL, 0x0ce00ce00ce00ce0ULL, },
+ { 0x5200520052005200ULL, 0x5200520052005200ULL, },
+ { 0xa348a348a348a348ULL, 0xa348a348a348a348ULL, },
+ { 0xc95484cc4110c954ULL, 0x84cc4110c95484ccULL, },
+ { 0x39b039b039b039b0ULL, 0x39b039b039b039b0ULL, },
+ { 0x9f4a9f4a9f4a9f4aULL, 0x9f4a9f4a9f4a9f4aULL, }, /* 40 */
+ { 0x9f4a9f4a9f4a9f4aULL, 0x9f4a9f4a9f4a9f4aULL, },
+ { 0xe306e306e306e306ULL, 0xe306e306e306e306ULL, },
+ { 0x04e404e404e404e4ULL, 0x04e404e404e404e4ULL, },
+ { 0x562c562c562c562cULL, 0x562c562c562c562cULL, },
+ { 0x6a7e6a7e6a7e6a7eULL, 0x6a7e6a7e6a7e6a7eULL, },
+ { 0xb401a2df91f0b401ULL, 0xa2df91f0b401a2dfULL, },
+ { 0xd018d018d018d018ULL, 0xd018d018d018d018ULL, },
+ { 0x3fa7e9fd95523fa7ULL, 0xe9fd95523fa7e9fdULL, }, /* 48 */
+ { 0x3fa7e9fd95523fa7ULL, 0xe9fd95523fa7e9fdULL, },
+ { 0x34b1a5eb18ce34b1ULL, 0xa5eb18ce34b1a5ebULL, },
+ { 0xaf3603e25a8caf36ULL, 0x03e25a8caf3603e2ULL, },
+ { 0xd542e566f854d542ULL, 0xe566f854d542e566ULL, },
+ { 0x1ec51dc71fc61ec5ULL, 0x1dc71fc61ec51dc7ULL, },
+ { 0x36d2f3507aca36d2ULL, 0xf3507aca36d2f350ULL, },
+ { 0x8e5437ace5008e54ULL, 0x37ace5008e5437acULL, },
+ { 0x1ac719c91bc81ac7ULL, 0x19c91bc81ac719c9ULL, }, /* 56 */
+ { 0x1ac719c91bc81ac7ULL, 0x19c91bc81ac719c9ULL, },
+ { 0x7869b087eaf87869ULL, 0xb087eaf87869b087ULL, },
+ { 0xa73afbe65290a73aULL, 0xfbe65290a73afbe6ULL, },
+ { 0x1796b0ca4b301796ULL, 0xb0ca4b301796b0caULL, },
+ { 0x33adde03895833adULL, 0xde03895833adde03ULL, },
+ { 0x8b2f225ff38e8b2fULL, 0x225ff38e8b2f225fULL, },
+ { 0xc020c020c020c020ULL, 0xc020c020c020c020ULL, },
+ { 0x34443154ebe4ec59ULL, 0xff8ae31df73d39b0ULL, }, /* 64 */
+ { 0x084880383032306cULL, 0x6831f4b22a587de0ULL, },
+ { 0x88eca4049c587e93ULL, 0xca865ad6e8ab9840ULL, },
+ { 0xe522f524bdcadd1dULL, 0x54ccaffeb00f3b20ULL, },
+ { 0xb926440802182130ULL, 0xbd73c193e32a7f50ULL, },
+ { 0x3c436a516daabc21ULL, 0xad084cd0f46491a4ULL, },
+ { 0x27b3ac0f1c2c2c2eULL, 0x802ef7580d00b12eULL, },
+ { 0xd025c9d65495de4cULL, 0x729f70a02b1b9712ULL, },
+ { 0x50c9eda2c0bb2c73ULL, 0xd4f4d6c4e96eb172ULL, }, /* 72 */
+ { 0x3c392f606f3d9c80ULL, 0xa81a814c020ad0fcULL, },
+ { 0xcf6d16889c4f27f9ULL, 0x644b18717b7cd7e5ULL, },
+ { 0x3673589e07dcc9afULL, 0x451e58c9f775050fULL, },
+ { 0x92a9a9be294e2839ULL, 0xcf64adf1bed9a7efULL, },
+ { 0x3b1bc78561b7da57ULL, 0xc1d52739dcf48dd3ULL, },
+ { 0xa221099bcd447c0dULL, 0xa2a8679158edbafdULL, },
+ { 0xeb8222a8f9295b55ULL, 0xd3326611d982e681ULL, },
+ { 0x9e2ec7142fc38eccULL, 0x252170b1ef468aadULL, }, /* 80 */
+ { 0x5b3cced0addf038eULL, 0x4792d47b141b612dULL, },
+ { 0xad78e4f4df354c2fULL, 0xcd93f2f8260072b6ULL, },
+ { 0x1e3041f03b3c9d99ULL, 0xc8df44c83f16491aULL, },
+ { 0x42003b965b6cf7faULL, 0x5d309124882a7c82ULL, },
+ { 0x82b67598b4cfbfcbULL, 0x920afeb79da82432ULL, },
+ { 0x1a0a2a0ede448d00ULL, 0xb0b8797422bf2d4eULL, },
+ { 0x288031e03ccc097aULL, 0xbee01b9c6a6f85c8ULL, },
+ { 0x72c0106694442af7ULL, 0x50aa560d08f0ea98ULL, }, /* 88 */
+ { 0x710637d8e7d45355ULL, 0xfa50963144a8cb2cULL, },
+ { 0xbf0eecaa3a2faae6ULL, 0x63e63b048e4cebf3ULL, },
+ { 0x16f03414587a870eULL, 0x72f35dbcffa25349ULL, },
+ { 0x860072bc94eeb761ULL, 0xf61ea6c34a7a8fc5ULL, },
+ { 0x0962bb704a1c48aaULL, 0x245c33d36e927f7fULL, },
+ { 0x31e284ea963ac4c2ULL, 0x77782d72d0929bc6ULL, },
+ { 0x8d10d6a4d868ace6ULL, 0x29fba58a7f86a05cULL, },
+ { 0xde98199821f81f82ULL, 0x9afbdf4d3dea12acULL, }, /* 96 */
+ { 0x9378a92e86104a4dULL, 0x2d160528eade271cULL, },
+ { 0x134065aca120761fULL, 0x431f140f3db4433cULL, },
+ { 0x37d8497ac688a50dULL, 0x63391a6dd0b6741cULL, },
+ { 0x0e1578a8502e25b8ULL, 0xa12e387d0e90b4d4ULL, },
+ { 0x2b65b9a082a8483bULL, 0xd8e26e173326bf2cULL, },
+ { 0xa084f7800a3a820bULL, 0xc220c0c740af27aaULL, },
+ { 0x9f5c29002e8ae771ULL, 0xeea4613d7100db80ULL, },
+ { 0x2a8844debf5e9d5eULL, 0x9d46e906bc7b0527ULL, }, /* 104 */
+ { 0x769006829567219dULL, 0xf041a3364eb808ecULL, },
+ { 0xf87860ea545d8208ULL, 0x4ba95712a1ba1c84ULL, },
+ { 0xc9483d8edc44cc9eULL, 0xe5aeac4a2c832ae0ULL, },
+ { 0x37706d823a10b0daULL, 0x079d461a6b55dbf4ULL, },
+ { 0x72109dfa526c8ea6ULL, 0x9f45813ac7e235caULL, },
+ { 0xa8e0f6aa85343e96ULL, 0x37cdf6b28585e2d4ULL, },
+ { 0x37803ef0bffea306ULL, 0x17150f92ff9c2ed8ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_U_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_U_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_U_H__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_U_H__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction DPADD_U.W
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Dot Product";
+ char *instruction_name = "DPADD_U.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xfffc0002fffc0002ULL, 0xfffc0002fffc0002ULL, }, /* 0 */
+ { 0xfffc0002fffc0002ULL, 0xfffc0002fffc0002ULL, },
+ { 0x554eaaae554eaaaeULL, 0x554eaaae554eaaaeULL, },
+ { 0xfff80004fff80004ULL, 0xfff80004fff80004ULL, },
+ { 0x998e666c998e666cULL, 0x998e666c998e666cULL, },
+ { 0xfff40006fff40006ULL, 0xfff40006fff40006ULL, },
+ { 0x1c63e39571b88e40ULL, 0xc70e38eb1c63e395ULL, },
+ { 0xfff00008fff00008ULL, 0xfff00008fff00008ULL, },
+ { 0xfff00008fff00008ULL, 0xfff00008fff00008ULL, }, /* 8 */
+ { 0xfff00008fff00008ULL, 0xfff00008fff00008ULL, },
+ { 0xfff00008fff00008ULL, 0xfff00008fff00008ULL, },
+ { 0xfff00008fff00008ULL, 0xfff00008fff00008ULL, },
+ { 0xfff00008fff00008ULL, 0xfff00008fff00008ULL, },
+ { 0xfff00008fff00008ULL, 0xfff00008fff00008ULL, },
+ { 0xfff00008fff00008ULL, 0xfff00008fff00008ULL, },
+ { 0xfff00008fff00008ULL, 0xfff00008fff00008ULL, },
+ { 0x5542aab45542aab4ULL, 0x5542aab45542aab4ULL, }, /* 16 */
+ { 0x5542aab45542aab4ULL, 0x5542aab45542aab4ULL, },
+ { 0x38cf1c7c38cf1c7cULL, 0x38cf1c7c38cf1c7cULL, },
+ { 0xaa955560aa955560ULL, 0xaa955560aa955560ULL, },
+ { 0xbba44450bba44450ULL, 0xbba44450bba44450ULL, },
+ { 0xffe8000cffe8000cULL, 0xffe8000cffe8000cULL, },
+ { 0xbd87ed16f66b0988ULL, 0x84a425fabd87ed16ULL, },
+ { 0x553aaab8553aaab8ULL, 0x553aaab8553aaab8ULL, },
+ { 0xffe4000effe4000eULL, 0xffe4000effe4000eULL, }, /* 24 */
+ { 0xffe4000effe4000eULL, 0xffe4000effe4000eULL, },
+ { 0x71aa38f271aa38f2ULL, 0x71aa38f271aa38f2ULL, },
+ { 0xaa8d5564aa8d5564ULL, 0xaa8d5564aa8d5564ULL, },
+ { 0x3314ccdc3314ccdcULL, 0x3314ccdc3314ccdcULL, },
+ { 0x5536aaba5536aabaULL, 0x5536aaba5536aabaULL, },
+ { 0xb406a13fd0782f78ULL, 0x9794bdb1b406a13fULL, },
+ { 0xffe00010ffe00010ULL, 0xffe00010ffe00010ULL, },
+ { 0x9976667899766678ULL, 0x9976667899766678ULL, }, /* 32 */
+ { 0x9976667899766678ULL, 0x9976667899766678ULL, },
+ { 0xaa855568aa855568ULL, 0xaa855568aa855568ULL, },
+ { 0x330ccce0330ccce0ULL, 0x330ccce0330ccce0ULL, },
+ { 0x7ab852007ab85200ULL, 0x7ab852007ab85200ULL, },
+ { 0xcca33348cca33348ULL, 0xcca33348cca33348ULL, },
+ { 0xb02fe954f473a510ULL, 0x6beb60ccb02fe954ULL, },
+ { 0x663999b0663999b0ULL, 0x663999b0663999b0ULL, },
+ { 0xcc9f334acc9f334aULL, 0xcc9f334acc9f334aULL, }, /* 40 */
+ { 0xcc9f334acc9f334aULL, 0xcc9f334acc9f334aULL, },
+ { 0x10e2ef0610e2ef06ULL, 0x10e2ef0610e2ef06ULL, },
+ { 0x3304cce43304cce4ULL, 0x3304cce43304cce4ULL, },
+ { 0x84efae2c84efae2cULL, 0x84efae2c84efae2cULL, },
+ { 0x996a667e996a667eULL, 0x996a667e996a667eULL, },
+ { 0xd24d9401e35e82f0ULL, 0xc13c71dfd24d9401ULL, },
+ { 0xffd00018ffd00018ULL, 0xffd00018ffd00018ULL, },
+ { 0x1c3fe3a771948e52ULL, 0xc6ea38fd1c3fe3a7ULL, }, /* 48 */
+ { 0x1c3fe3a771948e52ULL, 0xc6ea38fd1c3fe3a7ULL, },
+ { 0xd9dfd0b1681797ceULL, 0x4ba65eebd9dfd0b1ULL, },
+ { 0x38afc736e3591c8cULL, 0x8e0471e238afc736ULL, },
+ { 0x1c3c7d420b298e54ULL, 0x2d4c9f661c3c7d42ULL, },
+ { 0x551faac5551daac6ULL, 0x551eaac7551faac5ULL, },
+ { 0x2c08e6d26e64f9caULL, 0xb0c4f0502c08e6d2ULL, },
+ { 0x718f8e54c6e23900ULL, 0x1c38e3ac718f8e54ULL, },
+ { 0x551baac75519aac8ULL, 0x551aaac9551baac7ULL, }, /* 56 */
+ { 0x551baac75519aac8ULL, 0x551aaac9551baac7ULL, },
+ { 0xecce6869b3e94bf8ULL, 0x25b12f87ecce6869ULL, },
+ { 0x38a7c73ae3511c90ULL, 0x8dfc71e638a7c73aULL, },
+ { 0xeeb1779655171130ULL, 0x884aaacaeeb17796ULL, },
+ { 0x1c33e3ad71888e58ULL, 0xc6de39031c33e3adULL, },
+ { 0x61ba8b2fca05cd8eULL, 0x32522c5f61ba8b2fULL, },
+ { 0xffc00020ffc00020ULL, 0xffc00020ffc00020ULL, },
+ { 0x1883fe94228255a4ULL, 0x1676ba1575c8cfc9ULL, }, /* 64 */
+ { 0x9f026c24710669eaULL, 0x245b8a02c3f8aadeULL, },
+ { 0x985184e0bcca4328ULL, 0x38ede08c879f0f77ULL, },
+ { 0xe844f0f21702736aULL, 0x68d01ed3cbb87dadULL, },
+ { 0x6ec35e82658687b0ULL, 0x76b4eec019e858c2ULL, },
+ { 0x6651a5cf17c5ba59ULL, 0x00db97b536922653ULL, },
+ { 0x10115a59bc888b36ULL, 0x953fb40350cbb498ULL, },
+ { 0x7e8ac9c2890512c9ULL, 0x03c7477aa84e1b56ULL, },
+ { 0x77d9e27ed4c8ec07ULL, 0x18599e046bf47fefULL, }, /* 72 */
+ { 0x21999708798bbce4ULL, 0xacbdba52862e0e34ULL, },
+ { 0x0cce2f904c6cd245ULL, 0x4da0b293fdff50fdULL, },
+ { 0x67a1e4780c1be5e4ULL, 0xce178c138ffda993ULL, },
+ { 0xb795508a66541626ULL, 0xfdf9ca5ad41717c9ULL, },
+ { 0x260ebff332d09db9ULL, 0x6c815dd12b997e87ULL, },
+ { 0x80e274dbf27fb158ULL, 0xecf83751bd97d71dULL, },
+ { 0xb4190065dd35867dULL, 0x84d1ca72f61ef021ULL, },
+ { 0x146be93b2ce39d07ULL, 0xb4edb1658fe8e617ULL, }, /* 80 */
+ { 0x28da2b76b4930398ULL, 0x43fbb752e67034d3ULL, },
+ { 0x6202107639989575ULL, 0xdd1056c8882a591fULL, },
+ { 0x8e704692d2e83f33ULL, 0x8605bb9831163f53ULL, },
+ { 0x19f6294a0938f7c3ULL, 0xb5d3886b8d6db0c9ULL, },
+ { 0x338d977ccca46e03ULL, 0x26ffd0ded278d778ULL, },
+ { 0xbd9d53669d1f0d1fULL, 0xcf6d52287e678700ULL, },
+ { 0x18106087e287df80ULL, 0x6e5a3285497c7c8eULL, },
+ { 0x7be90cbb50b10f2eULL, 0x91193a91e83049caULL, }, /* 88 */
+ { 0xf5c762fa74f1dd41ULL, 0xc6a6d96a1360b472ULL, },
+ { 0xdec724f4426380a0ULL, 0x8e924c103a77a87aULL, },
+ { 0x43bb09c1cc850053ULL, 0x06479b02f6444a68ULL, },
+ { 0x709d98fbece3b6fdULL, 0x0f02ef4f1e3d11f4ULL, },
+ { 0xdf964592c2f0673eULL, 0xbf06914326915827ULL, },
+ { 0xa595174288afc04eULL, 0x4dac2c104d1f338eULL, },
+ { 0xf0400b1764f99f91ULL, 0x904ab47cadc0214cULL, },
+ { 0x7a4505ebaa0a3823ULL, 0xc2ce09ca715dec1cULL, }, /* 96 */
+ { 0xc0c227c1d78e87b7ULL, 0xfc9e0ad8846cfb1bULL, },
+ { 0x4b501be126c0ecd3ULL, 0x47813bbab4be1843ULL, },
+ { 0x8c94284d7bbb0613ULL, 0x5f37b7ed7918a6b1ULL, },
+ { 0x16e12feca5f2470cULL, 0xecb24110b92e33d5ULL, },
+ { 0x2d734e2e0f77e762ULL, 0x2dc8706ed959cbd3ULL, },
+ { 0x5a430652c80bfcc7ULL, 0x835871922d75cf6eULL, },
+ { 0xb30826c2c930c150ULL, 0xe0148a4e74790481ULL, },
+ { 0x46021066c48e3720ULL, 0x6e76bee0c30066e8ULL, }, /* 104 */
+ { 0x80543cd67141b3f2ULL, 0x14074d905449ba08ULL, },
+ { 0x003ba47a25839f81ULL, 0x536fe6e8a79655ebULL, },
+ { 0x709b823c97a86aeeULL, 0x13e9a6a824155b79ULL, },
+ { 0xad5a661d2dfbd29aULL, 0x780997c18cea8383ULL, },
+ { 0x024c799cf912e891ULL, 0x0bb620125e8129b7ULL, },
+ { 0x0de66afc224e0f31ULL, 0x23590398c1ea5059ULL, },
+ { 0x1d512ac23c5b270dULL, 0x38de17a18940924dULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_U_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_U_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_U_W__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPADD_U_W__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction DPSUB_S.D
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Dot Product";
+ char *instruction_name = "DPSUB_S.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xfffffffffffffffeULL, 0xfffffffffffffffeULL, }, /* 0 */
+ { 0xfffffffffffffffeULL, 0xfffffffffffffffeULL, },
+ { 0xffffffff55555552ULL, 0xffffffff55555552ULL, },
+ { 0xfffffffffffffffcULL, 0xfffffffffffffffcULL, },
+ { 0xffffffff99999994ULL, 0xffffffff99999994ULL, },
+ { 0xfffffffffffffffaULL, 0xfffffffffffffffaULL, },
+ { 0xffffffff71c71c6bULL, 0x000000001c71c715ULL, },
+ { 0xfffffffffffffff8ULL, 0xfffffffffffffff8ULL, },
+ { 0xfffffffffffffff8ULL, 0xfffffffffffffff8ULL, }, /* 8 */
+ { 0xfffffffffffffff8ULL, 0xfffffffffffffff8ULL, },
+ { 0xfffffffffffffff8ULL, 0xfffffffffffffff8ULL, },
+ { 0xfffffffffffffff8ULL, 0xfffffffffffffff8ULL, },
+ { 0xfffffffffffffff8ULL, 0xfffffffffffffff8ULL, },
+ { 0xfffffffffffffff8ULL, 0xfffffffffffffff8ULL, },
+ { 0xfffffffffffffff8ULL, 0xfffffffffffffff8ULL, },
+ { 0xfffffffffffffff8ULL, 0xfffffffffffffff8ULL, },
+ { 0xffffffff5555554cULL, 0xffffffff5555554cULL, }, /* 16 */
+ { 0xffffffff5555554cULL, 0xffffffff5555554cULL, },
+ { 0xc71c71c58e38e384ULL, 0xc71c71c58e38e384ULL, },
+ { 0xfffffffeaaaaaaa0ULL, 0xfffffffeaaaaaaa0ULL, },
+ { 0xdddddddbbbbbbbb0ULL, 0xdddddddbbbbbbbb0ULL, },
+ { 0xfffffffdfffffff4ULL, 0xfffffffdfffffff4ULL, },
+ { 0xd097b4234bda12eaULL, 0x097b425c684bda06ULL, },
+ { 0xfffffffd55555548ULL, 0xfffffffd55555548ULL, },
+ { 0xfffffffdfffffff2ULL, 0xfffffffdfffffff2ULL, }, /* 24 */
+ { 0xfffffffdfffffff2ULL, 0xfffffffdfffffff2ULL, },
+ { 0x38e38e371c71c70eULL, 0x38e38e371c71c70eULL, },
+ { 0xfffffffeaaaaaa9cULL, 0xfffffffeaaaaaa9cULL, },
+ { 0x2222222133333324ULL, 0x2222222133333324ULL, },
+ { 0xffffffff55555546ULL, 0xffffffff55555546ULL, },
+ { 0x2f684bd97b425ec1ULL, 0xf684bda1097b424fULL, },
+ { 0xfffffffffffffff0ULL, 0xfffffffffffffff0ULL, },
+ { 0xffffffff99999988ULL, 0xffffffff99999988ULL, }, /* 32 */
+ { 0xffffffff99999988ULL, 0xffffffff99999988ULL, },
+ { 0xdddddddcaaaaaa98ULL, 0xdddddddcaaaaaa98ULL, },
+ { 0xffffffff33333320ULL, 0xffffffff33333320ULL, },
+ { 0xeb851eb6e147ae00ULL, 0xeb851eb6e147ae00ULL, },
+ { 0xfffffffeccccccb8ULL, 0xfffffffeccccccb8ULL, },
+ { 0xe38e38e1c16c16acULL, 0x05b05b0449f49f34ULL, },
+ { 0xfffffffe66666650ULL, 0xfffffffe66666650ULL, },
+ { 0xfffffffeccccccb6ULL, 0xfffffffeccccccb6ULL, }, /* 40 */
+ { 0xfffffffeccccccb6ULL, 0xfffffffeccccccb6ULL, },
+ { 0x22222221111110faULL, 0x22222221111110faULL, },
+ { 0xffffffff3333331cULL, 0xffffffff3333331cULL, },
+ { 0x147ae1471eb851d4ULL, 0x147ae1471eb851d4ULL, },
+ { 0xffffffff99999982ULL, 0xffffffff99999982ULL, },
+ { 0x1c71c71c16c16bffULL, 0xfa4fa4fa38e38e21ULL, },
+ { 0xffffffffffffffe8ULL, 0xffffffffffffffe8ULL, },
+ { 0xffffffff71c71c59ULL, 0x000000001c71c703ULL, }, /* 48 */
+ { 0xffffffff71c71c59ULL, 0x000000001c71c703ULL, },
+ { 0xd097b424bda12f4fULL, 0x097b425e84bda115ULL, },
+ { 0xfffffffee38e38caULL, 0x0000000038e38e1eULL, },
+ { 0xe38e38e1d82d82beULL, 0x05b05b05b60b609aULL, },
+ { 0xfffffffe5555553bULL, 0x0000000055555539ULL, },
+ { 0xca4587e4ba78192eULL, 0xf0329162948b0fb0ULL, },
+ { 0xfffffffdc71c71acULL, 0x0000000071c71c54ULL, },
+ { 0xfffffffe55555539ULL, 0x0000000055555537ULL, }, /* 56 */
+ { 0xfffffffe55555539ULL, 0x0000000055555537ULL, },
+ { 0x2f684bd85ed09797ULL, 0xf684bda1425ed079ULL, },
+ { 0xfffffffee38e38c6ULL, 0x0000000038e38e1aULL, },
+ { 0x1c71c71b8888886aULL, 0xfa4fa4fa55555536ULL, },
+ { 0xffffffff71c71c53ULL, 0x000000001c71c6fdULL, },
+ { 0x35ba78187e6b74d1ULL, 0x0fcd6e9df9add3a1ULL, },
+ { 0xffffffffffffffe0ULL, 0xffffffffffffffe0ULL, },
+ { 0xc1c52b51ed993d50ULL, 0xe9c828da514248ccULL, }, /* 64 */
+ { 0xb38b1f29f5c2926cULL, 0xe4522d2260b25370ULL, },
+ { 0x978b1706bdfa46f4ULL, 0xd814f3be50d3cfdeULL, },
+ { 0xbd2549a81e90da18ULL, 0xf92987d1ec89a90eULL, },
+ { 0xaeeb3d8026ba2f34ULL, 0xf3b38c19fbf9b3b2ULL, },
+ { 0x9756e17673d898abULL, 0xf08852c874204cfeULL, },
+ { 0xab37d321be2e30edULL, 0xf49ef75a0c71ea68ULL, },
+ { 0x908aa2c1222edcb6ULL, 0x0445531d0abde6f8ULL, },
+ { 0x748a9a9dea66913eULL, 0xf80819b8fadf6366ULL, }, /* 72 */
+ { 0x886b8c4934bc2980ULL, 0xfc1ebe4a933100d0ULL, },
+ { 0x59d865e79904609cULL, 0xd9ce9972461ac53fULL, },
+ { 0x985e08e42661ba7aULL, 0xced13609df919197ULL, },
+ { 0xbdf83b8586f84d9eULL, 0xefe5ca1d7b476ac7ULL, },
+ { 0xa34b0b24eaf8f967ULL, 0xff8c25e079936757ULL, },
+ { 0xe1d0ae2178565345ULL, 0xf48ec278130a33afULL, },
+ { 0x8de2b645a0f53058ULL, 0xa45a44165015196fULL, },
+ { 0x6792d4f3d7eea55cULL, 0xbfd22ee1a25aa627ULL, }, /* 80 */
+ { 0x75702d5b9af89c83ULL, 0xcc593d1da09f7be9ULL, },
+ { 0x801c3e1c97724195ULL, 0xb4c868d4067dd2d2ULL, },
+ { 0xdeafd0d6f0bea5c3ULL, 0x957877eb733b98b2ULL, },
+ { 0xd1883629f50ec77bULL, 0xb587d85cf1ffef10ULL, },
+ { 0xd4133b37d7cbfcc8ULL, 0xbc35d373b6f24df8ULL, },
+ { 0xbab344ed957a4c42ULL, 0xae8dcb499ce6cd0bULL, },
+ { 0x004c193eb947b2ddULL, 0x68b0a9907b71a293ULL, },
+ { 0x0b979b74995fc935ULL, 0x4a9602f12aa080cfULL, }, /* 88 */
+ { 0x2ae2653846d12eb1ULL, 0x4185939a2d850f91ULL, },
+ { 0x4c5017cc0eed7401ULL, 0x466840b4575dc0d7ULL, },
+ { 0x255760c7e1e38957ULL, 0x8360b1037a4f3497ULL, },
+ { 0x3b88c1c3a41f6803ULL, 0xa8cf0d07b592cd69ULL, },
+ { 0x585dd51272f3e482ULL, 0xb5723c3756218857ULL, },
+ { 0x94c1c43b5f5b538eULL, 0xdd9794c5786cc9c2ULL, },
+ { 0xa0b80278cc3c6a8bULL, 0xf710a53506ea3e4aULL, },
+ { 0x7c607ecd0201d92bULL, 0xf9bcdab0e105825cULL, }, /* 96 */
+ { 0xb628bad7d2470e0fULL, 0xfb660e974362496cULL, },
+ { 0x9ae11df599c281fbULL, 0xfd2738784b8dbfeaULL, },
+ { 0x7bc5bf3b5e23aeffULL, 0xfe707ab5676dfce2ULL, },
+ { 0x614dabb2dc4e0a36ULL, 0xf5f8795b76d8fd08ULL, },
+ { 0x6dbd1a209fc658b0ULL, 0xecd982bc128c8ceaULL, },
+ { 0x8cb93c5d61b1a8d0ULL, 0xecbaa1839f7e477aULL, },
+ { 0x6d33947e52d25a59ULL, 0xf62aab8428f0bf14ULL, },
+ { 0xa7970469e4259b2dULL, 0x0543881aad9efd08ULL, }, /* 104 */
+ { 0x8310e5e55f8149f3ULL, 0xe925758a04d06282ULL, },
+ { 0x746e208dd13c0f61ULL, 0xee4c7bccbccd15e4ULL, },
+ { 0x8da69743b598403fULL, 0xdac93db8514253e0ULL, },
+ { 0xdb31a0aea0a5cde6ULL, 0xe5bd105b853454a0ULL, },
+ { 0x0e6cfc3a89e7bd7cULL, 0xb06ea3bad3a90bd8ULL, },
+ { 0x338cc47438edb042ULL, 0x7df572596f6dffe8ULL, },
+ { 0x07fce3091840a942ULL, 0xdbd5224936527bd0ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_S_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_S_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_S_D__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_S_D__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction DPSUB_S.H
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Dot Product";
+ char *instruction_name = "DPSUB_S.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xfffefffefffefffeULL, 0xfffefffefffefffeULL, }, /* 0 */
+ { 0xfffefffefffefffeULL, 0xfffefffefffefffeULL, },
+ { 0xff52ff52ff52ff52ULL, 0xff52ff52ff52ff52ULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xff94ff94ff94ff94ULL, 0xff94ff94ff94ff94ULL, },
+ { 0xfffafffafffafffaULL, 0xfffafffafffafffaULL, },
+ { 0xff6b0015ffc0ff6bULL, 0x0015ffc0ff6b0015ULL, },
+ { 0xfff8fff8fff8fff8ULL, 0xfff8fff8fff8fff8ULL, },
+ { 0xfff8fff8fff8fff8ULL, 0xfff8fff8fff8fff8ULL, }, /* 8 */
+ { 0xfff8fff8fff8fff8ULL, 0xfff8fff8fff8fff8ULL, },
+ { 0xfff8fff8fff8fff8ULL, 0xfff8fff8fff8fff8ULL, },
+ { 0xfff8fff8fff8fff8ULL, 0xfff8fff8fff8fff8ULL, },
+ { 0xfff8fff8fff8fff8ULL, 0xfff8fff8fff8fff8ULL, },
+ { 0xfff8fff8fff8fff8ULL, 0xfff8fff8fff8fff8ULL, },
+ { 0xfff8fff8fff8fff8ULL, 0xfff8fff8fff8fff8ULL, },
+ { 0xfff8fff8fff8fff8ULL, 0xfff8fff8fff8fff8ULL, },
+ { 0xff4cff4cff4cff4cULL, 0xff4cff4cff4cff4cULL, }, /* 16 */
+ { 0xff4cff4cff4cff4cULL, 0xff4cff4cff4cff4cULL, },
+ { 0xc584c584c584c584ULL, 0xc584c584c584c584ULL, },
+ { 0xfea0fea0fea0fea0ULL, 0xfea0fea0fea0fea0ULL, },
+ { 0xdbb0dbb0dbb0dbb0ULL, 0xdbb0dbb0dbb0dbb0ULL, },
+ { 0xfdf4fdf4fdf4fdf4ULL, 0xfdf4fdf4fdf4fdf4ULL, },
+ { 0xcdea0706ea78cdeaULL, 0x0706ea78cdea0706ULL, },
+ { 0xfd48fd48fd48fd48ULL, 0xfd48fd48fd48fd48ULL, },
+ { 0xfdf2fdf2fdf2fdf2ULL, 0xfdf2fdf2fdf2fdf2ULL, }, /* 24 */
+ { 0xfdf2fdf2fdf2fdf2ULL, 0xfdf2fdf2fdf2fdf2ULL, },
+ { 0x370e370e370e370eULL, 0x370e370e370e370eULL, },
+ { 0xfe9cfe9cfe9cfe9cULL, 0xfe9cfe9cfe9cfe9cULL, },
+ { 0x2124212421242124ULL, 0x2124212421242124ULL, },
+ { 0xff46ff46ff46ff46ULL, 0xff46ff46ff46ff46ULL, },
+ { 0x2ec1f64f12882ec1ULL, 0xf64f12882ec1f64fULL, },
+ { 0xfff0fff0fff0fff0ULL, 0xfff0fff0fff0fff0ULL, },
+ { 0xff88ff88ff88ff88ULL, 0xff88ff88ff88ff88ULL, }, /* 32 */
+ { 0xff88ff88ff88ff88ULL, 0xff88ff88ff88ff88ULL, },
+ { 0xdc98dc98dc98dc98ULL, 0xdc98dc98dc98dc98ULL, },
+ { 0xff20ff20ff20ff20ULL, 0xff20ff20ff20ff20ULL, },
+ { 0xea00ea00ea00ea00ULL, 0xea00ea00ea00ea00ULL, },
+ { 0xfeb8feb8feb8feb8ULL, 0xfeb8feb8feb8feb8ULL, },
+ { 0xe1ac0434f2f0e1acULL, 0x0434f2f0e1ac0434ULL, },
+ { 0xfe50fe50fe50fe50ULL, 0xfe50fe50fe50fe50ULL, },
+ { 0xfeb6feb6feb6feb6ULL, 0xfeb6feb6feb6feb6ULL, }, /* 40 */
+ { 0xfeb6feb6feb6feb6ULL, 0xfeb6feb6feb6feb6ULL, },
+ { 0x20fa20fa20fa20faULL, 0x20fa20fa20fa20faULL, },
+ { 0xff1cff1cff1cff1cULL, 0xff1cff1cff1cff1cULL, },
+ { 0x13d413d413d413d4ULL, 0x13d413d413d413d4ULL, },
+ { 0xff82ff82ff82ff82ULL, 0xff82ff82ff82ff82ULL, },
+ { 0x1bfffa210b101bffULL, 0xfa210b101bfffa21ULL, },
+ { 0xffe8ffe8ffe8ffe8ULL, 0xffe8ffe8ffe8ffe8ULL, },
+ { 0xff590003ffaeff59ULL, 0x0003ffaeff590003ULL, }, /* 48 */
+ { 0xff590003ffaeff59ULL, 0x0003ffaeff590003ULL, },
+ { 0xcf4f0915ec32cf4fULL, 0x0915ec32cf4f0915ULL, },
+ { 0xfeca001eff74fecaULL, 0x001eff74feca001eULL, },
+ { 0xe1be059af3ace1beULL, 0x059af3ace1be059aULL, },
+ { 0xfe3b0039ff3afe3bULL, 0x0039ff3afe3b0039ULL, },
+ { 0xc82ef0b0c036c82eULL, 0xf0b0c036c82ef0b0ULL, },
+ { 0xfdac0054ff00fdacULL, 0x0054ff00fdac0054ULL, },
+ { 0xfe390037ff38fe39ULL, 0x0037ff38fe390037ULL, }, /* 56 */
+ { 0xfe390037ff38fe39ULL, 0x0037ff38fe390037ULL, },
+ { 0x2d97f67912082d97ULL, 0xf67912082d97f679ULL, },
+ { 0xfec6001aff70fec6ULL, 0x001aff70fec6001aULL, },
+ { 0x1b6afa360ad01b6aULL, 0xfa360ad01b6afa36ULL, },
+ { 0xff53fffdffa8ff53ULL, 0xfffdffa8ff53fffdULL, },
+ { 0x34d10fa13e7234d1ULL, 0x0fa13e7234d10fa1ULL, },
+ { 0xffe0ffe0ffe0ffe0ULL, 0xffe0ffe0ffe0ffe0ULL, },
+ { 0x9bbcf2acd41cd3a7ULL, 0xc076dce3c4c3e650ULL, }, /* 64 */
+ { 0xb4b806c8f1cee494ULL, 0xbecfd64ea6a80020ULL, },
+ { 0x6814ecfc0fa82b6dULL, 0xc37ad92a91550ac0ULL, },
+ { 0x7bdefedcee3621e3ULL, 0xeb34ed0270f105e0ULL, },
+ { 0x94da12f80be832d0ULL, 0xe98de66d52d61fb0ULL, },
+ { 0x83bdecafc65625dfULL, 0xe7f8d130419c055cULL, },
+ { 0x994d0df1c6d40fd2ULL, 0xe3d2c1a83e00f9d2ULL, },
+ { 0xafdbf02abf6b06b4ULL, 0xeb61a56034e501eeULL, },
+ { 0x6337d65edd454d8dULL, 0xf00ca83c1f920c8eULL, }, /* 72 */
+ { 0x78c7f7a0ddc33780ULL, 0xebe698b41bf60104ULL, },
+ { 0x3d93c078c0b1c207ULL, 0xdfb58b8ff884fa1bULL, },
+ { 0x468de162e424db51ULL, 0xeee27037d08b05f1ULL, },
+ { 0x5a57f342c2b2d1c7ULL, 0x169c840fb0270111ULL, },
+ { 0x70e5d57bbb49c8a9ULL, 0x1e2b67c7a70c092dULL, },
+ { 0x79dff665debce1f3ULL, 0x2d584c6f7f131503ULL, },
+ { 0x307edd58b2d7c6abULL, 0xf8ce0def507eed7fULL, },
+ { 0x12d2ebaaceb9ef2dULL, 0x0f44139e1494e19bULL, }, /* 80 */
+ { 0x07500cecbf88e9fcULL, 0x109a22b12d84e9f5ULL, },
+ { 0xed7c0a0c9689dd79ULL, 0xfe3a2a165149ee24ULL, },
+ { 0xcf880594d43cb481ULL, 0x00ba413659fef988ULL, },
+ { 0xea40f026c424ed7dULL, 0x1ce42a975ba6fcf8ULL, },
+ { 0xfa52e174e584e55aULL, 0x19f040936a55fe20ULL, },
+ { 0xdb86fe7ec64b0603ULL, 0x13a14ea67f40fbeaULL, },
+ { 0x115cd8c4cd3c05cdULL, 0x1699652699e9f314ULL, },
+ { 0xf33cc884be3c10e4ULL, 0x399852dba428ee14ULL, }, /* 88 */
+ { 0x0273f878eba21554ULL, 0x31ee6cb7a1dcf428ULL, },
+ { 0xdaad1e38d3d148edULL, 0x27a784e6885df2c4ULL, },
+ { 0x04ea0acced565727ULL, 0x33f546b6479bdaa0ULL, },
+ { 0x0fe60140cf623084ULL, 0x29715ee078b0d340ULL, },
+ { 0x097de88007d93f14ULL, 0x2a887b768288e2aaULL, },
+ { 0xe07fb5d0025365dfULL, 0x116297ca6cdaedb8ULL, },
+ { 0xc74ecab2f1b47bc3ULL, 0x1ec35e229b5ad07eULL, },
+ { 0x8c4ab55e1124622cULL, 0x2e844d9c6f52bb96ULL, }, /* 96 */
+ { 0x3746c0d800b436a2ULL, 0x52ee6f0548caaafeULL, },
+ { 0x3412b2381dcc3c34ULL, 0x4226686a634c9036ULL, },
+ { 0x44feb5ac2d2c1b48ULL, 0x1f863d063f8e6aaeULL, },
+ { 0x45ced628325f1f0bULL, 0x190e4cdb56714772ULL, },
+ { 0x3a43c6b04bc8259aULL, 0x17ca65193394327cULL, },
+ { 0x4cabe5a01d613107ULL, 0x14467dc849f92468ULL, },
+ { 0x383d0ac03df53bb8ULL, 0x1554a52945b51a80ULL, },
+ { 0x352bf8744cc532afULL, 0x1f4190b4693720beULL, }, /* 104 */
+ { 0x37711cdc568e2109ULL, 0x24b0770882d72146ULL, },
+ { 0x21c319bc5896349eULL, 0x12b492065fe41709ULL, },
+ { 0x42090ae65cb41b62ULL, 0x0416792084231302ULL, },
+ { 0x226211dc497800b0ULL, 0x072cb6d850f915fcULL, },
+ { 0xf5441b3a17b21910ULL, 0x0ce58de86df716f2ULL, },
+ { 0xe51807761e2e171eULL, 0x10b4544095541446ULL, },
+ { 0xe980e35e0a5c10acULL, 0x137085a05b4f30deULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_S_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_S_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_S_H__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_S_H__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction DPSUB_S.W
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Dot Product";
+ char *instruction_name = "DPSUB_S.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xfffffffefffffffeULL, 0xfffffffefffffffeULL, }, /* 0 */
+ { 0xfffffffefffffffeULL, 0xfffffffefffffffeULL, },
+ { 0xffff5552ffff5552ULL, 0xffff5552ffff5552ULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xffff9994ffff9994ULL, 0xffff9994ffff9994ULL, },
+ { 0xfffffffafffffffaULL, 0xfffffffafffffffaULL, },
+ { 0x00001c6bffff71c0ULL, 0xffffc71500001c6bULL, },
+ { 0xfffffff8fffffff8ULL, 0xfffffff8fffffff8ULL, },
+ { 0xfffffff8fffffff8ULL, 0xfffffff8fffffff8ULL, }, /* 8 */
+ { 0xfffffff8fffffff8ULL, 0xfffffff8fffffff8ULL, },
+ { 0xfffffff8fffffff8ULL, 0xfffffff8fffffff8ULL, },
+ { 0xfffffff8fffffff8ULL, 0xfffffff8fffffff8ULL, },
+ { 0xfffffff8fffffff8ULL, 0xfffffff8fffffff8ULL, },
+ { 0xfffffff8fffffff8ULL, 0xfffffff8fffffff8ULL, },
+ { 0xfffffff8fffffff8ULL, 0xfffffff8fffffff8ULL, },
+ { 0xfffffff8fffffff8ULL, 0xfffffff8fffffff8ULL, },
+ { 0xffff554cffff554cULL, 0xffff554cffff554cULL, }, /* 16 */
+ { 0xffff554cffff554cULL, 0xffff554cffff554cULL, },
+ { 0xc71ae384c71ae384ULL, 0xc71ae384c71ae384ULL, },
+ { 0xfffeaaa0fffeaaa0ULL, 0xfffeaaa0fffeaaa0ULL, },
+ { 0xdddbbbb0dddbbbb0ULL, 0xdddbbbb0dddbbbb0ULL, },
+ { 0xfffdfff4fffdfff4ULL, 0xfffdfff4fffdfff4ULL, },
+ { 0x097912ead094f678ULL, 0xed06da06097912eaULL, },
+ { 0xfffd5548fffd5548ULL, 0xfffd5548fffd5548ULL, },
+ { 0xfffdfff2fffdfff2ULL, 0xfffdfff2fffdfff2ULL, }, /* 24 */
+ { 0xfffdfff2fffdfff2ULL, 0xfffdfff2fffdfff2ULL, },
+ { 0x38e1c70e38e1c70eULL, 0x38e1c70e38e1c70eULL, },
+ { 0xfffeaa9cfffeaa9cULL, 0xfffeaa9cfffeaa9cULL, },
+ { 0x2221332422213324ULL, 0x2221332422213324ULL, },
+ { 0xffff5546ffff5546ULL, 0xffff5546ffff5546ULL, },
+ { 0xf6845ec12f67d088ULL, 0x12f6424ff6845ec1ULL, },
+ { 0xfffffff0fffffff0ULL, 0xfffffff0fffffff0ULL, },
+ { 0xffff9988ffff9988ULL, 0xffff9988ffff9988ULL, }, /* 32 */
+ { 0xffff9988ffff9988ULL, 0xffff9988ffff9988ULL, },
+ { 0xdddcaa98dddcaa98ULL, 0xdddcaa98dddcaa98ULL, },
+ { 0xffff3320ffff3320ULL, 0xffff3320ffff3320ULL, },
+ { 0xeb83ae00eb83ae00ULL, 0xeb83ae00eb83ae00ULL, },
+ { 0xfffeccb8fffeccb8ULL, 0xfffeccb8fffeccb8ULL, },
+ { 0x05af16ace38c5af0ULL, 0xf49d9f3405af16acULL, },
+ { 0xfffe6650fffe6650ULL, 0xfffe6650fffe6650ULL, },
+ { 0xfffeccb6fffeccb6ULL, 0xfffeccb6fffeccb6ULL, }, /* 40 */
+ { 0xfffeccb6fffeccb6ULL, 0xfffeccb6fffeccb6ULL, },
+ { 0x222110fa222110faULL, 0x222110fa222110faULL, },
+ { 0xffff331cffff331cULL, 0xffff331cffff331cULL, },
+ { 0x147a51d4147a51d4ULL, 0x147a51d4147a51d4ULL, },
+ { 0xffff9982ffff9982ULL, 0xffff9982ffff9982ULL, },
+ { 0xfa4f6bff1c717d10ULL, 0x0b608e21fa4f6bffULL, },
+ { 0xffffffe8ffffffe8ULL, 0xffffffe8ffffffe8ULL, },
+ { 0x00001c59ffff71aeULL, 0xffffc70300001c59ULL, }, /* 48 */
+ { 0x00001c59ffff71aeULL, 0xffffc70300001c59ULL, },
+ { 0x097b2f4fd0966832ULL, 0xed08a115097b2f4fULL, },
+ { 0x000038cafffee374ULL, 0xffff8e1e000038caULL, },
+ { 0x05b082bee38c71acULL, 0xf49e609a05b082beULL, },
+ { 0x0000553bfffe553aULL, 0xffff55390000553bULL, },
+ { 0xf033192eca430636ULL, 0xc0c90fb0f033192eULL, },
+ { 0x000071acfffdc700ULL, 0xffff1c54000071acULL, },
+ { 0x00005539fffe5538ULL, 0xffff553700005539ULL, }, /* 56 */
+ { 0x00005539fffe5538ULL, 0xffff553700005539ULL, },
+ { 0xf68497972f66b408ULL, 0x12f5d079f6849797ULL, },
+ { 0x000038c6fffee370ULL, 0xffff8e1a000038c6ULL, },
+ { 0xfa4f886a1c70eed0ULL, 0x0b605536fa4f886aULL, },
+ { 0x00001c53ffff71a8ULL, 0xffffc6fd00001c53ULL, },
+ { 0x0fcd74d135ba3272ULL, 0x3f35d3a10fcd74d1ULL, },
+ { 0xffffffe0ffffffe0ULL, 0xffffffe0ffffffe0ULL, },
+ { 0xc5a8016cdd3daa5cULL, 0xe94945ebe7053037ULL, }, /* 64 */
+ { 0xc3b493dce3f99616ULL, 0xe6c275fe01105522ULL, },
+ { 0x949f7b2015d7bcd8ULL, 0xdd8e1f740c23f089ULL, },
+ { 0xcb480f0e10df8c96ULL, 0x0470e12d02738253ULL, },
+ { 0xc954a17e179b7850ULL, 0x01ea11401c7ea73eULL, },
+ { 0xc9425a31f36c45a7ULL, 0xedf7684bffd4d9adULL, },
+ { 0xc7fda5a7eec474caULL, 0xdbac4bfdfada4b68ULL, },
+ { 0xc9d3363ecb9ded37ULL, 0xc40db8860b92e4aaULL, },
+ { 0x9abe1d82fd7c13f9ULL, 0xbad961fc16a68011ULL, }, /* 72 */
+ { 0x997968f8f8d4431cULL, 0xa88e45ae11abf1ccULL, },
+ { 0x644cd070b0912dbbULL, 0x95a94d6df030af03ULL, },
+ { 0x90151b88bce11a1cULL, 0x8ce173edd7b3566dULL, },
+ { 0xc6bdaf76b7e8e9daULL, 0xb3c435a6ce02e837ULL, },
+ { 0xc893400d94c26247ULL, 0x9c25a22fdebb8179ULL, },
+ { 0xf45b8b25a1124ea8ULL, 0x935dc8afc63e28e3ULL, },
+ { 0xc124ff9b7af87983ULL, 0x2916358ea57b0fdfULL, },
+ { 0xa3bdf52f3f1bc6d3ULL, 0x1a9b7790a9e67552ULL, }, /* 80 */
+ { 0xa2394ebc1f432fbaULL, 0x38d091638b040700ULL, },
+ { 0x9c98e9da3d8da28dULL, 0x17578e46633c7554ULL, },
+ { 0xca2304601c11139aULL, 0xecce6f4f9252c75cULL, },
+ { 0xb167fd62111ca498ULL, 0xed848a6b7ffb85a6ULL, },
+ { 0xb01a590af79618c4ULL, 0xcf3de0319d05b479ULL, },
+ { 0xb2490b42008cb27aULL, 0xcfbf82ea8729672eULL, },
+ { 0xd36607e1f75b1a82ULL, 0x8006f7ab6a0e64dcULL, },
+ { 0xbf56e259efe4672cULL, 0xa61769778a2f91d2ULL, }, /* 88 */
+ { 0xbe4f061a0bbba5e0ULL, 0xc922e830b7ade689ULL, },
+ { 0xaac85110e5ef76abULL, 0xcc5f9db0a366adc6ULL, },
+ { 0xc91b5b88fd4a93d2ULL, 0x879c58c17a96cfbaULL, },
+ { 0xb8799dfa21be5efeULL, 0xa721331f6c3d78f0ULL, },
+ { 0xb76ef97e2ca86ef4ULL, 0xbb78ca223c0de8adULL, },
+ { 0x9da743266b64f51cULL, 0xba24b1045354f4faULL, },
+ { 0xc2f3162f429e4870ULL, 0x764125c06e4d3512ULL, },
+ { 0xa89d5e1d1ffccbf4ULL, 0x51bf6a197f87f33bULL, }, /* 96 */
+ { 0x890f17ff2c462c7cULL, 0x34f589127c4cc49aULL, },
+ { 0x53dc26951679feb0ULL, 0x2aa458e36a7c8cdeULL, },
+ { 0x7ed4f0c1135e605eULL, 0x1a22c08d472920e2ULL, },
+ { 0x80f6d8c622f1e674ULL, 0x071f986d36987e53ULL, },
+ { 0x7ee91ba012abf971ULL, 0xeab87172091da737ULL, },
+ { 0x80fac8d20b8e2fb8ULL, 0x0ad43e562523cff0ULL, },
+ { 0x7ef3481012ac516eULL, 0x1acdbd0e31a33d13ULL, },
+ { 0xbf53a8023cd97b5aULL, 0x07b9c024393d8136ULL, }, /* 104 */
+ { 0x8e3cb38085aaebe3ULL, 0xf84dd1305e923ebfULL, },
+ { 0x50c22f685af8caedULL, 0xef14166874d2544dULL, },
+ { 0x7a3548245bc2dee5ULL, 0xf6b38ff08f52b803ULL, },
+ { 0x3e4f96f53628fefdULL, 0xbe65c7ed60e1faffULL, },
+ { 0x2c2056e3221de63fULL, 0x871151e081227a9dULL, },
+ { 0x113314bc1293f380ULL, 0x774bb8df643781b9ULL, },
+ { 0x07d911730a4b3a5dULL, 0x8b56a81c77aef6ebULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_S_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_S_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_S_W__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_S_W__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction DPSUB_U.D
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Dot Product";
+ char *instruction_name = "DPSUB_U.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x00000003fffffffeULL, 0x00000003fffffffeULL, }, /* 0 */
+ { 0x00000003fffffffeULL, 0x00000003fffffffeULL, },
+ { 0xaaaaaab155555552ULL, 0xaaaaaab155555552ULL, },
+ { 0x00000007fffffffcULL, 0x00000007fffffffcULL, },
+ { 0x6666667199999994ULL, 0x6666667199999994ULL, },
+ { 0x0000000bfffffffaULL, 0x0000000bfffffffaULL, },
+ { 0x8e38e39c71c71c6bULL, 0xe38e38f21c71c715ULL, },
+ { 0x0000000ffffffff8ULL, 0x0000000ffffffff8ULL, },
+ { 0x0000000ffffffff8ULL, 0x0000000ffffffff8ULL, }, /* 8 */
+ { 0x0000000ffffffff8ULL, 0x0000000ffffffff8ULL, },
+ { 0x0000000ffffffff8ULL, 0x0000000ffffffff8ULL, },
+ { 0x0000000ffffffff8ULL, 0x0000000ffffffff8ULL, },
+ { 0x0000000ffffffff8ULL, 0x0000000ffffffff8ULL, },
+ { 0x0000000ffffffff8ULL, 0x0000000ffffffff8ULL, },
+ { 0x0000000ffffffff8ULL, 0x0000000ffffffff8ULL, },
+ { 0x0000000ffffffff8ULL, 0x0000000ffffffff8ULL, },
+ { 0xaaaaaabd5555554cULL, 0xaaaaaabd5555554cULL, }, /* 16 */
+ { 0xaaaaaabd5555554cULL, 0xaaaaaabd5555554cULL, },
+ { 0xc71c71db8e38e384ULL, 0xc71c71db8e38e384ULL, },
+ { 0x5555556aaaaaaaa0ULL, 0x5555556aaaaaaaa0ULL, },
+ { 0x4444445bbbbbbbb0ULL, 0x4444445bbbbbbbb0ULL, },
+ { 0x00000017fffffff4ULL, 0x00000017fffffff4ULL, },
+ { 0x097b42784bda12eaULL, 0x425ed0b1684bda06ULL, },
+ { 0xaaaaaac555555548ULL, 0xaaaaaac555555548ULL, },
+ { 0x0000001bfffffff2ULL, 0x0000001bfffffff2ULL, }, /* 24 */
+ { 0x0000001bfffffff2ULL, 0x0000001bfffffff2ULL, },
+ { 0x8e38e3ab1c71c70eULL, 0x8e38e3ab1c71c70eULL, },
+ { 0x55555572aaaaaa9cULL, 0x55555572aaaaaa9cULL, },
+ { 0xcccccceb33333324ULL, 0xcccccceb33333324ULL, },
+ { 0xaaaaaac955555546ULL, 0xaaaaaac955555546ULL, },
+ { 0x2f684bf97b425ec1ULL, 0x4bda1316097b424fULL, },
+ { 0x0000001ffffffff0ULL, 0x0000001ffffffff0ULL, },
+ { 0x6666668999999988ULL, 0x6666668999999988ULL, }, /* 32 */
+ { 0x6666668999999988ULL, 0x6666668999999988ULL, },
+ { 0x5555557aaaaaaa98ULL, 0x5555557aaaaaaa98ULL, },
+ { 0xccccccf333333320ULL, 0xccccccf333333320ULL, },
+ { 0x851eb87ae147ae00ULL, 0x851eb87ae147ae00ULL, },
+ { 0x3333335cccccccb8ULL, 0x3333335cccccccb8ULL, },
+ { 0x0b60b636c16c16acULL, 0x4fa4fa7b49f49f34ULL, },
+ { 0x999999c666666650ULL, 0x999999c666666650ULL, },
+ { 0x33333360ccccccb6ULL, 0x33333360ccccccb6ULL, }, /* 40 */
+ { 0x33333360ccccccb6ULL, 0x33333360ccccccb6ULL, },
+ { 0xeeeeef1d111110faULL, 0xeeeeef1d111110faULL, },
+ { 0xccccccfb3333331cULL, 0xccccccfb3333331cULL, },
+ { 0x7ae147dd1eb851d4ULL, 0x7ae147dd1eb851d4ULL, },
+ { 0x6666669599999982ULL, 0x6666669599999982ULL, },
+ { 0x1c71c74c16c16bffULL, 0x2d82d85d38e38e21ULL, },
+ { 0x0000002fffffffe8ULL, 0x0000002fffffffe8ULL, },
+ { 0x8e38e3c071c71c59ULL, 0xe38e39161c71c703ULL, }, /* 48 */
+ { 0x8e38e3c071c71c59ULL, 0xe38e39161c71c703ULL, },
+ { 0x97b42620bda12f4fULL, 0x25ed09af84bda115ULL, },
+ { 0x1c71c750e38e38caULL, 0xc71c71fc38e38e1eULL, },
+ { 0xf49f4a2ad82d82beULL, 0xe38e391ab60b609aULL, },
+ { 0xaaaaaae15555553bULL, 0xaaaaaae255555539ULL, },
+ { 0x9161f9e5ba78192eULL, 0xd3c0ca7e948b0fb0ULL, },
+ { 0x38e38e71c71c71acULL, 0x8e38e3c871c71c54ULL, },
+ { 0xaaaaaae555555539ULL, 0xaaaaaae655555537ULL, }, /* 56 */
+ { 0xaaaaaae555555539ULL, 0xaaaaaae655555537ULL, },
+ { 0x4bda13325ed09797ULL, 0x12f684fa425ed079ULL, },
+ { 0x1c71c758e38e38c6ULL, 0xc71c720438e38e1aULL, },
+ { 0xaaaaaae88888886aULL, 0x1111114f55555536ULL, },
+ { 0x8e38e3cc71c71c53ULL, 0xe38e39221c71c6fdULL, },
+ { 0x35ba78587e6b74d1ULL, 0x9e06526bf9add3a1ULL, },
+ { 0x0000003fffffffe0ULL, 0x0000003fffffffe0ULL, },
+ { 0xb0ef5df9ed993d50ULL, 0xecd0c902514248ccULL, }, /* 64 */
+ { 0x1e8c6aa2f5c2926cULL, 0xd21b7a4e60b25370ULL, },
+ { 0xa56477c9bdfa46f4ULL, 0x1c376bca50d3cfdeULL, },
+ { 0x5aaf941e1e90da18ULL, 0x4a2661d3ec89a90eULL, },
+ { 0xc84ca0c726ba2f34ULL, 0x2f71131ffbf9b3b2ULL, },
+ { 0xb93c43f773d898abULL, 0x2c45d9ce74204cfeULL, },
+ { 0xd770bf8dbe2e30edULL, 0x1b1d2b640c71ea68ULL, },
+ { 0x4c7478e0222edcb6ULL, 0x028c79110abde6f8ULL, },
+ { 0xd34c8606ea66913eULL, 0x4ca86a8cfadf6366ULL, }, /* 72 */
+ { 0xf181019d34bc2980ULL, 0x3b7fbc22933100d0ULL, },
+ { 0xf69966e79904609cULL, 0xc2d94d22461ac53fULL, },
+ { 0x669e11492661ba7aULL, 0x3b951b06df919197ULL, },
+ { 0x1be92d9d86f84d9eULL, 0x698411107b476ac7ULL, },
+ { 0x90ece6efeaf8f967ULL, 0x50f35ebd79936757ULL, },
+ { 0x00f1915178565345ULL, 0xc9af2ca2130a33afULL, },
+ { 0xad039975a0f53058ULL, 0x0b11d7505015196fULL, },
+ { 0x376d4d72ebbc7b1cULL, 0xb833881ecd4918dbULL, }, /* 80 */
+ { 0xb97c39c63d30eb26ULL, 0x9983e1a16fddbe3bULL, },
+ { 0x103118e687f4c4aaULL, 0x36d2d322776b1540ULL, },
+ { 0xd7103f328f5683b0ULL, 0xc97816b7d22d1890ULL, },
+ { 0x4dd93b94622edfd8ULL, 0xbd32853a6649bd9eULL, },
+ { 0xe38ab03df0d4eedcULL, 0xa6b087fab9ab9432ULL, },
+ { 0x9b8bc7cd79738e5aULL, 0x1099960abd7ff844ULL, },
+ { 0x2a9e79f404df0445ULL, 0x8a1a574d141add54ULL, },
+ { 0x1323c575df66a395ULL, 0x4d70aaa974eb601eULL, }, /* 88 */
+ { 0xbc9ea974b0ce57aeULL, 0x3dff93a625e35e6cULL, },
+ { 0xbd4cca940103a7a6ULL, 0x1b03e192077feba2ULL, },
+ { 0x69e12c9b9ff2608eULL, 0x0713d9101835bf32ULL, },
+ { 0x183a0715853e498aULL, 0xeced28ff102b04faULL, },
+ { 0xd806808efcdcfa1bULL, 0xda07aee4d9a29bfcULL, },
+ { 0x8f0ceb4c5a20614fULL, 0x2693974265c37330ULL, },
+ { 0x2f219f4eacacaf61ULL, 0xcde749de29866580ULL, },
+ { 0xfac6c540b5ec9bf9ULL, 0x67fa3d30bf85f9fcULL, }, /* 96 */
+ { 0x58719a8af58d41b9ULL, 0x8af69bdae8797a8cULL, },
+ { 0x0293ed8dc2154481ULL, 0x7aef92fa834de3f0ULL, },
+ { 0xe296644d91f354e5ULL, 0xd4332e315ac37ee4ULL, },
+ { 0xd78a5344aa8ce0f6ULL, 0xbcf1bf88825a127aULL, },
+ { 0xcfe6e77bd50e6bfaULL, 0xa42046c9a6110292ULL, },
+ { 0xc2e4e16ef7883199ULL, 0x8a2eb57c71a6b370ULL, },
+ { 0xb83af7ab54b68847ULL, 0x7682eb14d9902e98ULL, },
+ { 0xfeb58099fb6e2639ULL, 0xd298a4d4f4eef1ccULL, }, /* 104 */
+ { 0x9cbae3e8d8c9b31fULL, 0x0e0c2c1a33a56ab0ULL, },
+ { 0x95dc4a7a980a468fULL, 0xe95439aa32919b0aULL, },
+ { 0xc29c82993429f90bULL, 0xa33308195e2c1fecULL, },
+ { 0x5a0a569e52e5f3acULL, 0x0a72368b53acb754ULL, },
+ { 0x140968eb707c3bbeULL, 0xcd5491c571071d8cULL, },
+ { 0xe1db913744288b2bULL, 0x10c008b6922667d4ULL, },
+ { 0x65b190239a38c686ULL, 0xa6d4ec5b01d651c4ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_U_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_U_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_U_D__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_U_D__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction DPSUB_U.H
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Dot Product";
+ char *instruction_name = "DPSUB_U.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x03fe03fe03fe03feULL, 0x03fe03fe03fe03feULL, }, /* 0 */
+ { 0x03fe03fe03fe03feULL, 0x03fe03fe03fe03feULL, },
+ { 0xb152b152b152b152ULL, 0xb152b152b152b152ULL, },
+ { 0x07fc07fc07fc07fcULL, 0x07fc07fc07fc07fcULL, },
+ { 0x7194719471947194ULL, 0x7194719471947194ULL, },
+ { 0x0bfa0bfa0bfa0bfaULL, 0x0bfa0bfa0bfa0bfaULL, },
+ { 0x9c6bf21546c09c6bULL, 0xf21546c09c6bf215ULL, },
+ { 0x0ff80ff80ff80ff8ULL, 0x0ff80ff80ff80ff8ULL, },
+ { 0x0ff80ff80ff80ff8ULL, 0x0ff80ff80ff80ff8ULL, }, /* 8 */
+ { 0x0ff80ff80ff80ff8ULL, 0x0ff80ff80ff80ff8ULL, },
+ { 0x0ff80ff80ff80ff8ULL, 0x0ff80ff80ff80ff8ULL, },
+ { 0x0ff80ff80ff80ff8ULL, 0x0ff80ff80ff80ff8ULL, },
+ { 0x0ff80ff80ff80ff8ULL, 0x0ff80ff80ff80ff8ULL, },
+ { 0x0ff80ff80ff80ff8ULL, 0x0ff80ff80ff80ff8ULL, },
+ { 0x0ff80ff80ff80ff8ULL, 0x0ff80ff80ff80ff8ULL, },
+ { 0x0ff80ff80ff80ff8ULL, 0x0ff80ff80ff80ff8ULL, },
+ { 0xbd4cbd4cbd4cbd4cULL, 0xbd4cbd4cbd4cbd4cULL, }, /* 16 */
+ { 0xbd4cbd4cbd4cbd4cULL, 0xbd4cbd4cbd4cbd4cULL, },
+ { 0xdb84db84db84db84ULL, 0xdb84db84db84db84ULL, },
+ { 0x6aa06aa06aa06aa0ULL, 0x6aa06aa06aa06aa0ULL, },
+ { 0x5bb05bb05bb05bb0ULL, 0x5bb05bb05bb05bb0ULL, },
+ { 0x17f417f417f417f4ULL, 0x17f417f417f417f4ULL, },
+ { 0x22ea5c06947822eaULL, 0x5c06947822ea5c06ULL, },
+ { 0xc548c548c548c548ULL, 0xc548c548c548c548ULL, },
+ { 0x1bf21bf21bf21bf2ULL, 0x1bf21bf21bf21bf2ULL, }, /* 24 */
+ { 0x1bf21bf21bf21bf2ULL, 0x1bf21bf21bf21bf2ULL, },
+ { 0xab0eab0eab0eab0eULL, 0xab0eab0eab0eab0eULL, },
+ { 0x729c729c729c729cULL, 0x729c729c729c729cULL, },
+ { 0xeb24eb24eb24eb24ULL, 0xeb24eb24eb24eb24ULL, },
+ { 0xc946c946c946c946ULL, 0xc946c946c946c946ULL, },
+ { 0x4ec16b4f87884ec1ULL, 0x6b4f87884ec16b4fULL, },
+ { 0x1ff01ff01ff01ff0ULL, 0x1ff01ff01ff01ff0ULL, },
+ { 0x8988898889888988ULL, 0x8988898889888988ULL, }, /* 32 */
+ { 0x8988898889888988ULL, 0x8988898889888988ULL, },
+ { 0x7a987a987a987a98ULL, 0x7a987a987a987a98ULL, },
+ { 0xf320f320f320f320ULL, 0xf320f320f320f320ULL, },
+ { 0xae00ae00ae00ae00ULL, 0xae00ae00ae00ae00ULL, },
+ { 0x5cb85cb85cb85cb8ULL, 0x5cb85cb85cb85cb8ULL, },
+ { 0x36ac7b34bef036acULL, 0x7b34bef036ac7b34ULL, },
+ { 0xc650c650c650c650ULL, 0xc650c650c650c650ULL, },
+ { 0x60b660b660b660b6ULL, 0x60b660b660b660b6ULL, }, /* 40 */
+ { 0x60b660b660b660b6ULL, 0x60b660b660b660b6ULL, },
+ { 0x1cfa1cfa1cfa1cfaULL, 0x1cfa1cfa1cfa1cfaULL, },
+ { 0xfb1cfb1cfb1cfb1cULL, 0xfb1cfb1cfb1cfb1cULL, },
+ { 0xa9d4a9d4a9d4a9d4ULL, 0xa9d4a9d4a9d4a9d4ULL, },
+ { 0x9582958295829582ULL, 0x9582958295829582ULL, },
+ { 0x4bff5d216e104bffULL, 0x5d216e104bff5d21ULL, },
+ { 0x2fe82fe82fe82fe8ULL, 0x2fe82fe82fe82fe8ULL, },
+ { 0xc05916036aaec059ULL, 0x16036aaec0591603ULL, }, /* 48 */
+ { 0xc05916036aaec059ULL, 0x16036aaec0591603ULL, },
+ { 0xcb4f5a15e732cb4fULL, 0x5a15e732cb4f5a15ULL, },
+ { 0x50cafc1ea57450caULL, 0xfc1ea57450cafc1eULL, },
+ { 0x2abe1a9a07ac2abeULL, 0x1a9a07ac2abe1a9aULL, },
+ { 0xe13be239e03ae13bULL, 0xe239e03ae13be239ULL, },
+ { 0xc92e0cb08536c92eULL, 0x0cb08536c92e0cb0ULL, },
+ { 0x71acc8541b0071acULL, 0xc8541b0071acc854ULL, },
+ { 0xe539e637e438e539ULL, 0xe637e438e539e637ULL, }, /* 56 */
+ { 0xe539e637e438e539ULL, 0xe637e438e539e637ULL, },
+ { 0x87974f7915088797ULL, 0x4f79150887974f79ULL, },
+ { 0x58c6041aad7058c6ULL, 0x041aad7058c6041aULL, },
+ { 0xe86a4f36b4d0e86aULL, 0x4f36b4d0e86a4f36ULL, },
+ { 0xcc5321fd76a8cc53ULL, 0x21fd76a8cc5321fdULL, },
+ { 0x74d1dda10c7274d1ULL, 0xdda10c7274d1dda1ULL, },
+ { 0x3fe03fe03fe03fe0ULL, 0x3fe03fe03fe03fe0ULL, },
+ { 0xcbbcceac141c13a7ULL, 0x00761ce308c3c650ULL, }, /* 64 */
+ { 0xf7b87fc8cfcecf94ULL, 0x97cf0b4ed5a88220ULL, },
+ { 0x77145bfc63a8816dULL, 0x357aa52a175567c0ULL, },
+ { 0x1ade0adc423622e3ULL, 0xab3450024ff1c4e0ULL, },
+ { 0x46dabbf8fde8ded0ULL, 0x428d3e6d1cd680b0ULL, },
+ { 0xc3bd95af925643dfULL, 0x52f8b3300b9c6e5cULL, },
+ { 0xd84d53f1e3d4d3d2ULL, 0x7fd208a8f3004ed2ULL, },
+ { 0x2fdb362aab6b21b4ULL, 0x8d618f60d4e568eeULL, },
+ { 0xaf37125e3f45d38dULL, 0x2b0c293c16924e8eULL, }, /* 72 */
+ { 0xc3c7d0a090c36380ULL, 0x57e67eb4fdf62f04ULL, },
+ { 0x3093e97863b1d807ULL, 0x9bb5e78f8484281bULL, },
+ { 0xc98da762f8243651ULL, 0xbae2a737088bfaf1ULL, },
+ { 0x6d575642d6b2d7c7ULL, 0x309c520f41275811ULL, },
+ { 0xc4e5387b9e4925a9ULL, 0x3e2bd8c7230c722dULL, },
+ { 0x5ddff66532bc83f3ULL, 0x5d58986fa7134503ULL, },
+ { 0x147edd5806d7a4abULL, 0x2cce99ef267e197fULL, },
+ { 0xd5b2d0aab3994377ULL, 0xcd083b9ac440025bULL, }, /* 80 */
+ { 0x80bf8eec25e70baaULL, 0xb6e600dda46ca823ULL, },
+ { 0xe79991b05061b0b1ULL, 0xd91c24ba24bc8d1fULL, },
+ { 0x5352504a2070df63ULL, 0x473b74aadc80fd45ULL, },
+ { 0x0546cd72f0907c98ULL, 0x1ab13142c4b84c19ULL, },
+ { 0xcc6ba15c55b01774ULL, 0x6e1606c3875c1b25ULL, },
+ { 0x1dbdf6d689f3d0f7ULL, 0x4ac43fe21dbb145aULL, },
+ { 0xd6baa1542922ce15ULL, 0x697e5fbada60ca72ULL, },
+ { 0x1806cdbe15b6846fULL, 0x18091759d3f43a3aULL, }, /* 88 */
+ { 0xfc0a8444a6e31a5bULL, 0x0daafd828699ee8eULL, },
+ { 0x4f36fd647760debdULL, 0x7c3fb8561364c110ULL, },
+ { 0x1bfcc992394ee12bULL, 0xfca40e06ed110caeULL, },
+ { 0xa54ca0a4128a8bb6ULL, 0x70d40b38f9c0fc46ULL, },
+ { 0xcb1d6138bde219f9ULL, 0x9c68fd7fb61366a6ULL, },
+ { 0x3887fa1a7e8f8fe6ULL, 0x2ce4bb5039504af0ULL, },
+ { 0xf65edccc34eccb94ULL, 0x3e041478ff0f739cULL, },
+ { 0x4cc27494d274632dULL, 0x2a3ee78cfad81d3cULL, }, /* 96 */
+ { 0xd40e966c853c370eULL, 0x04feaa379b04067cULL, },
+ { 0x5da2b998597c214bULL, 0x9da08eb7ff4efc8cULL, },
+ { 0xe9269a421c1c0396ULL, 0x2f41456bdcd248bcULL, },
+ { 0xe87f80bc039cfc91ULL, 0xed3c08269718789cULL, },
+ { 0xa6c53808a9213425ULL, 0xa2aefe7284cdb89cULL, },
+ { 0x71cd34f063590a91ULL, 0xef6839544786e41cULL, },
+ { 0x6adcd8201277fe43ULL, 0x7a42072920b97f84ULL, },
+ { 0xd64c3010a53c52d9ULL, 0x2ffcd8e8ec4662d9ULL, }, /* 104 */
+ { 0x2bcc04d0fd7bb9d3ULL, 0x54334ac042e043bbULL, },
+ { 0xc73077f8e331ebe0ULL, 0x1c5f5244f12a2b70ULL, },
+ { 0x309c82661787fc47ULL, 0xc7f3cf1c49211c79ULL, },
+ { 0xeb78588cf53e082dULL, 0x75954984106eb821ULL, },
+ { 0x5fa026e08f6af367ULL, 0xa8dfb35ce9820111ULL, },
+ { 0x04b0e03c469efd7fULL, 0x7a6806a42e2df58fULL, },
+ { 0xcca0baf00eacf773ULL, 0xd54e79140435c3e5ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_U_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_U_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_U_H__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_U_H__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction DPSUB_U.W
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Dot Product";
+ char *instruction_name = "DPSUB_U.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0003fffe0003fffeULL, 0x0003fffe0003fffeULL, }, /* 0 */
+ { 0x0003fffe0003fffeULL, 0x0003fffe0003fffeULL, },
+ { 0xaab15552aab15552ULL, 0xaab15552aab15552ULL, },
+ { 0x0007fffc0007fffcULL, 0x0007fffc0007fffcULL, },
+ { 0x6671999466719994ULL, 0x6671999466719994ULL, },
+ { 0x000bfffa000bfffaULL, 0x000bfffa000bfffaULL, },
+ { 0xe39c1c6b8e4771c0ULL, 0x38f1c715e39c1c6bULL, },
+ { 0x000ffff8000ffff8ULL, 0x000ffff8000ffff8ULL, },
+ { 0x000ffff8000ffff8ULL, 0x000ffff8000ffff8ULL, }, /* 8 */
+ { 0x000ffff8000ffff8ULL, 0x000ffff8000ffff8ULL, },
+ { 0x000ffff8000ffff8ULL, 0x000ffff8000ffff8ULL, },
+ { 0x000ffff8000ffff8ULL, 0x000ffff8000ffff8ULL, },
+ { 0x000ffff8000ffff8ULL, 0x000ffff8000ffff8ULL, },
+ { 0x000ffff8000ffff8ULL, 0x000ffff8000ffff8ULL, },
+ { 0x000ffff8000ffff8ULL, 0x000ffff8000ffff8ULL, },
+ { 0x000ffff8000ffff8ULL, 0x000ffff8000ffff8ULL, },
+ { 0xaabd554caabd554cULL, 0xaabd554caabd554cULL, }, /* 16 */
+ { 0xaabd554caabd554cULL, 0xaabd554caabd554cULL, },
+ { 0xc730e384c730e384ULL, 0xc730e384c730e384ULL, },
+ { 0x556aaaa0556aaaa0ULL, 0x556aaaa0556aaaa0ULL, },
+ { 0x445bbbb0445bbbb0ULL, 0x445bbbb0445bbbb0ULL, },
+ { 0x0017fff40017fff4ULL, 0x0017fff40017fff4ULL, },
+ { 0x427812ea0994f678ULL, 0x7b5bda06427812eaULL, },
+ { 0xaac55548aac55548ULL, 0xaac55548aac55548ULL, },
+ { 0x001bfff2001bfff2ULL, 0x001bfff2001bfff2ULL, }, /* 24 */
+ { 0x001bfff2001bfff2ULL, 0x001bfff2001bfff2ULL, },
+ { 0x8e55c70e8e55c70eULL, 0x8e55c70e8e55c70eULL, },
+ { 0x5572aa9c5572aa9cULL, 0x5572aa9c5572aa9cULL, },
+ { 0xcceb3324cceb3324ULL, 0xcceb3324cceb3324ULL, },
+ { 0xaac95546aac95546ULL, 0xaac95546aac95546ULL, },
+ { 0x4bf95ec12f87d088ULL, 0x686b424f4bf95ec1ULL, },
+ { 0x001ffff0001ffff0ULL, 0x001ffff0001ffff0ULL, },
+ { 0x6689998866899988ULL, 0x6689998866899988ULL, }, /* 32 */
+ { 0x6689998866899988ULL, 0x6689998866899988ULL, },
+ { 0x557aaa98557aaa98ULL, 0x557aaa98557aaa98ULL, },
+ { 0xccf33320ccf33320ULL, 0xccf33320ccf33320ULL, },
+ { 0x8547ae008547ae00ULL, 0x8547ae008547ae00ULL, },
+ { 0x335cccb8335cccb8ULL, 0x335cccb8335cccb8ULL, },
+ { 0x4fd016ac0b8c5af0ULL, 0x94149f344fd016acULL, },
+ { 0x99c6665099c66650ULL, 0x99c6665099c66650ULL, },
+ { 0x3360ccb63360ccb6ULL, 0x3360ccb63360ccb6ULL, }, /* 40 */
+ { 0x3360ccb63360ccb6ULL, 0x3360ccb63360ccb6ULL, },
+ { 0xef1d10faef1d10faULL, 0xef1d10faef1d10faULL, },
+ { 0xccfb331cccfb331cULL, 0xccfb331cccfb331cULL, },
+ { 0x7b1051d47b1051d4ULL, 0x7b1051d47b1051d4ULL, },
+ { 0x6695998266959982ULL, 0x6695998266959982ULL, },
+ { 0x2db26bff1ca17d10ULL, 0x3ec38e212db26bffULL, },
+ { 0x002fffe8002fffe8ULL, 0x002fffe8002fffe8ULL, },
+ { 0xe3c01c598e6b71aeULL, 0x3915c703e3c01c59ULL, }, /* 48 */
+ { 0xe3c01c598e6b71aeULL, 0x3915c703e3c01c59ULL, },
+ { 0x26202f4f97e86832ULL, 0xb459a11526202f4fULL, },
+ { 0xc75038ca1ca6e374ULL, 0x71fb8e1ec75038caULL, },
+ { 0xe3c382bef4d671acULL, 0xd2b3609ae3c382beULL, },
+ { 0xaae0553baae2553aULL, 0xaae15539aae0553bULL, },
+ { 0xd3f7192e919b0636ULL, 0x4f3b0fb0d3f7192eULL, },
+ { 0x8e7071ac391dc700ULL, 0xe3c71c548e7071acULL, },
+ { 0xaae45539aae65538ULL, 0xaae55537aae45539ULL, }, /* 56 */
+ { 0xaae45539aae65538ULL, 0xaae55537aae45539ULL, },
+ { 0x133197974c16b408ULL, 0xda4ed07913319797ULL, },
+ { 0xc75838c61caee370ULL, 0x72038e1ac75838c6ULL, },
+ { 0x114e886aaae8eed0ULL, 0x77b55536114e886aULL, },
+ { 0xe3cc1c538e7771a8ULL, 0x3921c6fde3cc1c53ULL, },
+ { 0x9e4574d135fa3272ULL, 0xcdadd3a19e4574d1ULL, },
+ { 0x003fffe0003fffe0ULL, 0x003fffe0003fffe0ULL, },
+ { 0xe77c016cdd7daa5cULL, 0xe98945eb8a373037ULL, }, /* 64 */
+ { 0x60fd93dc8ef99616ULL, 0xdba475fe3c075522ULL, },
+ { 0x67ae7b204335bcd8ULL, 0xc7121f747860f089ULL, },
+ { 0x17bb0f0ee8fd8c96ULL, 0x972fe12d34478253ULL, },
+ { 0x913ca17e9a797850ULL, 0x894b1140e617a73eULL, },
+ { 0x99ae5a31e83a45a7ULL, 0xff24684bc96dd9adULL, },
+ { 0xefeea5a7437774caULL, 0x6ac04bfdaf344b68ULL, },
+ { 0x8175363e76faed37ULL, 0xfc38b88657b1e4aaULL, },
+ { 0x88261d822b3713f9ULL, 0xe7a661fc940b8011ULL, }, /* 72 */
+ { 0xde6668f88674431cULL, 0x534245ae79d1f1ccULL, },
+ { 0xf331d070b3932dbbULL, 0xb25f4d6d0200af03ULL, },
+ { 0x985e1b88f3e41a1cULL, 0x31e873ed7002566dULL, },
+ { 0x486aaf7699abe9daULL, 0x020635a62be8e837ULL, },
+ { 0xd9f1400dcd2f6247ULL, 0x937ea22fd4668179ULL, },
+ { 0x7f1d8b250d804ea8ULL, 0x1307c8af426828e3ULL, },
+ { 0x4be6ff9b22ca7983ULL, 0x7b2e358e09e10fdfULL, },
+ { 0x3d0470dbf4d6b86fULL, 0x548567e8f5250450ULL, }, /* 80 */
+ { 0x00d897321b41b715ULL, 0x02517c05df66c875ULL, },
+ { 0x991ec80ea3b5c306ULL, 0xa18dc9b22cff8e2fULL, },
+ { 0x44850796bb133f8dULL, 0xdc2a4cc591614211ULL, },
+ { 0x192b30fc8866f607ULL, 0x97e8c289d36e61aaULL, },
+ { 0x0058689e9fcad43dULL, 0xfe7a0cc7a239bc40ULL, },
+ { 0xb8bc4cc2b8296867ULL, 0xccf01b9e1a7e74adULL, },
+ { 0x61014864181c5d2cULL, 0x4c8bc05ea1b0cc11ULL, },
+ { 0xec0d0e4af547db74ULL, 0x2d758eed74a13bb5ULL, }, /* 88 */
+ { 0x03e797060056a10fULL, 0xc1a1d5f8579892eaULL, },
+ { 0x9a3ca5d4a8548905ULL, 0xfd2bfd1807c0081aULL, },
+ { 0x4820b48cf1454f6bULL, 0xe982ac5dfb74445aULL, },
+ { 0x7eec2fbcb0c3c941ULL, 0x9d1459e9d27d4766ULL, },
+ { 0x020a22e0debbd140ULL, 0x4fbb0ef3a9e0453bULL, },
+ { 0xe8df4a9ccb0c350bULL, 0x37b3761e2e442cffULL, },
+ { 0x7c3604df51731065ULL, 0xd9add64be7d81e17ULL, },
+ { 0x35a1aacf3f24481fULL, 0x900caa26ecaf303bULL, }, /* 96 */
+ { 0x7f0fd7311d2a2997ULL, 0x5e11155ee03d0362ULL, },
+ { 0x7959c1ef0ab6e6c3ULL, 0x41695f03ff01377bULL, },
+ { 0x89d8f6a1bc2ded57ULL, 0x29ed46aadb5c8a3cULL, },
+ { 0x01ec800ecaa24ac8ULL, 0xf32ccdbb9c58b788ULL, },
+ { 0xffd7297c53176782ULL, 0x4acc984953e0cc00ULL, },
+ { 0x04316ff6e9707c3dULL, 0xd5f54b0b0ac9f7e0ULL, },
+ { 0xffe6fc76421c7405ULL, 0x8f42f98ab98b12e9ULL, },
+ { 0xa75ea33ed2e809e1ULL, 0xb6fdbf643abee85cULL, }, /* 104 */
+ { 0xc75019063471bcc9ULL, 0x05bcd250f1d0ad42ULL, },
+ { 0x300d94eaa78224eaULL, 0x615cfa00370a0c2aULL, },
+ { 0xaa1a04f419d03dccULL, 0x8fe0ca60107a1a34ULL, },
+ { 0x5f0bb18ad9b000d4ULL, 0xd3ed3780ee630840ULL, },
+ { 0x25e24aa388dc4d8cULL, 0x40c1586349788fbaULL, },
+ { 0x0ec344de11f41ac8ULL, 0xed9aea2a99a95e8aULL, },
+ { 0x02499bebf3ac5a24ULL, 0xecb186c0e06045b8ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_U_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_U_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_U_W__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_DPSUB_U_W__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MADDV.B
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Multiply";
+ char *instruction_name = "MADDV.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, }, /* 0 */
+ { 0x0101010101010101ULL, 0x0101010101010101ULL, },
+ { 0x5757575757575757ULL, 0x5757575757575757ULL, },
+ { 0x0202020202020202ULL, 0x0202020202020202ULL, },
+ { 0x3636363636363636ULL, 0x3636363636363636ULL, },
+ { 0x0303030303030303ULL, 0x0303030303030303ULL, },
+ { 0x2075cb2075cb2075ULL, 0xcb2075cb2075cb20ULL, },
+ { 0x0404040404040404ULL, 0x0404040404040404ULL, },
+ { 0x0404040404040404ULL, 0x0404040404040404ULL, }, /* 8 */
+ { 0x0404040404040404ULL, 0x0404040404040404ULL, },
+ { 0x0404040404040404ULL, 0x0404040404040404ULL, },
+ { 0x0404040404040404ULL, 0x0404040404040404ULL, },
+ { 0x0404040404040404ULL, 0x0404040404040404ULL, },
+ { 0x0404040404040404ULL, 0x0404040404040404ULL, },
+ { 0x0404040404040404ULL, 0x0404040404040404ULL, },
+ { 0x0404040404040404ULL, 0x0404040404040404ULL, },
+ { 0x5a5a5a5a5a5a5a5aULL, 0x5a5a5a5a5a5a5a5aULL, }, /* 16 */
+ { 0x5a5a5a5a5a5a5a5aULL, 0x5a5a5a5a5a5a5a5aULL, },
+ { 0x3e3e3e3e3e3e3e3eULL, 0x3e3e3e3e3e3e3e3eULL, },
+ { 0xb0b0b0b0b0b0b0b0ULL, 0xb0b0b0b0b0b0b0b0ULL, },
+ { 0x2828282828282828ULL, 0x2828282828282828ULL, },
+ { 0x0606060606060606ULL, 0x0606060606060606ULL, },
+ { 0xc45236c45236c452ULL, 0x36c45236c45236c4ULL, },
+ { 0x5c5c5c5c5c5c5c5cULL, 0x5c5c5c5c5c5c5c5cULL, },
+ { 0x0707070707070707ULL, 0x0707070707070707ULL, }, /* 24 */
+ { 0x0707070707070707ULL, 0x0707070707070707ULL, },
+ { 0x7979797979797979ULL, 0x7979797979797979ULL, },
+ { 0xb2b2b2b2b2b2b2b2ULL, 0xb2b2b2b2b2b2b2b2ULL, },
+ { 0x6e6e6e6e6e6e6e6eULL, 0x6e6e6e6e6e6e6e6eULL, },
+ { 0x5d5d5d5d5d5d5d5dULL, 0x5d5d5d5d5d5d5d5dULL, },
+ { 0xbc83f5bc83f5bc83ULL, 0xf5bc83f5bc83f5bcULL, },
+ { 0x0808080808080808ULL, 0x0808080808080808ULL, },
+ { 0x3c3c3c3c3c3c3c3cULL, 0x3c3c3c3c3c3c3c3cULL, }, /* 32 */
+ { 0x3c3c3c3c3c3c3c3cULL, 0x3c3c3c3c3c3c3c3cULL, },
+ { 0xb4b4b4b4b4b4b4b4ULL, 0xb4b4b4b4b4b4b4b4ULL, },
+ { 0x7070707070707070ULL, 0x7070707070707070ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xa4a4a4a4a4a4a4a4ULL, 0xa4a4a4a4a4a4a4a4ULL, },
+ { 0x88cc4488cc4488ccULL, 0x4488cc4488cc4488ULL, },
+ { 0xd8d8d8d8d8d8d8d8ULL, 0xd8d8d8d8d8d8d8d8ULL, },
+ { 0xa5a5a5a5a5a5a5a5ULL, 0xa5a5a5a5a5a5a5a5ULL, }, /* 40 */
+ { 0xa5a5a5a5a5a5a5a5ULL, 0xa5a5a5a5a5a5a5a5ULL, },
+ { 0x8383838383838383ULL, 0x8383838383838383ULL, },
+ { 0x7272727272727272ULL, 0x7272727272727272ULL, },
+ { 0x1616161616161616ULL, 0x1616161616161616ULL, },
+ { 0x3f3f3f3f3f3f3f3fULL, 0x3f3f3f3f3f3f3f3fULL, },
+ { 0x7889677889677889ULL, 0x6778896778896778ULL, },
+ { 0x0c0c0c0c0c0c0c0cULL, 0x0c0c0c0c0c0c0c0cULL, },
+ { 0x297ed4297ed4297eULL, 0xd4297ed4297ed429ULL, }, /* 48 */
+ { 0x297ed4297ed4297eULL, 0xd4297ed4297ed429ULL, },
+ { 0xe7ca04e7ca04e7caULL, 0x04e7ca04e7ca04e7ULL, },
+ { 0x46f09c46f09c46f0ULL, 0x9c46f09c46f09c46ULL, },
+ { 0x2a183c2a183c2a18ULL, 0x3c2a183c2a183c2aULL, },
+ { 0x6362646362646362ULL, 0x6463626463626463ULL, },
+ { 0xac26a4ac26a4ac26ULL, 0xa4ac26a4ac26a4acULL, },
+ { 0x80d42c80d42c80d4ULL, 0x2c80d42c80d42c80ULL, },
+ { 0x6463656463656463ULL, 0x6564636564636564ULL, }, /* 56 */
+ { 0x6463656463656463ULL, 0x6564636564636564ULL, },
+ { 0xfc6d8bfc6d8bfc6dULL, 0x8bfc6d8bfc6d8bfcULL, },
+ { 0x48f29e48f29e48f2ULL, 0x9e48f29e48f29e48ULL, },
+ { 0x98fe3298fe3298feULL, 0x3298fe3298fe3298ULL, },
+ { 0x2c81d72c81d72c81ULL, 0xd72c81d72c81d72cULL, },
+ { 0x002f5f002f5f002fULL, 0x5f002f5f002f5f00ULL, },
+ { 0x1010101010101010ULL, 0x1010101010101010ULL, },
+ { 0x50f4b4a050944910ULL, 0x09818994142910a0ULL, }, /* 64 */
+ { 0xa8a0b48458da5c10ULL, 0x4fe29220ea6e7070ULL, },
+ { 0x08e408fc40188310ULL, 0xbcca14c29417e060ULL, },
+ { 0x889acc58f0da8d90ULL, 0x0bc1ec1242cd40e0ULL, },
+ { 0xe046cc3cf820a090ULL, 0x5122f59e1812a0b0ULL, },
+ { 0xf94acc85218951d0ULL, 0x95738e42d193e4c0ULL, },
+ { 0x9d16cc43c6665ed0ULL, 0x53db3028d828be70ULL, },
+ { 0x6db8cc0a0c890c40ULL, 0x3d628818b56622f0ULL, },
+ { 0xcdfc2082f4c73340ULL, 0xaa4a0aba5f0f92e0ULL, }, /* 72 */
+ { 0x71c8204099a44040ULL, 0x68b2aca066a46c90ULL, },
+ { 0x016c64244a05b940ULL, 0x59f2d0a19fddc520ULL, },
+ { 0x4132584638a46f40ULL, 0xd44a00c982f36fa0ULL, },
+ { 0xc1e81ca2e86679c0ULL, 0x2341d81930a9cf20ULL, },
+ { 0x918a1c692e892730ULL, 0x0dc830090de733a0ULL, },
+ { 0xd150108b1c28dd30ULL, 0x88206031f0fddd20ULL, },
+ { 0xd1b1f4b4a08961f4ULL, 0x3101a07181016120ULL, },
+ { 0xd9fb2c24a0fb96f4ULL, 0x8c6880ef7f7c11a0ULL, }, /* 80 */
+ { 0x9c452c10c01c3094ULL, 0x64c00035ea008320ULL, },
+ { 0x6c8714b080c04094ULL, 0xa0c00000380072a0ULL, },
+ { 0xac30cca08080c0acULL, 0xc0800000300016a0ULL, },
+ { 0x0c101420808080acULL, 0x00000000d0003620ULL, },
+ { 0xd0f014800000000cULL, 0x00000000e00082a0ULL, },
+ { 0x9050ac800000000cULL, 0x0000000080004c20ULL, },
+ { 0x90007400000000b4ULL, 0x0000000000006420ULL, },
+ { 0x1000ac00000000b4ULL, 0x00000000000024a0ULL, }, /* 88 */
+ { 0xc000ac0000000054ULL, 0x000000000000ac20ULL, },
+ { 0xc000940000000054ULL, 0x00000000000088a0ULL, },
+ { 0xc0004c00000000ecULL, 0x00000000000098a0ULL, },
+ { 0xc0009400000000ecULL, 0x0000000000001820ULL, },
+ { 0x000094000000004cULL, 0x000000000000c8a0ULL, },
+ { 0x00002c000000004cULL, 0x000000000000b020ULL, },
+ { 0x0000f40000000074ULL, 0x0000000000001020ULL, },
+ { 0x00002c0000000074ULL, 0x00000000000010a0ULL, }, /* 96 */
+ { 0x0000b40000000074ULL, 0x0000000000001020ULL, },
+ { 0x00006c0000000074ULL, 0x00000000000010a0ULL, },
+ { 0x0000740000000074ULL, 0x0000000000001020ULL, },
+ { 0x0000740000000014ULL, 0x00000000000030a0ULL, },
+ { 0x00007400000000b4ULL, 0x0000000000009020ULL, },
+ { 0x0000740000000054ULL, 0x000000000000b0a0ULL, },
+ { 0x00007400000000f4ULL, 0x0000000000001020ULL, },
+ { 0x00004c00000000f4ULL, 0x00000000000060a0ULL, }, /* 104 */
+ { 0x0000f400000000f4ULL, 0x0000000000004020ULL, },
+ { 0x0000cc00000000f4ULL, 0x00000000000080a0ULL, },
+ { 0x00007400000000f4ULL, 0x0000000000000020ULL, },
+ { 0x00006c000000004cULL, 0x0000000000000020ULL, },
+ { 0x0000b40000000074ULL, 0x0000000000000020ULL, },
+ { 0x00002c00000000ccULL, 0x0000000000000020ULL, },
+ { 0x0000f400000000f4ULL, 0x0000000000000020ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_B__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_B__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MADDV.D
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Multiply";
+ char *instruction_name = "MADDV.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, }, /* 0 */
+ { 0x0000000000000001ULL, 0x0000000000000001ULL, },
+ { 0x5555555555555557ULL, 0x5555555555555557ULL, },
+ { 0x0000000000000002ULL, 0x0000000000000002ULL, },
+ { 0x3333333333333336ULL, 0x3333333333333336ULL, },
+ { 0x0000000000000003ULL, 0x0000000000000003ULL, },
+ { 0x1c71c71c71c71c75ULL, 0xc71c71c71c71c720ULL, },
+ { 0x0000000000000004ULL, 0x0000000000000004ULL, },
+ { 0x0000000000000004ULL, 0x0000000000000004ULL, }, /* 8 */
+ { 0x0000000000000004ULL, 0x0000000000000004ULL, },
+ { 0x0000000000000004ULL, 0x0000000000000004ULL, },
+ { 0x0000000000000004ULL, 0x0000000000000004ULL, },
+ { 0x0000000000000004ULL, 0x0000000000000004ULL, },
+ { 0x0000000000000004ULL, 0x0000000000000004ULL, },
+ { 0x0000000000000004ULL, 0x0000000000000004ULL, },
+ { 0x0000000000000004ULL, 0x0000000000000004ULL, },
+ { 0x555555555555555aULL, 0x555555555555555aULL, }, /* 16 */
+ { 0x555555555555555aULL, 0x555555555555555aULL, },
+ { 0x8e38e38e38e38e3eULL, 0x8e38e38e38e38e3eULL, },
+ { 0xaaaaaaaaaaaaaab0ULL, 0xaaaaaaaaaaaaaab0ULL, },
+ { 0x2222222222222228ULL, 0x2222222222222228ULL, },
+ { 0x0000000000000006ULL, 0x0000000000000006ULL, },
+ { 0x12f684bda12f6852ULL, 0x2f684bda12f684c4ULL, },
+ { 0x555555555555555cULL, 0x555555555555555cULL, },
+ { 0x0000000000000007ULL, 0x0000000000000007ULL, }, /* 24 */
+ { 0x0000000000000007ULL, 0x0000000000000007ULL, },
+ { 0x1c71c71c71c71c79ULL, 0x1c71c71c71c71c79ULL, },
+ { 0xaaaaaaaaaaaaaab2ULL, 0xaaaaaaaaaaaaaab2ULL, },
+ { 0x666666666666666eULL, 0x666666666666666eULL, },
+ { 0x555555555555555dULL, 0x555555555555555dULL, },
+ { 0x5ed097b425ed0983ULL, 0xed097b425ed097bcULL, },
+ { 0x0000000000000008ULL, 0x0000000000000008ULL, },
+ { 0x333333333333333cULL, 0x333333333333333cULL, }, /* 32 */
+ { 0x333333333333333cULL, 0x333333333333333cULL, },
+ { 0xaaaaaaaaaaaaaab4ULL, 0xaaaaaaaaaaaaaab4ULL, },
+ { 0x6666666666666670ULL, 0x6666666666666670ULL, },
+ { 0x5c28f5c28f5c2900ULL, 0x5c28f5c28f5c2900ULL, },
+ { 0x99999999999999a4ULL, 0x99999999999999a4ULL, },
+ { 0x16c16c16c16c16ccULL, 0xd27d27d27d27d288ULL, },
+ { 0xccccccccccccccd8ULL, 0xccccccccccccccd8ULL, },
+ { 0x99999999999999a5ULL, 0x99999999999999a5ULL, }, /* 40 */
+ { 0x99999999999999a5ULL, 0x99999999999999a5ULL, },
+ { 0x7777777777777783ULL, 0x7777777777777783ULL, },
+ { 0x6666666666666672ULL, 0x6666666666666672ULL, },
+ { 0xa3d70a3d70a3d716ULL, 0xa3d70a3d70a3d716ULL, },
+ { 0x333333333333333fULL, 0x333333333333333fULL, },
+ { 0xd27d27d27d27d289ULL, 0xc16c16c16c16c178ULL, },
+ { 0x000000000000000cULL, 0x000000000000000cULL, },
+ { 0x1c71c71c71c71c7eULL, 0xc71c71c71c71c729ULL, }, /* 48 */
+ { 0x1c71c71c71c71c7eULL, 0xc71c71c71c71c729ULL, },
+ { 0x2f684bda12f684caULL, 0xf684bda12f684be7ULL, },
+ { 0x38e38e38e38e38f0ULL, 0x8e38e38e38e38e46ULL, },
+ { 0xb60b60b60b60b618ULL, 0xc71c71c71c71c72aULL, },
+ { 0x5555555555555562ULL, 0x5555555555555563ULL, },
+ { 0x06522c3f35ba7826ULL, 0xa781948b0fcd6eacULL, },
+ { 0x71c71c71c71c71d4ULL, 0x1c71c71c71c71c80ULL, },
+ { 0x5555555555555563ULL, 0x5555555555555564ULL, }, /* 56 */
+ { 0x5555555555555563ULL, 0x5555555555555564ULL, },
+ { 0x97b425ed097b426dULL, 0x7b425ed097b425fcULL, },
+ { 0x38e38e38e38e38f2ULL, 0x8e38e38e38e38e48ULL, },
+ { 0xeeeeeeeeeeeeeefeULL, 0x8888888888888898ULL, },
+ { 0x1c71c71c71c71c81ULL, 0xc71c71c71c71c72cULL, },
+ { 0x87e6b74f0329162fULL, 0x3c0ca4587e6b7500ULL, },
+ { 0x0000000000000010ULL, 0x0000000000000010ULL, },
+ { 0xad45be6961639010ULL, 0x3297fdea749880a0ULL, }, /* 64 */
+ { 0x9ced640a487afa10ULL, 0xeaa90809e3b1a470ULL, },
+ { 0xa5b377aa0caf5a10ULL, 0x95c9a7903bd12160ULL, },
+ { 0xa194ffe4fb27d390ULL, 0x17e6ccd3c9a1c0e0ULL, },
+ { 0x913ca585e23f3d90ULL, 0xcff7d6f338bae4b0ULL, },
+ { 0xc8ead0bee02cadd0ULL, 0x381c4d6a83a94cc0ULL, },
+ { 0x33b60e279e9989d0ULL, 0xe7f71f9b97ee3470ULL, },
+ { 0x217580abbfdd3e40ULL, 0x6779436687bc89f0ULL, },
+ { 0x2a3b944b84119e40ULL, 0x1299e2ecdfdc06e0ULL, }, /* 72 */
+ { 0x9506d1b4427e7a40ULL, 0xc274b51df420ee90ULL, },
+ { 0x1b2bb7962782ba40ULL, 0x9bf62dc42637b820ULL, },
+ { 0x91d16316b1663b40ULL, 0x3cf7c824fb128ca0ULL, },
+ { 0x8db2eb519fdeb4c0ULL, 0xbf14ed6888e32c20ULL, },
+ { 0x7b725dd5c1226930ULL, 0x3e97113378b181a0ULL, },
+ { 0xf21809564b05ea30ULL, 0xdf98ab944d8c5620ULL, },
+ { 0x3dcc402bfcefb9f4ULL, 0xf26a7a4530ab3a20ULL, },
+ { 0x81a8956a21043af4ULL, 0xe63ec4a9de07f3a0ULL, }, /* 80 */
+ { 0x14acc7eab115be94ULL, 0xa72fae300e450520ULL, },
+ { 0x4c5c3900181b6494ULL, 0xc26796e561c70ba0ULL, },
+ { 0x513451003792b1acULL, 0x5acad191d5b18fa0ULL, },
+ { 0x0daff27cb51538acULL, 0x31375ce2aea24b20ULL, },
+ { 0xbb9ebee52390b20cULL, 0xd8cfb350af547ea0ULL, },
+ { 0x4df25269204a3c0cULL, 0x07b9241bbd1b8320ULL, },
+ { 0x39b3c4d066371fb4ULL, 0x2a4dc00c264fb720ULL, },
+ { 0xf9aee458846dd0b4ULL, 0x79d838b37c524ca0ULL, }, /* 88 */
+ { 0x115f9e7f00744254ULL, 0x46ec87fe3540fa20ULL, },
+ { 0xb01458f6b0850854ULL, 0xde82246a25db24a0ULL, },
+ { 0xc18097bf5a7bb9ecULL, 0x4155f0da566748a0ULL, },
+ { 0x70c7391b1a7d90ecULL, 0x0400deec0a0cb020ULL, },
+ { 0xf7a41980bd958c4cULL, 0xedfeb14ff6d44fa0ULL, },
+ { 0x7906f19718fcf64cULL, 0x29e471752ecca820ULL, },
+ { 0xb6393967140b1974ULL, 0xbd0ed4c39361fc20ULL, },
+ { 0x74ecb57da4acfa74ULL, 0x36ea3f3dbcafcda0ULL, }, /* 96 */
+ { 0x5b14aa5e3f7c1b74ULL, 0xeb031f17fe2b7120ULL, },
+ { 0x0468573ef6087c74ULL, 0xe8ef35d2e05abea0ULL, },
+ { 0xd69cf5cf0de21d74ULL, 0x39f569701e89ae20ULL, },
+ { 0xf233f7a10f743514ULL, 0xf574fc00c1b755a0ULL, },
+ { 0x873c421a5ed469b4ULL, 0x96f393305dfcdf20ULL, },
+ { 0x17e80b0449fea354ULL, 0x2f05ddb06b40c2a0ULL, },
+ { 0x0741f67f982609f4ULL, 0x9c23f2dbc2b79820ULL, },
+ { 0x530275e3b2de7ff4ULL, 0xc6904e7f6f6c1aa0ULL, }, /* 104 */
+ { 0xf8214644bbe3f5f4ULL, 0xe44a0de01c974f20ULL, },
+ { 0xb59c90c0a8b66bf4ULL, 0x9abcf7a8e1391da0ULL, },
+ { 0xb67d543caed5e1f4ULL, 0x4ce8f72994d78e20ULL, },
+ { 0xcee67f5e9d2e224cULL, 0xba31bdf2ab48a220ULL, },
+ { 0x87acb43db40fad74ULL, 0x8a259794c40e3620ULL, },
+ { 0x45c27495332aeeccULL, 0xe81c4208ecf84a20ULL, },
+ { 0x50a99b794e1bc8f4ULL, 0x17cdf4c275d6de20ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_D__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_D__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MADDV.H
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Multiply";
+ char *instruction_name = "MADDV.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, }, /* 0 */
+ { 0x0001000100010001ULL, 0x0001000100010001ULL, },
+ { 0x5557555755575557ULL, 0x5557555755575557ULL, },
+ { 0x0002000200020002ULL, 0x0002000200020002ULL, },
+ { 0x3336333633363336ULL, 0x3336333633363336ULL, },
+ { 0x0003000300030003ULL, 0x0003000300030003ULL, },
+ { 0x1c75c72071cb1c75ULL, 0xc72071cb1c75c720ULL, },
+ { 0x0004000400040004ULL, 0x0004000400040004ULL, },
+ { 0x0004000400040004ULL, 0x0004000400040004ULL, }, /* 8 */
+ { 0x0004000400040004ULL, 0x0004000400040004ULL, },
+ { 0x0004000400040004ULL, 0x0004000400040004ULL, },
+ { 0x0004000400040004ULL, 0x0004000400040004ULL, },
+ { 0x0004000400040004ULL, 0x0004000400040004ULL, },
+ { 0x0004000400040004ULL, 0x0004000400040004ULL, },
+ { 0x0004000400040004ULL, 0x0004000400040004ULL, },
+ { 0x0004000400040004ULL, 0x0004000400040004ULL, },
+ { 0x555a555a555a555aULL, 0x555a555a555a555aULL, }, /* 16 */
+ { 0x555a555a555a555aULL, 0x555a555a555a555aULL, },
+ { 0x8e3e8e3e8e3e8e3eULL, 0x8e3e8e3e8e3e8e3eULL, },
+ { 0xaab0aab0aab0aab0ULL, 0xaab0aab0aab0aab0ULL, },
+ { 0x2228222822282228ULL, 0x2228222822282228ULL, },
+ { 0x0006000600060006ULL, 0x0006000600060006ULL, },
+ { 0x685284c4a1366852ULL, 0x84c4a136685284c4ULL, },
+ { 0x555c555c555c555cULL, 0x555c555c555c555cULL, },
+ { 0x0007000700070007ULL, 0x0007000700070007ULL, }, /* 24 */
+ { 0x0007000700070007ULL, 0x0007000700070007ULL, },
+ { 0x1c791c791c791c79ULL, 0x1c791c791c791c79ULL, },
+ { 0xaab2aab2aab2aab2ULL, 0xaab2aab2aab2aab2ULL, },
+ { 0x666e666e666e666eULL, 0x666e666e666e666eULL, },
+ { 0x555d555d555d555dULL, 0x555d555d555d555dULL, },
+ { 0x098397bc25f50983ULL, 0x97bc25f5098397bcULL, },
+ { 0x0008000800080008ULL, 0x0008000800080008ULL, },
+ { 0x333c333c333c333cULL, 0x333c333c333c333cULL, }, /* 32 */
+ { 0x333c333c333c333cULL, 0x333c333c333c333cULL, },
+ { 0xaab4aab4aab4aab4ULL, 0xaab4aab4aab4aab4ULL, },
+ { 0x6670667066706670ULL, 0x6670667066706670ULL, },
+ { 0x2900290029002900ULL, 0x2900290029002900ULL, },
+ { 0x99a499a499a499a4ULL, 0x99a499a499a499a4ULL, },
+ { 0x16ccd2888e4416ccULL, 0xd2888e4416ccd288ULL, },
+ { 0xccd8ccd8ccd8ccd8ULL, 0xccd8ccd8ccd8ccd8ULL, },
+ { 0x99a599a599a599a5ULL, 0x99a599a599a599a5ULL, }, /* 40 */
+ { 0x99a599a599a599a5ULL, 0x99a599a599a599a5ULL, },
+ { 0x7783778377837783ULL, 0x7783778377837783ULL, },
+ { 0x6672667266726672ULL, 0x6672667266726672ULL, },
+ { 0xd716d716d716d716ULL, 0xd716d716d716d716ULL, },
+ { 0x333f333f333f333fULL, 0x333f333f333f333fULL, },
+ { 0xd289c178b067d289ULL, 0xc178b067d289c178ULL, },
+ { 0x000c000c000c000cULL, 0x000c000c000c000cULL, },
+ { 0x1c7ec72971d41c7eULL, 0xc72971d41c7ec729ULL, }, /* 48 */
+ { 0x1c7ec72971d41c7eULL, 0xc72971d41c7ec729ULL, },
+ { 0x84ca4be7130484caULL, 0x4be7130484ca4be7ULL, },
+ { 0x38f08e46e39c38f0ULL, 0x8e46e39c38f08e46ULL, },
+ { 0xb618c72ad83cb618ULL, 0xc72ad83cb618c72aULL, },
+ { 0x5562556355645562ULL, 0x5563556455625563ULL, },
+ { 0x78266eac81a47826ULL, 0x6eac81a478266eacULL, },
+ { 0x71d41c80c72c71d4ULL, 0x1c80c72c71d41c80ULL, },
+ { 0x5563556455655563ULL, 0x5564556555635564ULL, }, /* 56 */
+ { 0x5563556455655563ULL, 0x5564556555635564ULL, },
+ { 0x426d25fc098b426dULL, 0x25fc098b426d25fcULL, },
+ { 0x38f28e48e39e38f2ULL, 0x8e48e39e38f28e48ULL, },
+ { 0xeefe88982232eefeULL, 0x88982232eefe8898ULL, },
+ { 0x1c81c72c71d71c81ULL, 0xc72c71d71c81c72cULL, },
+ { 0x162f7500b75f162fULL, 0x7500b75f162f7500ULL, },
+ { 0x0010001000100010ULL, 0x0010001000100010ULL, },
+ { 0xcbf432a0c5949010ULL, 0x838136944f2980a0ULL, }, /* 64 */
+ { 0xf8a073846fdafa10ULL, 0x81e20820066ea470ULL, },
+ { 0x25e45efce9185a10ULL, 0xd1ca0ec2ee172160ULL, },
+ { 0x9e9a52589fdad390ULL, 0x88c19612bccdc0e0ULL, },
+ { 0xcb46933c4a203d90ULL, 0x8722679e7412e4b0ULL, },
+ { 0xec4ab9850c89add0ULL, 0x31736642d9934cc0ULL, },
+ { 0x15164543016689d0ULL, 0xd2dbe12880283470ULL, },
+ { 0xe4b8e50ad4893e40ULL, 0xb8628f18916689f0ULL, },
+ { 0x11fcd0824dc79e40ULL, 0x084a95ba790f06e0ULL, }, /* 72 */
+ { 0x3ac85c4042a47a40ULL, 0xa9b210a01fa4ee90ULL, },
+ { 0x4a6ce5241805ba40ULL, 0x2ff282a198ddb820ULL, },
+ { 0xda320a46aaa43b40ULL, 0xaa4ae1c91cf38ca0ULL, },
+ { 0x52e8fda26166b4c0ULL, 0x61416919eba92c20ULL, },
+ { 0x228a9d6934896930ULL, 0x46c81709fce781a0ULL, },
+ { 0xb250c28bc728ea30ULL, 0xc120763180fd5620ULL, },
+ { 0xeab115b4cc89b9f4ULL, 0x1e01ac71b6013a20ULL, },
+ { 0x1ffb192480fb3af4ULL, 0x7b68d8ef267cf3a0ULL, }, /* 80 */
+ { 0xf545d210101cbe94ULL, 0xdcc07635cb000520ULL, },
+ { 0x8b8730b052c06494ULL, 0x5ec03300e4000ba0ULL, },
+ { 0xaa30f5a0a980b1acULL, 0x51803b00ac008fa0ULL, },
+ { 0xa21071208c8038acULL, 0x9c00e50050004b20ULL, },
+ { 0x99f03080ba00b20cULL, 0x2000270000007ea0ULL, },
+ { 0xf850658020003c0cULL, 0x2000000000008320ULL, },
+ { 0x9900ed0040001fb4ULL, 0x400000000000b720ULL, },
+ { 0xf300c900c000d0b4ULL, 0x0000000000004ca0ULL, }, /* 88 */
+ { 0x4d00840000004254ULL, 0x000000000000fa20ULL, },
+ { 0x5f002c0000000854ULL, 0x00000000000024a0ULL, },
+ { 0xb00068000000b9ecULL, 0x00000000000048a0ULL, },
+ { 0x90004800000090ecULL, 0x000000000000b020ULL, },
+ { 0x7000200000008c4cULL, 0x0000000000004fa0ULL, },
+ { 0xd00060000000f64cULL, 0x000000000000a820ULL, },
+ { 0x0000400000001974ULL, 0x000000000000fc20ULL, },
+ { 0x000040000000fa74ULL, 0x000000000000cda0ULL, }, /* 96 */
+ { 0x0000400000001b74ULL, 0x0000000000007120ULL, },
+ { 0x0000400000007c74ULL, 0x000000000000bea0ULL, },
+ { 0x0000400000001d74ULL, 0x000000000000ae20ULL, },
+ { 0x0000000000003514ULL, 0x00000000000055a0ULL, },
+ { 0x00000000000069b4ULL, 0x000000000000df20ULL, },
+ { 0x000000000000a354ULL, 0x000000000000c2a0ULL, },
+ { 0x00000000000009f4ULL, 0x0000000000009820ULL, },
+ { 0x0000000000007ff4ULL, 0x0000000000001aa0ULL, }, /* 104 */
+ { 0x000000000000f5f4ULL, 0x0000000000004f20ULL, },
+ { 0x0000000000006bf4ULL, 0x0000000000001da0ULL, },
+ { 0x000000000000e1f4ULL, 0x0000000000008e20ULL, },
+ { 0x000000000000224cULL, 0x000000000000a220ULL, },
+ { 0x000000000000ad74ULL, 0x0000000000003620ULL, },
+ { 0x000000000000eeccULL, 0x0000000000004a20ULL, },
+ { 0x000000000000c8f4ULL, 0x000000000000de20ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_H__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_H__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MADDV.W
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Multiply";
+ char *instruction_name = "MADDV.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, }, /* 0 */
+ { 0x0000000100000001ULL, 0x0000000100000001ULL, },
+ { 0x5555555755555557ULL, 0x5555555755555557ULL, },
+ { 0x0000000200000002ULL, 0x0000000200000002ULL, },
+ { 0x3333333633333336ULL, 0x3333333633333336ULL, },
+ { 0x0000000300000003ULL, 0x0000000300000003ULL, },
+ { 0x1c71c72071c71c75ULL, 0xc71c71cb1c71c720ULL, },
+ { 0x0000000400000004ULL, 0x0000000400000004ULL, },
+ { 0x0000000400000004ULL, 0x0000000400000004ULL, }, /* 8 */
+ { 0x0000000400000004ULL, 0x0000000400000004ULL, },
+ { 0x0000000400000004ULL, 0x0000000400000004ULL, },
+ { 0x0000000400000004ULL, 0x0000000400000004ULL, },
+ { 0x0000000400000004ULL, 0x0000000400000004ULL, },
+ { 0x0000000400000004ULL, 0x0000000400000004ULL, },
+ { 0x0000000400000004ULL, 0x0000000400000004ULL, },
+ { 0x0000000400000004ULL, 0x0000000400000004ULL, },
+ { 0x5555555a5555555aULL, 0x5555555a5555555aULL, }, /* 16 */
+ { 0x5555555a5555555aULL, 0x5555555a5555555aULL, },
+ { 0x38e38e3e38e38e3eULL, 0x38e38e3e38e38e3eULL, },
+ { 0xaaaaaab0aaaaaab0ULL, 0xaaaaaab0aaaaaab0ULL, },
+ { 0x2222222822222228ULL, 0x2222222822222228ULL, },
+ { 0x0000000600000006ULL, 0x0000000600000006ULL, },
+ { 0x12f684c4a12f6852ULL, 0x84bda13612f684c4ULL, },
+ { 0x5555555c5555555cULL, 0x5555555c5555555cULL, },
+ { 0x0000000700000007ULL, 0x0000000700000007ULL, }, /* 24 */
+ { 0x0000000700000007ULL, 0x0000000700000007ULL, },
+ { 0x71c71c7971c71c79ULL, 0x71c71c7971c71c79ULL, },
+ { 0xaaaaaab2aaaaaab2ULL, 0xaaaaaab2aaaaaab2ULL, },
+ { 0x6666666e6666666eULL, 0x6666666e6666666eULL, },
+ { 0x5555555d5555555dULL, 0x5555555d5555555dULL, },
+ { 0x5ed097bc25ed0983ULL, 0x97b425f55ed097bcULL, },
+ { 0x0000000800000008ULL, 0x0000000800000008ULL, },
+ { 0x3333333c3333333cULL, 0x3333333c3333333cULL, }, /* 32 */
+ { 0x3333333c3333333cULL, 0x3333333c3333333cULL, },
+ { 0xaaaaaab4aaaaaab4ULL, 0xaaaaaab4aaaaaab4ULL, },
+ { 0x6666667066666670ULL, 0x6666667066666670ULL, },
+ { 0x8f5c29008f5c2900ULL, 0x8f5c29008f5c2900ULL, },
+ { 0x999999a4999999a4ULL, 0x999999a4999999a4ULL, },
+ { 0x7d27d288c16c16ccULL, 0x38e38e447d27d288ULL, },
+ { 0xccccccd8ccccccd8ULL, 0xccccccd8ccccccd8ULL, },
+ { 0x999999a5999999a5ULL, 0x999999a5999999a5ULL, }, /* 40 */
+ { 0x999999a5999999a5ULL, 0x999999a5999999a5ULL, },
+ { 0x7777778377777783ULL, 0x7777778377777783ULL, },
+ { 0x6666667266666672ULL, 0x6666667266666672ULL, },
+ { 0x70a3d71670a3d716ULL, 0x70a3d71670a3d716ULL, },
+ { 0x3333333f3333333fULL, 0x3333333f3333333fULL, },
+ { 0x6c16c1787d27d289ULL, 0x5b05b0676c16c178ULL, },
+ { 0x0000000c0000000cULL, 0x0000000c0000000cULL, },
+ { 0x1c71c72971c71c7eULL, 0xc71c71d41c71c729ULL, }, /* 48 */
+ { 0x1c71c72971c71c7eULL, 0xc71c71d41c71c729ULL, },
+ { 0x2f684be712f684caULL, 0x4bda13042f684be7ULL, },
+ { 0x38e38e46e38e38f0ULL, 0x8e38e39c38e38e46ULL, },
+ { 0x1c71c72a0b60b618ULL, 0x2d82d83c1c71c72aULL, },
+ { 0x5555556355555562ULL, 0x5555556455555563ULL, },
+ { 0x0fcd6eac35ba7826ULL, 0x5ba781a40fcd6eacULL, },
+ { 0x71c71c80c71c71d4ULL, 0x1c71c72c71c71c80ULL, },
+ { 0x5555556455555563ULL, 0x5555556555555564ULL, }, /* 56 */
+ { 0x5555556455555563ULL, 0x5555556555555564ULL, },
+ { 0x97b425fc097b426dULL, 0x25ed098b97b425fcULL, },
+ { 0x38e38e48e38e38f2ULL, 0x8e38e39e38e38e48ULL, },
+ { 0x88888898eeeeeefeULL, 0x2222223288888898ULL, },
+ { 0x1c71c72c71c71c81ULL, 0xc71c71d71c71c72cULL, },
+ { 0x7e6b75000329162fULL, 0x87e6b75f7e6b7500ULL, },
+ { 0x0000001000000010ULL, 0x0000001000000010ULL, },
+ { 0xb10332a061639010ULL, 0x3a253694749880a0ULL, }, /* 64 */
+ { 0xc1c27384487afa10ULL, 0xbb9c0820e3b1a470ULL, },
+ { 0x35565efc0caf5a10ULL, 0x735b0ec23bd12160ULL, },
+ { 0xe6475258fb27d390ULL, 0x49d49612c9a1c0e0ULL, },
+ { 0xf706933ce23f3d90ULL, 0xcb4b679e38bae4b0ULL, },
+ { 0xabfab985e02cadd0ULL, 0x0836664283a94cc0ULL, },
+ { 0xa33845439e9989d0ULL, 0x5b9fe12897ee3470ULL, },
+ { 0x1df3e50abfdd3e40ULL, 0x6d858f1887bc89f0ULL, },
+ { 0x9187d08284119e40ULL, 0x254495badfdc06e0ULL, }, /* 72 */
+ { 0x88c55c40427e7a40ULL, 0x78ae10a0f420ee90ULL, },
+ { 0x3f78e5242782ba40ULL, 0x93ad82a12637b820ULL, },
+ { 0x28380a46b1663b40ULL, 0x255be1c9fb128ca0ULL, },
+ { 0xd928fda29fdeb4c0ULL, 0xfbd5691988e32c20ULL, },
+ { 0x53e49d69c1226930ULL, 0x0dbb170978b181a0ULL, },
+ { 0x3ca3c28b4b05ea30ULL, 0x9f6976314d8c5620ULL, },
+ { 0x621b15b4fcefb9f4ULL, 0x7f3fac7130ab3a20ULL, },
+ { 0x81b8192421043af4ULL, 0x7180d8efde07f3a0ULL, }, /* 80 */
+ { 0xa0a1d210b115be94ULL, 0x33a676350e450520ULL, },
+ { 0xe27e30b0181b6494ULL, 0x359b330061c70ba0ULL, },
+ { 0xe0f1f5a03792b1acULL, 0xe6a63b00d5b18fa0ULL, },
+ { 0x38af7120b51538acULL, 0x7938e500aea24b20ULL, },
+ { 0x7a4830802390b20cULL, 0x4b472700af547ea0ULL, },
+ { 0xcc2f6580204a3c0cULL, 0x37510000bd1b8320ULL, },
+ { 0x9ba9ed0066371fb4ULL, 0xeba90000264fb720ULL, },
+ { 0x7400c900846dd0b4ULL, 0xb6b700007c524ca0ULL, }, /* 88 */
+ { 0x7e4e840000744254ULL, 0xf24d00003540fa20ULL, },
+ { 0x242a2c00b0850854ULL, 0xdb00000025db24a0ULL, },
+ { 0x38a168005a7bb9ecULL, 0xa3000000566748a0ULL, },
+ { 0x6cb048001a7d90ecULL, 0x7d0000000a0cb020ULL, },
+ { 0xe4dc2000bd958c4cULL, 0x2f000000f6d44fa0ULL, },
+ { 0xbcc9600018fcf64cULL, 0x000000002ecca820ULL, },
+ { 0x739b4000140b1974ULL, 0x000000009361fc20ULL, },
+ { 0x8ed24000a4acfa74ULL, 0x00000000bcafcda0ULL, }, /* 96 */
+ { 0xc3dd40003f7c1b74ULL, 0x00000000fe2b7120ULL, },
+ { 0x1fac4000f6087c74ULL, 0x00000000e05abea0ULL, },
+ { 0x9e6f40000de21d74ULL, 0x000000001e89ae20ULL, },
+ { 0x637500000f743514ULL, 0x00000000c1b755a0ULL, },
+ { 0xd9b400005ed469b4ULL, 0x000000005dfcdf20ULL, },
+ { 0x0a50000049fea354ULL, 0x000000006b40c2a0ULL, },
+ { 0x07400000982609f4ULL, 0x00000000c2b79820ULL, },
+ { 0x57c00000b2de7ff4ULL, 0x000000006f6c1aa0ULL, }, /* 104 */
+ { 0x1d400000bbe3f5f4ULL, 0x000000001c974f20ULL, },
+ { 0x09c00000a8b66bf4ULL, 0x00000000e1391da0ULL, },
+ { 0x03400000aed5e1f4ULL, 0x0000000094d78e20ULL, },
+ { 0x7d8000009d2e224cULL, 0x00000000ab48a220ULL, },
+ { 0x3d000000b40fad74ULL, 0x00000000c40e3620ULL, },
+ { 0x96000000332aeeccULL, 0x00000000ecf84a20ULL, },
+ { 0xb40000004e1bc8f4ULL, 0x0000000075d6de20ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_W__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MADDV_W__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MSUBV.B
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Multiply";
+ char *instruction_name = "MSUBV.B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xa9a9a9a9a9a9a9a9ULL, 0xa9a9a9a9a9a9a9a9ULL, },
+ { 0xfefefefefefefefeULL, 0xfefefefefefefefeULL, },
+ { 0xcacacacacacacacaULL, 0xcacacacacacacacaULL, },
+ { 0xfdfdfdfdfdfdfdfdULL, 0xfdfdfdfdfdfdfdfdULL, },
+ { 0xe08b35e08b35e08bULL, 0x35e08b35e08b35e0ULL, },
+ { 0xfcfcfcfcfcfcfcfcULL, 0xfcfcfcfcfcfcfcfcULL, },
+ { 0xfcfcfcfcfcfcfcfcULL, 0xfcfcfcfcfcfcfcfcULL, }, /* 8 */
+ { 0xfcfcfcfcfcfcfcfcULL, 0xfcfcfcfcfcfcfcfcULL, },
+ { 0xfcfcfcfcfcfcfcfcULL, 0xfcfcfcfcfcfcfcfcULL, },
+ { 0xfcfcfcfcfcfcfcfcULL, 0xfcfcfcfcfcfcfcfcULL, },
+ { 0xfcfcfcfcfcfcfcfcULL, 0xfcfcfcfcfcfcfcfcULL, },
+ { 0xfcfcfcfcfcfcfcfcULL, 0xfcfcfcfcfcfcfcfcULL, },
+ { 0xfcfcfcfcfcfcfcfcULL, 0xfcfcfcfcfcfcfcfcULL, },
+ { 0xfcfcfcfcfcfcfcfcULL, 0xfcfcfcfcfcfcfcfcULL, },
+ { 0xa6a6a6a6a6a6a6a6ULL, 0xa6a6a6a6a6a6a6a6ULL, }, /* 16 */
+ { 0xa6a6a6a6a6a6a6a6ULL, 0xa6a6a6a6a6a6a6a6ULL, },
+ { 0xc2c2c2c2c2c2c2c2ULL, 0xc2c2c2c2c2c2c2c2ULL, },
+ { 0x5050505050505050ULL, 0x5050505050505050ULL, },
+ { 0xd8d8d8d8d8d8d8d8ULL, 0xd8d8d8d8d8d8d8d8ULL, },
+ { 0xfafafafafafafafaULL, 0xfafafafafafafafaULL, },
+ { 0x3caeca3caeca3caeULL, 0xca3caeca3caeca3cULL, },
+ { 0xa4a4a4a4a4a4a4a4ULL, 0xa4a4a4a4a4a4a4a4ULL, },
+ { 0xf9f9f9f9f9f9f9f9ULL, 0xf9f9f9f9f9f9f9f9ULL, }, /* 24 */
+ { 0xf9f9f9f9f9f9f9f9ULL, 0xf9f9f9f9f9f9f9f9ULL, },
+ { 0x8787878787878787ULL, 0x8787878787878787ULL, },
+ { 0x4e4e4e4e4e4e4e4eULL, 0x4e4e4e4e4e4e4e4eULL, },
+ { 0x9292929292929292ULL, 0x9292929292929292ULL, },
+ { 0xa3a3a3a3a3a3a3a3ULL, 0xa3a3a3a3a3a3a3a3ULL, },
+ { 0x447d0b447d0b447dULL, 0x0b447d0b447d0b44ULL, },
+ { 0xf8f8f8f8f8f8f8f8ULL, 0xf8f8f8f8f8f8f8f8ULL, },
+ { 0xc4c4c4c4c4c4c4c4ULL, 0xc4c4c4c4c4c4c4c4ULL, }, /* 32 */
+ { 0xc4c4c4c4c4c4c4c4ULL, 0xc4c4c4c4c4c4c4c4ULL, },
+ { 0x4c4c4c4c4c4c4c4cULL, 0x4c4c4c4c4c4c4c4cULL, },
+ { 0x9090909090909090ULL, 0x9090909090909090ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5c5c5c5c5c5c5c5cULL, 0x5c5c5c5c5c5c5c5cULL, },
+ { 0x7834bc7834bc7834ULL, 0xbc7834bc7834bc78ULL, },
+ { 0x2828282828282828ULL, 0x2828282828282828ULL, },
+ { 0x5b5b5b5b5b5b5b5bULL, 0x5b5b5b5b5b5b5b5bULL, }, /* 40 */
+ { 0x5b5b5b5b5b5b5b5bULL, 0x5b5b5b5b5b5b5b5bULL, },
+ { 0x7d7d7d7d7d7d7d7dULL, 0x7d7d7d7d7d7d7d7dULL, },
+ { 0x8e8e8e8e8e8e8e8eULL, 0x8e8e8e8e8e8e8e8eULL, },
+ { 0xeaeaeaeaeaeaeaeaULL, 0xeaeaeaeaeaeaeaeaULL, },
+ { 0xc1c1c1c1c1c1c1c1ULL, 0xc1c1c1c1c1c1c1c1ULL, },
+ { 0x8877998877998877ULL, 0x9988779988779988ULL, },
+ { 0xf4f4f4f4f4f4f4f4ULL, 0xf4f4f4f4f4f4f4f4ULL, },
+ { 0xd7822cd7822cd782ULL, 0x2cd7822cd7822cd7ULL, }, /* 48 */
+ { 0xd7822cd7822cd782ULL, 0x2cd7822cd7822cd7ULL, },
+ { 0x1936fc1936fc1936ULL, 0xfc1936fc1936fc19ULL, },
+ { 0xba1064ba1064ba10ULL, 0x64ba1064ba1064baULL, },
+ { 0xd6e8c4d6e8c4d6e8ULL, 0xc4d6e8c4d6e8c4d6ULL, },
+ { 0x9d9e9c9d9e9c9d9eULL, 0x9c9d9e9c9d9e9c9dULL, },
+ { 0x54da5c54da5c54daULL, 0x5c54da5c54da5c54ULL, },
+ { 0x802cd4802cd4802cULL, 0xd4802cd4802cd480ULL, },
+ { 0x9c9d9b9c9d9b9c9dULL, 0x9b9c9d9b9c9d9b9cULL, }, /* 56 */
+ { 0x9c9d9b9c9d9b9c9dULL, 0x9b9c9d9b9c9d9b9cULL, },
+ { 0x0493750493750493ULL, 0x7504937504937504ULL, },
+ { 0xb80e62b80e62b80eULL, 0x62b80e62b80e62b8ULL, },
+ { 0x6802ce6802ce6802ULL, 0xce6802ce6802ce68ULL, },
+ { 0xd47f29d47f29d47fULL, 0x29d47f29d47f29d4ULL, },
+ { 0x00d1a100d1a100d1ULL, 0xa100d1a100d1a100ULL, },
+ { 0xf0f0f0f0f0f0f0f0ULL, 0xf0f0f0f0f0f0f0f0ULL, },
+ { 0xb00c4c60b06cb7f0ULL, 0xf77f776cecd7f060ULL, }, /* 64 */
+ { 0x58604c7ca826a4f0ULL, 0xb11e6ee016929090ULL, },
+ { 0xf81cf804c0e87df0ULL, 0x4436ec3e6ce920a0ULL, },
+ { 0x786634a810267370ULL, 0xf53f14eebe33c020ULL, },
+ { 0x20ba34c408e06070ULL, 0xafde0b62e8ee6050ULL, },
+ { 0x07b6347bdf77af30ULL, 0x6b8d72be2f6d1c40ULL, },
+ { 0x63ea34bd3a9aa230ULL, 0xad25d0d828d84290ULL, },
+ { 0x934834f6f477f4c0ULL, 0xc39e78e84b9ade10ULL, },
+ { 0x3304e07e0c39cdc0ULL, 0x56b6f646a1f16e20ULL, }, /* 72 */
+ { 0x8f38e0c0675cc0c0ULL, 0x984e54609a5c9470ULL, },
+ { 0xff949cdcb6fb47c0ULL, 0xa70e305f61233be0ULL, },
+ { 0xbfcea8bac85c91c0ULL, 0x2cb600377e0d9160ULL, },
+ { 0x3f18e45e189a8740ULL, 0xddbf28e7d05731e0ULL, },
+ { 0x6f76e497d277d9d0ULL, 0xf338d0f7f319cd60ULL, },
+ { 0x2fb0f075e4d823d0ULL, 0x78e0a0cf100323e0ULL, },
+ { 0x2f4f0c4c60779f0cULL, 0xcfff608f7fff9fe0ULL, },
+ { 0x379944bc60e9d40cULL, 0x2a66400d7d7a4f60ULL, }, /* 80 */
+ { 0x4a0b4408801e08acULL, 0x36fc80bb3c7401e0ULL, },
+ { 0x922d0cb800dcb0acULL, 0xfc5c807628f8dc60ULL, },
+ { 0xb24a046000c05044ULL, 0x30c080e6c008a460ULL, },
+ { 0x22a66ce00040c044ULL, 0x208000724030e4e0ULL, },
+ { 0xcc726c4000808024ULL, 0xe00000de0060dc60ULL, },
+ { 0xbc5e04c000000024ULL, 0xc00000bc004010e0ULL, },
+ { 0x7c5cac000000002cULL, 0x0000001c00c0f0e0ULL, },
+ { 0x9c4424000000002cULL, 0x000000d40080f060ULL, }, /* 88 */
+ { 0xa8cc2400000000ccULL, 0x0000004c000010e0ULL, },
+ { 0xc814ac00000000ccULL, 0x000000980000c060ULL, },
+ { 0x48e8e400000000a4ULL, 0x0000005800004060ULL, },
+ { 0x08d80c00000000a4ULL, 0x00000008000040e0ULL, },
+ { 0x30880c0000000084ULL, 0x000000380000c060ULL, },
+ { 0xf0b8e40000000084ULL, 0x00000070000000e0ULL, },
+ { 0xf0f04c000000004cULL, 0x000000f0000000e0ULL, },
+ { 0x709004000000004cULL, 0x000000d000000060ULL, }, /* 96 */
+ { 0xf0f06c000000004cULL, 0x00000070000000e0ULL, },
+ { 0x709064000000004cULL, 0x0000005000000060ULL, },
+ { 0xf0f08c000000004cULL, 0x000000f0000000e0ULL, },
+ { 0xa0d08c00000000ecULL, 0x0000009000000060ULL, },
+ { 0xc0708c000000008cULL, 0x000000f0000000e0ULL, },
+ { 0x80508c000000002cULL, 0x0000009000000060ULL, },
+ { 0x00f08c00000000ccULL, 0x000000f0000000e0ULL, },
+ { 0x00906400000000ccULL, 0x000000e000000060ULL, }, /* 104 */
+ { 0x00f06c00000000ccULL, 0x000000c0000000e0ULL, },
+ { 0x00900400000000ccULL, 0x0000008000000060ULL, },
+ { 0x00f04c00000000ccULL, 0x00000000000000e0ULL, },
+ { 0x00e0c400000000a4ULL, 0x00000000000000e0ULL, },
+ { 0x00c0ec00000000acULL, 0x00000000000000e0ULL, },
+ { 0x0080a40000000044ULL, 0x00000000000000e0ULL, },
+ { 0x00008c000000008cULL, 0x00000000000000e0ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_B(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_B(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_B__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_B__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MSUBV.D
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Multiply";
+ char *instruction_name = "MSUBV.D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xaaaaaaaaaaaaaaa9ULL, 0xaaaaaaaaaaaaaaa9ULL, },
+ { 0xfffffffffffffffeULL, 0xfffffffffffffffeULL, },
+ { 0xcccccccccccccccaULL, 0xcccccccccccccccaULL, },
+ { 0xfffffffffffffffdULL, 0xfffffffffffffffdULL, },
+ { 0xe38e38e38e38e38bULL, 0x38e38e38e38e38e0ULL, },
+ { 0xfffffffffffffffcULL, 0xfffffffffffffffcULL, },
+ { 0xfffffffffffffffcULL, 0xfffffffffffffffcULL, }, /* 8 */
+ { 0xfffffffffffffffcULL, 0xfffffffffffffffcULL, },
+ { 0xfffffffffffffffcULL, 0xfffffffffffffffcULL, },
+ { 0xfffffffffffffffcULL, 0xfffffffffffffffcULL, },
+ { 0xfffffffffffffffcULL, 0xfffffffffffffffcULL, },
+ { 0xfffffffffffffffcULL, 0xfffffffffffffffcULL, },
+ { 0xfffffffffffffffcULL, 0xfffffffffffffffcULL, },
+ { 0xfffffffffffffffcULL, 0xfffffffffffffffcULL, },
+ { 0xaaaaaaaaaaaaaaa6ULL, 0xaaaaaaaaaaaaaaa6ULL, }, /* 16 */
+ { 0xaaaaaaaaaaaaaaa6ULL, 0xaaaaaaaaaaaaaaa6ULL, },
+ { 0x71c71c71c71c71c2ULL, 0x71c71c71c71c71c2ULL, },
+ { 0x5555555555555550ULL, 0x5555555555555550ULL, },
+ { 0xddddddddddddddd8ULL, 0xddddddddddddddd8ULL, },
+ { 0xfffffffffffffffaULL, 0xfffffffffffffffaULL, },
+ { 0xed097b425ed097aeULL, 0xd097b425ed097b3cULL, },
+ { 0xaaaaaaaaaaaaaaa4ULL, 0xaaaaaaaaaaaaaaa4ULL, },
+ { 0xfffffffffffffff9ULL, 0xfffffffffffffff9ULL, }, /* 24 */
+ { 0xfffffffffffffff9ULL, 0xfffffffffffffff9ULL, },
+ { 0xe38e38e38e38e387ULL, 0xe38e38e38e38e387ULL, },
+ { 0x555555555555554eULL, 0x555555555555554eULL, },
+ { 0x9999999999999992ULL, 0x9999999999999992ULL, },
+ { 0xaaaaaaaaaaaaaaa3ULL, 0xaaaaaaaaaaaaaaa3ULL, },
+ { 0xa12f684bda12f67dULL, 0x12f684bda12f6844ULL, },
+ { 0xfffffffffffffff8ULL, 0xfffffffffffffff8ULL, },
+ { 0xccccccccccccccc4ULL, 0xccccccccccccccc4ULL, }, /* 32 */
+ { 0xccccccccccccccc4ULL, 0xccccccccccccccc4ULL, },
+ { 0x555555555555554cULL, 0x555555555555554cULL, },
+ { 0x9999999999999990ULL, 0x9999999999999990ULL, },
+ { 0xa3d70a3d70a3d700ULL, 0xa3d70a3d70a3d700ULL, },
+ { 0x666666666666665cULL, 0x666666666666665cULL, },
+ { 0xe93e93e93e93e934ULL, 0x2d82d82d82d82d78ULL, },
+ { 0x3333333333333328ULL, 0x3333333333333328ULL, },
+ { 0x666666666666665bULL, 0x666666666666665bULL, }, /* 40 */
+ { 0x666666666666665bULL, 0x666666666666665bULL, },
+ { 0x888888888888887dULL, 0x888888888888887dULL, },
+ { 0x999999999999998eULL, 0x999999999999998eULL, },
+ { 0x5c28f5c28f5c28eaULL, 0x5c28f5c28f5c28eaULL, },
+ { 0xccccccccccccccc1ULL, 0xccccccccccccccc1ULL, },
+ { 0x2d82d82d82d82d77ULL, 0x3e93e93e93e93e88ULL, },
+ { 0xfffffffffffffff4ULL, 0xfffffffffffffff4ULL, },
+ { 0xe38e38e38e38e382ULL, 0x38e38e38e38e38d7ULL, }, /* 48 */
+ { 0xe38e38e38e38e382ULL, 0x38e38e38e38e38d7ULL, },
+ { 0xd097b425ed097b36ULL, 0x097b425ed097b419ULL, },
+ { 0xc71c71c71c71c710ULL, 0x71c71c71c71c71baULL, },
+ { 0x49f49f49f49f49e8ULL, 0x38e38e38e38e38d6ULL, },
+ { 0xaaaaaaaaaaaaaa9eULL, 0xaaaaaaaaaaaaaa9dULL, },
+ { 0xf9add3c0ca4587daULL, 0x587e6b74f0329154ULL, },
+ { 0x8e38e38e38e38e2cULL, 0xe38e38e38e38e380ULL, },
+ { 0xaaaaaaaaaaaaaa9dULL, 0xaaaaaaaaaaaaaa9cULL, }, /* 56 */
+ { 0xaaaaaaaaaaaaaa9dULL, 0xaaaaaaaaaaaaaa9cULL, },
+ { 0x684bda12f684bd93ULL, 0x84bda12f684bda04ULL, },
+ { 0xc71c71c71c71c70eULL, 0x71c71c71c71c71b8ULL, },
+ { 0x1111111111111102ULL, 0x7777777777777768ULL, },
+ { 0xe38e38e38e38e37fULL, 0x38e38e38e38e38d4ULL, },
+ { 0x781948b0fcd6e9d1ULL, 0xc3f35ba781948b00ULL, },
+ { 0xfffffffffffffff0ULL, 0xfffffffffffffff0ULL, },
+ { 0x52ba41969e9c6ff0ULL, 0xcd6802158b677f60ULL, }, /* 64 */
+ { 0x63129bf5b78505f0ULL, 0x1556f7f61c4e5b90ULL, },
+ { 0x5a4c8855f350a5f0ULL, 0x6a36586fc42edea0ULL, },
+ { 0x5e6b001b04d82c70ULL, 0xe819332c365e3f20ULL, },
+ { 0x6ec35a7a1dc0c270ULL, 0x3008290cc7451b50ULL, },
+ { 0x37152f411fd35230ULL, 0xc7e3b2957c56b340ULL, },
+ { 0xcc49f1d861667630ULL, 0x1808e0646811cb90ULL, },
+ { 0xde8a7f544022c1c0ULL, 0x9886bc9978437610ULL, },
+ { 0xd5c46bb47bee61c0ULL, 0xed661d132023f920ULL, }, /* 72 */
+ { 0x6af92e4bbd8185c0ULL, 0x3d8b4ae20bdf1170ULL, },
+ { 0xe4d44869d87d45c0ULL, 0x6409d23bd9c847e0ULL, },
+ { 0x6e2e9ce94e99c4c0ULL, 0xc30837db04ed7360ULL, },
+ { 0x724d14ae60214b40ULL, 0x40eb1297771cd3e0ULL, },
+ { 0x848da22a3edd96d0ULL, 0xc168eecc874e7e60ULL, },
+ { 0x0de7f6a9b4fa15d0ULL, 0x2067546bb273a9e0ULL, },
+ { 0xc233bfd40310460cULL, 0x0d9585bacf54c5e0ULL, },
+ { 0x061015122724c70cULL, 0x0169d01f7cb17f60ULL, }, /* 80 */
+ { 0x23dacc726f603aacULL, 0xf3ea8c4eaa8b5ce0ULL, },
+ { 0xd82df953c25380acULL, 0xba87b7f0f99bbb60ULL, },
+ { 0x546cb94a0c5e7444ULL, 0x3818c320ce1bdf60ULL, },
+ { 0xa38f9428761ecf44ULL, 0x63113b9e681b66e0ULL, },
+ { 0x7dc23fbe59fe7924ULL, 0x156ddd68750e6260ULL, },
+ { 0x8a17717d36df5b24ULL, 0x36b1f5939596d2e0ULL, },
+ { 0x7e854cd9a677ce2cULL, 0xf2b6202eb36946e0ULL, },
+ { 0x246d8d067437a72cULL, 0x04c6347e9c1ff460ULL, }, /* 88 */
+ { 0xc48a013a554339ccULL, 0xcb81fd31acc4a5e0ULL, },
+ { 0xb971282c0b508fccULL, 0x20d62d6344ce5060ULL, },
+ { 0x835f812f0bc6a7a4ULL, 0x17bd6b5a08275460ULL, },
+ { 0xc0ee1b9557ab4aa4ULL, 0x170471a9d22d5fe0ULL, },
+ { 0xc6f66d89431f7984ULL, 0x5c6f5a646cad3f60ULL, },
+ { 0x5ae0b289f6ac0b84ULL, 0x6f9f6bc81fdb6be0ULL, },
+ { 0x2f584ee03fd2014cULL, 0xa7e34ccbd1bc3fe0ULL, },
+ { 0x5947927731cb724cULL, 0xf76af1f9a05f4160ULL, }, /* 96 */
+ { 0x68112ad490e3a34cULL, 0x7f944a22f5d630e0ULL, },
+ { 0x1cf6705c5faa944cULL, 0x801292d47291e660ULL, },
+ { 0x5519f2782cb0454cULL, 0x3d691c2dd53919e0ULL, },
+ { 0xe5c979861aac06ecULL, 0x585247d6e899e160ULL, },
+ { 0x2450b27896665b8cULL, 0x8276d8ad504f46e0ULL, },
+ { 0x2716d456a4a5ab2cULL, 0x46e1f3460c71c260ULL, },
+ { 0x5751460331251dccULL, 0xdc1dc7a4a693abe0ULL, },
+ { 0x3bf387b7f37473ccULL, 0x8efb4ff7cc92de60ULL, }, /* 104 */
+ { 0xc3103a3df066c9ccULL, 0x7d3b07351cd59ee0ULL, },
+ { 0x0d612554557c1fccULL, 0x5dbabfc2ac8ed560ULL, },
+ { 0x1cd018ef103475ccULL, 0xca277277956f49e0ULL, },
+ { 0x15d520225c2e79a4ULL, 0x08f2025804e95de0ULL, },
+ { 0x820f9c65be3ea1acULL, 0x37094edbda6ef1e0ULL, },
+ { 0x0f18515c62838744ULL, 0xcfbd4b5627d005e0ULL, },
+ { 0x11d549f26502488cULL, 0x8de999d53cdc99e0ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_D(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_D(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_D__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_D__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MSUBV.H
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Multiply";
+ char *instruction_name = "MSUBV.H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xaaa9aaa9aaa9aaa9ULL, 0xaaa9aaa9aaa9aaa9ULL, },
+ { 0xfffefffefffefffeULL, 0xfffefffefffefffeULL, },
+ { 0xcccacccacccacccaULL, 0xcccacccacccacccaULL, },
+ { 0xfffdfffdfffdfffdULL, 0xfffdfffdfffdfffdULL, },
+ { 0xe38b38e08e35e38bULL, 0x38e08e35e38b38e0ULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, }, /* 8 */
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xfffcfffcfffcfffcULL, 0xfffcfffcfffcfffcULL, },
+ { 0xaaa6aaa6aaa6aaa6ULL, 0xaaa6aaa6aaa6aaa6ULL, }, /* 16 */
+ { 0xaaa6aaa6aaa6aaa6ULL, 0xaaa6aaa6aaa6aaa6ULL, },
+ { 0x71c271c271c271c2ULL, 0x71c271c271c271c2ULL, },
+ { 0x5550555055505550ULL, 0x5550555055505550ULL, },
+ { 0xddd8ddd8ddd8ddd8ULL, 0xddd8ddd8ddd8ddd8ULL, },
+ { 0xfffafffafffafffaULL, 0xfffafffafffafffaULL, },
+ { 0x97ae7b3c5eca97aeULL, 0x7b3c5eca97ae7b3cULL, },
+ { 0xaaa4aaa4aaa4aaa4ULL, 0xaaa4aaa4aaa4aaa4ULL, },
+ { 0xfff9fff9fff9fff9ULL, 0xfff9fff9fff9fff9ULL, }, /* 24 */
+ { 0xfff9fff9fff9fff9ULL, 0xfff9fff9fff9fff9ULL, },
+ { 0xe387e387e387e387ULL, 0xe387e387e387e387ULL, },
+ { 0x554e554e554e554eULL, 0x554e554e554e554eULL, },
+ { 0x9992999299929992ULL, 0x9992999299929992ULL, },
+ { 0xaaa3aaa3aaa3aaa3ULL, 0xaaa3aaa3aaa3aaa3ULL, },
+ { 0xf67d6844da0bf67dULL, 0x6844da0bf67d6844ULL, },
+ { 0xfff8fff8fff8fff8ULL, 0xfff8fff8fff8fff8ULL, },
+ { 0xccc4ccc4ccc4ccc4ULL, 0xccc4ccc4ccc4ccc4ULL, }, /* 32 */
+ { 0xccc4ccc4ccc4ccc4ULL, 0xccc4ccc4ccc4ccc4ULL, },
+ { 0x554c554c554c554cULL, 0x554c554c554c554cULL, },
+ { 0x9990999099909990ULL, 0x9990999099909990ULL, },
+ { 0xd700d700d700d700ULL, 0xd700d700d700d700ULL, },
+ { 0x665c665c665c665cULL, 0x665c665c665c665cULL, },
+ { 0xe9342d7871bce934ULL, 0x2d7871bce9342d78ULL, },
+ { 0x3328332833283328ULL, 0x3328332833283328ULL, },
+ { 0x665b665b665b665bULL, 0x665b665b665b665bULL, }, /* 40 */
+ { 0x665b665b665b665bULL, 0x665b665b665b665bULL, },
+ { 0x887d887d887d887dULL, 0x887d887d887d887dULL, },
+ { 0x998e998e998e998eULL, 0x998e998e998e998eULL, },
+ { 0x28ea28ea28ea28eaULL, 0x28ea28ea28ea28eaULL, },
+ { 0xccc1ccc1ccc1ccc1ULL, 0xccc1ccc1ccc1ccc1ULL, },
+ { 0x2d773e884f992d77ULL, 0x3e884f992d773e88ULL, },
+ { 0xfff4fff4fff4fff4ULL, 0xfff4fff4fff4fff4ULL, },
+ { 0xe38238d78e2ce382ULL, 0x38d78e2ce38238d7ULL, }, /* 48 */
+ { 0xe38238d78e2ce382ULL, 0x38d78e2ce38238d7ULL, },
+ { 0x7b36b419ecfc7b36ULL, 0xb419ecfc7b36b419ULL, },
+ { 0xc71071ba1c64c710ULL, 0x71ba1c64c71071baULL, },
+ { 0x49e838d627c449e8ULL, 0x38d627c449e838d6ULL, },
+ { 0xaa9eaa9daa9caa9eULL, 0xaa9daa9caa9eaa9dULL, },
+ { 0x87da91547e5c87daULL, 0x91547e5c87da9154ULL, },
+ { 0x8e2ce38038d48e2cULL, 0xe38038d48e2ce380ULL, },
+ { 0xaa9daa9caa9baa9dULL, 0xaa9caa9baa9daa9cULL, }, /* 56 */
+ { 0xaa9daa9caa9baa9dULL, 0xaa9caa9baa9daa9cULL, },
+ { 0xbd93da04f675bd93ULL, 0xda04f675bd93da04ULL, },
+ { 0xc70e71b81c62c70eULL, 0x71b81c62c70e71b8ULL, },
+ { 0x11027768ddce1102ULL, 0x7768ddce11027768ULL, },
+ { 0xe37f38d48e29e37fULL, 0x38d48e29e37f38d4ULL, },
+ { 0xe9d18b0048a1e9d1ULL, 0x8b0048a1e9d18b00ULL, },
+ { 0xfff0fff0fff0fff0ULL, 0xfff0fff0fff0fff0ULL, },
+ { 0x340ccd603a6c6ff0ULL, 0x7c7fc96cb0d77f60ULL, }, /* 64 */
+ { 0x07608c7c902605f0ULL, 0x7e1ef7e0f9925b90ULL, },
+ { 0xda1ca10416e8a5f0ULL, 0x2e36f13e11e9dea0ULL, },
+ { 0x6166ada860262c70ULL, 0x773f69ee43333f20ULL, },
+ { 0x34ba6cc4b5e0c270ULL, 0x78de98628bee1b50ULL, },
+ { 0x13b6467bf3775230ULL, 0xce8d99be266db340ULL, },
+ { 0xeaeababdfe9a7630ULL, 0x2d251ed87fd8cb90ULL, },
+ { 0x1b481af62b77c1c0ULL, 0x479e70e86e9a7610ULL, },
+ { 0xee042f7eb23961c0ULL, 0xf7b66a4686f1f920ULL, }, /* 72 */
+ { 0xc538a3c0bd5c85c0ULL, 0x564eef60e05c1170ULL, },
+ { 0xb5941adce7fb45c0ULL, 0xd00e7d5f672347e0ULL, },
+ { 0x25cef5ba555cc4c0ULL, 0x55b61e37e30d7360ULL, },
+ { 0xad18025e9e9a4b40ULL, 0x9ebf96e71457d3e0ULL, },
+ { 0xdd766297cb7796d0ULL, 0xb938e8f703197e60ULL, },
+ { 0x4db03d7538d815d0ULL, 0x3ee089cf7f03a9e0ULL, },
+ { 0x154fea4c3377460cULL, 0xe1ff538f49ffc5e0ULL, },
+ { 0x4a99edbce7e9c70cULL, 0x3f66800dba7a7f60ULL, }, /* 80 */
+ { 0xea0bfe08a81e3aacULL, 0xe7fcffbbd4745ce0ULL, },
+ { 0x3e2ddcb809dc80acULL, 0xc75ca276a8f8bb60ULL, },
+ { 0x5e4aa9605ec07444ULL, 0x6dc0dee66108df60ULL, },
+ { 0x03a670e01940cf44ULL, 0x05802472d23066e0ULL, },
+ { 0x8c72ca4059807924ULL, 0xb7002ade28606260ULL, },
+ { 0x945efbc07b005b24ULL, 0x4f00c3bc4040d2e0ULL, },
+ { 0xab5cc300f000ce2cULL, 0xf000bd1c6fc046e0ULL, },
+ { 0xd7445f001000a72cULL, 0x600018d43e80f460ULL, }, /* 88 */
+ { 0x66cca200e00039ccULL, 0xc000b74c5d00a5e0ULL, },
+ { 0x33140e00c0008fccULL, 0xc0005a98be005060ULL, },
+ { 0xafe8d8000000a7a4ULL, 0x00002a58c2005460ULL, },
+ { 0x99d8b80000004aa4ULL, 0x0000d6088c005fe0ULL, },
+ { 0xa388900000007984ULL, 0x0000413818003f60ULL, },
+ { 0xc5b8f00000000b84ULL, 0x0000fa7010006be0ULL, },
+ { 0x41f0c0000000014cULL, 0x00002bf0f0003fe0ULL, },
+ { 0x7490c0000000724cULL, 0x0000b9d0a0004160ULL, }, /* 96 */
+ { 0xb0f0c0000000a34cULL, 0x00008f70c00030e0ULL, },
+ { 0xed90c0000000944cULL, 0x000014508000e660ULL, },
+ { 0x0ff0c0000000454cULL, 0x00002ef0000019e0ULL, },
+ { 0xebd08000000006ecULL, 0x00001a900000e160ULL, },
+ { 0xf770000000005b8cULL, 0x000037f0000046e0ULL, },
+ { 0x825000000000ab2cULL, 0x000039900000c260ULL, },
+ { 0x5af0000000001dccULL, 0x000030f00000abe0ULL, },
+ { 0x22900000000073ccULL, 0x0000d1e00000de60ULL, }, /* 104 */
+ { 0x3bf000000000c9ccULL, 0x000083c000009ee0ULL, },
+ { 0xe990000000001fccULL, 0x0000c7800000d560ULL, },
+ { 0x0cf00000000075ccULL, 0x00000f00000049e0ULL, },
+ { 0x0ee00000000079a4ULL, 0x0000670000005de0ULL, },
+ { 0x77c000000000a1acULL, 0x00007f000000f1e0ULL, },
+ { 0x8380000000008744ULL, 0x00005700000005e0ULL, },
+ { 0xef0000000000488cULL, 0x0000ef00000099e0ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_H(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_H(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_H__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_H__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MSUBV.W
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL ( \
+ (PATTERN_INPUTS_SHORT_COUNT) * (PATTERN_INPUTS_SHORT_COUNT) + \
+ 3 * (RANDOM_INPUTS_SHORT_COUNT) * (RANDOM_INPUTS_SHORT_COUNT))
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Int Multiply";
+ char *instruction_name = "MSUBV.W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, },
+ { 0xaaaaaaa9aaaaaaa9ULL, 0xaaaaaaa9aaaaaaa9ULL, },
+ { 0xfffffffefffffffeULL, 0xfffffffefffffffeULL, },
+ { 0xcccccccacccccccaULL, 0xcccccccacccccccaULL, },
+ { 0xfffffffdfffffffdULL, 0xfffffffdfffffffdULL, },
+ { 0xe38e38e08e38e38bULL, 0x38e38e35e38e38e0ULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, }, /* 8 */
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xfffffffcfffffffcULL, 0xfffffffcfffffffcULL, },
+ { 0xaaaaaaa6aaaaaaa6ULL, 0xaaaaaaa6aaaaaaa6ULL, }, /* 16 */
+ { 0xaaaaaaa6aaaaaaa6ULL, 0xaaaaaaa6aaaaaaa6ULL, },
+ { 0xc71c71c2c71c71c2ULL, 0xc71c71c2c71c71c2ULL, },
+ { 0x5555555055555550ULL, 0x5555555055555550ULL, },
+ { 0xddddddd8ddddddd8ULL, 0xddddddd8ddddddd8ULL, },
+ { 0xfffffffafffffffaULL, 0xfffffffafffffffaULL, },
+ { 0xed097b3c5ed097aeULL, 0x7b425ecaed097b3cULL, },
+ { 0xaaaaaaa4aaaaaaa4ULL, 0xaaaaaaa4aaaaaaa4ULL, },
+ { 0xfffffff9fffffff9ULL, 0xfffffff9fffffff9ULL, }, /* 24 */
+ { 0xfffffff9fffffff9ULL, 0xfffffff9fffffff9ULL, },
+ { 0x8e38e3878e38e387ULL, 0x8e38e3878e38e387ULL, },
+ { 0x5555554e5555554eULL, 0x5555554e5555554eULL, },
+ { 0x9999999299999992ULL, 0x9999999299999992ULL, },
+ { 0xaaaaaaa3aaaaaaa3ULL, 0xaaaaaaa3aaaaaaa3ULL, },
+ { 0xa12f6844da12f67dULL, 0x684bda0ba12f6844ULL, },
+ { 0xfffffff8fffffff8ULL, 0xfffffff8fffffff8ULL, },
+ { 0xccccccc4ccccccc4ULL, 0xccccccc4ccccccc4ULL, }, /* 32 */
+ { 0xccccccc4ccccccc4ULL, 0xccccccc4ccccccc4ULL, },
+ { 0x5555554c5555554cULL, 0x5555554c5555554cULL, },
+ { 0x9999999099999990ULL, 0x9999999099999990ULL, },
+ { 0x70a3d70070a3d700ULL, 0x70a3d70070a3d700ULL, },
+ { 0x6666665c6666665cULL, 0x6666665c6666665cULL, },
+ { 0x82d82d783e93e934ULL, 0xc71c71bc82d82d78ULL, },
+ { 0x3333332833333328ULL, 0x3333332833333328ULL, },
+ { 0x6666665b6666665bULL, 0x6666665b6666665bULL, }, /* 40 */
+ { 0x6666665b6666665bULL, 0x6666665b6666665bULL, },
+ { 0x8888887d8888887dULL, 0x8888887d8888887dULL, },
+ { 0x9999998e9999998eULL, 0x9999998e9999998eULL, },
+ { 0x8f5c28ea8f5c28eaULL, 0x8f5c28ea8f5c28eaULL, },
+ { 0xccccccc1ccccccc1ULL, 0xccccccc1ccccccc1ULL, },
+ { 0x93e93e8882d82d77ULL, 0xa4fa4f9993e93e88ULL, },
+ { 0xfffffff4fffffff4ULL, 0xfffffff4fffffff4ULL, },
+ { 0xe38e38d78e38e382ULL, 0x38e38e2ce38e38d7ULL, }, /* 48 */
+ { 0xe38e38d78e38e382ULL, 0x38e38e2ce38e38d7ULL, },
+ { 0xd097b419ed097b36ULL, 0xb425ecfcd097b419ULL, },
+ { 0xc71c71ba1c71c710ULL, 0x71c71c64c71c71baULL, },
+ { 0xe38e38d6f49f49e8ULL, 0xd27d27c4e38e38d6ULL, },
+ { 0xaaaaaa9daaaaaa9eULL, 0xaaaaaa9caaaaaa9dULL, },
+ { 0xf0329154ca4587daULL, 0xa4587e5cf0329154ULL, },
+ { 0x8e38e38038e38e2cULL, 0xe38e38d48e38e380ULL, },
+ { 0xaaaaaa9caaaaaa9dULL, 0xaaaaaa9baaaaaa9cULL, }, /* 56 */
+ { 0xaaaaaa9caaaaaa9dULL, 0xaaaaaa9baaaaaa9cULL, },
+ { 0x684bda04f684bd93ULL, 0xda12f675684bda04ULL, },
+ { 0xc71c71b81c71c70eULL, 0x71c71c62c71c71b8ULL, },
+ { 0x7777776811111102ULL, 0xddddddce77777768ULL, },
+ { 0xe38e38d48e38e37fULL, 0x38e38e29e38e38d4ULL, },
+ { 0x81948b00fcd6e9d1ULL, 0x781948a181948b00ULL, },
+ { 0xfffffff0fffffff0ULL, 0xfffffff0fffffff0ULL, },
+ { 0x4efccd609e9c6ff0ULL, 0xc5dac96c8b677f60ULL, }, /* 64 */
+ { 0x3e3d8c7cb78505f0ULL, 0x4463f7e01c4e5b90ULL, },
+ { 0xcaa9a104f350a5f0ULL, 0x8ca4f13ec42edea0ULL, },
+ { 0x19b8ada804d82c70ULL, 0xb62b69ee365e3f20ULL, },
+ { 0x08f96cc41dc0c270ULL, 0x34b49862c7451b50ULL, },
+ { 0x5405467b1fd35230ULL, 0xf7c999be7c56b340ULL, },
+ { 0x5cc7babd61667630ULL, 0xa4601ed86811cb90ULL, },
+ { 0xe20c1af64022c1c0ULL, 0x927a70e878437610ULL, },
+ { 0x6e782f7e7bee61c0ULL, 0xdabb6a462023f920ULL, }, /* 72 */
+ { 0x773aa3c0bd8185c0ULL, 0x8751ef600bdf1170ULL, },
+ { 0xc0871adcd87d45c0ULL, 0x6c527d5fd9c847e0ULL, },
+ { 0xd7c7f5ba4e99c4c0ULL, 0xdaa41e3704ed7360ULL, },
+ { 0x26d7025e60214b40ULL, 0x042a96e7771cd3e0ULL, },
+ { 0xac1b62973edd96d0ULL, 0xf244e8f7874e7e60ULL, },
+ { 0xc35c3d75b4fa15d0ULL, 0x609689cfb273a9e0ULL, },
+ { 0x9de4ea4c0310460cULL, 0x80c0538fcf54c5e0ULL, },
+ { 0xbd81edbc2724c70cULL, 0x7301800d7cb17f60ULL, }, /* 80 */
+ { 0xaebafe086f603aacULL, 0x35c5ffbbaa8b5ce0ULL, },
+ { 0xdf14dcb8c25380acULL, 0x3ef9a276f99bbb60ULL, },
+ { 0x5e0ea9600c5e7444ULL, 0x8ef3dee6ce1bdf60ULL, },
+ { 0x1c7370e0761ecf44ULL, 0x864a2472681b66e0ULL, },
+ { 0xb58eca4059fe7924ULL, 0x8c252ade750e6260ULL, },
+ { 0xfcc4fbc036df5b24ULL, 0x36a7c3bc9596d2e0ULL, },
+ { 0x57a2c300a677ce2cULL, 0x2922bd1cb36946e0ULL, },
+ { 0x88bd5f007437a72cULL, 0x45fd18d49c1ff460ULL, }, /* 88 */
+ { 0x2581a200554339ccULL, 0x6c99b74cacc4a5e0ULL, },
+ { 0x2d500e000b508fccULL, 0x1f975a9844ce5060ULL, },
+ { 0x5907d8000bc6a7a4ULL, 0x0eaa2a5808275460ULL, },
+ { 0xeab7b80057ab4aa4ULL, 0x8af4d608d22d5fe0ULL, },
+ { 0x95ab9000431f7984ULL, 0x840741386cad3f60ULL, },
+ { 0xf5ddf000f6ac0b84ULL, 0xd51bfa701fdb6be0ULL, },
+ { 0xdf7cc0003fd2014cULL, 0xb5052bf0d1bc3fe0ULL, },
+ { 0x3393c00031cb724cULL, 0x06abb9d0a05f4160ULL, }, /* 96 */
+ { 0xdb56c00090e3a34cULL, 0x7ff18f70f5d630e0ULL, },
+ { 0xa1b5c0005faa944cULL, 0x9e0514507291e660ULL, },
+ { 0xfa60c0002cb0454cULL, 0xc4182ef0d53919e0ULL, },
+ { 0xa6f680001aac06ecULL, 0x05ca1a90e899e160ULL, },
+ { 0x15a3000096665b8cULL, 0x0cec37f0504f46e0ULL, },
+ { 0xb79a0000a4a5ab2cULL, 0x578239900c71c260ULL, },
+ { 0xb70c000031251dccULL, 0xaa4c30f0a693abe0ULL, },
+ { 0x01140000f37473ccULL, 0x400dd1e0cc92de60ULL, }, /* 104 */
+ { 0xb1cc0000f066c9ccULL, 0x8cf683c01cd59ee0ULL, },
+ { 0xf8540000557c1fccULL, 0x0f82c780ac8ed560ULL, },
+ { 0xf88c0000103475ccULL, 0xa1f10f00956f49e0ULL, },
+ { 0x2e7000005c2e79a4ULL, 0xcf94670004e95de0ULL, },
+ { 0x96c00000be3ea1acULL, 0xdca57f00da6ef1e0ULL, },
+ { 0xbf00000062838744ULL, 0x368a570027d005e0ULL, },
+ { 0x4c0000006502488cULL, 0xcc98ef003cdc99e0ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_W(b128_pattern[i], b128_pattern[j],
+ b128_result[PATTERN_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_W(b128_random[i], b128_random[j],
+ b128_result[((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_W__DDT(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ ((RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_SHORT_COUNT; j++) {
+ do_msa_MSUBV_W__DSD(b128_random[i], b128_random[j],
+ b128_result[
+ ((PATTERN_INPUTS_SHORT_COUNT) *
+ (PATTERN_INPUTS_SHORT_COUNT)) +
+ (2 * (RANDOM_INPUTS_SHORT_COUNT) *
+ (RANDOM_INPUTS_SHORT_COUNT)) +
+ RANDOM_INPUTS_SHORT_COUNT * i + j]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Test program for MSA instruction MOVE.V
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 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/>.
+ *
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_msa.h"
+#include "../../../../include/test_inputs_128.h"
+#include "../../../../include/test_utils_128.h"
+
+#define TEST_COUNT_TOTAL (PATTERN_INPUTS_COUNT + RANDOM_INPUTS_COUNT)
+
+
+int32_t main(void)
+{
+ char *isa_ase_name = "MSA";
+ char *group_name = "Move";
+ char *instruction_name = "MOVE.V";
+ int32_t ret;
+ uint32_t i;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b128_result[TEST_COUNT_TOTAL][2];
+ uint64_t b128_expect[TEST_COUNT_TOTAL][2] = {
+ { 0xffffffffffffffffULL, 0xffffffffffffffffULL, }, /* 0 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xaaaaaaaaaaaaaaaaULL, 0xaaaaaaaaaaaaaaaaULL, },
+ { 0x5555555555555555ULL, 0x5555555555555555ULL, },
+ { 0xccccccccccccccccULL, 0xccccccccccccccccULL, },
+ { 0x3333333333333333ULL, 0x3333333333333333ULL, },
+ { 0xe38e38e38e38e38eULL, 0x38e38e38e38e38e3ULL, },
+ { 0x1c71c71c71c71c71ULL, 0xc71c71c71c71c71cULL, },
+ { 0xf0f0f0f0f0f0f0f0ULL, 0xf0f0f0f0f0f0f0f0ULL, }, /* 8 */
+ { 0x0f0f0f0f0f0f0f0fULL, 0x0f0f0f0f0f0f0f0fULL, },
+ { 0xf83e0f83e0f83e0fULL, 0x83e0f83e0f83e0f8ULL, },
+ { 0x07c1f07c1f07c1f0ULL, 0x7c1f07c1f07c1f07ULL, },
+ { 0xfc0fc0fc0fc0fc0fULL, 0xc0fc0fc0fc0fc0fcULL, },
+ { 0x03f03f03f03f03f0ULL, 0x3f03f03f03f03f03ULL, },
+ { 0xfe03f80fe03f80feULL, 0x03f80fe03f80fe03ULL, },
+ { 0x01fc07f01fc07f01ULL, 0xfc07f01fc07f01fcULL, },
+ { 0xff00ff00ff00ff00ULL, 0xff00ff00ff00ff00ULL, }, /* 16 */
+ { 0x00ff00ff00ff00ffULL, 0x00ff00ff00ff00ffULL, },
+ { 0xff803fe00ff803feULL, 0x00ff803fe00ff803ULL, },
+ { 0x007fc01ff007fc01ULL, 0xff007fc01ff007fcULL, },
+ { 0xffc00ffc00ffc00fULL, 0xfc00ffc00ffc00ffULL, },
+ { 0x003ff003ff003ff0ULL, 0x03ff003ff003ff00ULL, },
+ { 0xffe003ff800ffe00ULL, 0x3ff800ffe003ff80ULL, },
+ { 0x001ffc007ff001ffULL, 0xc007ff001ffc007fULL, },
+ { 0xfff000fff000fff0ULL, 0x00fff000fff000ffULL, }, /* 24 */
+ { 0x000fff000fff000fULL, 0xff000fff000fff00ULL, },
+ { 0xfff8003ffe000fffULL, 0x8003ffe000fff800ULL, },
+ { 0x0007ffc001fff000ULL, 0x7ffc001fff0007ffULL, },
+ { 0xfffc000fffc000ffULL, 0xfc000fffc000fffcULL, },
+ { 0x0003fff0003fff00ULL, 0x03fff0003fff0003ULL, },
+ { 0xfffe0003fff8000fULL, 0xffe0003fff8000ffULL, },
+ { 0x0001fffc0007fff0ULL, 0x001fffc0007fff00ULL, },
+ { 0xffff0000ffff0000ULL, 0xffff0000ffff0000ULL, }, /* 32 */
+ { 0x0000ffff0000ffffULL, 0x0000ffff0000ffffULL, },
+ { 0xffff80003fffe000ULL, 0x0ffff80003fffe00ULL, },
+ { 0x00007fffc0001fffULL, 0xf00007fffc0001ffULL, },
+ { 0xffffc0000ffffc00ULL, 0x00ffffc0000ffffcULL, },
+ { 0x00003ffff00003ffULL, 0xff00003ffff00003ULL, },
+ { 0xffffe00003ffff80ULL, 0x000ffffe00003fffULL, },
+ { 0x00001ffffc00007fULL, 0xfff00001ffffc000ULL, },
+ { 0xfffff00000fffff0ULL, 0x0000fffff00000ffULL, }, /* 40 */
+ { 0x00000fffff00000fULL, 0xffff00000fffff00ULL, },
+ { 0xfffff800003ffffeULL, 0x00000fffff800003ULL, },
+ { 0x000007ffffc00001ULL, 0xfffff000007ffffcULL, },
+ { 0xfffffc00000fffffULL, 0xc00000fffffc0000ULL, },
+ { 0x000003fffff00000ULL, 0x3fffff000003ffffULL, },
+ { 0xfffffe000003ffffULL, 0xf800000fffffe000ULL, },
+ { 0x000001fffffc0000ULL, 0x07fffff000001fffULL, },
+ { 0xffffff000000ffffULL, 0xff000000ffffff00ULL, }, /* 48 */
+ { 0x000000ffffff0000ULL, 0x00ffffff000000ffULL, },
+ { 0xffffff8000003fffULL, 0xffe000000ffffff8ULL, },
+ { 0x0000007fffffc000ULL, 0x001ffffff0000007ULL, },
+ { 0xffffffc000000fffULL, 0xfffc000000ffffffULL, },
+ { 0x0000003ffffff000ULL, 0x0003ffffff000000ULL, },
+ { 0xffffffe0000003ffULL, 0xffff8000000fffffULL, },
+ { 0x0000001ffffffc00ULL, 0x00007ffffff00000ULL, },
+ { 0xfffffff0000000ffULL, 0xfffff0000000ffffULL, }, /* 56 */
+ { 0x0000000fffffff00ULL, 0x00000fffffff0000ULL, },
+ { 0xfffffff80000003fULL, 0xfffffe0000000fffULL, },
+ { 0x00000007ffffffc0ULL, 0x000001fffffff000ULL, },
+ { 0xfffffffc0000000fULL, 0xffffffc0000000ffULL, },
+ { 0x00000003fffffff0ULL, 0x0000003fffffff00ULL, },
+ { 0xfffffffe00000003ULL, 0xfffffff80000000fULL, },
+ { 0x00000001fffffffcULL, 0x00000007fffffff0ULL, },
+ { 0x886ae6cc28625540ULL, 0x4b670b5efe7bb00cULL, }, /* 64 */
+ { 0xfbbe00634d93c708ULL, 0x12f7bb1a153f52fcULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x704f164d5e31e24eULL, 0x8df188d8a942e2a0ULL, },
+ { 0xb9926b7c7daf4258ULL, 0xa1227caddcce65b6ULL, },
+ { 0xd027be89ff0a2ef9ULL, 0x170b5050fea53078ULL, },
+ { 0xb83b580665cabc4aULL, 0x91230822bff0ba62ULL, },
+ { 0xfc8f23f09aa6b782ULL, 0x93fd6637124275aeULL, },
+ { 0x201e09cd56aee649ULL, 0xef5de039a6a52758ULL, }, /* 72 */
+ { 0xa57cd91365d9e5d7ULL, 0x9321bc9881ecba5cULL, },
+ { 0xa2e8f6f5c9cbc61bULL, 0xb2c471545e0d7a12ULL, },
+ { 0xa89cf2f131a864aeULL, 0xd2a3e87a5db986e7ULL, },
+ { 0xe61438e9a652ea0aULL, 0xa85483d97879d41cULL, },
+ { 0x944a35fd192361a8ULL, 0xf3912da36a0b2d6bULL, },
+ { 0x4630426322bef79cULL, 0xeb5686f7cb19304eULL, },
+ { 0x8b5aa7a2f259deadULL, 0xd278cbcd696417e3ULL, },
+ };
+
+ reset_msa_registers();
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < TEST_COUNT_TOTAL; i++) {
+ if (i < PATTERN_INPUTS_COUNT) {
+ do_msa_MOVE_V(b128_pattern[i], b128_result[i]);
+ } else {
+ do_msa_MOVE_V(b128_random[i - PATTERN_INPUTS_COUNT],
+ b128_result[i]);
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_128(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time,
+ &b128_result[0][0], &b128_expect[0][0]);
+
+ return ret;
+}
{ 0xf71a3ffcbe639308ULL, 0xf1d842a04f4d314eULL, },
{ 0xd8ff2b145aaacf80ULL, 0xf1d842a04f4d314eULL, },
{ 0xf1d842a04f4d314eULL, 0xf1d842a04f4d314eULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 80 */
- { 0x00000000fc000000ULL, 0x000015000000001aULL, },
- { 0x0000000014000000ULL, 0x0000ab00000000ffULL, },
- { 0x00000000a0000000ULL, 0x0000a900000000d8ULL, },
- { 0x000040000000000cULL, 0x9300003f00120000ULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000800000000014ULL, 0x9300003f00120000ULL, },
- { 0x00004e00000000a0ULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0x8800000000fee6aaULL, }, /* 88 */
- { 0x0000000000000000ULL, 0xfb000000001500aaULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x0000000000000000ULL, 0x7000000000a916aaULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 96 */
- { 0x00000800000000fcULL, 0x6200007be64b0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeccULL, },
- { 0x00006a0000550000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae63ULL, },
- { 0x0000be0000c70000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 104 */
- { 0x00000800000000fcULL, 0xcf00002bae270000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x00005a00008b0000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x31000042168d0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae4dULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
+ { 0x675e7b0c6acc6240ULL, 0xd8a04d4ed8a04d4eULL, }, /* 80 */
+ { 0xf71a3ffcbe639308ULL, 0xa04ea04e5e0ccc40ULL, },
+ { 0xd8ff2b145aaacf80ULL, 0x4e4e0c401afc6308ULL, },
+ { 0xf1d842a04f4d314eULL, 0x4e40fc08ff14aa80ULL, },
+ { 0x675e7b0c6acc6240ULL, 0x40081480d8a04d4eULL, },
+ { 0xf71a3ffcbe639308ULL, 0x0880a04e5e0ccc40ULL, },
+ { 0xd8ff2b145aaacf80ULL, 0x804e0c401afc6308ULL, },
+ { 0xf1d842a04f4d314eULL, 0x4e40fc08ff14aa80ULL, },
+ { 0x675e7b0c6acc6240ULL, 0x40081480d8a04d4eULL, }, /* 88 */
+ { 0xf71a3ffcbe639308ULL, 0x0880a04e5e0ccc40ULL, },
+ { 0xd8ff2b145aaacf80ULL, 0x804e0c401afc6308ULL, },
+ { 0xf1d842a04f4d314eULL, 0x4e40fc08ff14aa80ULL, },
+ { 0x675e7b0c6acc6240ULL, 0x40081480d8a04d4eULL, },
+ { 0xf71a3ffcbe639308ULL, 0x0880a04e5e0ccc40ULL, },
+ { 0xd8ff2b145aaacf80ULL, 0x804e0c401afc6308ULL, },
+ { 0xf1d842a04f4d314eULL, 0x4e40fc08ff14aa80ULL, },
+ { 0x40081480d8a04d4eULL, 0x675e7b0c6acc6240ULL, }, /* 96 */
+ { 0x5e0ccc400880a04eULL, 0x675e7b0c6acc6240ULL, },
+ { 0x5e0ccc400c40804eULL, 0x675e7b0c6acc6240ULL, },
+ { 0x5e0ccc400c40404eULL, 0x675e7b0c6acc6240ULL, },
+ { 0x5e0ccc400c40404eULL, 0xf71a3ffcbe639308ULL, },
+ { 0x1afc63080c40404eULL, 0xf71a3ffcbe639308ULL, },
+ { 0x1afc6308fc08404eULL, 0xf71a3ffcbe639308ULL, },
+ { 0x1afc6308fc08084eULL, 0xf71a3ffcbe639308ULL, },
+ { 0x1afc6308fc08084eULL, 0xd8ff2b145aaacf80ULL, }, /* 104 */
+ { 0xff14aa80fc08084eULL, 0xd8ff2b145aaacf80ULL, },
+ { 0xff14aa801480084eULL, 0xd8ff2b145aaacf80ULL, },
+ { 0xff14aa801480804eULL, 0xd8ff2b145aaacf80ULL, },
+ { 0xff14aa801480804eULL, 0xf1d842a04f4d314eULL, },
+ { 0xd8a04d4e1480804eULL, 0xf1d842a04f4d314eULL, },
+ { 0xd8a04d4ea04e804eULL, 0xf1d842a04f4d314eULL, },
+ { 0xd8a04d4ea04e4e4eULL, 0xf1d842a04f4d314eULL, },
};
reset_msa_registers();
{ 0xfbbe00634d93c708ULL, 0x704f164d5e31e24eULL, },
{ 0xac5aaeaab9cf8b80ULL, 0x704f164d5e31e24eULL, },
{ 0x704f164d5e31e24eULL, 0x704f164d5e31e24eULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 80 */
- { 0x00000000fc000000ULL, 0x000015000000001aULL, },
- { 0x0000000014000000ULL, 0x0000ab00000000ffULL, },
- { 0x00000000a0000000ULL, 0x0000a900000000d8ULL, },
- { 0x000040000000000cULL, 0x9300003f00120000ULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000800000000014ULL, 0x9300003f00120000ULL, },
- { 0x00004e00000000a0ULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0x8800000000fee6aaULL, }, /* 88 */
- { 0x0000000000000000ULL, 0xfb000000001500aaULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x0000000000000000ULL, 0x7000000000a916aaULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 96 */
- { 0x00000800000000fcULL, 0x6200007be64b0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeccULL, },
- { 0x00006a0000550000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae63ULL, },
- { 0x0000be0000c70000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 104 */
- { 0x00000800000000fcULL, 0xcf00002bae270000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x00005a00008b0000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x31000042168d0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae4dULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
+ { 0x886ae6cc28625540ULL, 0x704f164d5e31e24eULL, }, /* 80 */
+ { 0xfbbe00634d93c708ULL, 0x886ae6cc28625540ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0xfbbe00634d93c708ULL, },
+ { 0x704f164d5e31e24eULL, 0xac5aaeaab9cf8b80ULL, },
+ { 0x886ae6cc28625540ULL, 0x704f164d5e31e24eULL, },
+ { 0xfbbe00634d93c708ULL, 0x886ae6cc28625540ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0xfbbe00634d93c708ULL, },
+ { 0x704f164d5e31e24eULL, 0xac5aaeaab9cf8b80ULL, },
+ { 0x886ae6cc28625540ULL, 0x704f164d5e31e24eULL, }, /* 88 */
+ { 0xfbbe00634d93c708ULL, 0x886ae6cc28625540ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0xfbbe00634d93c708ULL, },
+ { 0x704f164d5e31e24eULL, 0xac5aaeaab9cf8b80ULL, },
+ { 0x886ae6cc28625540ULL, 0x704f164d5e31e24eULL, },
+ { 0xfbbe00634d93c708ULL, 0x886ae6cc28625540ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0xfbbe00634d93c708ULL, },
+ { 0x704f164d5e31e24eULL, 0xac5aaeaab9cf8b80ULL, },
+ { 0x704f164d5e31e24eULL, 0x886ae6cc28625540ULL, }, /* 96 */
+ { 0x704f164d5e31e24eULL, 0x886ae6cc28625540ULL, },
+ { 0x704f164d5e31e24eULL, 0x886ae6cc28625540ULL, },
+ { 0x704f164d5e31e24eULL, 0x886ae6cc28625540ULL, },
+ { 0x704f164d5e31e24eULL, 0xfbbe00634d93c708ULL, },
+ { 0x704f164d5e31e24eULL, 0xfbbe00634d93c708ULL, },
+ { 0x704f164d5e31e24eULL, 0xfbbe00634d93c708ULL, },
+ { 0x704f164d5e31e24eULL, 0xfbbe00634d93c708ULL, },
+ { 0x704f164d5e31e24eULL, 0xac5aaeaab9cf8b80ULL, }, /* 104 */
+ { 0x704f164d5e31e24eULL, 0xac5aaeaab9cf8b80ULL, },
+ { 0x704f164d5e31e24eULL, 0xac5aaeaab9cf8b80ULL, },
+ { 0x704f164d5e31e24eULL, 0xac5aaeaab9cf8b80ULL, },
+ { 0x704f164d5e31e24eULL, 0x704f164d5e31e24eULL, },
+ { 0x704f164d5e31e24eULL, 0x704f164d5e31e24eULL, },
+ { 0x704f164d5e31e24eULL, 0x704f164d5e31e24eULL, },
+ { 0x704f164d5e31e24eULL, 0x704f164d5e31e24eULL, },
};
reset_msa_registers();
{ 0xbb1a52fc0063c708ULL, 0x88d8e2a0164de24eULL, },
{ 0xc6ff2514aeaa8b80ULL, 0x88d8e2a0164de24eULL, },
{ 0x88d8e2a0164de24eULL, 0x88d8e2a0164de24eULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 80 */
- { 0x00000000fc000000ULL, 0x000015000000001aULL, },
- { 0x0000000014000000ULL, 0x0000ab00000000ffULL, },
- { 0x00000000a0000000ULL, 0x0000a900000000d8ULL, },
- { 0x000040000000000cULL, 0x9300003f00120000ULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000800000000014ULL, 0x9300003f00120000ULL, },
- { 0x00004e00000000a0ULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0x8800000000fee6aaULL, }, /* 88 */
- { 0x0000000000000000ULL, 0xfb000000001500aaULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x0000000000000000ULL, 0x7000000000a916aaULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 96 */
- { 0x00000800000000fcULL, 0x6200007be64b0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeccULL, },
- { 0x00006a0000550000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae63ULL, },
- { 0x0000be0000c70000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 104 */
- { 0x00000800000000fcULL, 0xcf00002bae270000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x00005a00008b0000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x31000042168d0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae4dULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
+ { 0x0b5eb00ce6cc5540ULL, 0xe2a0e24ee2a0e24eULL, }, /* 80 */
+ { 0xbb1a52fc0063c708ULL, 0xe24ee24eb00c5540ULL, },
+ { 0xc6ff2514aeaa8b80ULL, 0xe24e554052fcc708ULL, },
+ { 0x88d8e2a0164de24eULL, 0x5540c70825148b80ULL, },
+ { 0x0b5eb00ce6cc5540ULL, 0xc7088b80e2a0e24eULL, },
+ { 0xbb1a52fc0063c708ULL, 0x8b80e24eb00c5540ULL, },
+ { 0xc6ff2514aeaa8b80ULL, 0xe24e554052fcc708ULL, },
+ { 0x88d8e2a0164de24eULL, 0x5540c70825148b80ULL, },
+ { 0x0b5eb00ce6cc5540ULL, 0xc7088b80e2a0e24eULL, }, /* 88 */
+ { 0xbb1a52fc0063c708ULL, 0x8b80e24eb00c5540ULL, },
+ { 0xc6ff2514aeaa8b80ULL, 0xe24e554052fcc708ULL, },
+ { 0x88d8e2a0164de24eULL, 0x5540c70825148b80ULL, },
+ { 0x0b5eb00ce6cc5540ULL, 0xc7088b80e2a0e24eULL, },
+ { 0xbb1a52fc0063c708ULL, 0x8b80e24eb00c5540ULL, },
+ { 0xc6ff2514aeaa8b80ULL, 0xe24e554052fcc708ULL, },
+ { 0x88d8e2a0164de24eULL, 0x5540c70825148b80ULL, },
+ { 0xc7088b80e2a0e24eULL, 0x0b5eb00ce6cc5540ULL, }, /* 96 */
+ { 0xb00c55408b80e24eULL, 0x0b5eb00ce6cc5540ULL, },
+ { 0xb00c55405540e24eULL, 0x0b5eb00ce6cc5540ULL, },
+ { 0xb00c55405540e24eULL, 0x0b5eb00ce6cc5540ULL, },
+ { 0xb00c55405540e24eULL, 0xbb1a52fc0063c708ULL, },
+ { 0x52fcc7085540e24eULL, 0xbb1a52fc0063c708ULL, },
+ { 0x52fcc708c708e24eULL, 0xbb1a52fc0063c708ULL, },
+ { 0x52fcc708c708e24eULL, 0xbb1a52fc0063c708ULL, },
+ { 0x52fcc708c708e24eULL, 0xc6ff2514aeaa8b80ULL, }, /* 104 */
+ { 0x25148b80c708e24eULL, 0xc6ff2514aeaa8b80ULL, },
+ { 0x25148b808b80e24eULL, 0xc6ff2514aeaa8b80ULL, },
+ { 0x25148b808b80e24eULL, 0xc6ff2514aeaa8b80ULL, },
+ { 0x25148b808b80e24eULL, 0x88d8e2a0164de24eULL, },
+ { 0xe2a0e24e8b80e24eULL, 0x88d8e2a0164de24eULL, },
+ { 0xe2a0e24ee24ee24eULL, 0x88d8e2a0164de24eULL, },
+ { 0xe2a0e24ee24ee24eULL, 0x88d8e2a0164de24eULL, },
};
reset_msa_registers();
{ 0x153f52fc4d93c708ULL, 0xa942e2a05e31e24eULL, },
{ 0xab2b2514b9cf8b80ULL, 0xa942e2a05e31e24eULL, },
{ 0xa942e2a05e31e24eULL, 0xa942e2a05e31e24eULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 80 */
- { 0x00000000fc000000ULL, 0x000015000000001aULL, },
- { 0x0000000014000000ULL, 0x0000ab00000000ffULL, },
- { 0x00000000a0000000ULL, 0x0000a900000000d8ULL, },
- { 0x000040000000000cULL, 0x9300003f00120000ULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000800000000014ULL, 0x9300003f00120000ULL, },
- { 0x00004e00000000a0ULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0x8800000000fee6aaULL, }, /* 88 */
- { 0x0000000000000000ULL, 0xfb000000001500aaULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x0000000000000000ULL, 0x7000000000a916aaULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 96 */
- { 0x00000800000000fcULL, 0x6200007be64b0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeccULL, },
- { 0x00006a0000550000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae63ULL, },
- { 0x0000be0000c70000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 104 */
- { 0x00000800000000fcULL, 0xcf00002bae270000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x00005a00008b0000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x31000042168d0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae4dULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
+ { 0xfe7bb00c28625540ULL, 0x5e31e24e5e31e24eULL, }, /* 80 */
+ { 0x153f52fc4d93c708ULL, 0x5e31e24e28625540ULL, },
+ { 0xab2b2514b9cf8b80ULL, 0x286255404d93c708ULL, },
+ { 0xa942e2a05e31e24eULL, 0x4d93c708b9cf8b80ULL, },
+ { 0xfe7bb00c28625540ULL, 0xb9cf8b805e31e24eULL, },
+ { 0x153f52fc4d93c708ULL, 0x5e31e24e28625540ULL, },
+ { 0xab2b2514b9cf8b80ULL, 0x286255404d93c708ULL, },
+ { 0xa942e2a05e31e24eULL, 0x4d93c708b9cf8b80ULL, },
+ { 0xfe7bb00c28625540ULL, 0xb9cf8b805e31e24eULL, }, /* 88 */
+ { 0x153f52fc4d93c708ULL, 0x5e31e24e28625540ULL, },
+ { 0xab2b2514b9cf8b80ULL, 0x286255404d93c708ULL, },
+ { 0xa942e2a05e31e24eULL, 0x4d93c708b9cf8b80ULL, },
+ { 0xfe7bb00c28625540ULL, 0xb9cf8b805e31e24eULL, },
+ { 0x153f52fc4d93c708ULL, 0x5e31e24e28625540ULL, },
+ { 0xab2b2514b9cf8b80ULL, 0x286255404d93c708ULL, },
+ { 0xa942e2a05e31e24eULL, 0x4d93c708b9cf8b80ULL, },
+ { 0xb9cf8b805e31e24eULL, 0xfe7bb00c28625540ULL, }, /* 96 */
+ { 0x286255405e31e24eULL, 0xfe7bb00c28625540ULL, },
+ { 0x286255405e31e24eULL, 0xfe7bb00c28625540ULL, },
+ { 0x286255405e31e24eULL, 0xfe7bb00c28625540ULL, },
+ { 0x286255405e31e24eULL, 0x153f52fc4d93c708ULL, },
+ { 0x4d93c7085e31e24eULL, 0x153f52fc4d93c708ULL, },
+ { 0x4d93c7085e31e24eULL, 0x153f52fc4d93c708ULL, },
+ { 0x4d93c7085e31e24eULL, 0x153f52fc4d93c708ULL, },
+ { 0x4d93c7085e31e24eULL, 0xab2b2514b9cf8b80ULL, }, /* 104 */
+ { 0xb9cf8b805e31e24eULL, 0xab2b2514b9cf8b80ULL, },
+ { 0xb9cf8b805e31e24eULL, 0xab2b2514b9cf8b80ULL, },
+ { 0xb9cf8b805e31e24eULL, 0xab2b2514b9cf8b80ULL, },
+ { 0xb9cf8b805e31e24eULL, 0xa942e2a05e31e24eULL, },
+ { 0x5e31e24e5e31e24eULL, 0xa942e2a05e31e24eULL, },
+ { 0x5e31e24e5e31e24eULL, 0xa942e2a05e31e24eULL, },
+ { 0x5e31e24e5e31e24eULL, 0xa942e2a05e31e24eULL, },
};
reset_msa_registers();
{ 0x12bb1552fb004dc7ULL, 0x8d88a9e270165ee2ULL, },
{ 0x27c6ab25acaeb98bULL, 0x8d88a9e270165ee2ULL, },
{ 0x8d88a9e270165ee2ULL, 0x8d88a9e270165ee2ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 80 */
- { 0x00000000fc000000ULL, 0x000015000000001aULL, },
- { 0x0000000014000000ULL, 0x0000ab00000000ffULL, },
- { 0x00000000a0000000ULL, 0x0000a900000000d8ULL, },
- { 0x000040000000000cULL, 0x9300003f00120000ULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000800000000014ULL, 0x9300003f00120000ULL, },
- { 0x00004e00000000a0ULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0x8800000000fee6aaULL, }, /* 88 */
- { 0x0000000000000000ULL, 0xfb000000001500aaULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x0000000000000000ULL, 0x7000000000a916aaULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 96 */
- { 0x00000800000000fcULL, 0x6200007be64b0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeccULL, },
- { 0x00006a0000550000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae63ULL, },
- { 0x0000be0000c70000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 104 */
- { 0x00000800000000fcULL, 0xcf00002bae270000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x00005a00008b0000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x31000042168d0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae4dULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
+ { 0x4b0bfeb088e62855ULL, 0x8da9705e8da9705eULL, }, /* 80 */
+ { 0x12bb1552fb004dc7ULL, 0x8d708d704bfe8828ULL, },
+ { 0x27c6ab25acaeb98bULL, 0x8d8d4b881215fb4dULL, },
+ { 0x8d88a9e270165ee2ULL, 0x8d4b12fb27abacb9ULL, },
+ { 0x4b0bfeb088e62855ULL, 0x8d1227ac8da9705eULL, },
+ { 0x12bb1552fb004dc7ULL, 0x8d278d704bfe8828ULL, },
+ { 0x27c6ab25acaeb98bULL, 0x8d8d4b881215fb4dULL, },
+ { 0x8d88a9e270165ee2ULL, 0x8d4b12fb27abacb9ULL, },
+ { 0x4b0bfeb088e62855ULL, 0x8d1227ac8da9705eULL, }, /* 88 */
+ { 0x12bb1552fb004dc7ULL, 0x8d278d704bfe8828ULL, },
+ { 0x27c6ab25acaeb98bULL, 0x8d8d4b881215fb4dULL, },
+ { 0x8d88a9e270165ee2ULL, 0x8d4b12fb27abacb9ULL, },
+ { 0x4b0bfeb088e62855ULL, 0x8d1227ac8da9705eULL, },
+ { 0x12bb1552fb004dc7ULL, 0x8d278d704bfe8828ULL, },
+ { 0x27c6ab25acaeb98bULL, 0x8d8d4b881215fb4dULL, },
+ { 0x8d88a9e270165ee2ULL, 0x8d4b12fb27abacb9ULL, },
+ { 0x8d1227ac8da9705eULL, 0x4b0bfeb088e62855ULL, }, /* 96 */
+ { 0x4bfe88288d278d70ULL, 0x4b0bfeb088e62855ULL, },
+ { 0x4bfe88284b888d8dULL, 0x4b0bfeb088e62855ULL, },
+ { 0x4bfe88284b884b8dULL, 0x4b0bfeb088e62855ULL, },
+ { 0x4bfe88284b884b4bULL, 0x12bb1552fb004dc7ULL, },
+ { 0x1215fb4d4b884b4bULL, 0x12bb1552fb004dc7ULL, },
+ { 0x1215fb4d12fb4b4bULL, 0x12bb1552fb004dc7ULL, },
+ { 0x1215fb4d12fb124bULL, 0x12bb1552fb004dc7ULL, },
+ { 0x1215fb4d12fb1212ULL, 0x27c6ab25acaeb98bULL, }, /* 104 */
+ { 0x27abacb912fb1212ULL, 0x27c6ab25acaeb98bULL, },
+ { 0x27abacb927ac1212ULL, 0x27c6ab25acaeb98bULL, },
+ { 0x27abacb927ac2712ULL, 0x27c6ab25acaeb98bULL, },
+ { 0x27abacb927ac2727ULL, 0x8d88a9e270165ee2ULL, },
+ { 0x8da9705e27ac2727ULL, 0x8d88a9e270165ee2ULL, },
+ { 0x8da9705e8d702727ULL, 0x8d88a9e270165ee2ULL, },
+ { 0x8da9705e8d708d27ULL, 0x8d88a9e270165ee2ULL, },
};
reset_msa_registers();
{ 0x12f7bb1a153f52fcULL, 0x8df188d8a942e2a0ULL, },
{ 0x27d8c6ffab2b2514ULL, 0x8df188d8a942e2a0ULL, },
{ 0x8df188d8a942e2a0ULL, 0x8df188d8a942e2a0ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 80 */
- { 0x00000000fc000000ULL, 0x000015000000001aULL, },
- { 0x0000000014000000ULL, 0x0000ab00000000ffULL, },
- { 0x00000000a0000000ULL, 0x0000a900000000d8ULL, },
- { 0x000040000000000cULL, 0x9300003f00120000ULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000800000000014ULL, 0x9300003f00120000ULL, },
- { 0x00004e00000000a0ULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0x8800000000fee6aaULL, }, /* 88 */
- { 0x0000000000000000ULL, 0xfb000000001500aaULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x0000000000000000ULL, 0x7000000000a916aaULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 96 */
- { 0x00000800000000fcULL, 0x6200007be64b0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeccULL, },
- { 0x00006a0000550000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae63ULL, },
- { 0x0000be0000c70000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 104 */
- { 0x00000800000000fcULL, 0xcf00002bae270000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x00005a00008b0000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x31000042168d0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae4dULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
+ { 0x4b670b5efe7bb00cULL, 0x8df188d8a942e2a0ULL, }, /* 80 */
+ { 0x12f7bb1a153f52fcULL, 0x8df188d8a942e2a0ULL, },
+ { 0x27d8c6ffab2b2514ULL, 0x8df188d8a942e2a0ULL, },
+ { 0x8df188d8a942e2a0ULL, 0x8df188d8a942e2a0ULL, },
+ { 0x4b670b5efe7bb00cULL, 0x8df188d8a942e2a0ULL, },
+ { 0x12f7bb1a153f52fcULL, 0x8df188d8a942e2a0ULL, },
+ { 0x27d8c6ffab2b2514ULL, 0x8df188d8a942e2a0ULL, },
+ { 0x8df188d8a942e2a0ULL, 0x8df188d8a942e2a0ULL, },
+ { 0x4b670b5efe7bb00cULL, 0x8df188d8a942e2a0ULL, }, /* 88 */
+ { 0x12f7bb1a153f52fcULL, 0x8df188d8a942e2a0ULL, },
+ { 0x27d8c6ffab2b2514ULL, 0x8df188d8a942e2a0ULL, },
+ { 0x8df188d8a942e2a0ULL, 0x8df188d8a942e2a0ULL, },
+ { 0x4b670b5efe7bb00cULL, 0x8df188d8a942e2a0ULL, },
+ { 0x12f7bb1a153f52fcULL, 0x8df188d8a942e2a0ULL, },
+ { 0x27d8c6ffab2b2514ULL, 0x8df188d8a942e2a0ULL, },
+ { 0x8df188d8a942e2a0ULL, 0x8df188d8a942e2a0ULL, },
+ { 0x8df188d8a942e2a0ULL, 0x4b670b5efe7bb00cULL, }, /* 96 */
+ { 0x4b670b5efe7bb00cULL, 0x4b670b5efe7bb00cULL, },
+ { 0x4b670b5efe7bb00cULL, 0x4b670b5efe7bb00cULL, },
+ { 0x4b670b5efe7bb00cULL, 0x4b670b5efe7bb00cULL, },
+ { 0x4b670b5efe7bb00cULL, 0x12f7bb1a153f52fcULL, },
+ { 0x12f7bb1a153f52fcULL, 0x12f7bb1a153f52fcULL, },
+ { 0x12f7bb1a153f52fcULL, 0x12f7bb1a153f52fcULL, },
+ { 0x12f7bb1a153f52fcULL, 0x12f7bb1a153f52fcULL, },
+ { 0x12f7bb1a153f52fcULL, 0x27d8c6ffab2b2514ULL, }, /* 104 */
+ { 0x27d8c6ffab2b2514ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x27d8c6ffab2b2514ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x27d8c6ffab2b2514ULL, 0x27d8c6ffab2b2514ULL, },
+ { 0x27d8c6ffab2b2514ULL, 0x8df188d8a942e2a0ULL, },
+ { 0x8df188d8a942e2a0ULL, 0x8df188d8a942e2a0ULL, },
+ { 0x8df188d8a942e2a0ULL, 0x8df188d8a942e2a0ULL, },
+ { 0x8df188d8a942e2a0ULL, 0x8df188d8a942e2a0ULL, },
};
reset_msa_registers();
{ 0x12f7153ffbbe4d93ULL, 0x8df1a942704f5e31ULL, },
{ 0x27d8ab2bac5ab9cfULL, 0x8df1a942704f5e31ULL, },
{ 0x8df1a942704f5e31ULL, 0x8df1a942704f5e31ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 80 */
- { 0x00000000fc000000ULL, 0x000015000000001aULL, },
- { 0x0000000014000000ULL, 0x0000ab00000000ffULL, },
- { 0x00000000a0000000ULL, 0x0000a900000000d8ULL, },
- { 0x000040000000000cULL, 0x9300003f00120000ULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000800000000014ULL, 0x9300003f00120000ULL, },
- { 0x00004e00000000a0ULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0x8800000000fee6aaULL, }, /* 88 */
- { 0x0000000000000000ULL, 0xfb000000001500aaULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x0000000000000000ULL, 0x7000000000a916aaULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 96 */
- { 0x00000800000000fcULL, 0x6200007be64b0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeccULL, },
- { 0x00006a0000550000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae63ULL, },
- { 0x0000be0000c70000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 104 */
- { 0x00000800000000fcULL, 0xcf00002bae270000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x00005a00008b0000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x31000042168d0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae4dULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
+ { 0x4b67fe7b886a2862ULL, 0x8df1704f8df1704fULL, }, /* 80 */
+ { 0x12f7153ffbbe4d93ULL, 0x8df18df14b67886aULL, },
+ { 0x27d8ab2bac5ab9cfULL, 0x8df14b6712f7fbbeULL, },
+ { 0x8df1a942704f5e31ULL, 0x8df112f727d8ac5aULL, },
+ { 0x4b67fe7b886a2862ULL, 0x8df127d88df1704fULL, },
+ { 0x12f7153ffbbe4d93ULL, 0x8df18df14b67886aULL, },
+ { 0x27d8ab2bac5ab9cfULL, 0x8df14b6712f7fbbeULL, },
+ { 0x8df1a942704f5e31ULL, 0x8df112f727d8ac5aULL, },
+ { 0x4b67fe7b886a2862ULL, 0x8df127d88df1704fULL, }, /* 88 */
+ { 0x12f7153ffbbe4d93ULL, 0x8df18df14b67886aULL, },
+ { 0x27d8ab2bac5ab9cfULL, 0x8df14b6712f7fbbeULL, },
+ { 0x8df1a942704f5e31ULL, 0x8df112f727d8ac5aULL, },
+ { 0x4b67fe7b886a2862ULL, 0x8df127d88df1704fULL, },
+ { 0x12f7153ffbbe4d93ULL, 0x8df18df14b67886aULL, },
+ { 0x27d8ab2bac5ab9cfULL, 0x8df14b6712f7fbbeULL, },
+ { 0x8df1a942704f5e31ULL, 0x8df112f727d8ac5aULL, },
+ { 0x8df127d88df1704fULL, 0x4b67fe7b886a2862ULL, }, /* 96 */
+ { 0x4b67886a8df18df1ULL, 0x4b67fe7b886a2862ULL, },
+ { 0x4b67886a4b678df1ULL, 0x4b67fe7b886a2862ULL, },
+ { 0x4b67886a4b674b67ULL, 0x4b67fe7b886a2862ULL, },
+ { 0x4b67886a4b674b67ULL, 0x12f7153ffbbe4d93ULL, },
+ { 0x12f7fbbe4b674b67ULL, 0x12f7153ffbbe4d93ULL, },
+ { 0x12f7fbbe12f74b67ULL, 0x12f7153ffbbe4d93ULL, },
+ { 0x12f7fbbe12f712f7ULL, 0x12f7153ffbbe4d93ULL, },
+ { 0x12f7fbbe12f712f7ULL, 0x27d8ab2bac5ab9cfULL, }, /* 104 */
+ { 0x27d8ac5a12f712f7ULL, 0x27d8ab2bac5ab9cfULL, },
+ { 0x27d8ac5a27d812f7ULL, 0x27d8ab2bac5ab9cfULL, },
+ { 0x27d8ac5a27d827d8ULL, 0x27d8ab2bac5ab9cfULL, },
+ { 0x27d8ac5a27d827d8ULL, 0x8df1a942704f5e31ULL, },
+ { 0x8df1704f27d827d8ULL, 0x8df1a942704f5e31ULL, },
+ { 0x8df1704f8df127d8ULL, 0x8df1a942704f5e31ULL, },
+ { 0x8df1704f8df18df1ULL, 0x8df1a942704f5e31ULL, },
};
reset_msa_registers();
{ 0x12f7bb1afbbe0063ULL, 0x8df188d8704f164dULL, },
{ 0x27d8c6ffac5aaeaaULL, 0x8df188d8704f164dULL, },
{ 0x8df188d8704f164dULL, 0x8df188d8704f164dULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 80 */
- { 0x00000000fc000000ULL, 0x000015000000001aULL, },
- { 0x0000000014000000ULL, 0x0000ab00000000ffULL, },
- { 0x00000000a0000000ULL, 0x0000a900000000d8ULL, },
- { 0x000040000000000cULL, 0x9300003f00120000ULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000800000000014ULL, 0x9300003f00120000ULL, },
- { 0x00004e00000000a0ULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0x8800000000fee6aaULL, }, /* 88 */
- { 0x0000000000000000ULL, 0xfb000000001500aaULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x0000000000000000ULL, 0x7000000000a916aaULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 96 */
- { 0x00000800000000fcULL, 0x6200007be64b0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeccULL, },
- { 0x00006a0000550000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae63ULL, },
- { 0x0000be0000c70000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 104 */
- { 0x00000800000000fcULL, 0xcf00002bae270000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x00005a00008b0000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x31000042168d0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae4dULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
+ { 0x4b670b5e886ae6ccULL, 0x8df188d88df188d8ULL, }, /* 80 */
+ { 0x12f7bb1afbbe0063ULL, 0x8df188d84b670b5eULL, },
+ { 0x27d8c6ffac5aaeaaULL, 0x8df188d812f7bb1aULL, },
+ { 0x8df188d8704f164dULL, 0x8df188d827d8c6ffULL, },
+ { 0x4b670b5e886ae6ccULL, 0x8df188d88df188d8ULL, },
+ { 0x12f7bb1afbbe0063ULL, 0x8df188d84b670b5eULL, },
+ { 0x27d8c6ffac5aaeaaULL, 0x8df188d812f7bb1aULL, },
+ { 0x8df188d8704f164dULL, 0x8df188d827d8c6ffULL, },
+ { 0x4b670b5e886ae6ccULL, 0x8df188d88df188d8ULL, }, /* 88 */
+ { 0x12f7bb1afbbe0063ULL, 0x8df188d84b670b5eULL, },
+ { 0x27d8c6ffac5aaeaaULL, 0x8df188d812f7bb1aULL, },
+ { 0x8df188d8704f164dULL, 0x8df188d827d8c6ffULL, },
+ { 0x4b670b5e886ae6ccULL, 0x8df188d88df188d8ULL, },
+ { 0x12f7bb1afbbe0063ULL, 0x8df188d84b670b5eULL, },
+ { 0x27d8c6ffac5aaeaaULL, 0x8df188d812f7bb1aULL, },
+ { 0x8df188d8704f164dULL, 0x8df188d827d8c6ffULL, },
+ { 0x8df188d88df188d8ULL, 0x4b670b5e886ae6ccULL, }, /* 96 */
+ { 0x4b670b5e8df188d8ULL, 0x4b670b5e886ae6ccULL, },
+ { 0x4b670b5e4b670b5eULL, 0x4b670b5e886ae6ccULL, },
+ { 0x4b670b5e4b670b5eULL, 0x4b670b5e886ae6ccULL, },
+ { 0x4b670b5e4b670b5eULL, 0x12f7bb1afbbe0063ULL, },
+ { 0x12f7bb1a4b670b5eULL, 0x12f7bb1afbbe0063ULL, },
+ { 0x12f7bb1a12f7bb1aULL, 0x12f7bb1afbbe0063ULL, },
+ { 0x12f7bb1a12f7bb1aULL, 0x12f7bb1afbbe0063ULL, },
+ { 0x12f7bb1a12f7bb1aULL, 0x27d8c6ffac5aaeaaULL, }, /* 104 */
+ { 0x27d8c6ff12f7bb1aULL, 0x27d8c6ffac5aaeaaULL, },
+ { 0x27d8c6ff27d8c6ffULL, 0x27d8c6ffac5aaeaaULL, },
+ { 0x27d8c6ff27d8c6ffULL, 0x27d8c6ffac5aaeaaULL, },
+ { 0x27d8c6ff27d8c6ffULL, 0x8df188d8704f164dULL, },
+ { 0x8df188d827d8c6ffULL, 0x8df188d8704f164dULL, },
+ { 0x8df188d88df188d8ULL, 0x8df188d8704f164dULL, },
+ { 0x8df188d88df188d8ULL, 0x8df188d8704f164dULL, },
};
reset_msa_registers();
{ 0x0000000000000000ULL, 0x0000000000000000ULL, },
{ 0x8080808080808080ULL, 0x8080808080808080ULL, },
{ 0x0000000000000000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 80 */
- { 0x00000000fc000000ULL, 0x000015000000001aULL, },
- { 0x0000000014000000ULL, 0x0000ab00000000ffULL, },
- { 0x00000000a0000000ULL, 0x0000a900000000d8ULL, },
- { 0x000040000000000cULL, 0x9300003f00120000ULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000800000000014ULL, 0x9300003f00120000ULL, },
- { 0x00004e00000000a0ULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0x8800000000fee6aaULL, }, /* 88 */
- { 0x0000000000000000ULL, 0xfb000000001500aaULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x0000000000000000ULL, 0x7000000000a916aaULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 96 */
- { 0x00000800000000fcULL, 0x6200007be64b0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeccULL, },
- { 0x00006a0000550000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae63ULL, },
- { 0x0000be0000c70000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 104 */
- { 0x00000800000000fcULL, 0xcf00002bae270000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x00005a00008b0000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x31000042168d0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae4dULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
+ { 0x4040404040404040ULL, 0x4040404040404040ULL, }, /* 80 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4040404040404040ULL, 0x4040404040404040ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4040404040404040ULL, 0x4040404040404040ULL, }, /* 88 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x4040404040404040ULL, 0x4040404040404040ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8080808080808080ULL, 0x8080808080808080ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 96 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 104 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
};
reset_msa_registers();
{ 0x0000000000000000ULL, 0x0000000000000000ULL, },
{ 0xac5aaeaab9cf8b80ULL, 0xac5aaeaab9cf8b80ULL, },
{ 0x0000000000000000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 80 */
- { 0x00000000fc000000ULL, 0x000015000000001aULL, },
- { 0x0000000014000000ULL, 0x0000ab00000000ffULL, },
- { 0x00000000a0000000ULL, 0x0000a900000000d8ULL, },
- { 0x000040000000000cULL, 0x9300003f00120000ULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000800000000014ULL, 0x9300003f00120000ULL, },
- { 0x00004e00000000a0ULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0x8800000000fee6aaULL, }, /* 88 */
- { 0x0000000000000000ULL, 0xfb000000001500aaULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x0000000000000000ULL, 0x7000000000a916aaULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 96 */
- { 0x00000800000000fcULL, 0x6200007be64b0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeccULL, },
- { 0x00006a0000550000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae63ULL, },
- { 0x0000be0000c70000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 104 */
- { 0x00000800000000fcULL, 0xcf00002bae270000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x00005a00008b0000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x31000042168d0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae4dULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
+ { 0x886ae6cc28625540ULL, 0x886ae6cc28625540ULL, }, /* 80 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0xac5aaeaab9cf8b80ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x886ae6cc28625540ULL, 0x886ae6cc28625540ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0xac5aaeaab9cf8b80ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x886ae6cc28625540ULL, 0x886ae6cc28625540ULL, }, /* 88 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0xac5aaeaab9cf8b80ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x886ae6cc28625540ULL, 0x886ae6cc28625540ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xac5aaeaab9cf8b80ULL, 0xac5aaeaab9cf8b80ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 96 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 104 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
};
reset_msa_registers();
{ 0x0000000000000000ULL, 0x0000000000000000ULL, },
{ 0x8b808b808b808b80ULL, 0x8b808b808b808b80ULL, },
{ 0x0000000000000000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 80 */
- { 0x00000000fc000000ULL, 0x000015000000001aULL, },
- { 0x0000000014000000ULL, 0x0000ab00000000ffULL, },
- { 0x00000000a0000000ULL, 0x0000a900000000d8ULL, },
- { 0x000040000000000cULL, 0x9300003f00120000ULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000800000000014ULL, 0x9300003f00120000ULL, },
- { 0x00004e00000000a0ULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0x8800000000fee6aaULL, }, /* 88 */
- { 0x0000000000000000ULL, 0xfb000000001500aaULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x0000000000000000ULL, 0x7000000000a916aaULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 96 */
- { 0x00000800000000fcULL, 0x6200007be64b0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeccULL, },
- { 0x00006a0000550000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae63ULL, },
- { 0x0000be0000c70000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 104 */
- { 0x00000800000000fcULL, 0xcf00002bae270000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x00005a00008b0000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x31000042168d0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae4dULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
+ { 0x5540554055405540ULL, 0x5540554055405540ULL, }, /* 80 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8b808b808b808b80ULL, 0x8b808b808b808b80ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5540554055405540ULL, 0x5540554055405540ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8b808b808b808b80ULL, 0x8b808b808b808b80ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5540554055405540ULL, 0x5540554055405540ULL, }, /* 88 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8b808b808b808b80ULL, 0x8b808b808b808b80ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x5540554055405540ULL, 0x5540554055405540ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x8b808b808b808b80ULL, 0x8b808b808b808b80ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 96 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 104 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
};
reset_msa_registers();
{ 0x0000000000000000ULL, 0x0000000000000000ULL, },
{ 0xb9cf8b80b9cf8b80ULL, 0xb9cf8b80b9cf8b80ULL, },
{ 0x0000000000000000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 80 */
- { 0x00000000fc000000ULL, 0x000015000000001aULL, },
- { 0x0000000014000000ULL, 0x0000ab00000000ffULL, },
- { 0x00000000a0000000ULL, 0x0000a900000000d8ULL, },
- { 0x000040000000000cULL, 0x9300003f00120000ULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000800000000014ULL, 0x9300003f00120000ULL, },
- { 0x00004e00000000a0ULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0x8800000000fee6aaULL, }, /* 88 */
- { 0x0000000000000000ULL, 0xfb000000001500aaULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x0000000000000000ULL, 0x7000000000a916aaULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 96 */
- { 0x00000800000000fcULL, 0x6200007be64b0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeccULL, },
- { 0x00006a0000550000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x9300003f00120000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae63ULL, },
- { 0x0000be0000c70000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, }, /* 104 */
- { 0x00000800000000fcULL, 0xcf00002bae270000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abaeaaULL, },
- { 0x00005a00008b0000ULL, 0x0000000000000000ULL, },
- { 0x000000000c000000ULL, 0x0000fe000000005eULL, },
- { 0x00000800000000fcULL, 0x31000042168d0000ULL, },
- { 0x0000000000000000ULL, 0xac00000000abae4dULL, },
- { 0x00004f0000e20000ULL, 0x0000000000000000ULL, },
+ { 0x2862554028625540ULL, 0x2862554028625540ULL, }, /* 80 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xb9cf8b80b9cf8b80ULL, 0xb9cf8b80b9cf8b80ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x2862554028625540ULL, 0x2862554028625540ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xb9cf8b80b9cf8b80ULL, 0xb9cf8b80b9cf8b80ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x2862554028625540ULL, 0x2862554028625540ULL, }, /* 88 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xb9cf8b80b9cf8b80ULL, 0xb9cf8b80b9cf8b80ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x2862554028625540ULL, 0x2862554028625540ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0xb9cf8b80b9cf8b80ULL, 0xb9cf8b80b9cf8b80ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 96 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, }, /* 104 */
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
+ { 0x0000000000000000ULL, 0x0000000000000000ULL, },
};
reset_msa_registers();
+++ /dev/null
-
-#
-# Bit Count
-# ---------
-#
-/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nloc_b
-/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nloc_h
-/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nloc_w
-/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nloc_d
-/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nlzc_b
-/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nlzc_h
-/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nlzc_w
-/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nlzc_d
-/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pcnt_b
-/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pcnt_h
-/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pcnt_w
-/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pcnt_d
-
-#
-# Bit move
-# --------
-#
-
-#
-# Bit Set
-# -------
-#
-/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bclr_b
-/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bclr_h
-/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bclr_w
-/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bclr_d
-/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bneg_b
-/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bneg_h
-/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bneg_w
-/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bneg_d
-/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bset_b
-/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bset_h
-/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bset_w
-/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bset_d
-
-#
-# Fixed Multiply
-# --------------
-#
-/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mul_q_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mul_q_h
-/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mul_q_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mul_q_w
-/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mulr_q_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulr_q_h
-/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mulr_q_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulr_q_w
-
-#
-# Float Max Min
-# -------------
-#
-/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_a_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmax_a_w
-/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_a_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmax_a_d
-/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmax_w
-/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmax_d
-/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_a_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmin_a_w
-/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_a_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmin_a_d
-/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmin_w
-/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmin_d
-
-#
-# Int Add
-# -------
-#
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_add_a_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_add_a_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_add_a_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_add_a_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_a_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_a_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_a_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_a_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_s_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_u_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_u_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_addv_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_addv_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_addv_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_addv_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_u_d
-
-#
-# Int Average
-# -----------
-#
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_s_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_u_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_u_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_s_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_u_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_u_d
-
-#
-# Int Compare
-# -----------
-#
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ceq_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ceq_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ceq_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ceq_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_s_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_u_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_u_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_s_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_u_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_u_d
-
-#
-# Int Divide
-# ----------
-#
-/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_s_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_u_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_u_d
-
-#
-# Int Dot Product
-# ---------------
-#
-/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_u_d
-
-#
-# Int Max Min
-# -----------
-#
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_a_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_a_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_a_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_a_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_s_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_u_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_u_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_a_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_a_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_a_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_a_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_s_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_u_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_u_d
-
-#
-# Int Modulo
-# ----------
-#
-/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_s_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_u_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_u_d
-
-#
-# Int Multiply
-# ------------
-#
-/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulv_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulv_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulv_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulv_d
-
-#
-# Int Subtract
-# ------------
-#
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_s_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_u_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_u_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_u_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_s_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_u_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_u_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsuu_s_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsuu_s_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsuu_s_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsuu_s_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsus_u_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsus_u_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsus_u_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsus_u_d
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subv_b
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subv_h
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subv_w
-/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subv_d
-
-#
-# Interleave
-# ----------
-#
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvev_b
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvev_h
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvev_w
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvev_d
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvod_b
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvod_h
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvod_w
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvod_d
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvl_b
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvl_h
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvl_w
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvl_d
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvr_b
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvr_h
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvr_w
-/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvr_d
-
-#
-# Logic
-# -----
-#
-/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_and_v.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_and_v
-/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_nor_v.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nor_v
-/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_or_v.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_or_v
-/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_xor_v.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_xor_v
-
-#
-# Pack
-# ----
-#
-/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckev_b
-/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckev_h
-/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckev_w
-/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckev_d
-/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckod_b
-/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckod_h
-/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckod_w
-/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckod_d
-/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_vshf_b
-/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_vshf_h
-/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_vshf_w
-/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_vshf_d
-
-#
-# Shift
-# -----
-#
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sll_b
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sll_h
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sll_w
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sll_d
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sra_b
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sra_h
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sra_w
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sra_d
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srar_b
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srar_h
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srar_w
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srar_d
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srl_b
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srl_h
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srl_w
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srl_d
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_b.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srlr_b
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_h.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srlr_h
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_w.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srlr_w
-/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_d.c \
--EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srlr_d
--- /dev/null
+
+#
+# Bit Count
+# ---------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nloc_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nloc_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nloc_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nloc_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nlzc_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nlzc_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nlzc_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nlzc_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pcnt_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pcnt_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pcnt_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pcnt_d_32r6eb
+
+#
+# Bit move
+# --------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsl_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsl_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsl_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsl_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsr_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsr_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsr_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsr_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_bmnz_v.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bmnz_v_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_bmz_v.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bmz_v_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_bsel_v.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bsel_v_32r6eb
+
+#
+# Bit Set
+# -------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bclr_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bclr_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bclr_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bclr_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bneg_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bneg_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bneg_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bneg_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bset_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bset_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bset_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bset_d_32r6eb
+
+#
+# Fixed Multiply
+# --------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_madd_q_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_madd_q_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_madd_q_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_madd_q_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_maddr_q_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_maddr_q_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_maddr_q_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_maddr_q_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msub_q_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msub_q_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msub_q_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msub_q_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msubr_q_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msubr_q_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msubr_q_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msubr_q_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mul_q_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mul_q_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mul_q_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mul_q_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mulr_q_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mulr_q_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mulr_q_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mulr_q_w_32r6eb
+
+#
+# Float Max Min
+# -------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_a_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmax_a_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_a_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmax_a_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmax_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmax_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_a_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmin_a_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_a_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmin_a_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmin_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmin_d_32r6eb
+
+#
+# Int Add
+# -------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_add_a_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_add_a_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_add_a_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_add_a_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_a_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_a_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_a_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_a_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_s_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_u_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_u_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_addv_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_addv_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_addv_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_addv_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hadd_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hadd_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hadd_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hadd_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hadd_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hadd_u_d_32r6eb
+
+#
+# Int Average
+# -----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_s_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_u_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_u_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_s_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_u_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_u_d_32r6eb
+
+#
+# Int Compare
+# -----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ceq_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ceq_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ceq_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ceq_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_s_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_u_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_u_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_s_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_u_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_u_d_32r6eb
+
+#
+# Int Divide
+# ----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_s_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_u_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_u_d_32r6eb
+
+#
+# Int Dot Product
+# ---------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dotp_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dotp_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dotp_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dotp_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dotp_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dotp_u_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpadd_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpadd_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpadd_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpadd_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpadd_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpadd_u_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpsub_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpsub_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpsub_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpsub_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpsub_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpsub_u_d_32r6eb
+
+#
+# Int Max Min
+# -----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_a_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_a_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_a_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_a_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_s_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_u_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_u_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_a_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_a_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_a_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_a_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_s_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_u_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_u_d_32r6eb
+
+#
+# Int Modulo
+# ----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_s_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_u_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_u_d_32r6eb
+
+#
+# Int Multiply
+# ------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_maddv_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_maddv_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_maddv_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_maddv_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msubv_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msubv_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msubv_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msubv_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mulv_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mulv_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mulv_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mulv_d_32r6eb
+
+#
+# Int Subtract
+# ------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_s_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_u_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_u_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hsub_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hsub_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hsub_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hsub_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hsub_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hsub_u_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_s_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_u_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_u_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsus_u_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsus_u_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsus_u_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsus_u_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsuu_s_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsuu_s_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsuu_s_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsuu_s_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subv_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subv_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subv_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subv_d_32r6eb
+
+#
+# Interleave
+# ----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvev_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvev_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvev_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvev_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvod_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvod_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvod_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvod_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvl_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvl_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvl_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvl_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvr_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvr_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvr_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvr_d_32r6eb
+
+#
+# Logic
+# -----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_and_v.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_and_v_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_nor_v.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nor_v_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_or_v.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_or_v_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_xor_v.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_xor_v_32r6eb
+
+#
+# Move
+# ----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc move/test_msa_move_v.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_move_v_32r6eb
+
+#
+# Pack
+# ----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckev_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckev_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckev_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckev_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckod_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckod_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckod_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckod_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_vshf_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_vshf_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_vshf_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_vshf_d_32r6eb
+
+#
+# Shift
+# -----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sll_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sll_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sll_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sll_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sra_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sra_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sra_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sra_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srar_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srar_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srar_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srar_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srl_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srl_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srl_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srl_d_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_b.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srlr_b_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_h.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srlr_h_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_w.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srlr_w_32r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_d.c \
+-EB -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srlr_d_32r6eb
--- /dev/null
+
+#
+# Bit Count
+# ---------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nloc_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nloc_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nloc_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nloc_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nlzc_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nlzc_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nlzc_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nlzc_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pcnt_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pcnt_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pcnt_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pcnt_d_32r6el
+
+#
+# Bit move
+# --------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsl_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsl_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsl_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsl_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsr_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsr_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsr_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_binsr_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_bmnz_v.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bmnz_v_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_bmz_v.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bmz_v_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_bsel_v.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bsel_v_32r6el
+
+#
+# Bit Set
+# -------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bclr_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bclr_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bclr_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bclr_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bneg_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bneg_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bneg_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bneg_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bset_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bset_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bset_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_bset_d_32r6el
+
+#
+# Fixed Multiply
+# --------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_madd_q_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_madd_q_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_madd_q_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_madd_q_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_maddr_q_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_maddr_q_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_maddr_q_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_maddr_q_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msub_q_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msub_q_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msub_q_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msub_q_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msubr_q_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msubr_q_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msubr_q_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msubr_q_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mul_q_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mul_q_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mul_q_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mul_q_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mulr_q_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mulr_q_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mulr_q_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mulr_q_w_32r6el
+
+#
+# Float Max Min
+# -------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_a_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmax_a_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_a_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmax_a_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmax_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmax_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_a_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmin_a_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_a_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmin_a_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmin_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_fmin_d_32r6el
+
+#
+# Int Add
+# -------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_add_a_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_add_a_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_add_a_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_add_a_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_a_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_a_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_a_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_a_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_s_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_u_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_adds_u_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_addv_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_addv_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_addv_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_addv_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hadd_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hadd_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hadd_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hadd_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hadd_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hadd_u_d_32r6el
+
+#
+# Int Average
+# -----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_s_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_u_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ave_u_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_s_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_u_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_aver_u_d_32r6el
+
+#
+# Int Compare
+# -----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ceq_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ceq_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ceq_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ceq_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_s_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_u_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_cle_u_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_s_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_u_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_clt_u_d_32r6el
+
+#
+# Int Divide
+# ----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_s_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_u_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_div_u_d_32r6el
+
+#
+# Int Dot Product
+# ---------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dotp_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dotp_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dotp_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dotp_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dotp_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dotp_u_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpadd_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpadd_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpadd_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpadd_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpadd_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpadd_u_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpsub_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpsub_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpsub_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpsub_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpsub_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_dpsub_u_d_32r6el
+
+#
+# Int Max Min
+# -----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_a_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_a_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_a_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_a_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_s_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_u_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_max_u_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_a_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_a_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_a_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_a_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_s_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_u_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_min_u_d_32r6el
+
+#
+# Int Modulo
+# ----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_s_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_u_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mod_u_d_32r6el
+
+#
+# Int Multiply
+# ------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_maddv_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_maddv_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_maddv_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_maddv_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msubv_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msubv_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msubv_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_msubv_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mulv_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mulv_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mulv_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_mulv_d_32r6el
+
+#
+# Int Subtract
+# ------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_s_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_u_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_asub_u_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hsub_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hsub_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hsub_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hsub_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hsub_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_hsub_u_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_s_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_u_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subs_u_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsus_u_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsus_u_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsus_u_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsus_u_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsuu_s_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsuu_s_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsuu_s_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subsuu_s_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subv_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subv_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subv_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_subv_d_32r6el
+
+#
+# Interleave
+# ----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvev_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvev_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvev_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvev_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvod_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvod_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvod_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvod_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvl_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvl_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvl_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvl_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvr_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvr_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvr_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_ilvr_d_32r6el
+
+#
+# Logic
+# -----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_and_v.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_and_v_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_nor_v.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_nor_v_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_or_v.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_or_v_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_xor_v.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_xor_v_32r6el
+
+#
+# Move
+# ----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc move/test_msa_move_v.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_move_v_32r6el
+
+#
+# Pack
+# ----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckev_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckev_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckev_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckev_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckod_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckod_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckod_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_pckod_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_vshf_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_vshf_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_vshf_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_vshf_d_32r6el
+
+#
+# Shift
+# -----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sll_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sll_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sll_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sll_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sra_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sra_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sra_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_sra_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srar_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srar_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srar_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srar_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srl_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srl_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srl_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srl_d_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_b.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srlr_b_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_h.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srlr_h_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_w.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srlr_w_32r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_d.c \
+-EL -static -mabi=32 -march=mips32r6 -mmsa -o /tmp/test_msa_srlr_d_32r6el
--- /dev/null
+
+#
+# Bit Count
+# ---------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nloc_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nloc_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nloc_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nloc_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nlzc_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nlzc_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nlzc_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nlzc_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pcnt_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pcnt_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pcnt_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pcnt_d_64r6eb
+
+#
+# Bit move
+# --------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsl_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsl_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsl_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsl_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsr_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsr_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsr_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsr_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_bmnz_v.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bmnz_v_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_bmz_v.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bmz_v_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_bsel_v.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bsel_v_64r6eb
+
+#
+# Bit Set
+# -------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bclr_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bclr_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bclr_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bclr_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bneg_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bneg_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bneg_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bneg_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bset_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bset_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bset_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bset_d_64r6eb
+
+#
+# Fixed Multiply
+# --------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_madd_q_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_madd_q_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_madd_q_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_madd_q_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_maddr_q_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_maddr_q_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_maddr_q_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_maddr_q_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msub_q_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msub_q_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msub_q_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msub_q_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msubr_q_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msubr_q_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msubr_q_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msubr_q_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mul_q_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mul_q_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mul_q_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mul_q_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mulr_q_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulr_q_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mulr_q_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulr_q_w_64r6eb
+
+#
+# Float Max Min
+# -------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_a_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmax_a_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_a_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmax_a_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmax_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmax_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_a_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmin_a_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_a_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmin_a_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmin_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmin_d_64r6eb
+
+#
+# Int Add
+# -------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_add_a_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_add_a_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_add_a_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_add_a_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_a_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_a_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_a_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_a_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_s_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_u_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_u_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_addv_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_addv_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_addv_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_addv_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_u_d_64r6eb
+
+#
+# Int Average
+# -----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_s_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_u_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_u_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_s_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_u_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_u_d_64r6eb
+
+#
+# Int Compare
+# -----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ceq_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ceq_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ceq_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ceq_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_s_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_u_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_u_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_s_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_u_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_u_d_64r6eb
+
+#
+# Int Divide
+# ----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_s_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_u_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_u_d_64r6eb
+
+#
+# Int Dot Product
+# ---------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_u_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpadd_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpadd_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpadd_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpadd_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpadd_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpadd_u_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpsub_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpsub_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpsub_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpsub_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpsub_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpsub_u_d_64r6eb
+
+#
+# Int Max Min
+# -----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_a_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_a_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_a_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_a_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_s_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_u_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_u_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_a_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_a_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_a_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_a_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_s_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_u_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_u_d_64r6eb
+
+#
+# Int Modulo
+# ----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_s_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_u_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_u_d_64r6eb
+
+#
+# Int Multiply
+# ------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_maddv_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_maddv_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_maddv_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_maddv_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msubv_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msubv_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msubv_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msubv_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulv_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulv_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulv_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulv_d_64r6eb
+
+#
+# Int Subtract
+# ------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_s_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_u_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_u_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_u_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_s_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_u_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_u_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsus_u_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsus_u_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsus_u_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsus_u_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsuu_s_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsuu_s_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsuu_s_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsuu_s_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subv_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subv_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subv_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subv_d_64r6eb
+
+#
+# Interleave
+# ----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvev_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvev_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvev_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvev_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvod_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvod_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvod_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvod_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvl_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvl_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvl_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvl_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvr_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvr_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvr_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvr_d_64r6eb
+
+#
+# Logic
+# -----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_and_v.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_and_v_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_nor_v.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nor_v_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_or_v.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_or_v_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_xor_v.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_xor_v_64r6eb
+
+#
+# Move
+# ----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc move/test_msa_move_v.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_move_v_64r6eb
+
+#
+# Pack
+# ----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckev_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckev_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckev_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckev_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckod_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckod_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckod_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckod_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_vshf_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_vshf_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_vshf_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_vshf_d_64r6eb
+
+#
+# Shift
+# -----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sll_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sll_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sll_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sll_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sra_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sra_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sra_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sra_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srar_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srar_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srar_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srar_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srl_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srl_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srl_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srl_d_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_b.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srlr_b_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_h.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srlr_h_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_w.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srlr_w_64r6eb
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_d.c \
+-EB -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srlr_d_64r6eb
--- /dev/null
+
+#
+# Bit Count
+# ---------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nloc_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nloc_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nloc_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nloc_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nloc_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nlzc_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nlzc_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nlzc_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_nlzc_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nlzc_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pcnt_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pcnt_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pcnt_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-count/test_msa_pcnt_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pcnt_d_64r6el
+
+#
+# Bit move
+# --------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsl_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsl_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsl_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsl_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsl_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsr_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsr_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsr_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_binsr_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_binsr_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_bmnz_v.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bmnz_v_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_bmz_v.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bmz_v_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-move/test_msa_bsel_v.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bsel_v_64r6el
+
+#
+# Bit Set
+# -------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bclr_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bclr_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bclr_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bclr_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bclr_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bneg_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bneg_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bneg_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bneg_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bneg_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bset_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bset_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bset_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc bit-set/test_msa_bset_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_bset_d_64r6el
+
+#
+# Fixed Multiply
+# --------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_madd_q_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_madd_q_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_madd_q_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_madd_q_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_maddr_q_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_maddr_q_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_maddr_q_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_maddr_q_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msub_q_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msub_q_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msub_q_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msub_q_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msubr_q_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msubr_q_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_msubr_q_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msubr_q_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mul_q_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mul_q_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mul_q_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mul_q_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mulr_q_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulr_q_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc fixed-multiply/test_msa_mulr_q_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulr_q_w_64r6el
+
+#
+# Float Max Min
+# -------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_a_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmax_a_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_a_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmax_a_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmax_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmax_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmax_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_a_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmin_a_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_a_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmin_a_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmin_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc float-max-min/test_msa_fmin_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_fmin_d_64r6el
+
+#
+# Int Add
+# -------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_add_a_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_add_a_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_add_a_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_add_a_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_add_a_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_a_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_a_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_a_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_a_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_a_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_s_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_u_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_adds_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_adds_u_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_addv_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_addv_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_addv_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_addv_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_addv_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-add/test_msa_hadd_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hadd_u_d_64r6el
+
+#
+# Int Average
+# -----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_s_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_u_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_ave_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ave_u_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_s_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_u_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-average/test_msa_aver_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_aver_u_d_64r6el
+
+#
+# Int Compare
+# -----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ceq_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ceq_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ceq_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_ceq_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ceq_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_s_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_u_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_cle_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_cle_u_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_s_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_u_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-compare/test_msa_clt_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_clt_u_d_64r6el
+
+#
+# Int Divide
+# ----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_s_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_u_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-divide/test_msa_div_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_div_u_d_64r6el
+
+#
+# Int Dot Product
+# ---------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dotp_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dotp_u_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpadd_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpadd_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpadd_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpadd_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpadd_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpadd_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpadd_u_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpsub_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpsub_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpsub_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpsub_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpsub_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-dot-product/test_msa_dpsub_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_dpsub_u_d_64r6el
+
+#
+# Int Max Min
+# -----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_a_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_a_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_a_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_a_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_a_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_s_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_u_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_max_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_max_u_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_a_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_a_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_a_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_a_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_a_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_s_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_u_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-max-min/test_msa_min_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_min_u_d_64r6el
+
+#
+# Int Modulo
+# ----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_s_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_u_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-modulo/test_msa_mod_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mod_u_d_64r6el
+
+#
+# Int Multiply
+# ------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_maddv_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_maddv_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_maddv_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_maddv_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_maddv_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msubv_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msubv_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msubv_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_msubv_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_msubv_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulv_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulv_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulv_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-multiply/test_msa_mulv_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_mulv_d_64r6el
+
+#
+# Int Subtract
+# ------------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_s_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_u_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_asub_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_asub_u_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_hsub_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_hsub_u_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_s_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_u_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subs_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subs_u_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsus_u_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsus_u_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsus_u_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsus_u_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsus_u_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsuu_s_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsuu_s_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsuu_s_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subsuu_s_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subsuu_s_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subv_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subv_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subv_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc int-subtract/test_msa_subv_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_subv_d_64r6el
+
+#
+# Interleave
+# ----------
+#
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvev_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvev_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvev_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvev_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvev_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvod_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvod_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvod_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvod_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvod_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvl_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvl_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvl_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvl_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvl_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvr_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvr_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvr_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc interleave/test_msa_ilvr_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_ilvr_d_64r6el
+
+#
+# Logic
+# -----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_and_v.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_and_v_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_nor_v.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_nor_v_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_or_v.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_or_v_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc logic/test_msa_xor_v.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_xor_v_64r6el
+
+#
+# Move
+# ----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc move/test_msa_move_v.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_move_v_64r6el
+
+#
+# Pack
+# ----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckev_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckev_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckev_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckev_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckev_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckod_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckod_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckod_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_pckod_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_pckod_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_vshf_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_vshf_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_vshf_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc pack/test_msa_vshf_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_vshf_d_64r6el
+
+#
+# Shift
+# -----
+#
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sll_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sll_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sll_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sll_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sll_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sra_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sra_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sra_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_sra_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_sra_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srar_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srar_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srar_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srar_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srar_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srl_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srl_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srl_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srl_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srl_d_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_b.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srlr_b_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_h.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srlr_h_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_w.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srlr_w_64r6el
+/opt/img/bin/mips-img-linux-gnu-gcc shift/test_msa_srlr_d.c \
+-EL -static -mabi=64 -march=mips64r6 -mmsa -o /tmp/test_msa_srlr_d_64r6el
+++ /dev/null
-PATH_TO_QEMU="../../../../../../mips64el-linux-user/qemu-mips64el"
-
-
-#
-# Bit Count
-# ---------
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_d
-
-#
-# Bit move
-# --------
-#
-
-#
-# Bit Set
-# -------
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_d
-
-#
-# Fixed Multiply
-# --------------
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mul_q_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mul_q_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulr_q_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulr_q_w
-
-#
-# Float Max Min
-# -------------
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_a_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_a_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_a_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_a_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_d
-
-#
-# Int Add
-# -------
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_d
-
-#
-# Int Average
-# -----------
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_d
-
-#
-# Int Compare
-# -----------
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_d
-
-#
-# Int Divide
-# ----------
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_d
-
-#
-# Int Dot Product
-# ---------------
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_d
-
-#
-# Int Max Min
-# -----------
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_d
-
-#
-# Int Modulo
-# ----------
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_d
-
-#
-# Int Multiply
-# ------------
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_d
-
-#
-# Int Subtract
-# ------------
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_d
-
-#
-# Interleave
-# ----------
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_d
-
-#
-# Logic
-# -----
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_and_v
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nor_v
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_or_v
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_xor_v
-
-#
-# Pack
-# ----
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_d
-
-#
-# Shift
-# -----
-#
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_d
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_b
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_h
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_w
-$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_d
--- /dev/null
+PATH_TO_QEMU="../../../../../../mips64-linux-user/qemu-mips64"
+
+
+#
+# Bit Count
+# ---------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_d_32r6eb
+
+#
+# Bit move
+# --------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bmnz_v_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bmz_v_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bsel_v_32r6eb
+
+#
+# Bit Set
+# -------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_d_32r6eb
+
+#
+# Fixed Multiply
+# --------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_madd_q_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_madd_q_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddr_q_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddr_q_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msub_q_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msub_q_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubr_q_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubr_q_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mul_q_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mul_q_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulr_q_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulr_q_w_32r6eb
+
+#
+# Float Max Min
+# -------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_a_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_a_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_a_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_a_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_d_32r6eb
+
+#
+# Int Add
+# -------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_d_32r6eb
+
+#
+# Int Average
+# -----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_d_32r6eb
+
+#
+# Int Compare
+# -----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_d_32r6eb
+
+#
+# Int Divide
+# ----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_d_32r6eb
+
+#
+# Int Dot Product
+# ---------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_u_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_u_d_32r6eb
+
+#
+# Int Max Min
+# -----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_d_32r6eb
+
+#
+# Int Modulo
+# ----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_d_32r6eb
+
+#
+# Int Multiply
+# ------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_d_32r6eb
+
+#
+# Int Subtract
+# ------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_d_32r6eb
+
+#
+# Interleave
+# ----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_d_32r6eb
+
+#
+# Logic
+# -----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_and_v_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nor_v_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_or_v_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_xor_v_32r6eb
+
+#
+# Move
+# ----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_move_v_32r6eb
+
+#
+# Pack
+# ----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_d_32r6eb
+
+#
+# Shift
+# -----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_d_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_b_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_h_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_w_32r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_d_32r6eb
--- /dev/null
+PATH_TO_QEMU="../../../../../../mips64el-linux-user/qemu-mips64el"
+
+
+#
+# Bit Count
+# ---------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_d_32r6el
+
+#
+# Bit move
+# --------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bmnz_v_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bmz_v_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bsel_v_32r6el
+
+#
+# Bit Set
+# -------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_d_32r6el
+
+#
+# Fixed Multiply
+# --------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_madd_q_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_madd_q_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddr_q_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddr_q_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msub_q_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msub_q_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubr_q_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubr_q_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mul_q_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mul_q_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulr_q_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulr_q_w_32r6el
+
+#
+# Float Max Min
+# -------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_a_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_a_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_a_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_a_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_d_32r6el
+
+#
+# Int Add
+# -------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_d_32r6el
+
+#
+# Int Average
+# -----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_d_32r6el
+
+#
+# Int Compare
+# -----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_d_32r6el
+
+#
+# Int Divide
+# ----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_d_32r6el
+
+#
+# Int Dot Product
+# ---------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_u_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_u_d_32r6el
+
+#
+# Int Max Min
+# -----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_d_32r6el
+
+#
+# Int Modulo
+# ----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_d_32r6el
+
+#
+# Int Multiply
+# ------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_d_32r6el
+
+#
+# Int Subtract
+# ------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_d_32r6el
+
+#
+# Interleave
+# ----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_d_32r6el
+
+#
+# Logic
+# -----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_and_v_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nor_v_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_or_v_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_xor_v_32r6el
+
+#
+# Move
+# ----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_move_v_32r6el
+
+#
+# Pack
+# ----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_d_32r6el
+
+#
+# Shift
+# -----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_d_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_b_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_h_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_w_32r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_d_32r6el
--- /dev/null
+PATH_TO_QEMU="../../../../../../mips64-linux-user/qemu-mips64"
+
+
+#
+# Bit Count
+# ---------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_d_64r6eb
+
+#
+# Bit move
+# --------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bmnz_v_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bmz_v_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bsel_v_64r6eb
+
+#
+# Bit Set
+# -------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_d_64r6eb
+
+#
+# Fixed Multiply
+# --------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_madd_q_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_madd_q_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddr_q_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddr_q_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msub_q_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msub_q_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubr_q_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubr_q_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mul_q_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mul_q_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulr_q_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulr_q_w_64r6eb
+
+#
+# Float Max Min
+# -------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_a_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_a_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_a_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_a_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_d_64r6eb
+
+#
+# Int Add
+# -------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_d_64r6eb
+
+#
+# Int Average
+# -----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_d_64r6eb
+
+#
+# Int Compare
+# -----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_d_64r6eb
+
+#
+# Int Divide
+# ----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_d_64r6eb
+
+#
+# Int Dot Product
+# ---------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_u_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_u_d_64r6eb
+
+#
+# Int Max Min
+# -----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_d_64r6eb
+
+#
+# Int Modulo
+# ----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_d_64r6eb
+
+#
+# Int Multiply
+# ------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_d_64r6eb
+
+#
+# Int Subtract
+# ------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_d_64r6eb
+
+#
+# Interleave
+# ----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_d_64r6eb
+
+#
+# Logic
+# -----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_and_v_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nor_v_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_or_v_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_xor_v_64r6eb
+
+#
+# Move
+# ----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_move_v_64r6eb
+
+#
+# Pack
+# ----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_d_64r6eb
+
+#
+# Shift
+# -----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_d_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_b_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_h_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_w_64r6eb
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_d_64r6eb
--- /dev/null
+PATH_TO_QEMU="../../../../../../mips64el-linux-user/qemu-mips64el"
+
+
+#
+# Bit Count
+# ---------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nloc_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nlzc_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pcnt_d_64r6el
+
+#
+# Bit move
+# --------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsl_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_binsr_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bmnz_v_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bmz_v_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bsel_v_64r6el
+
+#
+# Bit Set
+# -------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bclr_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bneg_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_bset_d_64r6el
+
+#
+# Fixed Multiply
+# --------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_madd_q_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_madd_q_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddr_q_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddr_q_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msub_q_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msub_q_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubr_q_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubr_q_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mul_q_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mul_q_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulr_q_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulr_q_w_64r6el
+
+#
+# Float Max Min
+# -------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_a_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_a_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmax_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_a_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_a_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_fmin_d_64r6el
+
+#
+# Int Add
+# -------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_add_a_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_a_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_adds_u_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_addv_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hadd_u_d_64r6el
+
+#
+# Int Average
+# -----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ave_u_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_aver_u_d_64r6el
+
+#
+# Int Compare
+# -----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ceq_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_cle_u_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_clt_u_d_64r6el
+
+#
+# Int Divide
+# ----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_div_u_d_64r6el
+
+#
+# Int Dot Product
+# ---------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dotp_u_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpadd_u_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_dpsub_u_d_64r6el
+
+#
+# Int Max Min
+# -----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_a_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_max_u_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_a_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_min_u_d_64r6el
+
+#
+# Int Modulo
+# ----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mod_u_d_64r6el
+
+#
+# Int Multiply
+# ------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_maddv_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_msubv_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_mulv_d_64r6el
+
+#
+# Int Subtract
+# ------------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_asub_u_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_hsub_u_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subs_u_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsus_u_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subsuu_s_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_subv_d_64r6el
+
+#
+# Interleave
+# ----------
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvev_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvod_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvl_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_ilvr_d_64r6el
+
+#
+# Logic
+# -----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_and_v_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_nor_v_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_or_v_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_xor_v_64r6el
+
+#
+# Move
+# ----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_move_v_64r6el
+
+#
+# Pack
+# ----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckev_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_pckod_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_vshf_d_64r6el
+
+#
+# Shift
+# -----
+#
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sll_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_sra_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srar_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srl_d_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_b_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_h_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_w_64r6el
+$PATH_TO_QEMU -cpu I6400 /tmp/test_msa_srlr_d_64r6el
int main(void)
{
- uint64_t parmlist[] = {
+ uint64_t parmlist[] __attribute__((aligned(16))) = {
0xfedcba9876543210ull,
0,
0x7777777777777777ull,
QDict *rsp;
int ret;
uint16_t *proto = (uint16_t *)&buffer[12];
+ size_t total_received = 0;
+ uint64_t start, now, last_rxt, deadline;
+ /* Send a set of packets over a few second period */
rsp = qmp("{ 'execute' : 'announce-self', "
" 'arguments': {"
- " 'initial': 50, 'max': 550,"
- " 'rounds': 10, 'step': 50 } }");
+ " 'initial': 20, 'max': 100,"
+ " 'rounds': 300, 'step': 10, 'id': 'bob' } }");
assert(!qdict_haskey(rsp, "error"));
qobject_unref(rsp);
- /* Catch the packet and make sure it's a RARP */
+ /* Catch the first packet and make sure it's a RARP */
ret = qemu_recv(sv[0], &len, sizeof(len), 0);
g_assert_cmpint(ret, ==, sizeof(len));
len = ntohl(len);
ret = qemu_recv(sv[0], buffer, len, 0);
g_assert_cmpint(*proto, ==, htons(ETH_P_RARP));
+
+ /*
+ * Stop the announcment by settings rounds to 0 on the
+ * existing timer.
+ */
+ rsp = qmp("{ 'execute' : 'announce-self', "
+ " 'arguments': {"
+ " 'initial': 20, 'max': 100,"
+ " 'rounds': 0, 'step': 10, 'id': 'bob' } }");
+ assert(!qdict_haskey(rsp, "error"));
+ qobject_unref(rsp);
+
+ /* Now make sure the packets stop */
+
+ /* Times are in us */
+ start = g_get_monotonic_time();
+ /* 30 packets, max gap 100ms, * 4 for wiggle */
+ deadline = start + 1000 * (100 * 30 * 4);
+ last_rxt = start;
+
+ while (true) {
+ int saved_err;
+ ret = qemu_recv(sv[0], buffer, 60, MSG_DONTWAIT);
+ saved_err = errno;
+ now = g_get_monotonic_time();
+ g_assert_cmpint(now, <, deadline);
+
+ if (ret >= 0) {
+ if (ret) {
+ last_rxt = now;
+ }
+ total_received += ret;
+
+ /* Check it's not spewing loads */
+ g_assert_cmpint(total_received, <, 60 * 30 * 2);
+ } else {
+ g_assert_cmpint(saved_err, ==, EAGAIN);
+
+ /* 400ms, i.e. 4 worst case gaps */
+ if ((now - last_rxt) > (1000 * 100 * 4)) {
+ /* Nothings arrived for a while - must have stopped */
+ break;
+ };
+
+ /* 100ms */
+ g_usleep(1000 * 100);
+ }
+ };
}
static void virtio_net_test_cleanup(void *sockets)
import time
import datetime
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-from qemu import QEMUMachine, kvm_available
+from qemu import kvm_available
+from qemu.machine import QEMUMachine
import subprocess
import hashlib
import optparse
#include <dirent.h>
#include "qemu/cutils.h"
#include "qemu/path.h"
+#include "qemu/thread.h"
-struct pathelem
-{
- /* Name of this, eg. lib */
- char *name;
- /* Full path name, eg. /usr/gnemul/x86-linux/lib. */
- char *pathname;
- struct pathelem *parent;
- /* Children */
- unsigned int num_entries;
- struct pathelem *entries[0];
-};
-
-static struct pathelem *base;
-
-/* First N chars of S1 match S2, and S2 is N chars long. */
-static int strneq(const char *s1, unsigned int n, const char *s2)
-{
- unsigned int i;
-
- for (i = 0; i < n; i++)
- if (s1[i] != s2[i])
- return 0;
- return s2[i] == 0;
-}
-
-static struct pathelem *add_entry(struct pathelem *root, const char *name,
- unsigned type);
+static const char *base;
+static GHashTable *hash;
+static QemuMutex lock;
-static struct pathelem *new_entry(const char *root,
- struct pathelem *parent,
- const char *name)
-{
- struct pathelem *new = g_malloc(sizeof(*new));
- new->name = g_strdup(name);
- new->pathname = g_strdup_printf("%s/%s", root, name);
- new->num_entries = 0;
- return new;
-}
-
-#define streq(a,b) (strcmp((a), (b)) == 0)
-
-/* Not all systems provide this feature */
-#if defined(DT_DIR) && defined(DT_UNKNOWN) && defined(DT_LNK)
-# define dirent_type(dirent) ((dirent)->d_type)
-# define is_dir_maybe(type) \
- ((type) == DT_DIR || (type) == DT_UNKNOWN || (type) == DT_LNK)
-#else
-# define dirent_type(dirent) (1)
-# define is_dir_maybe(type) (type)
-#endif
-
-static struct pathelem *add_dir_maybe(struct pathelem *path)
+void init_paths(const char *prefix)
{
- DIR *dir;
-
- if ((dir = opendir(path->pathname)) != NULL) {
- struct dirent *dirent;
-
- while ((dirent = readdir(dir)) != NULL) {
- if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){
- path = add_entry(path, dirent->d_name, dirent_type(dirent));
- }
- }
- closedir(dir);
+ if (prefix[0] == '\0' || !strcmp(prefix, "/")) {
+ return;
}
- return path;
-}
-
-static struct pathelem *add_entry(struct pathelem *root, const char *name,
- unsigned type)
-{
- struct pathelem **e;
-
- root->num_entries++;
-
- root = g_realloc(root, sizeof(*root)
- + sizeof(root->entries[0])*root->num_entries);
- e = &root->entries[root->num_entries-1];
- *e = new_entry(root->pathname, root, name);
- if (is_dir_maybe(type)) {
- *e = add_dir_maybe(*e);
+ if (prefix[0] == '/') {
+ base = g_strdup(prefix);
+ } else {
+ char *cwd = g_get_current_dir();
+ base = g_build_filename(cwd, prefix, NULL);
+ g_free(cwd);
}
- return root;
-}
-
-/* This needs to be done after tree is stabilized (ie. no more reallocs!). */
-static void set_parents(struct pathelem *child, struct pathelem *parent)
-{
- unsigned int i;
-
- child->parent = parent;
- for (i = 0; i < child->num_entries; i++)
- set_parents(child->entries[i], child);
+ hash = g_hash_table_new(g_str_hash, g_str_equal);
+ qemu_mutex_init(&lock);
}
-/* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */
-static const char *
-follow_path(const struct pathelem *cursor, const char *name)
-{
- unsigned int i, namelen;
-
- name += strspn(name, "/");
- namelen = strcspn(name, "/");
-
- if (namelen == 0)
- return cursor->pathname;
-
- if (strneq(name, namelen, ".."))
- return follow_path(cursor->parent, name + namelen);
-
- if (strneq(name, namelen, "."))
- return follow_path(cursor, name + namelen);
-
- for (i = 0; i < cursor->num_entries; i++)
- if (strneq(name, namelen, cursor->entries[i]->name))
- return follow_path(cursor->entries[i], name + namelen);
-
- /* Not found */
- return NULL;
-}
-
-void init_paths(const char *prefix)
+/* Look for path in emulation dir, otherwise return name. */
+const char *path(const char *name)
{
- char pref_buf[PATH_MAX];
-
- if (prefix[0] == '\0' ||
- !strcmp(prefix, "/"))
- return;
+ gpointer key, value;
+ const char *ret;
- if (prefix[0] != '/') {
- char *cwd = getcwd(NULL, 0);
- size_t pref_buf_len = sizeof(pref_buf);
+ /* Only do absolute paths: quick and dirty, but should mostly be OK. */
+ if (!base || !name || name[0] != '/') {
+ return name;
+ }
- if (!cwd)
- abort();
- pstrcpy(pref_buf, sizeof(pref_buf), cwd);
- pstrcat(pref_buf, pref_buf_len, "/");
- pstrcat(pref_buf, pref_buf_len, prefix);
- free(cwd);
- } else
- pstrcpy(pref_buf, sizeof(pref_buf), prefix + 1);
+ qemu_mutex_lock(&lock);
- base = new_entry("", NULL, pref_buf);
- base = add_dir_maybe(base);
- if (base->num_entries == 0) {
- g_free(base->pathname);
- g_free(base->name);
- g_free(base);
- base = NULL;
+ /* Have we looked up this file before? */
+ if (g_hash_table_lookup_extended(hash, name, &key, &value)) {
+ ret = value ? value : name;
} else {
- set_parents(base, base);
+ char *save = g_strdup(name);
+ char *full = g_build_filename(base, name, NULL);
+
+ /* Look for the path; record the result, pass or fail. */
+ if (access(full, F_OK) == 0) {
+ /* Exists. */
+ g_hash_table_insert(hash, save, full);
+ ret = full;
+ } else {
+ /* Does not exist. */
+ g_free(full);
+ g_hash_table_insert(hash, save, NULL);
+ ret = name;
+ }
}
-}
-
-/* Look for path in emulation dir, otherwise return name. */
-const char *path(const char *name)
-{
- /* Only do absolute paths: quick and dirty, but should mostly be OK.
- Could do relative by tracking cwd. */
- if (!base || !name || name[0] != '/')
- return name;
- return follow_path(base, name) ?: name;
+ qemu_mutex_unlock(&lock);
+ return ret;
}
#include "qemu/error-report.h"
#include "qemu/sockets.h"
#include "hw/hw.h"
-#include "hw/boards.h"
#include "sysemu/accel.h"
#include "hw/usb.h"
#include "hw/isa/isa.h"
#include "qapi/qapi-visit-block-core.h"
#include "qapi/qapi-visit-ui.h"
#include "qapi/qapi-commands-block-core.h"
-#include "qapi/qapi-commands-misc.h"
#include "qapi/qapi-commands-run-state.h"
#include "qapi/qapi-commands-ui.h"
#include "qapi/qmp/qerror.h"
return NULL;
}
-MachineInfoList *qmp_query_machines(Error **errp)
-{
- GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
- MachineInfoList *mach_list = NULL;
-
- for (el = machines; el; el = el->next) {
- MachineClass *mc = el->data;
- MachineInfoList *entry;
- MachineInfo *info;
-
- info = g_malloc0(sizeof(*info));
- if (mc->is_default) {
- info->has_is_default = true;
- info->is_default = true;
- }
-
- if (mc->alias) {
- info->has_alias = true;
- info->alias = g_strdup(mc->alias);
- }
-
- info->name = g_strdup(mc->name);
- info->cpu_max = !mc->max_cpus ? 1 : mc->max_cpus;
- info->hotpluggable_cpus = mc->has_hotpluggable_cpus;
-
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = mach_list;
- mach_list = entry;
- }
-
- g_slist_free(machines);
- return mach_list;
-}
-
static int machine_help_func(QemuOpts *opts, MachineState *machine)
{
ObjectProperty *prop;
return wakeup_suspend_enabled;
}
-CurrentMachineParams *qmp_query_current_machine(Error **errp)
-{
- CurrentMachineParams *params = g_malloc0(sizeof(*params));
- params->wakeup_suspend_support = qemu_wakeup_suspend_enabled();
-
- return params;
-}
-
void qemu_system_killed(int signal, pid_t pid)
{
shutdown_signal = signal;
+++ /dev/null
-/*
- * Windows crashdump
- *
- * Copyright (c) 2018 Virtuozzo International GmbH
- *
- * 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-common.h"
-#include "qemu/cutils.h"
-#include "elf.h"
-#include "cpu.h"
-#include "exec/hwaddr.h"
-#include "monitor/monitor.h"
-#include "sysemu/kvm.h"
-#include "sysemu/dump.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/memory_mapping.h"
-#include "sysemu/cpus.h"
-#include "qapi/error.h"
-#include "qapi/qmp/qerror.h"
-#include "qemu/error-report.h"
-#include "hw/misc/vmcoreinfo.h"
-#include "win_dump.h"
-
-static size_t write_run(WinDumpPhyMemRun64 *run, int fd, Error **errp)
-{
- void *buf;
- uint64_t addr = run->BasePage << TARGET_PAGE_BITS;
- uint64_t size = run->PageCount << TARGET_PAGE_BITS;
- uint64_t len, l;
- size_t total = 0;
-
- while (size) {
- len = size;
-
- buf = cpu_physical_memory_map(addr, &len, false);
- if (!buf) {
- error_setg(errp, "win-dump: failed to map physical range"
- " 0x%016" PRIx64 "-0x%016" PRIx64, addr, addr + size - 1);
- return 0;
- }
-
- l = qemu_write_full(fd, buf, len);
- cpu_physical_memory_unmap(buf, addr, false, len);
- if (l != len) {
- error_setg(errp, QERR_IO_ERROR);
- return 0;
- }
-
- addr += l;
- size -= l;
- total += l;
- }
-
- return total;
-}
-
-static void write_runs(DumpState *s, WinDumpHeader64 *h, Error **errp)
-{
- WinDumpPhyMemDesc64 *desc = &h->PhysicalMemoryBlock;
- WinDumpPhyMemRun64 *run = desc->Run;
- Error *local_err = NULL;
- int i;
-
- for (i = 0; i < desc->NumberOfRuns; i++) {
- s->written_size += write_run(run + i, s->fd, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
- }
-}
-
-static void patch_mm_pfn_database(WinDumpHeader64 *h, Error **errp)
-{
- if (cpu_memory_rw_debug(first_cpu,
- h->KdDebuggerDataBlock + KDBG_MM_PFN_DATABASE_OFFSET64,
- (uint8_t *)&h->PfnDatabase, sizeof(h->PfnDatabase), 0)) {
- error_setg(errp, "win-dump: failed to read MmPfnDatabase");
- return;
- }
-}
-
-static void patch_bugcheck_data(WinDumpHeader64 *h, Error **errp)
-{
- uint64_t KiBugcheckData;
-
- if (cpu_memory_rw_debug(first_cpu,
- h->KdDebuggerDataBlock + KDBG_KI_BUGCHECK_DATA_OFFSET64,
- (uint8_t *)&KiBugcheckData, sizeof(KiBugcheckData), 0)) {
- error_setg(errp, "win-dump: failed to read KiBugcheckData");
- return;
- }
-
- if (cpu_memory_rw_debug(first_cpu,
- KiBugcheckData,
- h->BugcheckData, sizeof(h->BugcheckData), 0)) {
- error_setg(errp, "win-dump: failed to read bugcheck data");
- return;
- }
-
- /*
- * If BugcheckCode wasn't saved, we consider guest OS as alive.
- */
-
- if (!h->BugcheckCode) {
- h->BugcheckCode = LIVE_SYSTEM_DUMP;
- }
-}
-
-/*
- * This routine tries to correct mistakes in crashdump header.
- */
-static void patch_header(WinDumpHeader64 *h)
-{
- Error *local_err = NULL;
-
- h->RequiredDumpSpace = sizeof(WinDumpHeader64) +
- (h->PhysicalMemoryBlock.NumberOfPages << TARGET_PAGE_BITS);
- h->PhysicalMemoryBlock.unused = 0;
- h->unused1 = 0;
-
- patch_mm_pfn_database(h, &local_err);
- if (local_err) {
- warn_report_err(local_err);
- local_err = NULL;
- }
- patch_bugcheck_data(h, &local_err);
- if (local_err) {
- warn_report_err(local_err);
- }
-}
-
-static void check_header(WinDumpHeader64 *h, Error **errp)
-{
- const char Signature[] = "PAGE";
- const char ValidDump[] = "DU64";
-
- if (memcmp(h->Signature, Signature, sizeof(h->Signature))) {
- error_setg(errp, "win-dump: invalid header, expected '%.4s',"
- " got '%.4s'", Signature, h->Signature);
- return;
- }
-
- if (memcmp(h->ValidDump, ValidDump, sizeof(h->ValidDump))) {
- error_setg(errp, "win-dump: invalid header, expected '%.4s',"
- " got '%.4s'", ValidDump, h->ValidDump);
- return;
- }
-}
-
-static void check_kdbg(WinDumpHeader64 *h, Error **errp)
-{
- const char OwnerTag[] = "KDBG";
- char read_OwnerTag[4];
- uint64_t KdDebuggerDataBlock = h->KdDebuggerDataBlock;
- bool try_fallback = true;
-
-try_again:
- if (cpu_memory_rw_debug(first_cpu,
- KdDebuggerDataBlock + KDBG_OWNER_TAG_OFFSET64,
- (uint8_t *)&read_OwnerTag, sizeof(read_OwnerTag), 0)) {
- error_setg(errp, "win-dump: failed to read OwnerTag");
- return;
- }
-
- if (memcmp(read_OwnerTag, OwnerTag, sizeof(read_OwnerTag))) {
- if (try_fallback) {
- /*
- * If attempt to use original KDBG failed
- * (most likely because of its encryption),
- * we try to use KDBG obtained by guest driver.
- */
-
- KdDebuggerDataBlock = h->BugcheckParameter1;
- try_fallback = false;
- goto try_again;
- } else {
- error_setg(errp, "win-dump: invalid KDBG OwnerTag,"
- " expected '%.4s', got '%.4s'",
- OwnerTag, read_OwnerTag);
- return;
- }
- }
-
- h->KdDebuggerDataBlock = KdDebuggerDataBlock;
-}
-
-struct saved_context {
- WinContext ctx;
- uint64_t addr;
-};
-
-static void patch_and_save_context(WinDumpHeader64 *h,
- struct saved_context *saved_ctx,
- Error **errp)
-{
- uint64_t KiProcessorBlock;
- uint16_t OffsetPrcbContext;
- CPUState *cpu;
- int i = 0;
-
- if (cpu_memory_rw_debug(first_cpu,
- h->KdDebuggerDataBlock + KDBG_KI_PROCESSOR_BLOCK_OFFSET64,
- (uint8_t *)&KiProcessorBlock, sizeof(KiProcessorBlock), 0)) {
- error_setg(errp, "win-dump: failed to read KiProcessorBlock");
- return;
- }
-
- if (cpu_memory_rw_debug(first_cpu,
- h->KdDebuggerDataBlock + KDBG_OFFSET_PRCB_CONTEXT_OFFSET64,
- (uint8_t *)&OffsetPrcbContext, sizeof(OffsetPrcbContext), 0)) {
- error_setg(errp, "win-dump: failed to read OffsetPrcbContext");
- return;
- }
-
- CPU_FOREACH(cpu) {
- X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
- uint64_t Prcb;
- uint64_t Context;
- WinContext ctx;
-
- if (cpu_memory_rw_debug(first_cpu,
- KiProcessorBlock + i * sizeof(uint64_t),
- (uint8_t *)&Prcb, sizeof(Prcb), 0)) {
- error_setg(errp, "win-dump: failed to read"
- " CPU #%d PRCB location", i);
- return;
- }
-
- if (cpu_memory_rw_debug(first_cpu,
- Prcb + OffsetPrcbContext,
- (uint8_t *)&Context, sizeof(Context), 0)) {
- error_setg(errp, "win-dump: failed to read"
- " CPU #%d ContextFrame location", i);
- return;
- }
-
- saved_ctx[i].addr = Context;
-
- ctx = (WinContext){
- .ContextFlags = WIN_CTX_ALL,
- .MxCsr = env->mxcsr,
-
- .SegEs = env->segs[0].selector,
- .SegCs = env->segs[1].selector,
- .SegSs = env->segs[2].selector,
- .SegDs = env->segs[3].selector,
- .SegFs = env->segs[4].selector,
- .SegGs = env->segs[5].selector,
- .EFlags = cpu_compute_eflags(env),
-
- .Dr0 = env->dr[0],
- .Dr1 = env->dr[1],
- .Dr2 = env->dr[2],
- .Dr3 = env->dr[3],
- .Dr6 = env->dr[6],
- .Dr7 = env->dr[7],
-
- .Rax = env->regs[R_EAX],
- .Rbx = env->regs[R_EBX],
- .Rcx = env->regs[R_ECX],
- .Rdx = env->regs[R_EDX],
- .Rsp = env->regs[R_ESP],
- .Rbp = env->regs[R_EBP],
- .Rsi = env->regs[R_ESI],
- .Rdi = env->regs[R_EDI],
- .R8 = env->regs[8],
- .R9 = env->regs[9],
- .R10 = env->regs[10],
- .R11 = env->regs[11],
- .R12 = env->regs[12],
- .R13 = env->regs[13],
- .R14 = env->regs[14],
- .R15 = env->regs[15],
-
- .Rip = env->eip,
- .FltSave = {
- .MxCsr = env->mxcsr,
- },
- };
-
- if (cpu_memory_rw_debug(first_cpu, Context,
- (uint8_t *)&saved_ctx[i].ctx, sizeof(WinContext), 0)) {
- error_setg(errp, "win-dump: failed to save CPU #%d context", i);
- return;
- }
-
- if (cpu_memory_rw_debug(first_cpu, Context,
- (uint8_t *)&ctx, sizeof(WinContext), 1)) {
- error_setg(errp, "win-dump: failed to write CPU #%d context", i);
- return;
- }
-
- i++;
- }
-}
-
-static void restore_context(WinDumpHeader64 *h,
- struct saved_context *saved_ctx)
-{
- int i;
- Error *err = NULL;
-
- for (i = 0; i < h->NumberProcessors; i++) {
- if (cpu_memory_rw_debug(first_cpu, saved_ctx[i].addr,
- (uint8_t *)&saved_ctx[i].ctx, sizeof(WinContext), 1)) {
- error_setg(&err, "win-dump: failed to restore CPU #%d context", i);
- warn_report_err(err);
- }
- }
-}
-
-void create_win_dump(DumpState *s, Error **errp)
-{
- WinDumpHeader64 *h = (WinDumpHeader64 *)(s->guest_note +
- VMCOREINFO_ELF_NOTE_HDR_SIZE);
- X86CPU *first_x86_cpu = X86_CPU(first_cpu);
- uint64_t saved_cr3 = first_x86_cpu->env.cr[3];
- struct saved_context *saved_ctx = NULL;
- Error *local_err = NULL;
-
- if (s->guest_note_size != sizeof(WinDumpHeader64) +
- VMCOREINFO_ELF_NOTE_HDR_SIZE) {
- error_setg(errp, "win-dump: invalid vmcoreinfo note size");
- return;
- }
-
- check_header(h, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- /*
- * Further access to kernel structures by virtual addresses
- * should be made from system context.
- */
-
- first_x86_cpu->env.cr[3] = h->DirectoryTableBase;
-
- check_kdbg(h, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- goto out_cr3;
- }
-
- patch_header(h);
-
- saved_ctx = g_new(struct saved_context, h->NumberProcessors);
-
- /*
- * Always patch context because there is no way
- * to determine if the system-saved context is valid
- */
-
- patch_and_save_context(h, saved_ctx, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- goto out_free;
- }
-
- s->total_size = h->RequiredDumpSpace;
-
- s->written_size = qemu_write_full(s->fd, h, sizeof(*h));
- if (s->written_size != sizeof(*h)) {
- error_setg(errp, QERR_IO_ERROR);
- goto out_restore;
- }
-
- write_runs(s, h, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- goto out_restore;
- }
-
-out_restore:
- restore_context(h, saved_ctx);
-out_free:
- g_free(saved_ctx);
-out_cr3:
- first_x86_cpu->env.cr[3] = saved_cr3;
-
- return;
-}
+++ /dev/null
-/*
- * Windows crashdump
- *
- * Copyright (c) 2018 Virtuozzo International GmbH
- *
- * 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 WIN_DUMP_H
-#define WIN_DUMP_H
-
-#include "qemu/win_dump_defs.h"
-
-void create_win_dump(DumpState *s, Error **errp);
-
-#endif /* WIN_DUMP_H */