aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.objs2
-rw-r--r--backends/Makefile.objs1
-rw-r--r--backends/rng-egd.c224
-rw-r--r--backends/rng-random.c161
-rw-r--r--backends/rng.c93
-rw-r--r--gen-icount.h2
-rw-r--r--hw/Makefile.objs1
-rw-r--r--hw/pci.h1
-rw-r--r--hw/s390-virtio-bus.c37
-rw-r--r--hw/s390-virtio-bus.h2
-rw-r--r--hw/virtio-pci.c80
-rw-r--r--hw/virtio-pci.h2
-rw-r--r--hw/virtio-rng.c258
-rw-r--r--hw/virtio-rng.h28
-rw-r--r--hw/virtio.h3
-rw-r--r--include/qemu/object.h16
-rw-r--r--include/qemu/rng-random.h22
-rw-r--r--include/qemu/rng.h93
-rw-r--r--qemu-config.c10
-rw-r--r--qemu-options.hx8
-rw-r--r--qom/object.c56
-rw-r--r--target-alpha/translate.c10
-rw-r--r--target-arm/translate.c10
-rw-r--r--target-cris/translate.c5040
-rw-r--r--target-i386/translate.c10
-rw-r--r--target-lm32/translate.c13
-rw-r--r--target-m68k/translate.c10
-rw-r--r--target-microblaze/translate.c13
-rw-r--r--target-mips/translate.c11
-rw-r--r--target-openrisc/translate.c13
-rw-r--r--target-ppc/translate.c11
-rw-r--r--target-s390x/translate.c11
-rw-r--r--target-sh4/translate.c10
-rw-r--r--target-sparc/translate.c10
-rw-r--r--target-unicore32/translate.c10
-rw-r--r--target-xtensa/translate.c8
-rw-r--r--tcg/optimize.c62
-rw-r--r--tcg/tcg-op.h324
-rw-r--r--tcg/tcg.c85
-rw-r--r--tcg/tcg.h10
-rw-r--r--translate-all.c3
-rw-r--r--vl.c56
42 files changed, 4013 insertions, 2817 deletions
diff --git a/Makefile.objs b/Makefile.objs
index 37be7e26f7..dc1e699914 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -100,6 +100,8 @@ common-obj-y += vl.o
common-obj-$(CONFIG_SLIRP) += slirp/
+common-obj-y += backends/
+
######################################################################
# libseccomp
ifeq ($(CONFIG_SECCOMP),y)
diff --git a/backends/Makefile.objs b/backends/Makefile.objs
new file mode 100644
index 0000000000..875eebce6a
--- /dev/null
+++ b/backends/Makefile.objs
@@ -0,0 +1 @@
+common-obj-y += rng.o rng-random.o rng-egd.o
diff --git a/backends/rng-egd.c b/backends/rng-egd.c
new file mode 100644
index 0000000000..ad8473777c
--- /dev/null
+++ b/backends/rng-egd.c
@@ -0,0 +1,224 @@
+/*
+ * QEMU Random Number Generator Backend
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.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/rng.h"
+#include "qemu-char.h"
+#include "qerror.h"
+#include "hw/qdev.h" /* just for DEFINE_PROP_CHR */
+
+#define TYPE_RNG_EGD "rng-egd"
+#define RNG_EGD(obj) OBJECT_CHECK(RngEgd, (obj), TYPE_RNG_EGD)
+
+typedef struct RngEgd
+{
+ RngBackend parent;
+
+ CharDriverState *chr;
+ char *chr_name;
+
+ GSList *requests;
+} RngEgd;
+
+typedef struct RngRequest
+{
+ EntropyReceiveFunc *receive_entropy;
+ uint8_t *data;
+ void *opaque;
+ size_t offset;
+ size_t size;
+} RngRequest;
+
+static void rng_egd_request_entropy(RngBackend *b, size_t size,
+ EntropyReceiveFunc *receive_entropy,
+ void *opaque)
+{
+ RngEgd *s = RNG_EGD(b);
+ RngRequest *req;
+
+ req = g_malloc(sizeof(*req));
+
+ req->offset = 0;
+ req->size = size;
+ req->receive_entropy = receive_entropy;
+ req->opaque = opaque;
+ req->data = g_malloc(req->size);
+
+ while (size > 0) {
+ uint8_t header[2];
+ uint8_t len = MIN(size, 255);
+
+ /* synchronous entropy request */
+ header[0] = 0x02;
+ header[1] = len;
+
+ qemu_chr_fe_write(s->chr, header, sizeof(header));
+
+ size -= len;
+ }
+
+ s->requests = g_slist_append(s->requests, req);
+}
+
+static void rng_egd_free_request(RngRequest *req)
+{
+ g_free(req->data);
+ g_free(req);
+}
+
+static int rng_egd_chr_can_read(void *opaque)
+{
+ RngEgd *s = RNG_EGD(opaque);
+ GSList *i;
+ int size = 0;
+
+ for (i = s->requests; i; i = i->next) {
+ RngRequest *req = i->data;
+ size += req->size - req->offset;
+ }
+
+ return size;
+}
+
+static void rng_egd_chr_read(void *opaque, const uint8_t *buf, int size)
+{
+ RngEgd *s = RNG_EGD(opaque);
+
+ while (size > 0 && s->requests) {
+ RngRequest *req = s->requests->data;
+ int len = MIN(size, req->size - req->offset);
+
+ memcpy(req->data + req->offset, buf, len);
+ req->offset += len;
+ size -= len;
+
+ if (req->offset == req->size) {
+ s->requests = g_slist_remove_link(s->requests, s->requests);
+
+ req->receive_entropy(req->opaque, req->data, req->size);
+
+ rng_egd_free_request(req);
+ }
+ }
+}
+
+static void rng_egd_free_requests(RngEgd *s)
+{
+ GSList *i;
+
+ for (i = s->requests; i; i = i->next) {
+ rng_egd_free_request(i->data);
+ }
+
+ g_slist_free(s->requests);
+ s->requests = NULL;
+}
+
+static void rng_egd_cancel_requests(RngBackend *b)
+{
+ RngEgd *s = RNG_EGD(b);
+
+ /* We simply delete the list of pending requests. If there is data in the
+ * queue waiting to be read, this is okay, because there will always be
+ * more data than we requested originally
+ */
+ rng_egd_free_requests(s);
+}
+
+static void rng_egd_opened(RngBackend *b, Error **errp)
+{
+ RngEgd *s = RNG_EGD(b);
+
+ if (s->chr_name == NULL) {
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+ "chardev", "a valid character device");
+ return;
+ }
+
+ s->chr = qemu_chr_find(s->chr_name);
+ if (s->chr == NULL) {
+ error_set(errp, QERR_DEVICE_NOT_FOUND, s->chr_name);
+ return;
+ }
+
+ /* FIXME we should resubmit pending requests when the CDS reconnects. */
+ qemu_chr_add_handlers(s->chr, rng_egd_chr_can_read, rng_egd_chr_read,
+ NULL, s);
+}
+
+static void rng_egd_set_chardev(Object *obj, const char *value, Error **errp)
+{
+ RngBackend *b = RNG_BACKEND(obj);
+ RngEgd *s = RNG_EGD(b);
+
+ if (b->opened) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ } else {
+ g_free(s->chr_name);
+ s->chr_name = g_strdup(value);
+ }
+}
+
+static char *rng_egd_get_chardev(Object *obj, Error **errp)
+{
+ RngEgd *s = RNG_EGD(obj);
+
+ if (s->chr && s->chr->label) {
+ return g_strdup(s->chr->label);
+ }
+
+ return NULL;
+}
+
+static void rng_egd_init(Object *obj)
+{
+ object_property_add_str(obj, "chardev",
+ rng_egd_get_chardev, rng_egd_set_chardev,
+ NULL);
+}
+
+static void rng_egd_finalize(Object *obj)
+{
+ RngEgd *s = RNG_EGD(obj);
+
+ if (s->chr) {
+ qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
+ }
+
+ g_free(s->chr_name);
+
+ rng_egd_free_requests(s);
+}
+
+static void rng_egd_class_init(ObjectClass *klass, void *data)
+{
+ RngBackendClass *rbc = RNG_BACKEND_CLASS(klass);
+
+ rbc->request_entropy = rng_egd_request_entropy;
+ rbc->cancel_requests = rng_egd_cancel_requests;
+ rbc->opened = rng_egd_opened;
+}
+
+static TypeInfo rng_egd_info = {
+ .name = TYPE_RNG_EGD,
+ .parent = TYPE_RNG_BACKEND,
+ .instance_size = sizeof(RngEgd),
+ .class_init = rng_egd_class_init,
+ .instance_init = rng_egd_init,
+ .instance_finalize = rng_egd_finalize,
+};
+
+static void register_types(void)
+{
+ type_register_static(&rng_egd_info);
+}
+
+type_init(register_types);
diff --git a/backends/rng-random.c b/backends/rng-random.c
new file mode 100644
index 0000000000..9c9923b2ac
--- /dev/null
+++ b/backends/rng-random.c
@@ -0,0 +1,161 @@
+/*
+ * QEMU Random Number Generator Backend
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.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/rng-random.h"
+#include "qemu/rng.h"
+#include "qerror.h"
+#include "main-loop.h"
+
+struct RndRandom
+{
+ RngBackend parent;
+
+ int fd;
+ char *filename;
+
+ EntropyReceiveFunc *receive_func;
+ void *opaque;
+ size_t size;
+};
+
+/**
+ * A simple and incomplete backend to request entropy from /dev/random.
+ *
+ * This backend exposes an additional "filename" property that can be used to
+ * set the filename to use to open the backend.
+ */
+
+static void entropy_available(void *opaque)
+{
+ RndRandom *s = RNG_RANDOM(opaque);
+ uint8_t buffer[s->size];
+ ssize_t len;
+
+ len = read(s->fd, buffer, s->size);
+ g_assert(len != -1);
+
+ s->receive_func(s->opaque, buffer, len);
+ s->receive_func = NULL;
+
+ qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
+}
+
+static void rng_random_request_entropy(RngBackend *b, size_t size,
+ EntropyReceiveFunc *receive_entropy,
+ void *opaque)
+{
+ RndRandom *s = RNG_RANDOM(b);
+
+ if (s->receive_func) {
+ s->receive_func(s->opaque, NULL, 0);
+ }
+
+ s->receive_func = receive_entropy;
+ s->opaque = opaque;
+ s->size = size;
+
+ qemu_set_fd_handler(s->fd, entropy_available, NULL, s);
+}
+
+static void rng_random_opened(RngBackend *b, Error **errp)
+{
+ RndRandom *s = RNG_RANDOM(b);
+
+ if (s->filename == NULL) {
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+ "filename", "a valid filename");
+ } else {
+ s->fd = open(s->filename, O_RDONLY | O_NONBLOCK);
+
+ if (s->fd == -1) {
+ error_set(errp, QERR_OPEN_FILE_FAILED, s->filename);
+ }
+ }
+}
+
+static char *rng_random_get_filename(Object *obj, Error **errp)
+{
+ RndRandom *s = RNG_RANDOM(obj);
+
+ if (s->filename) {
+ return g_strdup(s->filename);
+ }
+
+ return NULL;
+}
+
+static void rng_random_set_filename(Object *obj, const char *filename,
+ Error **errp)
+{
+ RngBackend *b = RNG_BACKEND(obj);
+ RndRandom *s = RNG_RANDOM(obj);
+
+ if (b->opened) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
+
+ if (s->filename) {
+ g_free(s->filename);
+ }
+
+ s->filename = g_strdup(filename);
+}
+
+static void rng_random_init(Object *obj)
+{
+ RndRandom *s = RNG_RANDOM(obj);
+
+ object_property_add_str(obj, "filename",
+ rng_random_get_filename,
+ rng_random_set_filename,
+ NULL);
+
+ s->filename = g_strdup("/dev/random");
+}
+
+static void rng_random_finalize(Object *obj)
+{
+ RndRandom *s = RNG_RANDOM(obj);
+
+ qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
+
+ if (s->fd != -1) {
+ close(s->fd);
+ }
+
+ g_free(s->filename);
+}
+
+static void rng_random_class_init(ObjectClass *klass, void *data)
+{
+ RngBackendClass *rbc = RNG_BACKEND_CLASS(klass);
+
+ rbc->request_entropy = rng_random_request_entropy;
+ rbc->opened = rng_random_opened;
+}
+
+static TypeInfo rng_random_info = {
+ .name = TYPE_RNG_RANDOM,
+ .parent = TYPE_RNG_BACKEND,
+ .instance_size = sizeof(RndRandom),
+ .class_init = rng_random_class_init,
+ .instance_init = rng_random_init,
+ .instance_finalize = rng_random_finalize,
+};
+
+static void register_types(void)
+{
+ type_register_static(&rng_random_info);
+}
+
+type_init(register_types);
diff --git a/backends/rng.c b/backends/rng.c
new file mode 100644
index 0000000000..06f261180c
--- /dev/null
+++ b/backends/rng.c
@@ -0,0 +1,93 @@
+/*
+ * QEMU Random Number Generator Backend
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.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/rng.h"
+#include "qerror.h"
+
+void rng_backend_request_entropy(RngBackend *s, size_t size,
+ EntropyReceiveFunc *receive_entropy,
+ void *opaque)
+{
+ RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
+
+ if (k->request_entropy) {
+ k->request_entropy(s, size, receive_entropy, opaque);
+ }
+}
+
+void rng_backend_cancel_requests(RngBackend *s)
+{
+ RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
+
+ if (k->cancel_requests) {
+ k->cancel_requests(s);
+ }
+}
+
+static bool rng_backend_prop_get_opened(Object *obj, Error **errp)
+{
+ RngBackend *s = RNG_BACKEND(obj);
+
+ return s->opened;
+}
+
+void rng_backend_open(RngBackend *s, Error **errp)
+{
+ object_property_set_bool(OBJECT(s), true, "opened", errp);
+}
+
+static void rng_backend_prop_set_opened(Object *obj, bool value, Error **errp)
+{
+ RngBackend *s = RNG_BACKEND(obj);
+ RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
+
+ if (value == s->opened) {
+ return;
+ }
+
+ if (!value && s->opened) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
+
+ if (k->opened) {
+ k->opened(s, errp);
+ }
+
+ if (!error_is_set(errp)) {
+ s->opened = value;
+ }
+}
+
+static void rng_backend_init(Object *obj)
+{
+ object_property_add_bool(obj, "opened",
+ rng_backend_prop_get_opened,
+ rng_backend_prop_set_opened,
+ NULL);
+}
+
+static TypeInfo rng_backend_info = {
+ .name = TYPE_RNG_BACKEND,
+ .parent = TYPE_OBJECT,
+ .instance_size = sizeof(RngBackend),
+ .instance_init = rng_backend_init,
+ .class_size = sizeof(RngBackendClass),
+ .abstract = true,
+};
+
+static void register_types(void)
+{
+ type_register_static(&rng_backend_info);
+}
+
+type_init(register_types);
diff --git a/gen-icount.h b/gen-icount.h
index 430cb446d0..248cf5b16d 100644
--- a/gen-icount.h
+++ b/gen-icount.h
@@ -16,7 +16,7 @@ static inline void gen_icount_start(void)
count = tcg_temp_local_new_i32();
tcg_gen_ld_i32(count, cpu_env, offsetof(CPUArchState, icount_decr.u32));
/* This is a horrid hack to allow fixing up the value later. */
- icount_arg = gen_opparam_ptr + 1;
+ icount_arg = tcg_ctx.gen_opparam_ptr + 1;
tcg_gen_subi_i32(count, count, 0xdeadbeef);
tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, icount_label);
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index af4ab0c735..ea46f8128e 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -1,6 +1,7 @@
common-obj-y = usb/ ide/
common-obj-y += loader.o
common-obj-$(CONFIG_VIRTIO) += virtio-console.o
+common-obj-$(CONFIG_VIRTIO) += virtio-rng.o
common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
common-obj-y += fw_cfg.o
common-obj-$(CONFIG_PCI) += pci.o pci_bridge.o pci_bridge_dev.o
diff --git a/hw/pci.h b/hw/pci.h
index 241c1d8905..4da0c2a4c9 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -76,6 +76,7 @@
#define PCI_DEVICE_ID_VIRTIO_BALLOON 0x1002
#define PCI_DEVICE_ID_VIRTIO_CONSOLE 0x1003
#define PCI_DEVICE_ID_VIRTIO_SCSI 0x1004
+#define PCI_DEVICE_ID_VIRTIO_RNG 0x1005
#define FMT_PCIBUS PRIx64
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 5849a964a4..e0ac2d1ec2 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -26,6 +26,7 @@
#include "loader.h"
#include "elf.h"
#include "hw/virtio.h"
+#include "hw/virtio-rng.h"
#include "hw/virtio-serial.h"
#include "hw/virtio-net.h"
#include "hw/sysbus.h"
@@ -206,6 +207,18 @@ static int s390_virtio_scsi_init(VirtIOS390Device *dev)
return s390_virtio_device_init(dev, vdev);
}
+static int s390_virtio_rng_init(VirtIOS390Device *dev)
+{
+ VirtIODevice *vdev;
+
+ vdev = virtio_rng_init((DeviceState *)dev, &dev->rng);
+ if (!vdev) {
+ return -1;
+ }
+
+ return s390_virtio_device_init(dev, vdev);
+}
+
static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
{
ram_addr_t token_off;
@@ -448,6 +461,29 @@ static TypeInfo s390_virtio_serial = {
.class_init = s390_virtio_serial_class_init,
};
+static void s390_virtio_rng_initfn(Object *obj)
+{
+ VirtIOS390Device *dev = VIRTIO_S390_DEVICE(obj);
+
+ object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
+ (Object **)&dev->rng.rng, NULL);
+}
+
+static void s390_virtio_rng_class_init(ObjectClass *klass, void *data)
+{
+ VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);
+
+ k->init = s390_virtio_rng_init;
+}
+
+static TypeInfo s390_virtio_rng = {
+ .name = "virtio-rng-s390",
+ .parent = TYPE_VIRTIO_S390_DEVICE,
+ .instance_size = sizeof(VirtIOS390Device),
+ .instance_init = s390_virtio_rng_initfn,
+ .class_init = s390_virtio_rng_class_init,
+};
+
static int s390_virtio_busdev_init(DeviceState *dev)
{
VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
@@ -528,6 +564,7 @@ static void s390_virtio_register_types(void)
type_register_static(&s390_virtio_blk);
type_register_static(&s390_virtio_net);
type_register_static(&s390_virtio_scsi);
+ type_register_static(&s390_virtio_rng);
type_register_static(&s390_virtio_bridge_info);
}
diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h
index 4873134ae9..a83afe785f 100644
--- a/hw/s390-virtio-bus.h
+++ b/hw/s390-virtio-bus.h
@@ -19,6 +19,7 @@
#include "virtio-blk.h"
#include "virtio-net.h"
+#include "virtio-rng.h"
#include "virtio-serial.h"
#include "virtio-scsi.h"
@@ -75,6 +76,7 @@ struct VirtIOS390Device {
virtio_serial_conf serial;
virtio_net_conf net;
VirtIOSCSIConf scsi;
+ VirtIORNGConf rng;
};
typedef struct VirtIOS390Bus {
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 96031500ee..71f4fb5dc6 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -852,6 +852,41 @@ static void virtio_balloon_exit_pci(PCIDevice *pci_dev)
virtio_exit_pci(pci_dev);
}
+static int virtio_rng_init_pci(PCIDevice *pci_dev)
+{
+ VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+ VirtIODevice *vdev;
+
+ if (proxy->rng.rng == NULL) {
+ proxy->rng.default_backend = RNG_RANDOM(object_new(TYPE_RNG_RANDOM));
+
+ object_property_add_child(OBJECT(pci_dev),
+ "default-backend",
+ OBJECT(proxy->rng.default_backend),
+ NULL);
+
+ object_property_set_link(OBJECT(pci_dev),
+ OBJECT(proxy->rng.default_backend),
+ "rng", NULL);
+ }
+
+ vdev = virtio_rng_init(&pci_dev->qdev, &proxy->rng);
+ if (!vdev) {
+ return -1;
+ }
+ virtio_init_pci(proxy, vdev);
+ return 0;
+}
+
+static void virtio_rng_exit_pci(PCIDevice *pci_dev)
+{
+ VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+ virtio_pci_stop_ioeventfd(proxy);
+ virtio_rng_exit(proxy->vdev);
+ virtio_exit_pci(pci_dev);
+}
+
static Property virtio_blk_properties[] = {
DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, blk.conf),
@@ -982,6 +1017,50 @@ static TypeInfo virtio_balloon_info = {
.class_init = virtio_balloon_class_init,
};
+static void virtio_rng_initfn(Object *obj)
+{
+ PCIDevice *pci_dev = PCI_DEVICE(obj);
+ VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+ object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
+ (Object **)&proxy->rng.rng, NULL);
+}
+
+static Property virtio_rng_properties[] = {
+ DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+ /* Set a default rate limit of 2^47 bytes per minute or roughly 2TB/s. If
+ you have an entropy source capable of generating more entropy than this
+ and you can pass it through via virtio-rng, then hats off to you. Until
+ then, this is unlimited for all practical purposes.
+ */
+ DEFINE_PROP_UINT64("max-bytes", VirtIOPCIProxy, rng.max_bytes, INT64_MAX),
+ DEFINE_PROP_UINT32("period", VirtIOPCIProxy, rng.period_ms, 1 << 16),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_rng_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+ k->init = virtio_rng_init_pci;
+ k->exit = virtio_rng_exit_pci;
+ k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+ k->device_id = PCI_DEVICE_ID_VIRTIO_RNG;
+ k->revision = VIRTIO_PCI_ABI_VERSION;
+ k->class_id = PCI_CLASS_OTHERS;
+ dc->reset = virtio_pci_reset;
+ dc->props = virtio_rng_properties;
+}
+
+static TypeInfo virtio_rng_info = {
+ .name = "virtio-rng-pci",
+ .parent = TYPE_PCI_DEVICE,
+ .instance_size = sizeof(VirtIOPCIProxy),
+ .instance_init = virtio_rng_initfn,
+ .class_init = virtio_rng_class_init,
+};
+
static int virtio_scsi_init_pci(PCIDevice *pci_dev)
{
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
@@ -1046,6 +1125,7 @@ static void virtio_pci_register_types(void)
type_register_static(&virtio_serial_info);
type_register_static(&virtio_balloon_info);
type_register_static(&virtio_scsi_info);
+ type_register_static(&virtio_rng_info);
}
type_init(virtio_pci_register_types)
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index ac9d522f37..b58d9a2d19 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -17,6 +17,7 @@
#include "virtio-blk.h"
#include "virtio-net.h"
+#include "virtio-rng.h"
#include "virtio-serial.h"
#include "virtio-scsi.h"
@@ -46,6 +47,7 @@ typedef struct {
virtio_serial_conf serial;
virtio_net_conf net;
VirtIOSCSIConf scsi;
+ VirtIORNGConf rng;
bool ioeventfd_disabled;
bool ioeventfd_started;
VirtIOIRQFD *vector_irqfd;
diff --git a/hw/virtio-rng.c b/hw/virtio-rng.c
new file mode 100644
index 0000000000..3ca96c855f
--- /dev/null
+++ b/hw/virtio-rng.c
@@ -0,0 +1,258 @@
+/*
+ * A virtio device implementing a hardware random number generator.
+ *
+ * Copyright 2012 Red Hat, Inc.
+ * Copyright 2012 Amit Shah <amit.shah@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.
+ */
+
+#include "iov.h"
+#include "qdev.h"
+#include "virtio.h"
+#include "virtio-rng.h"
+#include "qemu/rng.h"
+
+typedef struct VirtIORNG {
+ VirtIODevice vdev;
+
+ DeviceState *qdev;
+
+ /* Only one vq - guest puts buffer(s) on it when it needs entropy */
+ VirtQueue *vq;
+ VirtQueueElement elem;
+
+ /* Config data for the device -- currently only chardev */
+ VirtIORNGConf *conf;
+
+ /* Whether we've popped a vq element into 'elem' above */
+ bool popped;
+
+ RngBackend *rng;
+
+ /* We purposefully don't migrate this state. The quota will reset on the
+ * destination as a result. Rate limiting is host state, not guest state.
+ */
+ QEMUTimer *rate_limit_timer;
+ int64_t quota_remaining;
+} VirtIORNG;
+
+static bool is_guest_ready(VirtIORNG *vrng)
+{
+ if (virtio_queue_ready(vrng->vq)
+ && (vrng->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK)) {
+ return true;
+ }
+ return false;
+}
+
+static size_t pop_an_elem(VirtIORNG *vrng)
+{
+ size_t size;
+
+ if (!vrng->popped && !virtqueue_pop(vrng->vq, &vrng->elem)) {
+ return 0;
+ }
+ vrng->popped = true;
+
+ size = iov_size(vrng->elem.in_sg, vrng->elem.in_num);
+ return size;
+}
+
+static void virtio_rng_process(VirtIORNG *vrng);
+
+/* Send data from a char device over to the guest */
+static void chr_read(void *opaque, const void *buf, size_t size)
+{
+ VirtIORNG *vrng = opaque;
+ size_t len;
+ int offset;
+
+ if (!is_guest_ready(vrng)) {
+ return;
+ }
+
+ vrng->quota_remaining -= size;
+
+ offset = 0;
+ while (offset < size) {
+ if (!pop_an_elem(vrng)) {
+ break;
+ }
+ len = iov_from_buf(vrng->elem.in_sg, vrng->elem.in_num,
+ 0, buf + offset, size - offset);
+ offset += len;
+
+ virtqueue_push(vrng->vq, &vrng->elem, len);
+ vrng->popped = false;
+ }
+ virtio_notify(&vrng->vdev, vrng->vq);
+
+ /*
+ * Lastly, if we had multiple elems queued by the guest, and we
+ * didn't have enough data to fill them all, indicate we want more
+ * data.
+ */
+ virtio_rng_process(vrng);
+}
+
+static void virtio_rng_process(VirtIORNG *vrng)
+{
+ ssize_t size;
+
+ if (!is_guest_ready(vrng)) {
+ return;
+ }
+
+ size = pop_an_elem(vrng);
+ size = MIN(vrng->quota_remaining, size);
+
+ if (size > 0) {
+ rng_backend_request_entropy(vrng->rng, size, chr_read, vrng);
+ }
+}
+
+
+static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
+{
+ VirtIORNG *vrng = DO_UPCAST(VirtIORNG, vdev, vdev);
+ virtio_rng_process(vrng);
+}
+
+static uint32_t get_features(VirtIODevice *vdev, uint32_t f)
+{
+ return f;
+}
+
+static void virtio_rng_save(QEMUFile *f, void *opaque)
+{
+ VirtIORNG *vrng = opaque;
+
+ virtio_save(&vrng->vdev, f);
+
+ qemu_put_byte(f, vrng->popped);
+ if (vrng->popped) {
+ int i;
+
+ qemu_put_be32(f, vrng->elem.index);
+
+ qemu_put_be32(f, vrng->elem.in_num);
+ for (i = 0; i < vrng->elem.in_num; i++) {
+ qemu_put_be64(f, vrng->elem.in_addr[i]);
+ }
+
+ qemu_put_be32(f, vrng->elem.out_num);
+ for (i = 0; i < vrng->elem.out_num; i++) {
+ qemu_put_be64(f, vrng->elem.out_addr[i]);
+ }
+ }
+}
+
+static int virtio_rng_load(QEMUFile *f, void *opaque, int version_id)
+{
+ VirtIORNG *vrng = opaque;
+
+ if (version_id != 1) {
+ return -EINVAL;
+ }
+ virtio_load(&vrng->vdev, f);
+
+ vrng->popped = qemu_get_byte(f);
+ if (vrng->popped) {
+ int i;
+
+ vrng->elem.index = qemu_get_be32(f);
+
+ vrng->elem.in_num = qemu_get_be32(f);
+ g_assert(vrng->elem.in_num < VIRTQUEUE_MAX_SIZE);
+ for (i = 0; i < vrng->elem.in_num; i++) {
+ vrng->elem.in_addr[i] = qemu_get_be64(f);
+ }
+
+ vrng->elem.out_num = qemu_get_be32(f);
+ g_assert(vrng->elem.out_num < VIRTQUEUE_MAX_SIZE);
+ for (i = 0; i < vrng->elem.out_num; i++) {
+ vrng->elem.out_addr[i] = qemu_get_be64(f);
+ }
+
+ virtqueue_map_sg(vrng->elem.in_sg, vrng->elem.in_addr,
+ vrng->elem.in_num, 1);
+ virtqueue_map_sg(vrng->elem.out_sg, vrng->elem.out_addr,
+ vrng->elem.out_num, 0);
+ }
+
+ /* We may have an element ready but couldn't process it due to a quota
+ limit. Make sure to try again after live migration when the quota may
+ have been reset.
+ */
+ virtio_rng_process(vrng);
+
+ return 0;
+}
+
+static void check_rate_limit(void *opaque)
+{
+ VirtIORNG *s = opaque;
+
+ s->quota_remaining = s->conf->max_bytes;
+ virtio_rng_process(s);
+ qemu_mod_timer(s->rate_limit_timer,
+ qemu_get_clock_ms(vm_clock) + s->conf->period_ms);
+}
+
+
+VirtIODevice *virtio_rng_init(DeviceState *dev, VirtIORNGConf *conf)
+{
+ VirtIORNG *vrng;
+ VirtIODevice *vdev;
+ Error *local_err = NULL;
+
+ vdev = virtio_common_init("virtio-rng", VIRTIO_ID_RNG, 0,
+ sizeof(VirtIORNG));
+
+ vrng = DO_UPCAST(VirtIORNG, vdev, vdev);
+
+ vrng->rng = conf->rng;
+ if (vrng->rng == NULL) {
+ qerror_report(QERR_INVALID_PARAMETER_VALUE, "rng", "a valid object");
+ return NULL;
+ }
+
+ rng_backend_open(vrng->rng, &local_err);
+ if (local_err) {
+ qerror_report_err(local_err);
+ error_free(local_err);
+ return NULL;
+ }
+
+ vrng->vq = virtio_add_queue(vdev, 8, handle_input);
+ vrng->vdev.get_features = get_features;
+
+ vrng->qdev = dev;
+ vrng->conf = conf;
+ vrng->popped = false;
+ vrng->quota_remaining = vrng->conf->max_bytes;
+
+ g_assert_cmpint(vrng->conf->max_bytes, <=, INT64_MAX);
+
+ vrng->rate_limit_timer = qemu_new_timer_ms(vm_clock,
+ check_rate_limit, vrng);
+
+ qemu_mod_timer(vrng->rate_limit_timer,
+ qemu_get_clock_ms(vm_clock) + vrng->conf->period_ms);
+
+ register_savevm(dev, "virtio-rng", -1, 1, virtio_rng_save,
+ virtio_rng_load, vrng);
+
+ return vdev;
+}
+
+void virtio_rng_exit(VirtIODevice *vdev)
+{
+ VirtIORNG *vrng = DO_UPCAST(VirtIORNG, vdev, vdev);
+
+ unregister_savevm(vrng->qdev, "virtio-rng", vrng);
+ virtio_cleanup(vdev);
+}
diff --git a/hw/virtio-rng.h b/hw/virtio-rng.h
new file mode 100644
index 0000000000..f42d748eba
--- /dev/null
+++ b/hw/virtio-rng.h
@@ -0,0 +1,28 @@
+/*
+ * Virtio RNG Support
+ *
+ * Copyright Red Hat, Inc. 2012
+ * Copyright Amit Shah <amit.shah@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.
+ */
+
+#ifndef _QEMU_VIRTIO_RNG_H
+#define _QEMU_VIRTIO_RNG_H
+
+#include "qemu/rng.h"
+#include "qemu/rng-random.h"
+
+/* The Virtio ID for the virtio rng device */
+#define VIRTIO_ID_RNG 4
+
+struct VirtIORNGConf {
+ RngBackend *rng;
+ uint64_t max_bytes;
+ uint32_t period_ms;
+ RndRandom *default_backend;
+};
+
+#endif
diff --git a/hw/virtio.h b/hw/virtio.h
index ac482be24c..df8d0f7b69 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -203,6 +203,8 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *serial);
VirtIODevice *virtio_balloon_init(DeviceState *dev);
typedef struct VirtIOSCSIConf VirtIOSCSIConf;
VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *conf);
+typedef struct VirtIORNGConf VirtIORNGConf;
+VirtIODevice *virtio_rng_init(DeviceState *dev, VirtIORNGConf *conf);
#ifdef CONFIG_LINUX
VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf);
#endif
@@ -213,6 +215,7 @@ void virtio_blk_exit(VirtIODevice *vdev);
void virtio_serial_exit(VirtIODevice *vdev);
void virtio_balloon_exit(VirtIODevice *vdev);
void virtio_scsi_exit(VirtIODevice *vdev);
+void virtio_rng_exit(VirtIODevice *vdev);
#define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
DEFINE_PROP_BIT("indirect_desc", _state, _field, \
diff --git a/include/qemu/object.h b/include/qemu/object.h
index cc75feed66..be707f1a36 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -947,6 +947,22 @@ void object_property_add_str(Object *obj, const char *name,
struct Error **errp);
/**
+ * object_property_add_bool:
+ * @obj: the object to add a property to
+ * @name: the name of the property
+ * @get: the getter or NULL if the property is write-only.
+ * @set: the setter or NULL if the property is read-only
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Add a bool property using getters/setters. This function will add a
+ * property of type 'bool'.
+ */
+void object_property_add_bool(Object *obj, const char *name,
+ bool (*get)(Object *, struct Error **),
+ void (*set)(Object *, bool, struct Error **),
+ struct Error **errp);
+
+/**
* object_child_foreach:
* @obj: the object whose children will be navigated
* @fn: the iterator function to be called
diff --git a/include/qemu/rng-random.h b/include/qemu/rng-random.h
new file mode 100644
index 0000000000..6249290cc4
--- /dev/null
+++ b/include/qemu/rng-random.h
@@ -0,0 +1,22 @@
+/*
+ * QEMU Random Number Generator Backend
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_RNG_RANDOM_H
+#define QEMU_RNG_RANDOM_H
+
+#include "qemu/object.h"
+
+#define TYPE_RNG_RANDOM "rng-random"
+#define RNG_RANDOM(obj) OBJECT_CHECK(RndRandom, (obj), TYPE_RNG_RANDOM)
+
+typedef struct RndRandom RndRandom;
+
+#endif
diff --git a/include/qemu/rng.h b/include/qemu/rng.h
new file mode 100644
index 0000000000..7e9d6723ff
--- /dev/null
+++ b/include/qemu/rng.h
@@ -0,0 +1,93 @@
+/*
+ * QEMU Random Number Generator Backend
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QEMU_RNG_H
+#define QEMU_RNG_H
+
+#include "qemu/object.h"
+#include "qemu-common.h"
+#include "error.h"
+
+#define TYPE_RNG_BACKEND "rng-backend"
+#define RNG_BACKEND(obj) \
+ OBJECT_CHECK(RngBackend, (obj), TYPE_RNG_BACKEND)
+#define RNG_BACKEND_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(RngBackendClass, (obj), TYPE_RNG_BACKEND)
+#define RNG_BACKEND_CLASS(klass) \
+ OBJECT_CLASS_CHECK(RngBackendClass, (klass), TYPE_RNG_BACKEND)
+
+typedef struct RngBackendClass RngBackendClass;
+typedef struct RngBackend RngBackend;
+
+typedef void (EntropyReceiveFunc)(void *opaque,
+ const void *data,
+ size_t size);
+
+struct RngBackendClass
+{
+ ObjectClass parent_class;
+
+ void (*request_entropy)(RngBackend *s, size_t size,
+ EntropyReceiveFunc *recieve_entropy, void *opaque);
+ void (*cancel_requests)(RngBackend *s);
+
+ void (*opened)(RngBackend *s, Error **errp);
+};
+
+struct RngBackend
+{
+ Object parent;
+
+ /*< protected >*/
+ bool opened;
+};
+
+/**
+ * rng_backend_request_entropy:
+ * @s: the backend to request entropy from
+ * @size: the number of bytes of data to request
+ * @receive_entropy: a function to be invoked when entropy is available
+ * @opaque: data that should be passed to @receive_entropy
+ *
+ * This function is used by the front-end to request entropy from an entropy
+ * source. This function can be called multiple times before @receive_entropy
+ * is invoked with different values of @receive_entropy and @opaque. The
+ * backend will queue each request and handle appropriate.
+ *
+ * The backend does not need to pass the full amount of data to @receive_entropy
+ * but will pass at a value greater than 0.
+ */
+void rng_backend_request_entropy(RngBackend *s, size_t size,
+ EntropyReceiveFunc *receive_entropy,
+ void *opaque);
+
+/**
+ * rng_backend_cancel_requests:
+ * @s: the backend to cancel all pending requests in
+ *
+ * Cancels all pending requests submitted by @rng_backend_request_entropy. This
+ * should be used by a device during reset or in preparation for live migration
+ * to stop tracking any request.
+ */
+void rng_backend_cancel_requests(RngBackend *s);
+
+/**
+ * rng_backend_open:
+ * @s: the backend to open
+ * @errp: a pointer to return the #Error object if an error occurs.
+ *
+ * This function will open the backend if it is not already open. Calling this
+ * function on an already opened backend will not result in an error.
+ */
+void rng_backend_open(RngBackend *s, Error **errp);
+
+#endif
diff --git a/qemu-config.c b/qemu-config.c
index 3154cac10f..10d1ba4176 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -682,6 +682,15 @@ static QemuOptsList qemu_add_fd_opts = {
},
};
+static QemuOptsList qemu_object_opts = {
+ .name = "object",
+ .implied_opt_name = "qom-type",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
+ .desc = {
+ { }
+ },
+};
+
static QemuOptsList *vm_config_groups[32] = {
&qemu_drive_opts,
&qemu_chardev_opts,
@@ -699,6 +708,7 @@ static QemuOptsList *vm_config_groups[32] = {
&qemu_iscsi_opts,
&qemu_sandbox_opts,
&qemu_add_fd_opts,
+ &qemu_object_opts,
NULL,
};
diff --git a/qemu-options.hx b/qemu-options.hx
index fe8f15c541..dd86bfee6a 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2904,6 +2904,14 @@ DEF("no-kvm-irqchip", HAS_ARG, QEMU_OPTION_no_kvm_irqchip, "", QEMU_ARCH_I386)
HXCOMM Deprecated (ignored)
DEF("tdf", 0, QEMU_OPTION_tdf,"", QEMU_ARCH_ALL)
+DEF("object", HAS_ARG, QEMU_OPTION_object,
+ "-object TYPENAME[,PROP1=VALUE1,...]\n"
+ " create an new object of type TYPENAME setting properties\n"
+ " in the order they are specified. Note that the 'id'\n"
+ " property must be set. These objects are placed in the\n"
+ " '/objects' path.\n",
+ QEMU_ARCH_ALL)
+
HXCOMM This is the last statement. Insert new options before this line!
STEXI
@end table
diff --git a/qom/object.c b/qom/object.c
index e3e9242638..d7092b09d8 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1183,6 +1183,62 @@ void object_property_add_str(Object *obj, const char *name,
prop, errp);
}
+typedef struct BoolProperty
+{
+ bool (*get)(Object *, Error **);
+ void (*set)(Object *, bool, Error **);
+} BoolProperty;
+
+static void property_get_bool(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ BoolProperty *prop = opaque;
+ bool value;
+
+ value = prop->get(obj, errp);
+ visit_type_bool(v, &value, name, errp);
+}
+
+static void property_set_bool(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ BoolProperty *prop = opaque;
+ bool value;
+ Error *local_err = NULL;
+
+ visit_type_bool(v, &value, name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ prop->set(obj, value, errp);
+}
+
+static void property_release_bool(Object *obj, const char *name,
+ void *opaque)
+{
+ BoolProperty *prop = opaque;
+ g_free(prop);
+}
+
+void object_property_add_bool(Object *obj, const char *name,
+ bool (*get)(Object *, Error **),
+ void (*set)(Object *, bool, Error **),
+ Error **errp)
+{
+ BoolProperty *prop = g_malloc0(sizeof(*prop));
+
+ prop->get = get;
+ prop->set = set;
+
+ object_property_add(obj, name, "bool",
+ get ? property_get_bool : NULL,
+ set ? property_set_bool : NULL,
+ property_release_bool,
+ prop, errp);
+}
+
static char *qdev_get_type(Object *obj, Error **errp)
{
return g_strdup(object_get_typename(obj));
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 8c4dd021f3..4045f788ea 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3373,7 +3373,7 @@ static inline void gen_intermediate_code_internal(CPUAlphaState *env,
int max_insns;
pc_start = tb->pc;
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
ctx.tb = tb;
ctx.env = env;
@@ -3406,7 +3406,7 @@ static inline void gen_intermediate_code_internal(CPUAlphaState *env,
}
}
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j)
@@ -3432,7 +3432,7 @@ static inline void gen_intermediate_code_internal(CPUAlphaState *env,
or exhaust instruction count, stop generation. */
if (ret == NO_EXIT
&& ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0
- || gen_opc_ptr >= gen_opc_end
+ || tcg_ctx.gen_opc_ptr >= gen_opc_end
|| num_insns >= max_insns
|| singlestep
|| env->singlestep_enabled)) {
@@ -3463,9 +3463,9 @@ static inline void gen_intermediate_code_internal(CPUAlphaState *env,
}
gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j)
gen_opc_instr_start[lj++] = 0;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 7d8f8e5edc..c42110ab0d 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9727,7 +9727,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
dc->tb = tb;
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
dc->is_jmp = DISAS_NEXT;
dc->pc = pc_start;
@@ -9834,7 +9834,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
}
}
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j)
@@ -9881,7 +9881,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
* Also stop translation when a page boundary is reached. This
* ensures prefetch aborts occur at the right place. */
num_insns ++;
- } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
+ } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
!env->singlestep_enabled &&
!singlestep &&
dc->pc < next_page_start &&
@@ -9962,7 +9962,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
done_generating:
gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
#ifdef DEBUG_DISAS
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
@@ -9974,7 +9974,7 @@ done_generating:
}
#endif
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j)
gen_opc_instr_start[lj++] = 0;
diff --git a/target-cris/translate.c b/target-cris/translate.c
index f8ebc43a86..0b0e86dbd1 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -74,89 +74,89 @@ static TCGv env_pc;
/* This is the state at translation time. */
typedef struct DisasContext {
- CPUCRISState *env;
- target_ulong pc, ppc;
+ CPUCRISState *env;
+ target_ulong pc, ppc;
- /* Decoder. */
+ /* Decoder. */
unsigned int (*decoder)(CPUCRISState *env, struct DisasContext *dc);
- uint32_t ir;
- uint32_t opcode;
- unsigned int op1;
- unsigned int op2;
- unsigned int zsize, zzsize;
- unsigned int mode;
- unsigned int postinc;
-
- unsigned int size;
- unsigned int src;
- unsigned int dst;
- unsigned int cond;
-
- int update_cc;
- int cc_op;
- int cc_size;
- uint32_t cc_mask;
-
- int cc_size_uptodate; /* -1 invalid or last written value. */
-
- int cc_x_uptodate; /* 1 - ccs, 2 - known | X_FLAG. 0 not uptodate. */
- int flags_uptodate; /* Wether or not $ccs is uptodate. */
- int flagx_known; /* Wether or not flags_x has the x flag known at
- translation time. */
- int flags_x;
-
- int clear_x; /* Clear x after this insn? */
- int clear_prefix; /* Clear prefix after this insn? */
- int clear_locked_irq; /* Clear the irq lockout. */
- int cpustate_changed;
- unsigned int tb_flags; /* tb dependent flags. */
- int is_jmp;
+ uint32_t ir;
+ uint32_t opcode;
+ unsigned int op1;
+ unsigned int op2;
+ unsigned int zsize, zzsize;
+ unsigned int mode;
+ unsigned int postinc;
+
+ unsigned int size;
+ unsigned int src;
+ unsigned int dst;
+ unsigned int cond;
+
+ int update_cc;
+ int cc_op;
+ int cc_size;
+ uint32_t cc_mask;
+
+ int cc_size_uptodate; /* -1 invalid or last written value. */
+
+ int cc_x_uptodate; /* 1 - ccs, 2 - known | X_FLAG. 0 not uptodate. */
+ int flags_uptodate; /* Wether or not $ccs is uptodate. */
+ int flagx_known; /* Wether or not flags_x has the x flag known at
+ translation time. */
+ int flags_x;
+
+ int clear_x; /* Clear x after this insn? */
+ int clear_prefix; /* Clear prefix after this insn? */
+ int clear_locked_irq; /* Clear the irq lockout. */
+ int cpustate_changed;
+ unsigned int tb_flags; /* tb dependent flags. */
+ int is_jmp;
#define JMP_NOJMP 0
#define JMP_DIRECT 1
#define JMP_DIRECT_CC 2
#define JMP_INDIRECT 3
- int jmp; /* 0=nojmp, 1=direct, 2=indirect. */
- uint32_t jmp_pc;
+ int jmp; /* 0=nojmp, 1=direct, 2=indirect. */
+ uint32_t jmp_pc;
- int delayed_branch;
+ int delayed_branch;
- struct TranslationBlock *tb;
- int singlestep_enabled;
+ struct TranslationBlock *tb;
+ int singlestep_enabled;
} DisasContext;
static void gen_BUG(DisasContext *dc, const char *file, int line)
{
- printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
- qemu_log("BUG: pc=%x %s %d\n", dc->pc, file, line);
- cpu_abort(dc->env, "%s:%d\n", file, line);
+ printf("BUG: pc=%x %s %d\n", dc->pc, file, line);
+ qemu_log("BUG: pc=%x %s %d\n", dc->pc, file, line);
+ cpu_abort(dc->env, "%s:%d\n", file, line);
}
static const char *regnames[] =
{
- "$r0", "$r1", "$r2", "$r3",
- "$r4", "$r5", "$r6", "$r7",
- "$r8", "$r9", "$r10", "$r11",
- "$r12", "$r13", "$sp", "$acr",
+ "$r0", "$r1", "$r2", "$r3",
+ "$r4", "$r5", "$r6", "$r7",
+ "$r8", "$r9", "$r10", "$r11",
+ "$r12", "$r13", "$sp", "$acr",
};
static const char *pregnames[] =
{
- "$bz", "$vr", "$pid", "$srs",
- "$wz", "$exs", "$eda", "$mof",
- "$dz", "$ebp", "$erp", "$srp",
- "$nrp", "$ccs", "$usp", "$spc",
+ "$bz", "$vr", "$pid", "$srs",
+ "$wz", "$exs", "$eda", "$mof",
+ "$dz", "$ebp", "$erp", "$srp",
+ "$nrp", "$ccs", "$usp", "$spc",
};
/* We need this table to handle preg-moves with implicit width. */
static int preg_sizes[] = {
- 1, /* bz. */
- 1, /* vr. */
- 4, /* pid. */
- 1, /* srs. */
- 2, /* wz. */
- 4, 4, 4,
- 4, 4, 4, 4,
- 4, 4, 4, 4,
+ 1, /* bz. */
+ 1, /* vr. */
+ 4, /* pid. */
+ 1, /* srs. */
+ 2, /* wz. */
+ 4, 4, 4,
+ 4, 4, 4, 4,
+ 4, 4, 4, 4,
};
#define t_gen_mov_TN_env(tn, member) \
@@ -166,113 +166,122 @@ static int preg_sizes[] = {
static inline void t_gen_mov_TN_reg(TCGv tn, int r)
{
- if (r < 0 || r > 15)
- fprintf(stderr, "wrong register read $r%d\n", r);
- tcg_gen_mov_tl(tn, cpu_R[r]);
+ if (r < 0 || r > 15) {
+ fprintf(stderr, "wrong register read $r%d\n", r);
+ }
+ tcg_gen_mov_tl(tn, cpu_R[r]);
}
static inline void t_gen_mov_reg_TN(int r, TCGv tn)
{
- if (r < 0 || r > 15)
- fprintf(stderr, "wrong register write $r%d\n", r);
- tcg_gen_mov_tl(cpu_R[r], tn);
+ if (r < 0 || r > 15) {
+ fprintf(stderr, "wrong register write $r%d\n", r);
+ }
+ tcg_gen_mov_tl(cpu_R[r], tn);
}
static inline void _t_gen_mov_TN_env(TCGv tn, int offset)
{
- if (offset > sizeof (CPUCRISState))
- fprintf(stderr, "wrong load from env from off=%d\n", offset);
- tcg_gen_ld_tl(tn, cpu_env, offset);
+ if (offset > sizeof(CPUCRISState)) {
+ fprintf(stderr, "wrong load from env from off=%d\n", offset);
+ }
+ tcg_gen_ld_tl(tn, cpu_env, offset);
}
static inline void _t_gen_mov_env_TN(int offset, TCGv tn)
{
- if (offset > sizeof (CPUCRISState))
- fprintf(stderr, "wrong store to env at off=%d\n", offset);
- tcg_gen_st_tl(tn, cpu_env, offset);
+ if (offset > sizeof(CPUCRISState)) {
+ fprintf(stderr, "wrong store to env at off=%d\n", offset);
+ }
+ tcg_gen_st_tl(tn, cpu_env, offset);
}
static inline void t_gen_mov_TN_preg(TCGv tn, int r)
{
- if (r < 0 || r > 15)
- fprintf(stderr, "wrong register read $p%d\n", r);
- if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
- tcg_gen_mov_tl(tn, tcg_const_tl(0));
- else if (r == PR_VR)
- tcg_gen_mov_tl(tn, tcg_const_tl(32));
- else
- tcg_gen_mov_tl(tn, cpu_PR[r]);
+ if (r < 0 || r > 15) {
+ fprintf(stderr, "wrong register read $p%d\n", r);
+ }
+ if (r == PR_BZ || r == PR_WZ || r == PR_DZ) {
+ tcg_gen_mov_tl(tn, tcg_const_tl(0));
+ } else if (r == PR_VR) {
+ tcg_gen_mov_tl(tn, tcg_const_tl(32));
+ } else {
+ tcg_gen_mov_tl(tn, cpu_PR[r]);
+ }
}
static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
{
- if (r < 0 || r > 15)
- fprintf(stderr, "wrong register write $p%d\n", r);
- if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
- return;
- else if (r == PR_SRS)
- tcg_gen_andi_tl(cpu_PR[r], tn, 3);
- else {
- if (r == PR_PID)
- gen_helper_tlb_flush_pid(cpu_env, tn);
- if (dc->tb_flags & S_FLAG && r == PR_SPC)
- gen_helper_spc_write(cpu_env, tn);
- else if (r == PR_CCS)
- dc->cpustate_changed = 1;
- tcg_gen_mov_tl(cpu_PR[r], tn);
- }
+ if (r < 0 || r > 15) {
+ fprintf(stderr, "wrong register write $p%d\n", r);
+ }
+ if (r == PR_BZ || r == PR_WZ || r == PR_DZ) {
+ return;
+ } else if (r == PR_SRS) {
+ tcg_gen_andi_tl(cpu_PR[r], tn, 3);
+ } else {
+ if (r == PR_PID) {
+ gen_helper_tlb_flush_pid(cpu_env, tn);
+ }
+ if (dc->tb_flags & S_FLAG && r == PR_SPC) {
+ gen_helper_spc_write(cpu_env, tn);
+ } else if (r == PR_CCS) {
+ dc->cpustate_changed = 1;
+ }
+ tcg_gen_mov_tl(cpu_PR[r], tn);
+ }
}
/* Sign extend at translation time. */
static int sign_extend(unsigned int val, unsigned int width)
{
- int sval;
+ int sval;
- /* LSL. */
- val <<= 31 - width;
- sval = val;
- /* ASR. */
- sval >>= 31 - width;
- return sval;
+ /* LSL. */
+ val <<= 31 - width;
+ sval = val;
+ /* ASR. */
+ sval >>= 31 - width;
+ return sval;
}
static int cris_fetch(CPUCRISState *env, DisasContext *dc, uint32_t addr,
- unsigned int size, unsigned int sign)
-{
- int r;
-
- switch (size) {
- case 4:
- {
- r = cpu_ldl_code(env, addr);
- break;
- }
- case 2:
- {
- if (sign) {
- r = cpu_ldsw_code(env, addr);
- } else {
- r = cpu_lduw_code(env, addr);
- }
- break;
- }
- case 1:
- {
- if (sign) {
- r = cpu_ldsb_code(env, addr);
- } else {
- r = cpu_ldub_code(env, addr);
- }
- break;
- }
- default:
- cpu_abort(dc->env, "Invalid fetch size %d\n", size);
- break;
- }
- return r;
+ unsigned int size, unsigned int sign)
+{
+ int r;
+
+ switch (size) {
+ case 4:
+ {
+ r = cpu_ldl_code(env, addr);
+ break;
+ }
+ case 2:
+ {
+ if (sign) {
+ r = cpu_ldsw_code(env, addr);
+ } else {
+ r = cpu_lduw_code(env, addr);
+ }
+ break;
+ }
+ case 1:
+ {
+ if (sign) {
+ r = cpu_ldsb_code(env, addr);
+ } else {
+ r = cpu_ldub_code(env, addr);
+ }
+ break;
+ }
+ default:
+ cpu_abort(dc->env, "Invalid fetch size %d\n", size);
+ break;
+ }
+ return r;
}
static void cris_lock_irq(DisasContext *dc)
{
- dc->clear_locked_irq = 0;
- t_gen_mov_env_TN(locked_irq, tcg_const_tl(1));
+ dc->clear_locked_irq = 0;
+ t_gen_mov_env_TN(locked_irq, tcg_const_tl(1));
}
static inline void t_gen_raise_exception(uint32_t index)
@@ -284,240 +293,241 @@ static inline void t_gen_raise_exception(uint32_t index)
static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
{
- TCGv t0, t_31;
+ TCGv t0, t_31;
- t0 = tcg_temp_new();
- t_31 = tcg_const_tl(31);
- tcg_gen_shl_tl(d, a, b);
+ t0 = tcg_temp_new();
+ t_31 = tcg_const_tl(31);
+ tcg_gen_shl_tl(d, a, b);
- tcg_gen_sub_tl(t0, t_31, b);
- tcg_gen_sar_tl(t0, t0, t_31);
- tcg_gen_and_tl(t0, t0, d);
- tcg_gen_xor_tl(d, d, t0);
- tcg_temp_free(t0);
- tcg_temp_free(t_31);
+ tcg_gen_sub_tl(t0, t_31, b);
+ tcg_gen_sar_tl(t0, t0, t_31);
+ tcg_gen_and_tl(t0, t0, d);
+ tcg_gen_xor_tl(d, d, t0);
+ tcg_temp_free(t0);
+ tcg_temp_free(t_31);
}
static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
{
- TCGv t0, t_31;
+ TCGv t0, t_31;
- t0 = tcg_temp_new();
- t_31 = tcg_temp_new();
- tcg_gen_shr_tl(d, a, b);
+ t0 = tcg_temp_new();
+ t_31 = tcg_temp_new();
+ tcg_gen_shr_tl(d, a, b);
- tcg_gen_movi_tl(t_31, 31);
- tcg_gen_sub_tl(t0, t_31, b);
- tcg_gen_sar_tl(t0, t0, t_31);
- tcg_gen_and_tl(t0, t0, d);
- tcg_gen_xor_tl(d, d, t0);
- tcg_temp_free(t0);
- tcg_temp_free(t_31);
+ tcg_gen_movi_tl(t_31, 31);
+ tcg_gen_sub_tl(t0, t_31, b);
+ tcg_gen_sar_tl(t0, t0, t_31);
+ tcg_gen_and_tl(t0, t0, d);
+ tcg_gen_xor_tl(d, d, t0);
+ tcg_temp_free(t0);
+ tcg_temp_free(t_31);
}
static void t_gen_asr(TCGv d, TCGv a, TCGv b)
{
- TCGv t0, t_31;
+ TCGv t0, t_31;
- t0 = tcg_temp_new();
- t_31 = tcg_temp_new();
- tcg_gen_sar_tl(d, a, b);
+ t0 = tcg_temp_new();
+ t_31 = tcg_temp_new();
+ tcg_gen_sar_tl(d, a, b);
- tcg_gen_movi_tl(t_31, 31);
- tcg_gen_sub_tl(t0, t_31, b);
- tcg_gen_sar_tl(t0, t0, t_31);
- tcg_gen_or_tl(d, d, t0);
- tcg_temp_free(t0);
- tcg_temp_free(t_31);
+ tcg_gen_movi_tl(t_31, 31);
+ tcg_gen_sub_tl(t0, t_31, b);
+ tcg_gen_sar_tl(t0, t0, t_31);
+ tcg_gen_or_tl(d, d, t0);
+ tcg_temp_free(t0);
+ tcg_temp_free(t_31);
}
/* 64-bit signed mul, lower result in d and upper in d2. */
static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
{
- TCGv_i64 t0, t1;
+ TCGv_i64 t0, t1;
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
- tcg_gen_ext_i32_i64(t0, a);
- tcg_gen_ext_i32_i64(t1, b);
- tcg_gen_mul_i64(t0, t0, t1);
+ tcg_gen_ext_i32_i64(t0, a);
+ tcg_gen_ext_i32_i64(t1, b);
+ tcg_gen_mul_i64(t0, t0, t1);
- tcg_gen_trunc_i64_i32(d, t0);
- tcg_gen_shri_i64(t0, t0, 32);
- tcg_gen_trunc_i64_i32(d2, t0);
+ tcg_gen_trunc_i64_i32(d, t0);
+ tcg_gen_shri_i64(t0, t0, 32);
+ tcg_gen_trunc_i64_i32(d2, t0);
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
}
/* 64-bit unsigned muls, lower result in d and upper in d2. */
static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
{
- TCGv_i64 t0, t1;
+ TCGv_i64 t0, t1;
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
- tcg_gen_extu_i32_i64(t0, a);
- tcg_gen_extu_i32_i64(t1, b);
- tcg_gen_mul_i64(t0, t0, t1);
+ tcg_gen_extu_i32_i64(t0, a);
+ tcg_gen_extu_i32_i64(t1, b);
+ tcg_gen_mul_i64(t0, t0, t1);
- tcg_gen_trunc_i64_i32(d, t0);
- tcg_gen_shri_i64(t0, t0, 32);
- tcg_gen_trunc_i64_i32(d2, t0);
+ tcg_gen_trunc_i64_i32(d, t0);
+ tcg_gen_shri_i64(t0, t0, 32);
+ tcg_gen_trunc_i64_i32(d2, t0);
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
}
static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
{
- int l1;
+ int l1;
- l1 = gen_new_label();
+ l1 = gen_new_label();
- /*
- * d <<= 1
- * if (d >= s)
- * d -= s;
- */
- tcg_gen_shli_tl(d, a, 1);
- tcg_gen_brcond_tl(TCG_COND_LTU, d, b, l1);
- tcg_gen_sub_tl(d, d, b);
- gen_set_label(l1);
+ /*
+ * d <<= 1
+ * if (d >= s)
+ * d -= s;
+ */
+ tcg_gen_shli_tl(d, a, 1);
+ tcg_gen_brcond_tl(TCG_COND_LTU, d, b, l1);
+ tcg_gen_sub_tl(d, d, b);
+ gen_set_label(l1);
}
static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs)
{
- TCGv t;
+ TCGv t;
- /*
- * d <<= 1
- * if (n)
- * d += s;
- */
- t = tcg_temp_new();
- tcg_gen_shli_tl(d, a, 1);
- tcg_gen_shli_tl(t, ccs, 31 - 3);
- tcg_gen_sari_tl(t, t, 31);
- tcg_gen_and_tl(t, t, b);
- tcg_gen_add_tl(d, d, t);
- tcg_temp_free(t);
+ /*
+ * d <<= 1
+ * if (n)
+ * d += s;
+ */
+ t = tcg_temp_new();
+ tcg_gen_shli_tl(d, a, 1);
+ tcg_gen_shli_tl(t, ccs, 31 - 3);
+ tcg_gen_sari_tl(t, t, 31);
+ tcg_gen_and_tl(t, t, b);
+ tcg_gen_add_tl(d, d, t);
+ tcg_temp_free(t);
}
/* Extended arithmetics on CRIS. */
static inline void t_gen_add_flag(TCGv d, int flag)
{
- TCGv c;
+ TCGv c;
- c = tcg_temp_new();
- t_gen_mov_TN_preg(c, PR_CCS);
- /* Propagate carry into d. */
- tcg_gen_andi_tl(c, c, 1 << flag);
- if (flag)
- tcg_gen_shri_tl(c, c, flag);
- tcg_gen_add_tl(d, d, c);
- tcg_temp_free(c);
+ c = tcg_temp_new();
+ t_gen_mov_TN_preg(c, PR_CCS);
+ /* Propagate carry into d. */
+ tcg_gen_andi_tl(c, c, 1 << flag);
+ if (flag) {
+ tcg_gen_shri_tl(c, c, flag);
+ }
+ tcg_gen_add_tl(d, d, c);
+ tcg_temp_free(c);
}
static inline void t_gen_addx_carry(DisasContext *dc, TCGv d)
{
- if (dc->flagx_known) {
- if (dc->flags_x) {
- TCGv c;
+ if (dc->flagx_known) {
+ if (dc->flags_x) {
+ TCGv c;
- c = tcg_temp_new();
- t_gen_mov_TN_preg(c, PR_CCS);
- /* C flag is already at bit 0. */
- tcg_gen_andi_tl(c, c, C_FLAG);
- tcg_gen_add_tl(d, d, c);
- tcg_temp_free(c);
- }
- } else {
- TCGv x, c;
-
- x = tcg_temp_new();
- c = tcg_temp_new();
- t_gen_mov_TN_preg(x, PR_CCS);
- tcg_gen_mov_tl(c, x);
-
- /* Propagate carry into d if X is set. Branch free. */
- tcg_gen_andi_tl(c, c, C_FLAG);
- tcg_gen_andi_tl(x, x, X_FLAG);
- tcg_gen_shri_tl(x, x, 4);
-
- tcg_gen_and_tl(x, x, c);
- tcg_gen_add_tl(d, d, x);
- tcg_temp_free(x);
- tcg_temp_free(c);
- }
+ c = tcg_temp_new();
+ t_gen_mov_TN_preg(c, PR_CCS);
+ /* C flag is already at bit 0. */
+ tcg_gen_andi_tl(c, c, C_FLAG);
+ tcg_gen_add_tl(d, d, c);
+ tcg_temp_free(c);
+ }
+ } else {
+ TCGv x, c;
+
+ x = tcg_temp_new();
+ c = tcg_temp_new();
+ t_gen_mov_TN_preg(x, PR_CCS);
+ tcg_gen_mov_tl(c, x);
+
+ /* Propagate carry into d if X is set. Branch free. */
+ tcg_gen_andi_tl(c, c, C_FLAG);
+ tcg_gen_andi_tl(x, x, X_FLAG);
+ tcg_gen_shri_tl(x, x, 4);
+
+ tcg_gen_and_tl(x, x, c);
+ tcg_gen_add_tl(d, d, x);
+ tcg_temp_free(x);
+ tcg_temp_free(c);
+ }
}
static inline void t_gen_subx_carry(DisasContext *dc, TCGv d)
{
- if (dc->flagx_known) {
- if (dc->flags_x) {
- TCGv c;
+ if (dc->flagx_known) {
+ if (dc->flags_x) {
+ TCGv c;
- c = tcg_temp_new();
- t_gen_mov_TN_preg(c, PR_CCS);
- /* C flag is already at bit 0. */
- tcg_gen_andi_tl(c, c, C_FLAG);
- tcg_gen_sub_tl(d, d, c);
- tcg_temp_free(c);
- }
- } else {
- TCGv x, c;
-
- x = tcg_temp_new();
- c = tcg_temp_new();
- t_gen_mov_TN_preg(x, PR_CCS);
- tcg_gen_mov_tl(c, x);
-
- /* Propagate carry into d if X is set. Branch free. */
- tcg_gen_andi_tl(c, c, C_FLAG);
- tcg_gen_andi_tl(x, x, X_FLAG);
- tcg_gen_shri_tl(x, x, 4);
-
- tcg_gen_and_tl(x, x, c);
- tcg_gen_sub_tl(d, d, x);
- tcg_temp_free(x);
- tcg_temp_free(c);
- }
+ c = tcg_temp_new();
+ t_gen_mov_TN_preg(c, PR_CCS);
+ /* C flag is already at bit 0. */
+ tcg_gen_andi_tl(c, c, C_FLAG);
+ tcg_gen_sub_tl(d, d, c);
+ tcg_temp_free(c);
+ }
+ } else {
+ TCGv x, c;
+
+ x = tcg_temp_new();
+ c = tcg_temp_new();
+ t_gen_mov_TN_preg(x, PR_CCS);
+ tcg_gen_mov_tl(c, x);
+
+ /* Propagate carry into d if X is set. Branch free. */
+ tcg_gen_andi_tl(c, c, C_FLAG);
+ tcg_gen_andi_tl(x, x, X_FLAG);
+ tcg_gen_shri_tl(x, x, 4);
+
+ tcg_gen_and_tl(x, x, c);
+ tcg_gen_sub_tl(d, d, x);
+ tcg_temp_free(x);
+ tcg_temp_free(c);
+ }
}
/* Swap the two bytes within each half word of the s operand.
T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff) */
static inline void t_gen_swapb(TCGv d, TCGv s)
{
- TCGv t, org_s;
+ TCGv t, org_s;
- t = tcg_temp_new();
- org_s = tcg_temp_new();
+ t = tcg_temp_new();
+ org_s = tcg_temp_new();
- /* d and s may refer to the same object. */
- tcg_gen_mov_tl(org_s, s);
- tcg_gen_shli_tl(t, org_s, 8);
- tcg_gen_andi_tl(d, t, 0xff00ff00);
- tcg_gen_shri_tl(t, org_s, 8);
- tcg_gen_andi_tl(t, t, 0x00ff00ff);
- tcg_gen_or_tl(d, d, t);
- tcg_temp_free(t);
- tcg_temp_free(org_s);
+ /* d and s may refer to the same object. */
+ tcg_gen_mov_tl(org_s, s);
+ tcg_gen_shli_tl(t, org_s, 8);
+ tcg_gen_andi_tl(d, t, 0xff00ff00);
+ tcg_gen_shri_tl(t, org_s, 8);
+ tcg_gen_andi_tl(t, t, 0x00ff00ff);
+ tcg_gen_or_tl(d, d, t);
+ tcg_temp_free(t);
+ tcg_temp_free(org_s);
}
/* Swap the halfwords of the s operand. */
static inline void t_gen_swapw(TCGv d, TCGv s)
{
- TCGv t;
- /* d and s refer the same object. */
- t = tcg_temp_new();
- tcg_gen_mov_tl(t, s);
- tcg_gen_shli_tl(d, t, 16);
- tcg_gen_shri_tl(t, t, 16);
- tcg_gen_or_tl(d, d, t);
- tcg_temp_free(t);
+ TCGv t;
+ /* d and s refer the same object. */
+ t = tcg_temp_new();
+ tcg_gen_mov_tl(t, s);
+ tcg_gen_shli_tl(d, t, 16);
+ tcg_gen_shri_tl(t, t, 16);
+ tcg_gen_or_tl(d, d, t);
+ tcg_temp_free(t);
}
/* Reverse the within each byte.
@@ -532,607 +542,611 @@ static inline void t_gen_swapw(TCGv d, TCGv s)
*/
static inline void t_gen_swapr(TCGv d, TCGv s)
{
- struct {
- int shift; /* LSL when positive, LSR when negative. */
- uint32_t mask;
- } bitrev [] = {
- {7, 0x80808080},
- {5, 0x40404040},
- {3, 0x20202020},
- {1, 0x10101010},
- {-1, 0x08080808},
- {-3, 0x04040404},
- {-5, 0x02020202},
- {-7, 0x01010101}
- };
- int i;
- TCGv t, org_s;
-
- /* d and s refer the same object. */
- t = tcg_temp_new();
- org_s = tcg_temp_new();
- tcg_gen_mov_tl(org_s, s);
-
- tcg_gen_shli_tl(t, org_s, bitrev[0].shift);
- tcg_gen_andi_tl(d, t, bitrev[0].mask);
- for (i = 1; i < ARRAY_SIZE(bitrev); i++) {
- if (bitrev[i].shift >= 0) {
- tcg_gen_shli_tl(t, org_s, bitrev[i].shift);
- } else {
- tcg_gen_shri_tl(t, org_s, -bitrev[i].shift);
- }
- tcg_gen_andi_tl(t, t, bitrev[i].mask);
- tcg_gen_or_tl(d, d, t);
- }
- tcg_temp_free(t);
- tcg_temp_free(org_s);
+ struct {
+ int shift; /* LSL when positive, LSR when negative. */
+ uint32_t mask;
+ } bitrev[] = {
+ {7, 0x80808080},
+ {5, 0x40404040},
+ {3, 0x20202020},
+ {1, 0x10101010},
+ {-1, 0x08080808},
+ {-3, 0x04040404},
+ {-5, 0x02020202},
+ {-7, 0x01010101}
+ };
+ int i;
+ TCGv t, org_s;
+
+ /* d and s refer the same object. */
+ t = tcg_temp_new();
+ org_s = tcg_temp_new();
+ tcg_gen_mov_tl(org_s, s);
+
+ tcg_gen_shli_tl(t, org_s, bitrev[0].shift);
+ tcg_gen_andi_tl(d, t, bitrev[0].mask);
+ for (i = 1; i < ARRAY_SIZE(bitrev); i++) {
+ if (bitrev[i].shift >= 0) {
+ tcg_gen_shli_tl(t, org_s, bitrev[i].shift);
+ } else {
+ tcg_gen_shri_tl(t, org_s, -bitrev[i].shift);
+ }
+ tcg_gen_andi_tl(t, t, bitrev[i].mask);
+ tcg_gen_or_tl(d, d, t);
+ }
+ tcg_temp_free(t);
+ tcg_temp_free(org_s);
}
static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
{
- int l1;
+ int l1;
- l1 = gen_new_label();
+ l1 = gen_new_label();
- /* Conditional jmp. */
- tcg_gen_mov_tl(env_pc, pc_false);
- tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
- tcg_gen_mov_tl(env_pc, pc_true);
- gen_set_label(l1);
+ /* Conditional jmp. */
+ tcg_gen_mov_tl(env_pc, pc_false);
+ tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
+ tcg_gen_mov_tl(env_pc, pc_true);
+ gen_set_label(l1);
}
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
{
- TranslationBlock *tb;
- tb = dc->tb;
- if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
- tcg_gen_goto_tb(n);
- tcg_gen_movi_tl(env_pc, dest);
+ TranslationBlock *tb;
+ tb = dc->tb;
+ if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
+ tcg_gen_goto_tb(n);
+ tcg_gen_movi_tl(env_pc, dest);
tcg_gen_exit_tb((tcg_target_long)tb + n);
- } else {
- tcg_gen_movi_tl(env_pc, dest);
- tcg_gen_exit_tb(0);
- }
+ } else {
+ tcg_gen_movi_tl(env_pc, dest);
+ tcg_gen_exit_tb(0);
+ }
}
static inline void cris_clear_x_flag(DisasContext *dc)
{
- if (dc->flagx_known && dc->flags_x)
- dc->flags_uptodate = 0;
+ if (dc->flagx_known && dc->flags_x) {
+ dc->flags_uptodate = 0;
+ }
- dc->flagx_known = 1;
- dc->flags_x = 0;
+ dc->flagx_known = 1;
+ dc->flags_x = 0;
}
static void cris_flush_cc_state(DisasContext *dc)
{
- if (dc->cc_size_uptodate != dc->cc_size) {
- tcg_gen_movi_tl(cc_size, dc->cc_size);
- dc->cc_size_uptodate = dc->cc_size;
- }
- tcg_gen_movi_tl(cc_op, dc->cc_op);
- tcg_gen_movi_tl(cc_mask, dc->cc_mask);
+ if (dc->cc_size_uptodate != dc->cc_size) {
+ tcg_gen_movi_tl(cc_size, dc->cc_size);
+ dc->cc_size_uptodate = dc->cc_size;
+ }
+ tcg_gen_movi_tl(cc_op, dc->cc_op);
+ tcg_gen_movi_tl(cc_mask, dc->cc_mask);
}
static void cris_evaluate_flags(DisasContext *dc)
{
- if (dc->flags_uptodate)
- return;
-
- cris_flush_cc_state(dc);
-
- switch (dc->cc_op)
- {
- case CC_OP_MCP:
- gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS], cpu_env,
- cpu_PR[PR_CCS], cc_src,
- cc_dest, cc_result);
- break;
- case CC_OP_MULS:
- gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS], cpu_env,
- cpu_PR[PR_CCS], cc_result,
- cpu_PR[PR_MOF]);
- break;
- case CC_OP_MULU:
- gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS], cpu_env,
- cpu_PR[PR_CCS], cc_result,
- cpu_PR[PR_MOF]);
- break;
- case CC_OP_MOVE:
- case CC_OP_AND:
- case CC_OP_OR:
- case CC_OP_XOR:
- case CC_OP_ASR:
- case CC_OP_LSR:
- case CC_OP_LSL:
- switch (dc->cc_size)
- {
- case 4:
- gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
- cpu_env, cpu_PR[PR_CCS], cc_result);
- break;
- case 2:
- gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
- cpu_env, cpu_PR[PR_CCS], cc_result);
- break;
- default:
- gen_helper_evaluate_flags(cpu_env);
- break;
- }
- break;
- case CC_OP_FLAGS:
- /* live. */
- break;
- case CC_OP_SUB:
- case CC_OP_CMP:
- if (dc->cc_size == 4)
- gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS], cpu_env,
- cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
- else
- gen_helper_evaluate_flags(cpu_env);
-
- break;
- default:
- switch (dc->cc_size)
- {
- case 4:
- gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS], cpu_env,
- cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
- break;
- default:
- gen_helper_evaluate_flags(cpu_env);
- break;
- }
- break;
- }
-
- if (dc->flagx_known) {
- if (dc->flags_x)
- tcg_gen_ori_tl(cpu_PR[PR_CCS],
- cpu_PR[PR_CCS], X_FLAG);
- else if (dc->cc_op == CC_OP_FLAGS)
- tcg_gen_andi_tl(cpu_PR[PR_CCS],
- cpu_PR[PR_CCS], ~X_FLAG);
+ if (dc->flags_uptodate) {
+ return;
+ }
+
+ cris_flush_cc_state(dc);
+
+ switch (dc->cc_op) {
+ case CC_OP_MCP:
+ gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS], cpu_env,
+ cpu_PR[PR_CCS], cc_src,
+ cc_dest, cc_result);
+ break;
+ case CC_OP_MULS:
+ gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS], cpu_env,
+ cpu_PR[PR_CCS], cc_result,
+ cpu_PR[PR_MOF]);
+ break;
+ case CC_OP_MULU:
+ gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS], cpu_env,
+ cpu_PR[PR_CCS], cc_result,
+ cpu_PR[PR_MOF]);
+ break;
+ case CC_OP_MOVE:
+ case CC_OP_AND:
+ case CC_OP_OR:
+ case CC_OP_XOR:
+ case CC_OP_ASR:
+ case CC_OP_LSR:
+ case CC_OP_LSL:
+ switch (dc->cc_size) {
+ case 4:
+ gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
+ cpu_env, cpu_PR[PR_CCS], cc_result);
+ break;
+ case 2:
+ gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
+ cpu_env, cpu_PR[PR_CCS], cc_result);
+ break;
+ default:
+ gen_helper_evaluate_flags(cpu_env);
+ break;
+ }
+ break;
+ case CC_OP_FLAGS:
+ /* live. */
+ break;
+ case CC_OP_SUB:
+ case CC_OP_CMP:
+ if (dc->cc_size == 4) {
+ gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS], cpu_env,
+ cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
+ } else {
+ gen_helper_evaluate_flags(cpu_env);
+ }
+
+ break;
+ default:
+ switch (dc->cc_size) {
+ case 4:
+ gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS], cpu_env,
+ cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
+ break;
+ default:
+ gen_helper_evaluate_flags(cpu_env);
+ break;
}
- dc->flags_uptodate = 1;
+ break;
+ }
+
+ if (dc->flagx_known) {
+ if (dc->flags_x) {
+ tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], X_FLAG);
+ } else if (dc->cc_op == CC_OP_FLAGS) {
+ tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~X_FLAG);
+ }
+ }
+ dc->flags_uptodate = 1;
}
static void cris_cc_mask(DisasContext *dc, unsigned int mask)
{
- uint32_t ovl;
+ uint32_t ovl;
- if (!mask) {
- dc->update_cc = 0;
- return;
- }
+ if (!mask) {
+ dc->update_cc = 0;
+ return;
+ }
- /* Check if we need to evaluate the condition codes due to
- CC overlaying. */
- ovl = (dc->cc_mask ^ mask) & ~mask;
- if (ovl) {
- /* TODO: optimize this case. It trigs all the time. */
- cris_evaluate_flags (dc);
- }
- dc->cc_mask = mask;
- dc->update_cc = 1;
+ /* Check if we need to evaluate the condition codes due to
+ CC overlaying. */
+ ovl = (dc->cc_mask ^ mask) & ~mask;
+ if (ovl) {
+ /* TODO: optimize this case. It trigs all the time. */
+ cris_evaluate_flags(dc);
+ }
+ dc->cc_mask = mask;
+ dc->update_cc = 1;
}
static void cris_update_cc_op(DisasContext *dc, int op, int size)
{
- dc->cc_op = op;
- dc->cc_size = size;
- dc->flags_uptodate = 0;
+ dc->cc_op = op;
+ dc->cc_size = size;
+ dc->flags_uptodate = 0;
}
static inline void cris_update_cc_x(DisasContext *dc)
{
- /* Save the x flag state at the time of the cc snapshot. */
- if (dc->flagx_known) {
- if (dc->cc_x_uptodate == (2 | dc->flags_x))
- return;
- tcg_gen_movi_tl(cc_x, dc->flags_x);
- dc->cc_x_uptodate = 2 | dc->flags_x;
- }
- else {
- tcg_gen_andi_tl(cc_x, cpu_PR[PR_CCS], X_FLAG);
- dc->cc_x_uptodate = 1;
- }
+ /* Save the x flag state at the time of the cc snapshot. */
+ if (dc->flagx_known) {
+ if (dc->cc_x_uptodate == (2 | dc->flags_x)) {
+ return;
+ }
+ tcg_gen_movi_tl(cc_x, dc->flags_x);
+ dc->cc_x_uptodate = 2 | dc->flags_x;
+ } else {
+ tcg_gen_andi_tl(cc_x, cpu_PR[PR_CCS], X_FLAG);
+ dc->cc_x_uptodate = 1;
+ }
}
/* Update cc prior to executing ALU op. Needs source operands untouched. */
static void cris_pre_alu_update_cc(DisasContext *dc, int op,
- TCGv dst, TCGv src, int size)
-{
- if (dc->update_cc) {
- cris_update_cc_op(dc, op, size);
- tcg_gen_mov_tl(cc_src, src);
-
- if (op != CC_OP_MOVE
- && op != CC_OP_AND
- && op != CC_OP_OR
- && op != CC_OP_XOR
- && op != CC_OP_ASR
- && op != CC_OP_LSR
- && op != CC_OP_LSL)
- tcg_gen_mov_tl(cc_dest, dst);
+ TCGv dst, TCGv src, int size)
+{
+ if (dc->update_cc) {
+ cris_update_cc_op(dc, op, size);
+ tcg_gen_mov_tl(cc_src, src);
+
+ if (op != CC_OP_MOVE
+ && op != CC_OP_AND
+ && op != CC_OP_OR
+ && op != CC_OP_XOR
+ && op != CC_OP_ASR
+ && op != CC_OP_LSR
+ && op != CC_OP_LSL) {
+ tcg_gen_mov_tl(cc_dest, dst);
+ }
- cris_update_cc_x(dc);
- }
+ cris_update_cc_x(dc);
+ }
}
/* Update cc after executing ALU op. needs the result. */
static inline void cris_update_result(DisasContext *dc, TCGv res)
{
- if (dc->update_cc)
- tcg_gen_mov_tl(cc_result, res);
+ if (dc->update_cc) {
+ tcg_gen_mov_tl(cc_result, res);
+ }
}
/* Returns one if the write back stage should execute. */
static void cris_alu_op_exec(DisasContext *dc, int op,
- TCGv dst, TCGv a, TCGv b, int size)
-{
- /* Emit the ALU insns. */
- switch (op)
- {
- case CC_OP_ADD:
- tcg_gen_add_tl(dst, a, b);
- /* Extended arithmetics. */
- t_gen_addx_carry(dc, dst);
- break;
- case CC_OP_ADDC:
- tcg_gen_add_tl(dst, a, b);
- t_gen_add_flag(dst, 0); /* C_FLAG. */
- break;
- case CC_OP_MCP:
- tcg_gen_add_tl(dst, a, b);
- t_gen_add_flag(dst, 8); /* R_FLAG. */
- break;
- case CC_OP_SUB:
- tcg_gen_sub_tl(dst, a, b);
- /* Extended arithmetics. */
- t_gen_subx_carry(dc, dst);
- break;
- case CC_OP_MOVE:
- tcg_gen_mov_tl(dst, b);
- break;
- case CC_OP_OR:
- tcg_gen_or_tl(dst, a, b);
- break;
- case CC_OP_AND:
- tcg_gen_and_tl(dst, a, b);
- break;
- case CC_OP_XOR:
- tcg_gen_xor_tl(dst, a, b);
- break;
- case CC_OP_LSL:
- t_gen_lsl(dst, a, b);
- break;
- case CC_OP_LSR:
- t_gen_lsr(dst, a, b);
- break;
- case CC_OP_ASR:
- t_gen_asr(dst, a, b);
- break;
- case CC_OP_NEG:
- tcg_gen_neg_tl(dst, b);
- /* Extended arithmetics. */
- t_gen_subx_carry(dc, dst);
- break;
- case CC_OP_LZ:
- gen_helper_lz(dst, b);
- break;
- case CC_OP_MULS:
- t_gen_muls(dst, cpu_PR[PR_MOF], a, b);
- break;
- case CC_OP_MULU:
- t_gen_mulu(dst, cpu_PR[PR_MOF], a, b);
- break;
- case CC_OP_DSTEP:
- t_gen_cris_dstep(dst, a, b);
- break;
- case CC_OP_MSTEP:
- t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]);
- break;
- case CC_OP_BOUND:
- {
- int l1;
- l1 = gen_new_label();
- tcg_gen_mov_tl(dst, a);
- tcg_gen_brcond_tl(TCG_COND_LEU, a, b, l1);
- tcg_gen_mov_tl(dst, b);
- gen_set_label(l1);
- }
- break;
- case CC_OP_CMP:
- tcg_gen_sub_tl(dst, a, b);
- /* Extended arithmetics. */
- t_gen_subx_carry(dc, dst);
- break;
- default:
- qemu_log("illegal ALU op.\n");
- BUG();
- break;
- }
-
- if (size == 1)
- tcg_gen_andi_tl(dst, dst, 0xff);
- else if (size == 2)
- tcg_gen_andi_tl(dst, dst, 0xffff);
+ TCGv dst, TCGv a, TCGv b, int size)
+{
+ /* Emit the ALU insns. */
+ switch (op) {
+ case CC_OP_ADD:
+ tcg_gen_add_tl(dst, a, b);
+ /* Extended arithmetics. */
+ t_gen_addx_carry(dc, dst);
+ break;
+ case CC_OP_ADDC:
+ tcg_gen_add_tl(dst, a, b);
+ t_gen_add_flag(dst, 0); /* C_FLAG. */
+ break;
+ case CC_OP_MCP:
+ tcg_gen_add_tl(dst, a, b);
+ t_gen_add_flag(dst, 8); /* R_FLAG. */
+ break;
+ case CC_OP_SUB:
+ tcg_gen_sub_tl(dst, a, b);
+ /* Extended arithmetics. */
+ t_gen_subx_carry(dc, dst);
+ break;
+ case CC_OP_MOVE:
+ tcg_gen_mov_tl(dst, b);
+ break;
+ case CC_OP_OR:
+ tcg_gen_or_tl(dst, a, b);
+ break;
+ case CC_OP_AND:
+ tcg_gen_and_tl(dst, a, b);
+ break;
+ case CC_OP_XOR:
+ tcg_gen_xor_tl(dst, a, b);
+ break;
+ case CC_OP_LSL:
+ t_gen_lsl(dst, a, b);
+ break;
+ case CC_OP_LSR:
+ t_gen_lsr(dst, a, b);
+ break;
+ case CC_OP_ASR:
+ t_gen_asr(dst, a, b);
+ break;
+ case CC_OP_NEG:
+ tcg_gen_neg_tl(dst, b);
+ /* Extended arithmetics. */
+ t_gen_subx_carry(dc, dst);
+ break;
+ case CC_OP_LZ:
+ gen_helper_lz(dst, b);
+ break;
+ case CC_OP_MULS:
+ t_gen_muls(dst, cpu_PR[PR_MOF], a, b);
+ break;
+ case CC_OP_MULU:
+ t_gen_mulu(dst, cpu_PR[PR_MOF], a, b);
+ break;
+ case CC_OP_DSTEP:
+ t_gen_cris_dstep(dst, a, b);
+ break;
+ case CC_OP_MSTEP:
+ t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]);
+ break;
+ case CC_OP_BOUND:
+ {
+ int l1;
+ l1 = gen_new_label();
+ tcg_gen_mov_tl(dst, a);
+ tcg_gen_brcond_tl(TCG_COND_LEU, a, b, l1);
+ tcg_gen_mov_tl(dst, b);
+ gen_set_label(l1);
+ }
+ break;
+ case CC_OP_CMP:
+ tcg_gen_sub_tl(dst, a, b);
+ /* Extended arithmetics. */
+ t_gen_subx_carry(dc, dst);
+ break;
+ default:
+ qemu_log("illegal ALU op.\n");
+ BUG();
+ break;
+ }
+
+ if (size == 1) {
+ tcg_gen_andi_tl(dst, dst, 0xff);
+ } else if (size == 2) {
+ tcg_gen_andi_tl(dst, dst, 0xffff);
+ }
}
static void cris_alu(DisasContext *dc, int op,
- TCGv d, TCGv op_a, TCGv op_b, int size)
+ TCGv d, TCGv op_a, TCGv op_b, int size)
{
- TCGv tmp;
- int writeback;
+ TCGv tmp;
+ int writeback;
- writeback = 1;
+ writeback = 1;
- if (op == CC_OP_CMP) {
- tmp = tcg_temp_new();
- writeback = 0;
- } else if (size == 4) {
- tmp = d;
- writeback = 0;
- } else
- tmp = tcg_temp_new();
+ if (op == CC_OP_CMP) {
+ tmp = tcg_temp_new();
+ writeback = 0;
+ } else if (size == 4) {
+ tmp = d;
+ writeback = 0;
+ } else {
+ tmp = tcg_temp_new();
+ }
- cris_pre_alu_update_cc(dc, op, op_a, op_b, size);
- cris_alu_op_exec(dc, op, tmp, op_a, op_b, size);
- cris_update_result(dc, tmp);
+ cris_pre_alu_update_cc(dc, op, op_a, op_b, size);
+ cris_alu_op_exec(dc, op, tmp, op_a, op_b, size);
+ cris_update_result(dc, tmp);
- /* Writeback. */
- if (writeback) {
- if (size == 1)
- tcg_gen_andi_tl(d, d, ~0xff);
- else
- tcg_gen_andi_tl(d, d, ~0xffff);
- tcg_gen_or_tl(d, d, tmp);
- }
- if (!TCGV_EQUAL(tmp, d))
- tcg_temp_free(tmp);
+ /* Writeback. */
+ if (writeback) {
+ if (size == 1) {
+ tcg_gen_andi_tl(d, d, ~0xff);
+ } else {
+ tcg_gen_andi_tl(d, d, ~0xffff);
+ }
+ tcg_gen_or_tl(d, d, tmp);
+ }
+ if (!TCGV_EQUAL(tmp, d)) {
+ tcg_temp_free(tmp);
+ }
}
static int arith_cc(DisasContext *dc)
{
- if (dc->update_cc) {
- switch (dc->cc_op) {
- case CC_OP_ADDC: return 1;
- case CC_OP_ADD: return 1;
- case CC_OP_SUB: return 1;
- case CC_OP_DSTEP: return 1;
- case CC_OP_LSL: return 1;
- case CC_OP_LSR: return 1;
- case CC_OP_ASR: return 1;
- case CC_OP_CMP: return 1;
- case CC_OP_NEG: return 1;
- case CC_OP_OR: return 1;
- case CC_OP_AND: return 1;
- case CC_OP_XOR: return 1;
- case CC_OP_MULU: return 1;
- case CC_OP_MULS: return 1;
- default:
- return 0;
- }
- }
- return 0;
+ if (dc->update_cc) {
+ switch (dc->cc_op) {
+ case CC_OP_ADDC: return 1;
+ case CC_OP_ADD: return 1;
+ case CC_OP_SUB: return 1;
+ case CC_OP_DSTEP: return 1;
+ case CC_OP_LSL: return 1;
+ case CC_OP_LSR: return 1;
+ case CC_OP_ASR: return 1;
+ case CC_OP_CMP: return 1;
+ case CC_OP_NEG: return 1;
+ case CC_OP_OR: return 1;
+ case CC_OP_AND: return 1;
+ case CC_OP_XOR: return 1;
+ case CC_OP_MULU: return 1;
+ case CC_OP_MULS: return 1;
+ default:
+ return 0;
+ }
+ }
+ return 0;
}
static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
{
- int arith_opt, move_opt;
-
- /* TODO: optimize more condition codes. */
-
- /*
- * If the flags are live, we've gotta look into the bits of CCS.
- * Otherwise, if we just did an arithmetic operation we try to
- * evaluate the condition code faster.
- *
- * When this function is done, T0 should be non-zero if the condition
- * code is true.
- */
- arith_opt = arith_cc(dc) && !dc->flags_uptodate;
- move_opt = (dc->cc_op == CC_OP_MOVE);
- switch (cond) {
- case CC_EQ:
- if ((arith_opt || move_opt)
- && dc->cc_x_uptodate != (2 | X_FLAG)) {
- tcg_gen_setcond_tl(TCG_COND_EQ, cc,
- cc_result, tcg_const_tl(0));
- }
- else {
- cris_evaluate_flags(dc);
- tcg_gen_andi_tl(cc,
- cpu_PR[PR_CCS], Z_FLAG);
- }
- break;
- case CC_NE:
- if ((arith_opt || move_opt)
- && dc->cc_x_uptodate != (2 | X_FLAG)) {
- tcg_gen_mov_tl(cc, cc_result);
- } else {
- cris_evaluate_flags(dc);
- tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
- Z_FLAG);
- tcg_gen_andi_tl(cc, cc, Z_FLAG);
- }
- break;
- case CC_CS:
- cris_evaluate_flags(dc);
- tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], C_FLAG);
- break;
- case CC_CC:
- cris_evaluate_flags(dc);
- tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], C_FLAG);
- tcg_gen_andi_tl(cc, cc, C_FLAG);
- break;
- case CC_VS:
- cris_evaluate_flags(dc);
- tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], V_FLAG);
- break;
- case CC_VC:
- cris_evaluate_flags(dc);
- tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
- V_FLAG);
- tcg_gen_andi_tl(cc, cc, V_FLAG);
- break;
- case CC_PL:
- if (arith_opt || move_opt) {
- int bits = 31;
-
- if (dc->cc_size == 1)
- bits = 7;
- else if (dc->cc_size == 2)
- bits = 15;
-
- tcg_gen_shri_tl(cc, cc_result, bits);
- tcg_gen_xori_tl(cc, cc, 1);
- } else {
- cris_evaluate_flags(dc);
- tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
- N_FLAG);
- tcg_gen_andi_tl(cc, cc, N_FLAG);
- }
- break;
- case CC_MI:
- if (arith_opt || move_opt) {
- int bits = 31;
-
- if (dc->cc_size == 1)
- bits = 7;
- else if (dc->cc_size == 2)
- bits = 15;
-
- tcg_gen_shri_tl(cc, cc_result, bits);
- tcg_gen_andi_tl(cc, cc, 1);
- }
- else {
- cris_evaluate_flags(dc);
- tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
- N_FLAG);
- }
- break;
- case CC_LS:
- cris_evaluate_flags(dc);
- tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
- C_FLAG | Z_FLAG);
- break;
- case CC_HI:
- cris_evaluate_flags(dc);
- {
- TCGv tmp;
-
- tmp = tcg_temp_new();
- tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
- C_FLAG | Z_FLAG);
- /* Overlay the C flag on top of the Z. */
- tcg_gen_shli_tl(cc, tmp, 2);
- tcg_gen_and_tl(cc, tmp, cc);
- tcg_gen_andi_tl(cc, cc, Z_FLAG);
-
- tcg_temp_free(tmp);
- }
- break;
- case CC_GE:
- cris_evaluate_flags(dc);
- /* Overlay the V flag on top of the N. */
- tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
- tcg_gen_xor_tl(cc,
- cpu_PR[PR_CCS], cc);
- tcg_gen_andi_tl(cc, cc, N_FLAG);
- tcg_gen_xori_tl(cc, cc, N_FLAG);
- break;
- case CC_LT:
- cris_evaluate_flags(dc);
- /* Overlay the V flag on top of the N. */
- tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
- tcg_gen_xor_tl(cc,
- cpu_PR[PR_CCS], cc);
- tcg_gen_andi_tl(cc, cc, N_FLAG);
- break;
- case CC_GT:
- cris_evaluate_flags(dc);
- {
- TCGv n, z;
-
- n = tcg_temp_new();
- z = tcg_temp_new();
-
- /* To avoid a shift we overlay everything on
- the V flag. */
- tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
- tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
- /* invert Z. */
- tcg_gen_xori_tl(z, z, 2);
-
- tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
- tcg_gen_xori_tl(n, n, 2);
- tcg_gen_and_tl(cc, z, n);
- tcg_gen_andi_tl(cc, cc, 2);
-
- tcg_temp_free(n);
- tcg_temp_free(z);
- }
- break;
- case CC_LE:
- cris_evaluate_flags(dc);
- {
- TCGv n, z;
-
- n = tcg_temp_new();
- z = tcg_temp_new();
-
- /* To avoid a shift we overlay everything on
- the V flag. */
- tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
- tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
-
- tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
- tcg_gen_or_tl(cc, z, n);
- tcg_gen_andi_tl(cc, cc, 2);
-
- tcg_temp_free(n);
- tcg_temp_free(z);
- }
- break;
- case CC_P:
- cris_evaluate_flags(dc);
- tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], P_FLAG);
- break;
- case CC_A:
- tcg_gen_movi_tl(cc, 1);
- break;
- default:
- BUG();
- break;
- };
+ int arith_opt, move_opt;
+
+ /* TODO: optimize more condition codes. */
+
+ /*
+ * If the flags are live, we've gotta look into the bits of CCS.
+ * Otherwise, if we just did an arithmetic operation we try to
+ * evaluate the condition code faster.
+ *
+ * When this function is done, T0 should be non-zero if the condition
+ * code is true.
+ */
+ arith_opt = arith_cc(dc) && !dc->flags_uptodate;
+ move_opt = (dc->cc_op == CC_OP_MOVE);
+ switch (cond) {
+ case CC_EQ:
+ if ((arith_opt || move_opt)
+ && dc->cc_x_uptodate != (2 | X_FLAG)) {
+ tcg_gen_setcond_tl(TCG_COND_EQ, cc,
+ cc_result, tcg_const_tl(0));
+ } else {
+ cris_evaluate_flags(dc);
+ tcg_gen_andi_tl(cc,
+ cpu_PR[PR_CCS], Z_FLAG);
+ }
+ break;
+ case CC_NE:
+ if ((arith_opt || move_opt)
+ && dc->cc_x_uptodate != (2 | X_FLAG)) {
+ tcg_gen_mov_tl(cc, cc_result);
+ } else {
+ cris_evaluate_flags(dc);
+ tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
+ Z_FLAG);
+ tcg_gen_andi_tl(cc, cc, Z_FLAG);
+ }
+ break;
+ case CC_CS:
+ cris_evaluate_flags(dc);
+ tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], C_FLAG);
+ break;
+ case CC_CC:
+ cris_evaluate_flags(dc);
+ tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], C_FLAG);
+ tcg_gen_andi_tl(cc, cc, C_FLAG);
+ break;
+ case CC_VS:
+ cris_evaluate_flags(dc);
+ tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], V_FLAG);
+ break;
+ case CC_VC:
+ cris_evaluate_flags(dc);
+ tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
+ V_FLAG);
+ tcg_gen_andi_tl(cc, cc, V_FLAG);
+ break;
+ case CC_PL:
+ if (arith_opt || move_opt) {
+ int bits = 31;
+
+ if (dc->cc_size == 1) {
+ bits = 7;
+ } else if (dc->cc_size == 2) {
+ bits = 15;
+ }
+
+ tcg_gen_shri_tl(cc, cc_result, bits);
+ tcg_gen_xori_tl(cc, cc, 1);
+ } else {
+ cris_evaluate_flags(dc);
+ tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
+ N_FLAG);
+ tcg_gen_andi_tl(cc, cc, N_FLAG);
+ }
+ break;
+ case CC_MI:
+ if (arith_opt || move_opt) {
+ int bits = 31;
+
+ if (dc->cc_size == 1) {
+ bits = 7;
+ } else if (dc->cc_size == 2) {
+ bits = 15;
+ }
+
+ tcg_gen_shri_tl(cc, cc_result, bits);
+ tcg_gen_andi_tl(cc, cc, 1);
+ } else {
+ cris_evaluate_flags(dc);
+ tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
+ N_FLAG);
+ }
+ break;
+ case CC_LS:
+ cris_evaluate_flags(dc);
+ tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
+ C_FLAG | Z_FLAG);
+ break;
+ case CC_HI:
+ cris_evaluate_flags(dc);
+ {
+ TCGv tmp;
+
+ tmp = tcg_temp_new();
+ tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
+ C_FLAG | Z_FLAG);
+ /* Overlay the C flag on top of the Z. */
+ tcg_gen_shli_tl(cc, tmp, 2);
+ tcg_gen_and_tl(cc, tmp, cc);
+ tcg_gen_andi_tl(cc, cc, Z_FLAG);
+
+ tcg_temp_free(tmp);
+ }
+ break;
+ case CC_GE:
+ cris_evaluate_flags(dc);
+ /* Overlay the V flag on top of the N. */
+ tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
+ tcg_gen_xor_tl(cc,
+ cpu_PR[PR_CCS], cc);
+ tcg_gen_andi_tl(cc, cc, N_FLAG);
+ tcg_gen_xori_tl(cc, cc, N_FLAG);
+ break;
+ case CC_LT:
+ cris_evaluate_flags(dc);
+ /* Overlay the V flag on top of the N. */
+ tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
+ tcg_gen_xor_tl(cc,
+ cpu_PR[PR_CCS], cc);
+ tcg_gen_andi_tl(cc, cc, N_FLAG);
+ break;
+ case CC_GT:
+ cris_evaluate_flags(dc);
+ {
+ TCGv n, z;
+
+ n = tcg_temp_new();
+ z = tcg_temp_new();
+
+ /* To avoid a shift we overlay everything on
+ the V flag. */
+ tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
+ tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
+ /* invert Z. */
+ tcg_gen_xori_tl(z, z, 2);
+
+ tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
+ tcg_gen_xori_tl(n, n, 2);
+ tcg_gen_and_tl(cc, z, n);
+ tcg_gen_andi_tl(cc, cc, 2);
+
+ tcg_temp_free(n);
+ tcg_temp_free(z);
+ }
+ break;
+ case CC_LE:
+ cris_evaluate_flags(dc);
+ {
+ TCGv n, z;
+
+ n = tcg_temp_new();
+ z = tcg_temp_new();
+
+ /* To avoid a shift we overlay everything on
+ the V flag. */
+ tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
+ tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
+
+ tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
+ tcg_gen_or_tl(cc, z, n);
+ tcg_gen_andi_tl(cc, cc, 2);
+
+ tcg_temp_free(n);
+ tcg_temp_free(z);
+ }
+ break;
+ case CC_P:
+ cris_evaluate_flags(dc);
+ tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], P_FLAG);
+ break;
+ case CC_A:
+ tcg_gen_movi_tl(cc, 1);
+ break;
+ default:
+ BUG();
+ break;
+ };
}
static void cris_store_direct_jmp(DisasContext *dc)
{
- /* Store the direct jmp state into the cpu-state. */
- if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
- if (dc->jmp == JMP_DIRECT) {
- tcg_gen_movi_tl(env_btaken, 1);
- }
- tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
- dc->jmp = JMP_INDIRECT;
- }
+ /* Store the direct jmp state into the cpu-state. */
+ if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
+ if (dc->jmp == JMP_DIRECT) {
+ tcg_gen_movi_tl(env_btaken, 1);
+ }
+ tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
+ dc->jmp = JMP_INDIRECT;
+ }
}
static void cris_prepare_cc_branch (DisasContext *dc,
- int offset, int cond)
+ int offset, int cond)
{
- /* This helps us re-schedule the micro-code to insns in delay-slots
- before the actual jump. */
- dc->delayed_branch = 2;
- dc->jmp = JMP_DIRECT_CC;
- dc->jmp_pc = dc->pc + offset;
+ /* This helps us re-schedule the micro-code to insns in delay-slots
+ before the actual jump. */
+ dc->delayed_branch = 2;
+ dc->jmp = JMP_DIRECT_CC;
+ dc->jmp_pc = dc->pc + offset;
- gen_tst_cc (dc, env_btaken, cond);
- tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
+ gen_tst_cc(dc, env_btaken, cond);
+ tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
}
@@ -1140,199 +1154,207 @@ static void cris_prepare_cc_branch (DisasContext *dc,
when the dest addr is constant to allow tb chaining. */
static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
{
- /* This helps us re-schedule the micro-code to insns in delay-slots
- before the actual jump. */
- dc->delayed_branch = 2;
- dc->jmp = type;
- if (type == JMP_INDIRECT) {
- tcg_gen_movi_tl(env_btaken, 1);
- }
+ /* This helps us re-schedule the micro-code to insns in delay-slots
+ before the actual jump. */
+ dc->delayed_branch = 2;
+ dc->jmp = type;
+ if (type == JMP_INDIRECT) {
+ tcg_gen_movi_tl(env_btaken, 1);
+ }
}
static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
{
- int mem_index = cpu_mmu_index(dc->env);
+ int mem_index = cpu_mmu_index(dc->env);
- /* If we get a fault on a delayslot we must keep the jmp state in
- the cpu-state to be able to re-execute the jmp. */
- if (dc->delayed_branch == 1)
- cris_store_direct_jmp(dc);
+ /* If we get a fault on a delayslot we must keep the jmp state in
+ the cpu-state to be able to re-execute the jmp. */
+ if (dc->delayed_branch == 1) {
+ cris_store_direct_jmp(dc);
+ }
- tcg_gen_qemu_ld64(dst, addr, mem_index);
+ tcg_gen_qemu_ld64(dst, addr, mem_index);
}
static void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
- unsigned int size, int sign)
-{
- int mem_index = cpu_mmu_index(dc->env);
-
- /* If we get a fault on a delayslot we must keep the jmp state in
- the cpu-state to be able to re-execute the jmp. */
- if (dc->delayed_branch == 1)
- cris_store_direct_jmp(dc);
-
- if (size == 1) {
- if (sign)
- tcg_gen_qemu_ld8s(dst, addr, mem_index);
- else
- tcg_gen_qemu_ld8u(dst, addr, mem_index);
- }
- else if (size == 2) {
- if (sign)
- tcg_gen_qemu_ld16s(dst, addr, mem_index);
- else
- tcg_gen_qemu_ld16u(dst, addr, mem_index);
- }
- else if (size == 4) {
- tcg_gen_qemu_ld32u(dst, addr, mem_index);
- }
- else {
- abort();
- }
+ unsigned int size, int sign)
+{
+ int mem_index = cpu_mmu_index(dc->env);
+
+ /* If we get a fault on a delayslot we must keep the jmp state in
+ the cpu-state to be able to re-execute the jmp. */
+ if (dc->delayed_branch == 1) {
+ cris_store_direct_jmp(dc);
+ }
+
+ if (size == 1) {
+ if (sign) {
+ tcg_gen_qemu_ld8s(dst, addr, mem_index);
+ } else {
+ tcg_gen_qemu_ld8u(dst, addr, mem_index);
+ }
+ } else if (size == 2) {
+ if (sign) {
+ tcg_gen_qemu_ld16s(dst, addr, mem_index);
+ } else {
+ tcg_gen_qemu_ld16u(dst, addr, mem_index);
+ }
+ } else if (size == 4) {
+ tcg_gen_qemu_ld32u(dst, addr, mem_index);
+ } else {
+ abort();
+ }
}
static void gen_store (DisasContext *dc, TCGv addr, TCGv val,
- unsigned int size)
+ unsigned int size)
{
- int mem_index = cpu_mmu_index(dc->env);
+ int mem_index = cpu_mmu_index(dc->env);
- /* If we get a fault on a delayslot we must keep the jmp state in
- the cpu-state to be able to re-execute the jmp. */
- if (dc->delayed_branch == 1)
- cris_store_direct_jmp(dc);
+ /* If we get a fault on a delayslot we must keep the jmp state in
+ the cpu-state to be able to re-execute the jmp. */
+ if (dc->delayed_branch == 1) {
+ cris_store_direct_jmp(dc);
+ }
- /* Conditional writes. We only support the kind were X and P are known
- at translation time. */
- if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) {
- dc->postinc = 0;
- cris_evaluate_flags(dc);
- tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
- return;
- }
+ /* Conditional writes. We only support the kind were X and P are known
+ at translation time. */
+ if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) {
+ dc->postinc = 0;
+ cris_evaluate_flags(dc);
+ tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
+ return;
+ }
- if (size == 1)
- tcg_gen_qemu_st8(val, addr, mem_index);
- else if (size == 2)
- tcg_gen_qemu_st16(val, addr, mem_index);
- else
- tcg_gen_qemu_st32(val, addr, mem_index);
+ if (size == 1) {
+ tcg_gen_qemu_st8(val, addr, mem_index);
+ } else if (size == 2) {
+ tcg_gen_qemu_st16(val, addr, mem_index);
+ } else {
+ tcg_gen_qemu_st32(val, addr, mem_index);
+ }
- if (dc->flagx_known && dc->flags_x) {
- cris_evaluate_flags(dc);
- tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
- }
+ if (dc->flagx_known && dc->flags_x) {
+ cris_evaluate_flags(dc);
+ tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
+ }
}
static inline void t_gen_sext(TCGv d, TCGv s, int size)
{
- if (size == 1)
- tcg_gen_ext8s_i32(d, s);
- else if (size == 2)
- tcg_gen_ext16s_i32(d, s);
- else if(!TCGV_EQUAL(d, s))
- tcg_gen_mov_tl(d, s);
+ if (size == 1) {
+ tcg_gen_ext8s_i32(d, s);
+ } else if (size == 2) {
+ tcg_gen_ext16s_i32(d, s);
+ } else if (!TCGV_EQUAL(d, s)) {
+ tcg_gen_mov_tl(d, s);
+ }
}
static inline void t_gen_zext(TCGv d, TCGv s, int size)
{
- if (size == 1)
- tcg_gen_ext8u_i32(d, s);
- else if (size == 2)
- tcg_gen_ext16u_i32(d, s);
- else if (!TCGV_EQUAL(d, s))
- tcg_gen_mov_tl(d, s);
+ if (size == 1) {
+ tcg_gen_ext8u_i32(d, s);
+ } else if (size == 2) {
+ tcg_gen_ext16u_i32(d, s);
+ } else if (!TCGV_EQUAL(d, s)) {
+ tcg_gen_mov_tl(d, s);
+ }
}
#if DISAS_CRIS
static char memsize_char(int size)
{
- switch (size)
- {
- case 1: return 'b'; break;
- case 2: return 'w'; break;
- case 4: return 'd'; break;
- default:
- return 'x';
- break;
- }
+ switch (size) {
+ case 1: return 'b'; break;
+ case 2: return 'w'; break;
+ case 4: return 'd'; break;
+ default:
+ return 'x';
+ break;
+ }
}
#endif
static inline unsigned int memsize_z(DisasContext *dc)
{
- return dc->zsize + 1;
+ return dc->zsize + 1;
}
static inline unsigned int memsize_zz(DisasContext *dc)
{
- switch (dc->zzsize)
- {
- case 0: return 1;
- case 1: return 2;
- default:
- return 4;
- }
+ switch (dc->zzsize) {
+ case 0: return 1;
+ case 1: return 2;
+ default:
+ return 4;
+ }
}
static inline void do_postinc (DisasContext *dc, int size)
{
- if (dc->postinc)
- tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
+ if (dc->postinc) {
+ tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
+ }
}
static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
- int size, int s_ext, TCGv dst)
+ int size, int s_ext, TCGv dst)
{
- if (s_ext)
- t_gen_sext(dst, cpu_R[rs], size);
- else
- t_gen_zext(dst, cpu_R[rs], size);
+ if (s_ext) {
+ t_gen_sext(dst, cpu_R[rs], size);
+ } else {
+ t_gen_zext(dst, cpu_R[rs], size);
+ }
}
/* Prepare T0 and T1 for a register alu operation.
s_ext decides if the operand1 should be sign-extended or zero-extended when
needed. */
static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
- int size, int s_ext, TCGv dst, TCGv src)
+ int size, int s_ext, TCGv dst, TCGv src)
{
- dec_prep_move_r(dc, rs, rd, size, s_ext, src);
+ dec_prep_move_r(dc, rs, rd, size, s_ext, src);
- if (s_ext)
- t_gen_sext(dst, cpu_R[rd], size);
- else
- t_gen_zext(dst, cpu_R[rd], size);
+ if (s_ext) {
+ t_gen_sext(dst, cpu_R[rd], size);
+ } else {
+ t_gen_zext(dst, cpu_R[rd], size);
+ }
}
static int dec_prep_move_m(CPUCRISState *env, DisasContext *dc,
int s_ext, int memsize, TCGv dst)
{
- unsigned int rs;
- uint32_t imm;
- int is_imm;
- int insn_len = 2;
-
- rs = dc->op1;
- is_imm = rs == 15 && dc->postinc;
-
- /* Load [$rs] onto T1. */
- if (is_imm) {
- insn_len = 2 + memsize;
- if (memsize == 1)
- insn_len++;
-
- imm = cris_fetch(env, dc, dc->pc + 2, memsize, s_ext);
- tcg_gen_movi_tl(dst, imm);
- dc->postinc = 0;
- } else {
- cris_flush_cc_state(dc);
- gen_load(dc, dst, cpu_R[rs], memsize, 0);
- if (s_ext)
- t_gen_sext(dst, dst, memsize);
- else
- t_gen_zext(dst, dst, memsize);
- }
- return insn_len;
+ unsigned int rs;
+ uint32_t imm;
+ int is_imm;
+ int insn_len = 2;
+
+ rs = dc->op1;
+ is_imm = rs == 15 && dc->postinc;
+
+ /* Load [$rs] onto T1. */
+ if (is_imm) {
+ insn_len = 2 + memsize;
+ if (memsize == 1) {
+ insn_len++;
+ }
+
+ imm = cris_fetch(env, dc, dc->pc + 2, memsize, s_ext);
+ tcg_gen_movi_tl(dst, imm);
+ dc->postinc = 0;
+ } else {
+ cris_flush_cc_state(dc);
+ gen_load(dc, dst, cpu_R[rs], memsize, 0);
+ if (s_ext) {
+ t_gen_sext(dst, dst, memsize);
+ } else {
+ t_gen_zext(dst, dst, memsize);
+ }
+ }
+ return insn_len;
}
/* Prepare T0 and T1 for a memory + alu operation.
@@ -1341,22 +1363,22 @@ static int dec_prep_move_m(CPUCRISState *env, DisasContext *dc,
static int dec_prep_alu_m(CPUCRISState *env, DisasContext *dc,
int s_ext, int memsize, TCGv dst, TCGv src)
{
- int insn_len;
+ int insn_len;
- insn_len = dec_prep_move_m(env, dc, s_ext, memsize, src);
- tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
- return insn_len;
+ insn_len = dec_prep_move_m(env, dc, s_ext, memsize, src);
+ tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
+ return insn_len;
}
#if DISAS_CRIS
static const char *cc_name(int cc)
{
- static const char *cc_names[16] = {
- "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
- "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
- };
- assert(cc < 16);
- return cc_names[cc];
+ static const char *cc_names[16] = {
+ "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
+ "ls", "hi", "ge", "lt", "gt", "le", "a", "p"
+ };
+ assert(cc < 16);
+ return cc_names[cc];
}
#endif
@@ -1364,1773 +1386,1781 @@ static const char *cc_name(int cc)
static int dec_bccq(CPUCRISState *env, DisasContext *dc)
{
- int32_t offset;
- int sign;
- uint32_t cond = dc->op2;
+ int32_t offset;
+ int sign;
+ uint32_t cond = dc->op2;
- offset = EXTRACT_FIELD (dc->ir, 1, 7);
- sign = EXTRACT_FIELD(dc->ir, 0, 0);
+ offset = EXTRACT_FIELD(dc->ir, 1, 7);
+ sign = EXTRACT_FIELD(dc->ir, 0, 0);
- offset *= 2;
- offset |= sign << 8;
- offset = sign_extend(offset, 8);
+ offset *= 2;
+ offset |= sign << 8;
+ offset = sign_extend(offset, 8);
- LOG_DIS("b%s %x\n", cc_name(cond), dc->pc + offset);
+ LOG_DIS("b%s %x\n", cc_name(cond), dc->pc + offset);
- /* op2 holds the condition-code. */
- cris_cc_mask(dc, 0);
- cris_prepare_cc_branch (dc, offset, cond);
- return 2;
+ /* op2 holds the condition-code. */
+ cris_cc_mask(dc, 0);
+ cris_prepare_cc_branch(dc, offset, cond);
+ return 2;
}
static int dec_addoq(CPUCRISState *env, DisasContext *dc)
{
- int32_t imm;
+ int32_t imm;
- dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
- imm = sign_extend(dc->op1, 7);
+ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
+ imm = sign_extend(dc->op1, 7);
- LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
- cris_cc_mask(dc, 0);
- /* Fetch register operand, */
- tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
+ LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
+ cris_cc_mask(dc, 0);
+ /* Fetch register operand, */
+ tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
- return 2;
+ return 2;
}
static int dec_addq(CPUCRISState *env, DisasContext *dc)
{
- LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
+ LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
- dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
+ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
- cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_ADD,
- cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
- return 2;
+ cris_alu(dc, CC_OP_ADD,
+ cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
+ return 2;
}
static int dec_moveq(CPUCRISState *env, DisasContext *dc)
{
- uint32_t imm;
+ uint32_t imm;
- dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
- imm = sign_extend(dc->op1, 5);
- LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);
+ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
+ imm = sign_extend(dc->op1, 5);
+ LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);
- tcg_gen_movi_tl(cpu_R[dc->op2], imm);
- return 2;
+ tcg_gen_movi_tl(cpu_R[dc->op2], imm);
+ return 2;
}
static int dec_subq(CPUCRISState *env, DisasContext *dc)
{
- dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
+ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
- LOG_DIS("subq %u, $r%u\n", dc->op1, dc->op2);
+ LOG_DIS("subq %u, $r%u\n", dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_SUB,
- cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
- return 2;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_SUB,
+ cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
+ return 2;
}
static int dec_cmpq(CPUCRISState *env, DisasContext *dc)
{
- uint32_t imm;
- dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
- imm = sign_extend(dc->op1, 5);
+ uint32_t imm;
+ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
+ imm = sign_extend(dc->op1, 5);
- LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZVC);
+ LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_CMP,
- cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
- return 2;
+ cris_alu(dc, CC_OP_CMP,
+ cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
+ return 2;
}
static int dec_andq(CPUCRISState *env, DisasContext *dc)
{
- uint32_t imm;
- dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
- imm = sign_extend(dc->op1, 5);
+ uint32_t imm;
+ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
+ imm = sign_extend(dc->op1, 5);
- LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
+ LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu(dc, CC_OP_AND,
- cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
- return 2;
+ cris_alu(dc, CC_OP_AND,
+ cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
+ return 2;
}
static int dec_orq(CPUCRISState *env, DisasContext *dc)
{
- uint32_t imm;
- dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
- imm = sign_extend(dc->op1, 5);
- LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
+ uint32_t imm;
+ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
+ imm = sign_extend(dc->op1, 5);
+ LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu(dc, CC_OP_OR,
- cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
- return 2;
+ cris_alu(dc, CC_OP_OR,
+ cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
+ return 2;
}
static int dec_btstq(CPUCRISState *env, DisasContext *dc)
{
- dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
- LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
+ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
+ LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_evaluate_flags(dc);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_evaluate_flags(dc);
gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
- tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
- cris_alu(dc, CC_OP_MOVE,
- cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
- cris_update_cc_op(dc, CC_OP_FLAGS, 4);
- dc->flags_uptodate = 1;
- return 2;
+ tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
+ cris_alu(dc, CC_OP_MOVE,
+ cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
+ cris_update_cc_op(dc, CC_OP_FLAGS, 4);
+ dc->flags_uptodate = 1;
+ return 2;
}
static int dec_asrq(CPUCRISState *env, DisasContext *dc)
{
- dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
- LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
+ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
+ LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZ);
- tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
- cris_alu(dc, CC_OP_MOVE,
- cpu_R[dc->op2],
- cpu_R[dc->op2], cpu_R[dc->op2], 4);
- return 2;
+ tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
+ cris_alu(dc, CC_OP_MOVE,
+ cpu_R[dc->op2],
+ cpu_R[dc->op2], cpu_R[dc->op2], 4);
+ return 2;
}
static int dec_lslq(CPUCRISState *env, DisasContext *dc)
{
- dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
- LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
+ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
+ LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
+ cris_cc_mask(dc, CC_MASK_NZ);
- tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
+ tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
- cris_alu(dc, CC_OP_MOVE,
- cpu_R[dc->op2],
- cpu_R[dc->op2], cpu_R[dc->op2], 4);
- return 2;
+ cris_alu(dc, CC_OP_MOVE,
+ cpu_R[dc->op2],
+ cpu_R[dc->op2], cpu_R[dc->op2], 4);
+ return 2;
}
static int dec_lsrq(CPUCRISState *env, DisasContext *dc)
{
- dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
- LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
+ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
+ LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
+ cris_cc_mask(dc, CC_MASK_NZ);
- tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
- cris_alu(dc, CC_OP_MOVE,
- cpu_R[dc->op2],
- cpu_R[dc->op2], cpu_R[dc->op2], 4);
- return 2;
+ tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
+ cris_alu(dc, CC_OP_MOVE,
+ cpu_R[dc->op2],
+ cpu_R[dc->op2], cpu_R[dc->op2], 4);
+ return 2;
}
static int dec_move_r(CPUCRISState *env, DisasContext *dc)
{
- int size = memsize_zz(dc);
-
- LOG_DIS("move.%c $r%u, $r%u\n",
- memsize_char(size), dc->op1, dc->op2);
-
- cris_cc_mask(dc, CC_MASK_NZ);
- if (size == 4) {
- dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_update_cc_op(dc, CC_OP_MOVE, 4);
- cris_update_cc_x(dc);
- cris_update_result(dc, cpu_R[dc->op2]);
- }
- else {
- TCGv t0;
-
- t0 = tcg_temp_new();
- dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
- cris_alu(dc, CC_OP_MOVE,
- cpu_R[dc->op2],
- cpu_R[dc->op2], t0, size);
- tcg_temp_free(t0);
- }
- return 2;
+ int size = memsize_zz(dc);
+
+ LOG_DIS("move.%c $r%u, $r%u\n",
+ memsize_char(size), dc->op1, dc->op2);
+
+ cris_cc_mask(dc, CC_MASK_NZ);
+ if (size == 4) {
+ dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_update_cc_op(dc, CC_OP_MOVE, 4);
+ cris_update_cc_x(dc);
+ cris_update_result(dc, cpu_R[dc->op2]);
+ } else {
+ TCGv t0;
+
+ t0 = tcg_temp_new();
+ dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
+ cris_alu(dc, CC_OP_MOVE,
+ cpu_R[dc->op2],
+ cpu_R[dc->op2], t0, size);
+ tcg_temp_free(t0);
+ }
+ return 2;
}
static int dec_scc_r(CPUCRISState *env, DisasContext *dc)
{
- int cond = dc->op2;
+ int cond = dc->op2;
- LOG_DIS("s%s $r%u\n",
- cc_name(cond), dc->op1);
+ LOG_DIS("s%s $r%u\n",
+ cc_name(cond), dc->op1);
- if (cond != CC_A)
- {
- int l1;
+ if (cond != CC_A) {
+ int l1;
- gen_tst_cc (dc, cpu_R[dc->op1], cond);
- l1 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->op1], 0, l1);
- tcg_gen_movi_tl(cpu_R[dc->op1], 1);
- gen_set_label(l1);
- }
- else
- tcg_gen_movi_tl(cpu_R[dc->op1], 1);
+ gen_tst_cc(dc, cpu_R[dc->op1], cond);
+ l1 = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->op1], 0, l1);
+ tcg_gen_movi_tl(cpu_R[dc->op1], 1);
+ gen_set_label(l1);
+ } else {
+ tcg_gen_movi_tl(cpu_R[dc->op1], 1);
+ }
- cris_cc_mask(dc, 0);
- return 2;
+ cris_cc_mask(dc, 0);
+ return 2;
}
static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
{
- if (size == 4) {
- t[0] = cpu_R[dc->op2];
- t[1] = cpu_R[dc->op1];
- } else {
- t[0] = tcg_temp_new();
- t[1] = tcg_temp_new();
- }
+ if (size == 4) {
+ t[0] = cpu_R[dc->op2];
+ t[1] = cpu_R[dc->op1];
+ } else {
+ t[0] = tcg_temp_new();
+ t[1] = tcg_temp_new();
+ }
}
static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
{
- if (size != 4) {
- tcg_temp_free(t[0]);
- tcg_temp_free(t[1]);
- }
+ if (size != 4) {
+ tcg_temp_free(t[0]);
+ tcg_temp_free(t[1]);
+ }
}
static int dec_and_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int size = memsize_zz(dc);
+ TCGv t[2];
+ int size = memsize_zz(dc);
- LOG_DIS("and.%c $r%u, $r%u\n",
- memsize_char(size), dc->op1, dc->op2);
+ LOG_DIS("and.%c $r%u, $r%u\n",
+ memsize_char(size), dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
+ cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu_alloc_temps(dc, size, t);
- dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
- cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
- cris_alu_free_temps(dc, size, t);
- return 2;
+ cris_alu_alloc_temps(dc, size, t);
+ dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
+ cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
+ cris_alu_free_temps(dc, size, t);
+ return 2;
}
static int dec_lz_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t0;
- LOG_DIS("lz $r%u, $r%u\n",
- dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
- t0 = tcg_temp_new();
- dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
- cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
- tcg_temp_free(t0);
- return 2;
+ TCGv t0;
+ LOG_DIS("lz $r%u, $r%u\n",
+ dc->op1, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ t0 = tcg_temp_new();
+ dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
+ cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
+ tcg_temp_free(t0);
+ return 2;
}
static int dec_lsl_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int size = memsize_zz(dc);
+ TCGv t[2];
+ int size = memsize_zz(dc);
- LOG_DIS("lsl.%c $r%u, $r%u\n",
- memsize_char(size), dc->op1, dc->op2);
+ LOG_DIS("lsl.%c $r%u, $r%u\n",
+ memsize_char(size), dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu_alloc_temps(dc, size, t);
- dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
- tcg_gen_andi_tl(t[1], t[1], 63);
- cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
- cris_alu_alloc_temps(dc, size, t);
- return 2;
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu_alloc_temps(dc, size, t);
+ dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
+ tcg_gen_andi_tl(t[1], t[1], 63);
+ cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
+ cris_alu_alloc_temps(dc, size, t);
+ return 2;
}
static int dec_lsr_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int size = memsize_zz(dc);
+ TCGv t[2];
+ int size = memsize_zz(dc);
- LOG_DIS("lsr.%c $r%u, $r%u\n",
- memsize_char(size), dc->op1, dc->op2);
+ LOG_DIS("lsr.%c $r%u, $r%u\n",
+ memsize_char(size), dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu_alloc_temps(dc, size, t);
- dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
- tcg_gen_andi_tl(t[1], t[1], 63);
- cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
- cris_alu_free_temps(dc, size, t);
- return 2;
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu_alloc_temps(dc, size, t);
+ dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
+ tcg_gen_andi_tl(t[1], t[1], 63);
+ cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
+ cris_alu_free_temps(dc, size, t);
+ return 2;
}
static int dec_asr_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int size = memsize_zz(dc);
+ TCGv t[2];
+ int size = memsize_zz(dc);
- LOG_DIS("asr.%c $r%u, $r%u\n",
- memsize_char(size), dc->op1, dc->op2);
+ LOG_DIS("asr.%c $r%u, $r%u\n",
+ memsize_char(size), dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu_alloc_temps(dc, size, t);
- dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
- tcg_gen_andi_tl(t[1], t[1], 63);
- cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
- cris_alu_free_temps(dc, size, t);
- return 2;
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu_alloc_temps(dc, size, t);
+ dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
+ tcg_gen_andi_tl(t[1], t[1], 63);
+ cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
+ cris_alu_free_temps(dc, size, t);
+ return 2;
}
static int dec_muls_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int size = memsize_zz(dc);
+ TCGv t[2];
+ int size = memsize_zz(dc);
- LOG_DIS("muls.%c $r%u, $r%u\n",
- memsize_char(size), dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZV);
- cris_alu_alloc_temps(dc, size, t);
- dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
+ LOG_DIS("muls.%c $r%u, $r%u\n",
+ memsize_char(size), dc->op1, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZV);
+ cris_alu_alloc_temps(dc, size, t);
+ dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
- cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
- cris_alu_free_temps(dc, size, t);
- return 2;
+ cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
+ cris_alu_free_temps(dc, size, t);
+ return 2;
}
static int dec_mulu_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int size = memsize_zz(dc);
+ TCGv t[2];
+ int size = memsize_zz(dc);
- LOG_DIS("mulu.%c $r%u, $r%u\n",
- memsize_char(size), dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZV);
- cris_alu_alloc_temps(dc, size, t);
- dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
+ LOG_DIS("mulu.%c $r%u, $r%u\n",
+ memsize_char(size), dc->op1, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZV);
+ cris_alu_alloc_temps(dc, size, t);
+ dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
- cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
- cris_alu_alloc_temps(dc, size, t);
- return 2;
+ cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
+ cris_alu_alloc_temps(dc, size, t);
+ return 2;
}
static int dec_dstep_r(CPUCRISState *env, DisasContext *dc)
{
- LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu(dc, CC_OP_DSTEP,
- cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
- return 2;
+ LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu(dc, CC_OP_DSTEP,
+ cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
+ return 2;
}
static int dec_xor_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int size = memsize_zz(dc);
- LOG_DIS("xor.%c $r%u, $r%u\n",
- memsize_char(size), dc->op1, dc->op2);
- BUG_ON(size != 4); /* xor is dword. */
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu_alloc_temps(dc, size, t);
- dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
+ TCGv t[2];
+ int size = memsize_zz(dc);
+ LOG_DIS("xor.%c $r%u, $r%u\n",
+ memsize_char(size), dc->op1, dc->op2);
+ BUG_ON(size != 4); /* xor is dword. */
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu_alloc_temps(dc, size, t);
+ dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
- cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
- cris_alu_free_temps(dc, size, t);
- return 2;
+ cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
+ cris_alu_free_temps(dc, size, t);
+ return 2;
}
static int dec_bound_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv l0;
- int size = memsize_zz(dc);
- LOG_DIS("bound.%c $r%u, $r%u\n",
- memsize_char(size), dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
- l0 = tcg_temp_local_new();
- dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
- cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
- tcg_temp_free(l0);
- return 2;
+ TCGv l0;
+ int size = memsize_zz(dc);
+ LOG_DIS("bound.%c $r%u, $r%u\n",
+ memsize_char(size), dc->op1, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ l0 = tcg_temp_local_new();
+ dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
+ cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
+ tcg_temp_free(l0);
+ return 2;
}
static int dec_cmp_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int size = memsize_zz(dc);
- LOG_DIS("cmp.%c $r%u, $r%u\n",
- memsize_char(size), dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu_alloc_temps(dc, size, t);
- dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
+ TCGv t[2];
+ int size = memsize_zz(dc);
+ LOG_DIS("cmp.%c $r%u, $r%u\n",
+ memsize_char(size), dc->op1, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu_alloc_temps(dc, size, t);
+ dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
- cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
- cris_alu_free_temps(dc, size, t);
- return 2;
+ cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
+ cris_alu_free_temps(dc, size, t);
+ return 2;
}
static int dec_abs_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t0;
+ TCGv t0;
- LOG_DIS("abs $r%u, $r%u\n",
- dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
+ LOG_DIS("abs $r%u, $r%u\n",
+ dc->op1, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZ);
- t0 = tcg_temp_new();
- tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
- tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
- tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
- tcg_temp_free(t0);
+ t0 = tcg_temp_new();
+ tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
+ tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
+ tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
+ tcg_temp_free(t0);
- cris_alu(dc, CC_OP_MOVE,
- cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
- return 2;
+ cris_alu(dc, CC_OP_MOVE,
+ cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
+ return 2;
}
static int dec_add_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int size = memsize_zz(dc);
- LOG_DIS("add.%c $r%u, $r%u\n",
- memsize_char(size), dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu_alloc_temps(dc, size, t);
- dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
+ TCGv t[2];
+ int size = memsize_zz(dc);
+ LOG_DIS("add.%c $r%u, $r%u\n",
+ memsize_char(size), dc->op1, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu_alloc_temps(dc, size, t);
+ dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
- cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
- cris_alu_free_temps(dc, size, t);
- return 2;
+ cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
+ cris_alu_free_temps(dc, size, t);
+ return 2;
}
static int dec_addc_r(CPUCRISState *env, DisasContext *dc)
{
- LOG_DIS("addc $r%u, $r%u\n",
- dc->op1, dc->op2);
- cris_evaluate_flags(dc);
- /* Set for this insn. */
- dc->flagx_known = 1;
- dc->flags_x = X_FLAG;
+ LOG_DIS("addc $r%u, $r%u\n",
+ dc->op1, dc->op2);
+ cris_evaluate_flags(dc);
+ /* Set for this insn. */
+ dc->flagx_known = 1;
+ dc->flags_x = X_FLAG;
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_ADDC,
- cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
- return 2;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_ADDC,
+ cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
+ return 2;
}
static int dec_mcp_r(CPUCRISState *env, DisasContext *dc)
{
- LOG_DIS("mcp $p%u, $r%u\n",
- dc->op2, dc->op1);
- cris_evaluate_flags(dc);
- cris_cc_mask(dc, CC_MASK_RNZV);
- cris_alu(dc, CC_OP_MCP,
- cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
- return 2;
+ LOG_DIS("mcp $p%u, $r%u\n",
+ dc->op2, dc->op1);
+ cris_evaluate_flags(dc);
+ cris_cc_mask(dc, CC_MASK_RNZV);
+ cris_alu(dc, CC_OP_MCP,
+ cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
+ return 2;
}
#if DISAS_CRIS
static char * swapmode_name(int mode, char *modename) {
- int i = 0;
- if (mode & 8)
- modename[i++] = 'n';
- if (mode & 4)
- modename[i++] = 'w';
- if (mode & 2)
- modename[i++] = 'b';
- if (mode & 1)
- modename[i++] = 'r';
- modename[i++] = 0;
- return modename;
+ int i = 0;
+ if (mode & 8) {
+ modename[i++] = 'n';
+ }
+ if (mode & 4) {
+ modename[i++] = 'w';
+ }
+ if (mode & 2) {
+ modename[i++] = 'b';
+ }
+ if (mode & 1) {
+ modename[i++] = 'r';
+ }
+ modename[i++] = 0;
+ return modename;
}
#endif
static int dec_swap_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t0;
+ TCGv t0;
#if DISAS_CRIS
- char modename[4];
+ char modename[4];
#endif
- LOG_DIS("swap%s $r%u\n",
- swapmode_name(dc->op2, modename), dc->op1);
-
- cris_cc_mask(dc, CC_MASK_NZ);
- t0 = tcg_temp_new();
- t_gen_mov_TN_reg(t0, dc->op1);
- if (dc->op2 & 8)
- tcg_gen_not_tl(t0, t0);
- if (dc->op2 & 4)
- t_gen_swapw(t0, t0);
- if (dc->op2 & 2)
- t_gen_swapb(t0, t0);
- if (dc->op2 & 1)
- t_gen_swapr(t0, t0);
- cris_alu(dc, CC_OP_MOVE,
- cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
- tcg_temp_free(t0);
- return 2;
+ LOG_DIS("swap%s $r%u\n",
+ swapmode_name(dc->op2, modename), dc->op1);
+
+ cris_cc_mask(dc, CC_MASK_NZ);
+ t0 = tcg_temp_new();
+ t_gen_mov_TN_reg(t0, dc->op1);
+ if (dc->op2 & 8) {
+ tcg_gen_not_tl(t0, t0);
+ }
+ if (dc->op2 & 4) {
+ t_gen_swapw(t0, t0);
+ }
+ if (dc->op2 & 2) {
+ t_gen_swapb(t0, t0);
+ }
+ if (dc->op2 & 1) {
+ t_gen_swapr(t0, t0);
+ }
+ cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
+ tcg_temp_free(t0);
+ return 2;
}
static int dec_or_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int size = memsize_zz(dc);
- LOG_DIS("or.%c $r%u, $r%u\n",
- memsize_char(size), dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu_alloc_temps(dc, size, t);
- dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
- cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
- cris_alu_free_temps(dc, size, t);
- return 2;
+ TCGv t[2];
+ int size = memsize_zz(dc);
+ LOG_DIS("or.%c $r%u, $r%u\n",
+ memsize_char(size), dc->op1, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu_alloc_temps(dc, size, t);
+ dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
+ cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
+ cris_alu_free_temps(dc, size, t);
+ return 2;
}
static int dec_addi_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t0;
- LOG_DIS("addi.%c $r%u, $r%u\n",
- memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
- cris_cc_mask(dc, 0);
- t0 = tcg_temp_new();
- tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
- tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
- tcg_temp_free(t0);
- return 2;
+ TCGv t0;
+ LOG_DIS("addi.%c $r%u, $r%u\n",
+ memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
+ cris_cc_mask(dc, 0);
+ t0 = tcg_temp_new();
+ tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
+ tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
+ tcg_temp_free(t0);
+ return 2;
}
static int dec_addi_acr(CPUCRISState *env, DisasContext *dc)
{
- TCGv t0;
- LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
- memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
- cris_cc_mask(dc, 0);
- t0 = tcg_temp_new();
- tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
- tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
- tcg_temp_free(t0);
- return 2;
+ TCGv t0;
+ LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
+ memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
+ cris_cc_mask(dc, 0);
+ t0 = tcg_temp_new();
+ tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
+ tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
+ tcg_temp_free(t0);
+ return 2;
}
static int dec_neg_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int size = memsize_zz(dc);
- LOG_DIS("neg.%c $r%u, $r%u\n",
- memsize_char(size), dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu_alloc_temps(dc, size, t);
- dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
+ TCGv t[2];
+ int size = memsize_zz(dc);
+ LOG_DIS("neg.%c $r%u, $r%u\n",
+ memsize_char(size), dc->op1, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu_alloc_temps(dc, size, t);
+ dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
- cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
- cris_alu_free_temps(dc, size, t);
- return 2;
+ cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
+ cris_alu_free_temps(dc, size, t);
+ return 2;
}
static int dec_btst_r(CPUCRISState *env, DisasContext *dc)
{
- LOG_DIS("btst $r%u, $r%u\n",
- dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_evaluate_flags(dc);
+ LOG_DIS("btst $r%u, $r%u\n",
+ dc->op1, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_evaluate_flags(dc);
gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
- cpu_R[dc->op1], cpu_PR[PR_CCS]);
- cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
- cpu_R[dc->op2], cpu_R[dc->op2], 4);
- cris_update_cc_op(dc, CC_OP_FLAGS, 4);
- dc->flags_uptodate = 1;
- return 2;
+ cpu_R[dc->op1], cpu_PR[PR_CCS]);
+ cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
+ cpu_R[dc->op2], cpu_R[dc->op2], 4);
+ cris_update_cc_op(dc, CC_OP_FLAGS, 4);
+ dc->flags_uptodate = 1;
+ return 2;
}
static int dec_sub_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int size = memsize_zz(dc);
- LOG_DIS("sub.%c $r%u, $r%u\n",
- memsize_char(size), dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu_alloc_temps(dc, size, t);
- dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
- cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
- cris_alu_free_temps(dc, size, t);
- return 2;
+ TCGv t[2];
+ int size = memsize_zz(dc);
+ LOG_DIS("sub.%c $r%u, $r%u\n",
+ memsize_char(size), dc->op1, dc->op2);
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu_alloc_temps(dc, size, t);
+ dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
+ cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
+ cris_alu_free_temps(dc, size, t);
+ return 2;
}
/* Zero extension. From size to dword. */
static int dec_movu_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t0;
- int size = memsize_z(dc);
- LOG_DIS("movu.%c $r%u, $r%u\n",
- memsize_char(size),
- dc->op1, dc->op2);
+ TCGv t0;
+ int size = memsize_z(dc);
+ LOG_DIS("movu.%c $r%u, $r%u\n",
+ memsize_char(size),
+ dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
- t0 = tcg_temp_new();
- dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
- cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
- tcg_temp_free(t0);
- return 2;
+ cris_cc_mask(dc, CC_MASK_NZ);
+ t0 = tcg_temp_new();
+ dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
+ cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
+ tcg_temp_free(t0);
+ return 2;
}
/* Sign extension. From size to dword. */
static int dec_movs_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t0;
- int size = memsize_z(dc);
- LOG_DIS("movs.%c $r%u, $r%u\n",
- memsize_char(size),
- dc->op1, dc->op2);
+ TCGv t0;
+ int size = memsize_z(dc);
+ LOG_DIS("movs.%c $r%u, $r%u\n",
+ memsize_char(size),
+ dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZ);
- t0 = tcg_temp_new();
- /* Size can only be qi or hi. */
- t_gen_sext(t0, cpu_R[dc->op1], size);
- cris_alu(dc, CC_OP_MOVE,
- cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
- tcg_temp_free(t0);
- return 2;
+ cris_cc_mask(dc, CC_MASK_NZ);
+ t0 = tcg_temp_new();
+ /* Size can only be qi or hi. */
+ t_gen_sext(t0, cpu_R[dc->op1], size);
+ cris_alu(dc, CC_OP_MOVE,
+ cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
+ tcg_temp_free(t0);
+ return 2;
}
/* zero extension. From size to dword. */
static int dec_addu_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t0;
- int size = memsize_z(dc);
- LOG_DIS("addu.%c $r%u, $r%u\n",
- memsize_char(size),
- dc->op1, dc->op2);
+ TCGv t0;
+ int size = memsize_z(dc);
+ LOG_DIS("addu.%c $r%u, $r%u\n",
+ memsize_char(size),
+ dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZVC);
- t0 = tcg_temp_new();
- /* Size can only be qi or hi. */
- t_gen_zext(t0, cpu_R[dc->op1], size);
- cris_alu(dc, CC_OP_ADD,
- cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
- tcg_temp_free(t0);
- return 2;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ t0 = tcg_temp_new();
+ /* Size can only be qi or hi. */
+ t_gen_zext(t0, cpu_R[dc->op1], size);
+ cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
+ tcg_temp_free(t0);
+ return 2;
}
/* Sign extension. From size to dword. */
static int dec_adds_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t0;
- int size = memsize_z(dc);
- LOG_DIS("adds.%c $r%u, $r%u\n",
- memsize_char(size),
- dc->op1, dc->op2);
+ TCGv t0;
+ int size = memsize_z(dc);
+ LOG_DIS("adds.%c $r%u, $r%u\n",
+ memsize_char(size),
+ dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZVC);
- t0 = tcg_temp_new();
- /* Size can only be qi or hi. */
- t_gen_sext(t0, cpu_R[dc->op1], size);
- cris_alu(dc, CC_OP_ADD,
- cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
- tcg_temp_free(t0);
- return 2;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ t0 = tcg_temp_new();
+ /* Size can only be qi or hi. */
+ t_gen_sext(t0, cpu_R[dc->op1], size);
+ cris_alu(dc, CC_OP_ADD,
+ cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
+ tcg_temp_free(t0);
+ return 2;
}
/* Zero extension. From size to dword. */
static int dec_subu_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t0;
- int size = memsize_z(dc);
- LOG_DIS("subu.%c $r%u, $r%u\n",
- memsize_char(size),
- dc->op1, dc->op2);
+ TCGv t0;
+ int size = memsize_z(dc);
+ LOG_DIS("subu.%c $r%u, $r%u\n",
+ memsize_char(size),
+ dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZVC);
- t0 = tcg_temp_new();
- /* Size can only be qi or hi. */
- t_gen_zext(t0, cpu_R[dc->op1], size);
- cris_alu(dc, CC_OP_SUB,
- cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
- tcg_temp_free(t0);
- return 2;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ t0 = tcg_temp_new();
+ /* Size can only be qi or hi. */
+ t_gen_zext(t0, cpu_R[dc->op1], size);
+ cris_alu(dc, CC_OP_SUB,
+ cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
+ tcg_temp_free(t0);
+ return 2;
}
/* Sign extension. From size to dword. */
static int dec_subs_r(CPUCRISState *env, DisasContext *dc)
{
- TCGv t0;
- int size = memsize_z(dc);
- LOG_DIS("subs.%c $r%u, $r%u\n",
- memsize_char(size),
- dc->op1, dc->op2);
+ TCGv t0;
+ int size = memsize_z(dc);
+ LOG_DIS("subs.%c $r%u, $r%u\n",
+ memsize_char(size),
+ dc->op1, dc->op2);
- cris_cc_mask(dc, CC_MASK_NZVC);
- t0 = tcg_temp_new();
- /* Size can only be qi or hi. */
- t_gen_sext(t0, cpu_R[dc->op1], size);
- cris_alu(dc, CC_OP_SUB,
- cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
- tcg_temp_free(t0);
- return 2;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ t0 = tcg_temp_new();
+ /* Size can only be qi or hi. */
+ t_gen_sext(t0, cpu_R[dc->op1], size);
+ cris_alu(dc, CC_OP_SUB,
+ cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
+ tcg_temp_free(t0);
+ return 2;
}
static int dec_setclrf(CPUCRISState *env, DisasContext *dc)
{
- uint32_t flags;
- int set = (~dc->opcode >> 2) & 1;
-
-
- flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
- | EXTRACT_FIELD(dc->ir, 0, 3);
- if (set && flags == 0) {
- LOG_DIS("nop\n");
- return 2;
- } else if (!set && (flags & 0x20)) {
- LOG_DIS("di\n");
- }
- else {
- LOG_DIS("%sf %x\n",
- set ? "set" : "clr",
- flags);
- }
-
- /* User space is not allowed to touch these. Silently ignore. */
- if (dc->tb_flags & U_FLAG) {
- flags &= ~(S_FLAG | I_FLAG | U_FLAG);
- }
-
- if (flags & X_FLAG) {
- dc->flagx_known = 1;
- if (set)
- dc->flags_x = X_FLAG;
- else
- dc->flags_x = 0;
- }
-
- /* Break the TB if any of the SPI flag changes. */
- if (flags & (P_FLAG | S_FLAG)) {
- tcg_gen_movi_tl(env_pc, dc->pc + 2);
- dc->is_jmp = DISAS_UPDATE;
- dc->cpustate_changed = 1;
- }
-
- /* For the I flag, only act on posedge. */
- if ((flags & I_FLAG)) {
- tcg_gen_movi_tl(env_pc, dc->pc + 2);
- dc->is_jmp = DISAS_UPDATE;
- dc->cpustate_changed = 1;
- }
-
-
- /* Simply decode the flags. */
- cris_evaluate_flags (dc);
- cris_update_cc_op(dc, CC_OP_FLAGS, 4);
- cris_update_cc_x(dc);
- tcg_gen_movi_tl(cc_op, dc->cc_op);
-
- if (set) {
- if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
- /* Enter user mode. */
- t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
- tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
- dc->cpustate_changed = 1;
- }
- tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
- }
- else
- tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
-
- dc->flags_uptodate = 1;
- dc->clear_x = 0;
- return 2;
+ uint32_t flags;
+ int set = (~dc->opcode >> 2) & 1;
+
+
+ flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
+ | EXTRACT_FIELD(dc->ir, 0, 3);
+ if (set && flags == 0) {
+ LOG_DIS("nop\n");
+ return 2;
+ } else if (!set && (flags & 0x20)) {
+ LOG_DIS("di\n");
+ } else {
+ LOG_DIS("%sf %x\n", set ? "set" : "clr", flags);
+ }
+
+ /* User space is not allowed to touch these. Silently ignore. */
+ if (dc->tb_flags & U_FLAG) {
+ flags &= ~(S_FLAG | I_FLAG | U_FLAG);
+ }
+
+ if (flags & X_FLAG) {
+ dc->flagx_known = 1;
+ if (set) {
+ dc->flags_x = X_FLAG;
+ } else {
+ dc->flags_x = 0;
+ }
+ }
+
+ /* Break the TB if any of the SPI flag changes. */
+ if (flags & (P_FLAG | S_FLAG)) {
+ tcg_gen_movi_tl(env_pc, dc->pc + 2);
+ dc->is_jmp = DISAS_UPDATE;
+ dc->cpustate_changed = 1;
+ }
+
+ /* For the I flag, only act on posedge. */
+ if ((flags & I_FLAG)) {
+ tcg_gen_movi_tl(env_pc, dc->pc + 2);
+ dc->is_jmp = DISAS_UPDATE;
+ dc->cpustate_changed = 1;
+ }
+
+
+ /* Simply decode the flags. */
+ cris_evaluate_flags(dc);
+ cris_update_cc_op(dc, CC_OP_FLAGS, 4);
+ cris_update_cc_x(dc);
+ tcg_gen_movi_tl(cc_op, dc->cc_op);
+
+ if (set) {
+ if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
+ /* Enter user mode. */
+ t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
+ tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
+ dc->cpustate_changed = 1;
+ }
+ tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
+ } else {
+ tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
+ }
+
+ dc->flags_uptodate = 1;
+ dc->clear_x = 0;
+ return 2;
}
static int dec_move_rs(CPUCRISState *env, DisasContext *dc)
{
- LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
- cris_cc_mask(dc, 0);
+ LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
+ cris_cc_mask(dc, 0);
gen_helper_movl_sreg_reg(cpu_env, tcg_const_tl(dc->op2),
tcg_const_tl(dc->op1));
- return 2;
+ return 2;
}
static int dec_move_sr(CPUCRISState *env, DisasContext *dc)
{
- LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
- cris_cc_mask(dc, 0);
+ LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
+ cris_cc_mask(dc, 0);
gen_helper_movl_reg_sreg(cpu_env, tcg_const_tl(dc->op1),
tcg_const_tl(dc->op2));
- return 2;
+ return 2;
}
static int dec_move_rp(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
- cris_cc_mask(dc, 0);
-
- t[0] = tcg_temp_new();
- if (dc->op2 == PR_CCS) {
- cris_evaluate_flags(dc);
- t_gen_mov_TN_reg(t[0], dc->op1);
- if (dc->tb_flags & U_FLAG) {
- t[1] = tcg_temp_new();
- /* User space is not allowed to touch all flags. */
- tcg_gen_andi_tl(t[0], t[0], 0x39f);
- tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
- tcg_gen_or_tl(t[0], t[1], t[0]);
- tcg_temp_free(t[1]);
- }
- }
- else
- t_gen_mov_TN_reg(t[0], dc->op1);
-
- t_gen_mov_preg_TN(dc, dc->op2, t[0]);
- if (dc->op2 == PR_CCS) {
- cris_update_cc_op(dc, CC_OP_FLAGS, 4);
- dc->flags_uptodate = 1;
- }
- tcg_temp_free(t[0]);
- return 2;
+ TCGv t[2];
+ LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
+ cris_cc_mask(dc, 0);
+
+ t[0] = tcg_temp_new();
+ if (dc->op2 == PR_CCS) {
+ cris_evaluate_flags(dc);
+ t_gen_mov_TN_reg(t[0], dc->op1);
+ if (dc->tb_flags & U_FLAG) {
+ t[1] = tcg_temp_new();
+ /* User space is not allowed to touch all flags. */
+ tcg_gen_andi_tl(t[0], t[0], 0x39f);
+ tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
+ tcg_gen_or_tl(t[0], t[1], t[0]);
+ tcg_temp_free(t[1]);
+ }
+ } else {
+ t_gen_mov_TN_reg(t[0], dc->op1);
+ }
+
+ t_gen_mov_preg_TN(dc, dc->op2, t[0]);
+ if (dc->op2 == PR_CCS) {
+ cris_update_cc_op(dc, CC_OP_FLAGS, 4);
+ dc->flags_uptodate = 1;
+ }
+ tcg_temp_free(t[0]);
+ return 2;
}
static int dec_move_pr(CPUCRISState *env, DisasContext *dc)
{
- TCGv t0;
- LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
- cris_cc_mask(dc, 0);
+ TCGv t0;
+ LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
+ cris_cc_mask(dc, 0);
- if (dc->op2 == PR_CCS)
- cris_evaluate_flags(dc);
+ if (dc->op2 == PR_CCS) {
+ cris_evaluate_flags(dc);
+ }
- if (dc->op2 == PR_DZ) {
- tcg_gen_movi_tl(cpu_R[dc->op1], 0);
- } else {
- t0 = tcg_temp_new();
- t_gen_mov_TN_preg(t0, dc->op2);
- cris_alu(dc, CC_OP_MOVE,
- cpu_R[dc->op1], cpu_R[dc->op1], t0,
- preg_sizes[dc->op2]);
- tcg_temp_free(t0);
- }
- return 2;
+ if (dc->op2 == PR_DZ) {
+ tcg_gen_movi_tl(cpu_R[dc->op1], 0);
+ } else {
+ t0 = tcg_temp_new();
+ t_gen_mov_TN_preg(t0, dc->op2);
+ cris_alu(dc, CC_OP_MOVE,
+ cpu_R[dc->op1], cpu_R[dc->op1], t0,
+ preg_sizes[dc->op2]);
+ tcg_temp_free(t0);
+ }
+ return 2;
}
static int dec_move_mr(CPUCRISState *env, DisasContext *dc)
{
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("move.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
-
- if (memsize == 4) {
- insn_len = dec_prep_move_m(env, dc, 0, 4, cpu_R[dc->op2]);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_update_cc_op(dc, CC_OP_MOVE, 4);
- cris_update_cc_x(dc);
- cris_update_result(dc, cpu_R[dc->op2]);
- }
- else {
- TCGv t0;
-
- t0 = tcg_temp_new();
- insn_len = dec_prep_move_m(env, dc, 0, memsize, t0);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu(dc, CC_OP_MOVE,
- cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
- tcg_temp_free(t0);
- }
- do_postinc(dc, memsize);
- return insn_len;
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("move.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
+
+ if (memsize == 4) {
+ insn_len = dec_prep_move_m(env, dc, 0, 4, cpu_R[dc->op2]);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_update_cc_op(dc, CC_OP_MOVE, 4);
+ cris_update_cc_x(dc);
+ cris_update_result(dc, cpu_R[dc->op2]);
+ } else {
+ TCGv t0;
+
+ t0 = tcg_temp_new();
+ insn_len = dec_prep_move_m(env, dc, 0, memsize, t0);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu(dc, CC_OP_MOVE,
+ cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
+ tcg_temp_free(t0);
+ }
+ do_postinc(dc, memsize);
+ return insn_len;
}
static inline void cris_alu_m_alloc_temps(TCGv *t)
{
- t[0] = tcg_temp_new();
- t[1] = tcg_temp_new();
+ t[0] = tcg_temp_new();
+ t[1] = tcg_temp_new();
}
static inline void cris_alu_m_free_temps(TCGv *t)
{
- tcg_temp_free(t[0]);
- tcg_temp_free(t[1]);
+ tcg_temp_free(t[0]);
+ tcg_temp_free(t[1]);
}
static int dec_movs_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
- LOG_DIS("movs.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+ LOG_DIS("movs.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_alu_m_alloc_temps(t);
- /* sign extend. */
+ cris_alu_m_alloc_temps(t);
+ /* sign extend. */
insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu(dc, CC_OP_MOVE,
- cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu(dc, CC_OP_MOVE,
+ cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_addu_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
- LOG_DIS("addu.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+ LOG_DIS("addu.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_alu_m_alloc_temps(t);
- /* sign extend. */
+ cris_alu_m_alloc_temps(t);
+ /* sign extend. */
insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_ADD,
- cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_ADD,
+ cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_adds_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
- LOG_DIS("adds.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+ LOG_DIS("adds.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_alu_m_alloc_temps(t);
- /* sign extend. */
+ cris_alu_m_alloc_temps(t);
+ /* sign extend. */
insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_subu_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
- LOG_DIS("subu.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+ LOG_DIS("subu.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_alu_m_alloc_temps(t);
- /* sign extend. */
+ cris_alu_m_alloc_temps(t);
+ /* sign extend. */
insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_subs_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
- LOG_DIS("subs.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+ LOG_DIS("subs.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_alu_m_alloc_temps(t);
- /* sign extend. */
+ cris_alu_m_alloc_temps(t);
+ /* sign extend. */
insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_movu_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
- LOG_DIS("movu.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ LOG_DIS("movu.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_alu_m_alloc_temps(t);
+ cris_alu_m_alloc_temps(t);
insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_cmpu_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
- LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+ LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_alu_m_alloc_temps(t);
+ cris_alu_m_alloc_temps(t);
insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_cmps_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_z(dc);
- int insn_len;
- LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ TCGv t[2];
+ int memsize = memsize_z(dc);
+ int insn_len;
+ LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_alu_m_alloc_temps(t);
+ cris_alu_m_alloc_temps(t);
insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_CMP,
- cpu_R[dc->op2], cpu_R[dc->op2], t[1],
- memsize_zz(dc));
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_CMP,
+ cpu_R[dc->op2], cpu_R[dc->op2], t[1],
+ memsize_zz(dc));
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_cmp_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_alu_m_alloc_temps(t);
+ cris_alu_m_alloc_temps(t);
insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_CMP,
- cpu_R[dc->op2], cpu_R[dc->op2], t[1],
- memsize_zz(dc));
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_CMP,
+ cpu_R[dc->op2], cpu_R[dc->op2], t[1],
+ memsize_zz(dc));
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_test_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("test.%c [$r%u%s] op2=%x\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("test.%c [$r%u%s] op2=%x\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_evaluate_flags(dc);
+ cris_evaluate_flags(dc);
- cris_alu_m_alloc_temps(t);
+ cris_alu_m_alloc_temps(t);
insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZ);
- tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
+ cris_cc_mask(dc, CC_MASK_NZ);
+ tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
- cris_alu(dc, CC_OP_CMP,
- cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_alu(dc, CC_OP_CMP,
+ cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_and_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("and.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("and.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_alu_m_alloc_temps(t);
+ cris_alu_m_alloc_temps(t);
insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_add_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("add.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("add.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_alu_m_alloc_temps(t);
+ cris_alu_m_alloc_temps(t);
insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_ADD,
- cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_ADD,
+ cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_addo_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("add.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("add.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_alu_m_alloc_temps(t);
+ cris_alu_m_alloc_temps(t);
insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
- cris_cc_mask(dc, 0);
- cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, 0);
+ cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_bound_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv l[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("bound.%c [$r%u%s, $r%u\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ TCGv l[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("bound.%c [$r%u%s, $r%u\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- l[0] = tcg_temp_local_new();
- l[1] = tcg_temp_local_new();
+ l[0] = tcg_temp_local_new();
+ l[1] = tcg_temp_local_new();
insn_len = dec_prep_alu_m(env, dc, 0, memsize, l[0], l[1]);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
- do_postinc(dc, memsize);
- tcg_temp_free(l[0]);
- tcg_temp_free(l[1]);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
+ do_postinc(dc, memsize);
+ tcg_temp_free(l[0]);
+ tcg_temp_free(l[1]);
+ return insn_len;
}
static int dec_addc_mr(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int insn_len = 2;
- LOG_DIS("addc [$r%u%s, $r%u\n",
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2);
+ TCGv t[2];
+ int insn_len = 2;
+ LOG_DIS("addc [$r%u%s, $r%u\n",
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_evaluate_flags(dc);
+ cris_evaluate_flags(dc);
- /* Set for this insn. */
- dc->flagx_known = 1;
- dc->flags_x = X_FLAG;
+ /* Set for this insn. */
+ dc->flagx_known = 1;
+ dc->flags_x = X_FLAG;
- cris_alu_m_alloc_temps(t);
+ cris_alu_m_alloc_temps(t);
insn_len = dec_prep_alu_m(env, dc, 0, 4, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
- do_postinc(dc, 4);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
+ do_postinc(dc, 4);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_sub_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2, dc->ir, dc->zzsize);
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2, dc->ir, dc->zzsize);
- cris_alu_m_alloc_temps(t);
+ cris_alu_m_alloc_temps(t);
insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZVC);
- cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZVC);
+ cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_or_m(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len;
- LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
- memsize_char(memsize),
- dc->op1, dc->postinc ? "+]" : "]",
- dc->op2, dc->pc);
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len;
+ LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
+ memsize_char(memsize),
+ dc->op1, dc->postinc ? "+]" : "]",
+ dc->op2, dc->pc);
- cris_alu_m_alloc_temps(t);
+ cris_alu_m_alloc_temps(t);
insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, CC_MASK_NZ);
- cris_alu(dc, CC_OP_OR,
- cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ cris_cc_mask(dc, CC_MASK_NZ);
+ cris_alu(dc, CC_OP_OR,
+ cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_move_mp(CPUCRISState *env, DisasContext *dc)
{
- TCGv t[2];
- int memsize = memsize_zz(dc);
- int insn_len = 2;
+ TCGv t[2];
+ int memsize = memsize_zz(dc);
+ int insn_len = 2;
- LOG_DIS("move.%c [$r%u%s, $p%u\n",
- memsize_char(memsize),
- dc->op1,
- dc->postinc ? "+]" : "]",
- dc->op2);
+ LOG_DIS("move.%c [$r%u%s, $p%u\n",
+ memsize_char(memsize),
+ dc->op1,
+ dc->postinc ? "+]" : "]",
+ dc->op2);
- cris_alu_m_alloc_temps(t);
+ cris_alu_m_alloc_temps(t);
insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
- cris_cc_mask(dc, 0);
- if (dc->op2 == PR_CCS) {
- cris_evaluate_flags(dc);
- if (dc->tb_flags & U_FLAG) {
- /* User space is not allowed to touch all flags. */
- tcg_gen_andi_tl(t[1], t[1], 0x39f);
- tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
- tcg_gen_or_tl(t[1], t[0], t[1]);
- }
- }
+ cris_cc_mask(dc, 0);
+ if (dc->op2 == PR_CCS) {
+ cris_evaluate_flags(dc);
+ if (dc->tb_flags & U_FLAG) {
+ /* User space is not allowed to touch all flags. */
+ tcg_gen_andi_tl(t[1], t[1], 0x39f);
+ tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
+ tcg_gen_or_tl(t[1], t[0], t[1]);
+ }
+ }
- t_gen_mov_preg_TN(dc, dc->op2, t[1]);
+ t_gen_mov_preg_TN(dc, dc->op2, t[1]);
- do_postinc(dc, memsize);
- cris_alu_m_free_temps(t);
- return insn_len;
+ do_postinc(dc, memsize);
+ cris_alu_m_free_temps(t);
+ return insn_len;
}
static int dec_move_pm(CPUCRISState *env, DisasContext *dc)
{
- TCGv t0;
- int memsize;
+ TCGv t0;
+ int memsize;
- memsize = preg_sizes[dc->op2];
+ memsize = preg_sizes[dc->op2];
- LOG_DIS("move.%c $p%u, [$r%u%s\n",
- memsize_char(memsize),
- dc->op2, dc->op1, dc->postinc ? "+]" : "]");
+ LOG_DIS("move.%c $p%u, [$r%u%s\n",
+ memsize_char(memsize),
+ dc->op2, dc->op1, dc->postinc ? "+]" : "]");
- /* prepare store. Address in T0, value in T1. */
- if (dc->op2 == PR_CCS)
- cris_evaluate_flags(dc);
- t0 = tcg_temp_new();
- t_gen_mov_TN_preg(t0, dc->op2);
- cris_flush_cc_state(dc);
- gen_store(dc, cpu_R[dc->op1], t0, memsize);
- tcg_temp_free(t0);
-
- cris_cc_mask(dc, 0);
- if (dc->postinc)
- tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
- return 2;
+ /* prepare store. Address in T0, value in T1. */
+ if (dc->op2 == PR_CCS) {
+ cris_evaluate_flags(dc);
+ }
+ t0 = tcg_temp_new();
+ t_gen_mov_TN_preg(t0, dc->op2);
+ cris_flush_cc_state(dc);
+ gen_store(dc, cpu_R[dc->op1], t0, memsize);
+ tcg_temp_free(t0);
+
+ cris_cc_mask(dc, 0);
+ if (dc->postinc) {
+ tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
+ }
+ return 2;
}
static int dec_movem_mr(CPUCRISState *env, DisasContext *dc)
{
- TCGv_i64 tmp[16];
- TCGv tmp32;
- TCGv addr;
- int i;
- int nr = dc->op2 + 1;
-
- LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1,
- dc->postinc ? "+]" : "]", dc->op2);
-
- addr = tcg_temp_new();
- /* There are probably better ways of doing this. */
- cris_flush_cc_state(dc);
- for (i = 0; i < (nr >> 1); i++) {
- tmp[i] = tcg_temp_new_i64();
- tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
- gen_load64(dc, tmp[i], addr);
- }
- if (nr & 1) {
- tmp32 = tcg_temp_new_i32();
- tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
- gen_load(dc, tmp32, addr, 4, 0);
- } else
- TCGV_UNUSED(tmp32);
- tcg_temp_free(addr);
-
- for (i = 0; i < (nr >> 1); i++) {
- tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);
- tcg_gen_shri_i64(tmp[i], tmp[i], 32);
- tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
- tcg_temp_free_i64(tmp[i]);
- }
- if (nr & 1) {
- tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
- tcg_temp_free(tmp32);
- }
-
- /* writeback the updated pointer value. */
- if (dc->postinc)
- tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
-
- /* gen_load might want to evaluate the previous insns flags. */
- cris_cc_mask(dc, 0);
- return 2;
+ TCGv_i64 tmp[16];
+ TCGv tmp32;
+ TCGv addr;
+ int i;
+ int nr = dc->op2 + 1;
+
+ LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1,
+ dc->postinc ? "+]" : "]", dc->op2);
+
+ addr = tcg_temp_new();
+ /* There are probably better ways of doing this. */
+ cris_flush_cc_state(dc);
+ for (i = 0; i < (nr >> 1); i++) {
+ tmp[i] = tcg_temp_new_i64();
+ tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
+ gen_load64(dc, tmp[i], addr);
+ }
+ if (nr & 1) {
+ tmp32 = tcg_temp_new_i32();
+ tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
+ gen_load(dc, tmp32, addr, 4, 0);
+ } else {
+ TCGV_UNUSED(tmp32);
+ }
+ tcg_temp_free(addr);
+
+ for (i = 0; i < (nr >> 1); i++) {
+ tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);
+ tcg_gen_shri_i64(tmp[i], tmp[i], 32);
+ tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
+ tcg_temp_free_i64(tmp[i]);
+ }
+ if (nr & 1) {
+ tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
+ tcg_temp_free(tmp32);
+ }
+
+ /* writeback the updated pointer value. */
+ if (dc->postinc) {
+ tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);
+ }
+
+ /* gen_load might want to evaluate the previous insns flags. */
+ cris_cc_mask(dc, 0);
+ return 2;
}
static int dec_movem_rm(CPUCRISState *env, DisasContext *dc)
{
- TCGv tmp;
- TCGv addr;
- int i;
-
- LOG_DIS("movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
- dc->postinc ? "+]" : "]");
-
- cris_flush_cc_state(dc);
-
- tmp = tcg_temp_new();
- addr = tcg_temp_new();
- tcg_gen_movi_tl(tmp, 4);
- tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
- for (i = 0; i <= dc->op2; i++) {
- /* Displace addr. */
- /* Perform the store. */
- gen_store(dc, addr, cpu_R[i], 4);
- tcg_gen_add_tl(addr, addr, tmp);
- }
- if (dc->postinc)
- tcg_gen_mov_tl(cpu_R[dc->op1], addr);
- cris_cc_mask(dc, 0);
- tcg_temp_free(tmp);
- tcg_temp_free(addr);
- return 2;
+ TCGv tmp;
+ TCGv addr;
+ int i;
+
+ LOG_DIS("movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
+ dc->postinc ? "+]" : "]");
+
+ cris_flush_cc_state(dc);
+
+ tmp = tcg_temp_new();
+ addr = tcg_temp_new();
+ tcg_gen_movi_tl(tmp, 4);
+ tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
+ for (i = 0; i <= dc->op2; i++) {
+ /* Displace addr. */
+ /* Perform the store. */
+ gen_store(dc, addr, cpu_R[i], 4);
+ tcg_gen_add_tl(addr, addr, tmp);
+ }
+ if (dc->postinc) {
+ tcg_gen_mov_tl(cpu_R[dc->op1], addr);
+ }
+ cris_cc_mask(dc, 0);
+ tcg_temp_free(tmp);
+ tcg_temp_free(addr);
+ return 2;
}
static int dec_move_rm(CPUCRISState *env, DisasContext *dc)
{
- int memsize;
+ int memsize;
- memsize = memsize_zz(dc);
+ memsize = memsize_zz(dc);
- LOG_DIS("move.%c $r%u, [$r%u]\n",
- memsize_char(memsize), dc->op2, dc->op1);
+ LOG_DIS("move.%c $r%u, [$r%u]\n",
+ memsize_char(memsize), dc->op2, dc->op1);
- /* prepare store. */
- cris_flush_cc_state(dc);
- gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
+ /* prepare store. */
+ cris_flush_cc_state(dc);
+ gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);
- if (dc->postinc)
- tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
- cris_cc_mask(dc, 0);
- return 2;
+ if (dc->postinc) {
+ tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
+ }
+ cris_cc_mask(dc, 0);
+ return 2;
}
static int dec_lapcq(CPUCRISState *env, DisasContext *dc)
{
- LOG_DIS("lapcq %x, $r%u\n",
- dc->pc + dc->op1*2, dc->op2);
- cris_cc_mask(dc, 0);
- tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
- return 2;
+ LOG_DIS("lapcq %x, $r%u\n",
+ dc->pc + dc->op1*2, dc->op2);
+ cris_cc_mask(dc, 0);
+ tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
+ return 2;
}
static int dec_lapc_im(CPUCRISState *env, DisasContext *dc)
{
- unsigned int rd;
- int32_t imm;
- int32_t pc;
+ unsigned int rd;
+ int32_t imm;
+ int32_t pc;
- rd = dc->op2;
+ rd = dc->op2;
- cris_cc_mask(dc, 0);
- imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
- LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
+ cris_cc_mask(dc, 0);
+ imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
+ LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
- pc = dc->pc;
- pc += imm;
- tcg_gen_movi_tl(cpu_R[rd], pc);
- return 6;
+ pc = dc->pc;
+ pc += imm;
+ tcg_gen_movi_tl(cpu_R[rd], pc);
+ return 6;
}
/* Jump to special reg. */
static int dec_jump_p(CPUCRISState *env, DisasContext *dc)
{
- LOG_DIS("jump $p%u\n", dc->op2);
+ LOG_DIS("jump $p%u\n", dc->op2);
- if (dc->op2 == PR_CCS)
- cris_evaluate_flags(dc);
- t_gen_mov_TN_preg(env_btarget, dc->op2);
- /* rete will often have low bit set to indicate delayslot. */
- tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
- cris_cc_mask(dc, 0);
- cris_prepare_jmp(dc, JMP_INDIRECT);
- return 2;
+ if (dc->op2 == PR_CCS) {
+ cris_evaluate_flags(dc);
+ }
+ t_gen_mov_TN_preg(env_btarget, dc->op2);
+ /* rete will often have low bit set to indicate delayslot. */
+ tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
+ cris_cc_mask(dc, 0);
+ cris_prepare_jmp(dc, JMP_INDIRECT);
+ return 2;
}
/* Jump and save. */
static int dec_jas_r(CPUCRISState *env, DisasContext *dc)
{
- LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
- cris_cc_mask(dc, 0);
- /* Store the return address in Pd. */
- tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
- if (dc->op2 > 15)
- abort();
- t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4));
+ LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
+ cris_cc_mask(dc, 0);
+ /* Store the return address in Pd. */
+ tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
+ if (dc->op2 > 15) {
+ abort();
+ }
+ t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4));
- cris_prepare_jmp(dc, JMP_INDIRECT);
- return 2;
+ cris_prepare_jmp(dc, JMP_INDIRECT);
+ return 2;
}
static int dec_jas_im(CPUCRISState *env, DisasContext *dc)
{
- uint32_t imm;
+ uint32_t imm;
- imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
+ imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
- LOG_DIS("jas 0x%x\n", imm);
- cris_cc_mask(dc, 0);
- /* Store the return address in Pd. */
- t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
+ LOG_DIS("jas 0x%x\n", imm);
+ cris_cc_mask(dc, 0);
+ /* Store the return address in Pd. */
+ t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
- dc->jmp_pc = imm;
- cris_prepare_jmp(dc, JMP_DIRECT);
- return 6;
+ dc->jmp_pc = imm;
+ cris_prepare_jmp(dc, JMP_DIRECT);
+ return 6;
}
static int dec_jasc_im(CPUCRISState *env, DisasContext *dc)
{
- uint32_t imm;
+ uint32_t imm;
- imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
+ imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
- LOG_DIS("jasc 0x%x\n", imm);
- cris_cc_mask(dc, 0);
- /* Store the return address in Pd. */
- t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8 + 4));
+ LOG_DIS("jasc 0x%x\n", imm);
+ cris_cc_mask(dc, 0);
+ /* Store the return address in Pd. */
+ t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8 + 4));
- dc->jmp_pc = imm;
- cris_prepare_jmp(dc, JMP_DIRECT);
- return 6;
+ dc->jmp_pc = imm;
+ cris_prepare_jmp(dc, JMP_DIRECT);
+ return 6;
}
static int dec_jasc_r(CPUCRISState *env, DisasContext *dc)
{
- LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
- cris_cc_mask(dc, 0);
- /* Store the return address in Pd. */
- tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
- t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4 + 4));
- cris_prepare_jmp(dc, JMP_INDIRECT);
- return 2;
+ LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
+ cris_cc_mask(dc, 0);
+ /* Store the return address in Pd. */
+ tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
+ t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4 + 4));
+ cris_prepare_jmp(dc, JMP_INDIRECT);
+ return 2;
}
static int dec_bcc_im(CPUCRISState *env, DisasContext *dc)
{
- int32_t offset;
- uint32_t cond = dc->op2;
+ int32_t offset;
+ uint32_t cond = dc->op2;
- offset = cris_fetch(env, dc, dc->pc + 2, 2, 1);
+ offset = cris_fetch(env, dc, dc->pc + 2, 2, 1);
- LOG_DIS("b%s %d pc=%x dst=%x\n",
- cc_name(cond), offset,
- dc->pc, dc->pc + offset);
+ LOG_DIS("b%s %d pc=%x dst=%x\n",
+ cc_name(cond), offset,
+ dc->pc, dc->pc + offset);
- cris_cc_mask(dc, 0);
- /* op2 holds the condition-code. */
- cris_prepare_cc_branch (dc, offset, cond);
- return 4;
+ cris_cc_mask(dc, 0);
+ /* op2 holds the condition-code. */
+ cris_prepare_cc_branch(dc, offset, cond);
+ return 4;
}
static int dec_bas_im(CPUCRISState *env, DisasContext *dc)
{
- int32_t simm;
+ int32_t simm;
+ simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
- simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
+ LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
+ cris_cc_mask(dc, 0);
+ /* Store the return address in Pd. */
+ t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
- LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
- cris_cc_mask(dc, 0);
- /* Store the return address in Pd. */
- t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));
-
- dc->jmp_pc = dc->pc + simm;
- cris_prepare_jmp(dc, JMP_DIRECT);
- return 6;
+ dc->jmp_pc = dc->pc + simm;
+ cris_prepare_jmp(dc, JMP_DIRECT);
+ return 6;
}
static int dec_basc_im(CPUCRISState *env, DisasContext *dc)
{
- int32_t simm;
- simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
+ int32_t simm;
+ simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
- LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
- cris_cc_mask(dc, 0);
- /* Store the return address in Pd. */
- t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 12));
+ LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
+ cris_cc_mask(dc, 0);
+ /* Store the return address in Pd. */
+ t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 12));
- dc->jmp_pc = dc->pc + simm;
- cris_prepare_jmp(dc, JMP_DIRECT);
- return 6;
+ dc->jmp_pc = dc->pc + simm;
+ cris_prepare_jmp(dc, JMP_DIRECT);
+ return 6;
}
static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
{
- cris_cc_mask(dc, 0);
-
- if (dc->op2 == 15) {
- t_gen_mov_env_TN(halted, tcg_const_tl(1));
- tcg_gen_movi_tl(env_pc, dc->pc + 2);
- t_gen_raise_exception(EXCP_HLT);
- return 2;
- }
-
- switch (dc->op2 & 7) {
- case 2:
- /* rfe. */
- LOG_DIS("rfe\n");
- cris_evaluate_flags(dc);
- gen_helper_rfe(cpu_env);
- dc->is_jmp = DISAS_UPDATE;
- break;
- case 5:
- /* rfn. */
- LOG_DIS("rfn\n");
- cris_evaluate_flags(dc);
- gen_helper_rfn(cpu_env);
- dc->is_jmp = DISAS_UPDATE;
- break;
- case 6:
- LOG_DIS("break %d\n", dc->op1);
- cris_evaluate_flags (dc);
- /* break. */
- tcg_gen_movi_tl(env_pc, dc->pc + 2);
-
- /* Breaks start at 16 in the exception vector. */
- t_gen_mov_env_TN(trap_vector,
- tcg_const_tl(dc->op1 + 16));
- t_gen_raise_exception(EXCP_BREAK);
- dc->is_jmp = DISAS_UPDATE;
- break;
- default:
- printf ("op2=%x\n", dc->op2);
- BUG();
- break;
-
- }
- return 2;
+ cris_cc_mask(dc, 0);
+
+ if (dc->op2 == 15) {
+ t_gen_mov_env_TN(halted, tcg_const_tl(1));
+ tcg_gen_movi_tl(env_pc, dc->pc + 2);
+ t_gen_raise_exception(EXCP_HLT);
+ return 2;
+ }
+
+ switch (dc->op2 & 7) {
+ case 2:
+ /* rfe. */
+ LOG_DIS("rfe\n");
+ cris_evaluate_flags(dc);
+ gen_helper_rfe(cpu_env);
+ dc->is_jmp = DISAS_UPDATE;
+ break;
+ case 5:
+ /* rfn. */
+ LOG_DIS("rfn\n");
+ cris_evaluate_flags(dc);
+ gen_helper_rfn(cpu_env);
+ dc->is_jmp = DISAS_UPDATE;
+ break;
+ case 6:
+ LOG_DIS("break %d\n", dc->op1);
+ cris_evaluate_flags(dc);
+ /* break. */
+ tcg_gen_movi_tl(env_pc, dc->pc + 2);
+
+ /* Breaks start at 16 in the exception vector. */
+ t_gen_mov_env_TN(trap_vector,
+ tcg_const_tl(dc->op1 + 16));
+ t_gen_raise_exception(EXCP_BREAK);
+ dc->is_jmp = DISAS_UPDATE;
+ break;
+ default:
+ printf("op2=%x\n", dc->op2);
+ BUG();
+ break;
+
+ }
+ return 2;
}
static int dec_ftag_fidx_d_m(CPUCRISState *env, DisasContext *dc)
{
- return 2;
+ return 2;
}
static int dec_ftag_fidx_i_m(CPUCRISState *env, DisasContext *dc)
{
- return 2;
+ return 2;
}
static int dec_null(CPUCRISState *env, DisasContext *dc)
{
- printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
- dc->pc, dc->opcode, dc->op1, dc->op2);
- fflush(NULL);
- BUG();
- return 2;
+ printf("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
+ dc->pc, dc->opcode, dc->op1, dc->op2);
+ fflush(NULL);
+ BUG();
+ return 2;
}
static struct decoder_info {
- struct {
- uint32_t bits;
- uint32_t mask;
- };
- int (*dec)(CPUCRISState *env, DisasContext *dc);
+ struct {
+ uint32_t bits;
+ uint32_t mask;
+ };
+ int (*dec)(CPUCRISState *env, DisasContext *dc);
} decinfo[] = {
- /* Order matters here. */
- {DEC_MOVEQ, dec_moveq},
- {DEC_BTSTQ, dec_btstq},
- {DEC_CMPQ, dec_cmpq},
- {DEC_ADDOQ, dec_addoq},
- {DEC_ADDQ, dec_addq},
- {DEC_SUBQ, dec_subq},
- {DEC_ANDQ, dec_andq},
- {DEC_ORQ, dec_orq},
- {DEC_ASRQ, dec_asrq},
- {DEC_LSLQ, dec_lslq},
- {DEC_LSRQ, dec_lsrq},
- {DEC_BCCQ, dec_bccq},
-
- {DEC_BCC_IM, dec_bcc_im},
- {DEC_JAS_IM, dec_jas_im},
- {DEC_JAS_R, dec_jas_r},
- {DEC_JASC_IM, dec_jasc_im},
- {DEC_JASC_R, dec_jasc_r},
- {DEC_BAS_IM, dec_bas_im},
- {DEC_BASC_IM, dec_basc_im},
- {DEC_JUMP_P, dec_jump_p},
- {DEC_LAPC_IM, dec_lapc_im},
- {DEC_LAPCQ, dec_lapcq},
-
- {DEC_RFE_ETC, dec_rfe_etc},
- {DEC_ADDC_MR, dec_addc_mr},
-
- {DEC_MOVE_MP, dec_move_mp},
- {DEC_MOVE_PM, dec_move_pm},
- {DEC_MOVEM_MR, dec_movem_mr},
- {DEC_MOVEM_RM, dec_movem_rm},
- {DEC_MOVE_PR, dec_move_pr},
- {DEC_SCC_R, dec_scc_r},
- {DEC_SETF, dec_setclrf},
- {DEC_CLEARF, dec_setclrf},
-
- {DEC_MOVE_SR, dec_move_sr},
- {DEC_MOVE_RP, dec_move_rp},
- {DEC_SWAP_R, dec_swap_r},
- {DEC_ABS_R, dec_abs_r},
- {DEC_LZ_R, dec_lz_r},
- {DEC_MOVE_RS, dec_move_rs},
- {DEC_BTST_R, dec_btst_r},
- {DEC_ADDC_R, dec_addc_r},
-
- {DEC_DSTEP_R, dec_dstep_r},
- {DEC_XOR_R, dec_xor_r},
- {DEC_MCP_R, dec_mcp_r},
- {DEC_CMP_R, dec_cmp_r},
-
- {DEC_ADDI_R, dec_addi_r},
- {DEC_ADDI_ACR, dec_addi_acr},
-
- {DEC_ADD_R, dec_add_r},
- {DEC_SUB_R, dec_sub_r},
-
- {DEC_ADDU_R, dec_addu_r},
- {DEC_ADDS_R, dec_adds_r},
- {DEC_SUBU_R, dec_subu_r},
- {DEC_SUBS_R, dec_subs_r},
- {DEC_LSL_R, dec_lsl_r},
-
- {DEC_AND_R, dec_and_r},
- {DEC_OR_R, dec_or_r},
- {DEC_BOUND_R, dec_bound_r},
- {DEC_ASR_R, dec_asr_r},
- {DEC_LSR_R, dec_lsr_r},
-
- {DEC_MOVU_R, dec_movu_r},
- {DEC_MOVS_R, dec_movs_r},
- {DEC_NEG_R, dec_neg_r},
- {DEC_MOVE_R, dec_move_r},
-
- {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
- {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
-
- {DEC_MULS_R, dec_muls_r},
- {DEC_MULU_R, dec_mulu_r},
-
- {DEC_ADDU_M, dec_addu_m},
- {DEC_ADDS_M, dec_adds_m},
- {DEC_SUBU_M, dec_subu_m},
- {DEC_SUBS_M, dec_subs_m},
-
- {DEC_CMPU_M, dec_cmpu_m},
- {DEC_CMPS_M, dec_cmps_m},
- {DEC_MOVU_M, dec_movu_m},
- {DEC_MOVS_M, dec_movs_m},
-
- {DEC_CMP_M, dec_cmp_m},
- {DEC_ADDO_M, dec_addo_m},
- {DEC_BOUND_M, dec_bound_m},
- {DEC_ADD_M, dec_add_m},
- {DEC_SUB_M, dec_sub_m},
- {DEC_AND_M, dec_and_m},
- {DEC_OR_M, dec_or_m},
- {DEC_MOVE_RM, dec_move_rm},
- {DEC_TEST_M, dec_test_m},
- {DEC_MOVE_MR, dec_move_mr},
-
- {{0, 0}, dec_null}
+ /* Order matters here. */
+ {DEC_MOVEQ, dec_moveq},
+ {DEC_BTSTQ, dec_btstq},
+ {DEC_CMPQ, dec_cmpq},
+ {DEC_ADDOQ, dec_addoq},
+ {DEC_ADDQ, dec_addq},
+ {DEC_SUBQ, dec_subq},
+ {DEC_ANDQ, dec_andq},
+ {DEC_ORQ, dec_orq},
+ {DEC_ASRQ, dec_asrq},
+ {DEC_LSLQ, dec_lslq},
+ {DEC_LSRQ, dec_lsrq},
+ {DEC_BCCQ, dec_bccq},
+
+ {DEC_BCC_IM, dec_bcc_im},
+ {DEC_JAS_IM, dec_jas_im},
+ {DEC_JAS_R, dec_jas_r},
+ {DEC_JASC_IM, dec_jasc_im},
+ {DEC_JASC_R, dec_jasc_r},
+ {DEC_BAS_IM, dec_bas_im},
+ {DEC_BASC_IM, dec_basc_im},
+ {DEC_JUMP_P, dec_jump_p},
+ {DEC_LAPC_IM, dec_lapc_im},
+ {DEC_LAPCQ, dec_lapcq},
+
+ {DEC_RFE_ETC, dec_rfe_etc},
+ {DEC_ADDC_MR, dec_addc_mr},
+
+ {DEC_MOVE_MP, dec_move_mp},
+ {DEC_MOVE_PM, dec_move_pm},
+ {DEC_MOVEM_MR, dec_movem_mr},
+ {DEC_MOVEM_RM, dec_movem_rm},
+ {DEC_MOVE_PR, dec_move_pr},
+ {DEC_SCC_R, dec_scc_r},
+ {DEC_SETF, dec_setclrf},
+ {DEC_CLEARF, dec_setclrf},
+
+ {DEC_MOVE_SR, dec_move_sr},
+ {DEC_MOVE_RP, dec_move_rp},
+ {DEC_SWAP_R, dec_swap_r},
+ {DEC_ABS_R, dec_abs_r},
+ {DEC_LZ_R, dec_lz_r},
+ {DEC_MOVE_RS, dec_move_rs},
+ {DEC_BTST_R, dec_btst_r},
+ {DEC_ADDC_R, dec_addc_r},
+
+ {DEC_DSTEP_R, dec_dstep_r},
+ {DEC_XOR_R, dec_xor_r},
+ {DEC_MCP_R, dec_mcp_r},
+ {DEC_CMP_R, dec_cmp_r},
+
+ {DEC_ADDI_R, dec_addi_r},
+ {DEC_ADDI_ACR, dec_addi_acr},
+
+ {DEC_ADD_R, dec_add_r},
+ {DEC_SUB_R, dec_sub_r},
+
+ {DEC_ADDU_R, dec_addu_r},
+ {DEC_ADDS_R, dec_adds_r},
+ {DEC_SUBU_R, dec_subu_r},
+ {DEC_SUBS_R, dec_subs_r},
+ {DEC_LSL_R, dec_lsl_r},
+
+ {DEC_AND_R, dec_and_r},
+ {DEC_OR_R, dec_or_r},
+ {DEC_BOUND_R, dec_bound_r},
+ {DEC_ASR_R, dec_asr_r},
+ {DEC_LSR_R, dec_lsr_r},
+
+ {DEC_MOVU_R, dec_movu_r},
+ {DEC_MOVS_R, dec_movs_r},
+ {DEC_NEG_R, dec_neg_r},
+ {DEC_MOVE_R, dec_move_r},
+
+ {DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
+ {DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},
+
+ {DEC_MULS_R, dec_muls_r},
+ {DEC_MULU_R, dec_mulu_r},
+
+ {DEC_ADDU_M, dec_addu_m},
+ {DEC_ADDS_M, dec_adds_m},
+ {DEC_SUBU_M, dec_subu_m},
+ {DEC_SUBS_M, dec_subs_m},
+
+ {DEC_CMPU_M, dec_cmpu_m},
+ {DEC_CMPS_M, dec_cmps_m},
+ {DEC_MOVU_M, dec_movu_m},
+ {DEC_MOVS_M, dec_movs_m},
+
+ {DEC_CMP_M, dec_cmp_m},
+ {DEC_ADDO_M, dec_addo_m},
+ {DEC_BOUND_M, dec_bound_m},
+ {DEC_ADD_M, dec_add_m},
+ {DEC_SUB_M, dec_sub_m},
+ {DEC_AND_M, dec_and_m},
+ {DEC_OR_M, dec_or_m},
+ {DEC_MOVE_RM, dec_move_rm},
+ {DEC_TEST_M, dec_test_m},
+ {DEC_MOVE_MR, dec_move_mr},
+
+ {{0, 0}, dec_null}
};
static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
{
- int insn_len = 2;
- int i;
+ int insn_len = 2;
+ int i;
- if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
- tcg_gen_debug_insn_start(dc->pc);
+ if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
+ tcg_gen_debug_insn_start(dc->pc);
}
- /* Load a halfword onto the instruction register. */
+ /* Load a halfword onto the instruction register. */
dc->ir = cris_fetch(env, dc, dc->pc, 2, 0);
- /* Now decode it. */
- dc->opcode = EXTRACT_FIELD(dc->ir, 4, 11);
- dc->op1 = EXTRACT_FIELD(dc->ir, 0, 3);
- dc->op2 = EXTRACT_FIELD(dc->ir, 12, 15);
- dc->zsize = EXTRACT_FIELD(dc->ir, 4, 4);
- dc->zzsize = EXTRACT_FIELD(dc->ir, 4, 5);
- dc->postinc = EXTRACT_FIELD(dc->ir, 10, 10);
-
- /* Large switch for all insns. */
- for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
- if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
- {
- insn_len = decinfo[i].dec(env, dc);
- break;
- }
- }
+ /* Now decode it. */
+ dc->opcode = EXTRACT_FIELD(dc->ir, 4, 11);
+ dc->op1 = EXTRACT_FIELD(dc->ir, 0, 3);
+ dc->op2 = EXTRACT_FIELD(dc->ir, 12, 15);
+ dc->zsize = EXTRACT_FIELD(dc->ir, 4, 4);
+ dc->zzsize = EXTRACT_FIELD(dc->ir, 4, 5);
+ dc->postinc = EXTRACT_FIELD(dc->ir, 10, 10);
+
+ /* Large switch for all insns. */
+ for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
+ if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
+ insn_len = decinfo[i].dec(env, dc);
+ break;
+ }
+ }
#if !defined(CONFIG_USER_ONLY)
- /* Single-stepping ? */
- if (dc->tb_flags & S_FLAG) {
- int l1;
-
- l1 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_NE, cpu_PR[PR_SPC], dc->pc, l1);
- /* We treat SPC as a break with an odd trap vector. */
- cris_evaluate_flags (dc);
- t_gen_mov_env_TN(trap_vector, tcg_const_tl(3));
- tcg_gen_movi_tl(env_pc, dc->pc + insn_len);
- tcg_gen_movi_tl(cpu_PR[PR_SPC], dc->pc + insn_len);
- t_gen_raise_exception(EXCP_BREAK);
- gen_set_label(l1);
- }
+ /* Single-stepping ? */
+ if (dc->tb_flags & S_FLAG) {
+ int l1;
+
+ l1 = gen_new_label();
+ tcg_gen_brcondi_tl(TCG_COND_NE, cpu_PR[PR_SPC], dc->pc, l1);
+ /* We treat SPC as a break with an odd trap vector. */
+ cris_evaluate_flags(dc);
+ t_gen_mov_env_TN(trap_vector, tcg_const_tl(3));
+ tcg_gen_movi_tl(env_pc, dc->pc + insn_len);
+ tcg_gen_movi_tl(cpu_PR[PR_SPC], dc->pc + insn_len);
+ t_gen_raise_exception(EXCP_BREAK);
+ gen_set_label(l1);
+ }
#endif
- return insn_len;
+ return insn_len;
}
static void check_breakpoint(CPUCRISState *env, DisasContext *dc)
{
- CPUBreakpoint *bp;
+ CPUBreakpoint *bp;
- if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
- QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
- if (bp->pc == dc->pc) {
- cris_evaluate_flags (dc);
- tcg_gen_movi_tl(env_pc, dc->pc);
- t_gen_raise_exception(EXCP_DEBUG);
- dc->is_jmp = DISAS_UPDATE;
- }
- }
- }
+ if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
+ QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+ if (bp->pc == dc->pc) {
+ cris_evaluate_flags(dc);
+ tcg_gen_movi_tl(env_pc, dc->pc);
+ t_gen_raise_exception(EXCP_DEBUG);
+ dc->is_jmp = DISAS_UPDATE;
+ }
+ }
+ }
}
#include "translate_v10.c"
@@ -3174,250 +3204,256 @@ static void
gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
int search_pc)
{
- uint16_t *gen_opc_end;
- uint32_t pc_start;
- unsigned int insn_len;
- int j, lj;
- struct DisasContext ctx;
- struct DisasContext *dc = &ctx;
- uint32_t next_page_start;
- target_ulong npc;
- int num_insns;
- int max_insns;
-
- qemu_log_try_set_file(stderr);
-
- if (env->pregs[PR_VR] == 32) {
- dc->decoder = crisv32_decoder;
- dc->clear_locked_irq = 0;
- } else {
- dc->decoder = crisv10_decoder;
- dc->clear_locked_irq = 1;
- }
-
- /* Odd PC indicates that branch is rexecuting due to exception in the
- * delayslot, like in real hw.
- */
- pc_start = tb->pc & ~1;
- dc->env = env;
- dc->tb = tb;
-
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-
- dc->is_jmp = DISAS_NEXT;
- dc->ppc = pc_start;
- dc->pc = pc_start;
- dc->singlestep_enabled = env->singlestep_enabled;
- dc->flags_uptodate = 1;
- dc->flagx_known = 1;
- dc->flags_x = tb->flags & X_FLAG;
- dc->cc_x_uptodate = 0;
- dc->cc_mask = 0;
- dc->update_cc = 0;
- dc->clear_prefix = 0;
-
- cris_update_cc_op(dc, CC_OP_FLAGS, 4);
- dc->cc_size_uptodate = -1;
-
- /* Decode TB flags. */
- dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
- | X_FLAG | PFIX_FLAG);
- dc->delayed_branch = !!(tb->flags & 7);
- if (dc->delayed_branch)
- dc->jmp = JMP_INDIRECT;
- else
- dc->jmp = JMP_NOJMP;
-
- dc->cpustate_changed = 0;
-
- if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
- qemu_log(
- "srch=%d pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n"
- "pid=%x usp=%x\n"
- "%x.%x.%x.%x\n"
- "%x.%x.%x.%x\n"
- "%x.%x.%x.%x\n"
- "%x.%x.%x.%x\n",
- search_pc, dc->pc, dc->ppc,
- (uint64_t)tb->flags,
- env->btarget, (unsigned)tb->flags & 7,
- env->pregs[PR_CCS],
- env->pregs[PR_PID], env->pregs[PR_USP],
- env->regs[0], env->regs[1], env->regs[2], env->regs[3],
- env->regs[4], env->regs[5], env->regs[6], env->regs[7],
- env->regs[8], env->regs[9],
- env->regs[10], env->regs[11],
- env->regs[12], env->regs[13],
- env->regs[14], env->regs[15]);
- qemu_log("--------------\n");
- qemu_log("IN: %s\n", lookup_symbol(pc_start));
- }
-
- next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
- lj = -1;
- num_insns = 0;
- max_insns = tb->cflags & CF_COUNT_MASK;
- if (max_insns == 0)
- max_insns = CF_COUNT_MASK;
-
- gen_icount_start();
- do
- {
- check_breakpoint(env, dc);
-
- if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
- if (lj < j) {
- lj++;
- while (lj < j)
- gen_opc_instr_start[lj++] = 0;
- }
- if (dc->delayed_branch == 1)
- gen_opc_pc[lj] = dc->ppc | 1;
- else
- gen_opc_pc[lj] = dc->pc;
- gen_opc_instr_start[lj] = 1;
- gen_opc_icount[lj] = num_insns;
- }
-
- /* Pretty disas. */
- LOG_DIS("%8.8x:\t", dc->pc);
-
- if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
- gen_io_start();
- dc->clear_x = 1;
-
- insn_len = dc->decoder(env, dc);
- dc->ppc = dc->pc;
- dc->pc += insn_len;
- if (dc->clear_x)
- cris_clear_x_flag(dc);
-
- num_insns++;
- /* Check for delayed branches here. If we do it before
- actually generating any host code, the simulator will just
- loop doing nothing for on this program location. */
- if (dc->delayed_branch) {
- dc->delayed_branch--;
- if (dc->delayed_branch == 0)
- {
- if (tb->flags & 7)
- t_gen_mov_env_TN(dslot,
- tcg_const_tl(0));
- if (dc->cpustate_changed || !dc->flagx_known
- || (dc->flags_x != (tb->flags & X_FLAG))) {
- cris_store_direct_jmp(dc);
- }
-
- if (dc->clear_locked_irq) {
- dc->clear_locked_irq = 0;
- t_gen_mov_env_TN(locked_irq,
- tcg_const_tl(0));
- }
-
- if (dc->jmp == JMP_DIRECT_CC) {
- int l1;
-
- l1 = gen_new_label();
- cris_evaluate_flags(dc);
-
- /* Conditional jmp. */
- tcg_gen_brcondi_tl(TCG_COND_EQ,
- env_btaken, 0, l1);
- gen_goto_tb(dc, 1, dc->jmp_pc);
- gen_set_label(l1);
- gen_goto_tb(dc, 0, dc->pc);
- dc->is_jmp = DISAS_TB_JUMP;
- dc->jmp = JMP_NOJMP;
- } else if (dc->jmp == JMP_DIRECT) {
- cris_evaluate_flags(dc);
- gen_goto_tb(dc, 0, dc->jmp_pc);
- dc->is_jmp = DISAS_TB_JUMP;
- dc->jmp = JMP_NOJMP;
- } else {
- t_gen_cc_jmp(env_btarget,
- tcg_const_tl(dc->pc));
- dc->is_jmp = DISAS_JUMP;
- }
- break;
- }
- }
-
- /* If we are rexecuting a branch due to exceptions on
- delay slots dont break. */
- if (!(tb->pc & 1) && env->singlestep_enabled)
- break;
- } while (!dc->is_jmp && !dc->cpustate_changed
- && gen_opc_ptr < gen_opc_end
- && !singlestep
- && (dc->pc < next_page_start)
- && num_insns < max_insns);
-
- if (dc->clear_locked_irq)
- t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
-
- npc = dc->pc;
+ uint16_t *gen_opc_end;
+ uint32_t pc_start;
+ unsigned int insn_len;
+ int j, lj;
+ struct DisasContext ctx;
+ struct DisasContext *dc = &ctx;
+ uint32_t next_page_start;
+ target_ulong npc;
+ int num_insns;
+ int max_insns;
+
+ qemu_log_try_set_file(stderr);
+
+ if (env->pregs[PR_VR] == 32) {
+ dc->decoder = crisv32_decoder;
+ dc->clear_locked_irq = 0;
+ } else {
+ dc->decoder = crisv10_decoder;
+ dc->clear_locked_irq = 1;
+ }
+
+ /* Odd PC indicates that branch is rexecuting due to exception in the
+ * delayslot, like in real hw.
+ */
+ pc_start = tb->pc & ~1;
+ dc->env = env;
+ dc->tb = tb;
+
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
+
+ dc->is_jmp = DISAS_NEXT;
+ dc->ppc = pc_start;
+ dc->pc = pc_start;
+ dc->singlestep_enabled = env->singlestep_enabled;
+ dc->flags_uptodate = 1;
+ dc->flagx_known = 1;
+ dc->flags_x = tb->flags & X_FLAG;
+ dc->cc_x_uptodate = 0;
+ dc->cc_mask = 0;
+ dc->update_cc = 0;
+ dc->clear_prefix = 0;
+
+ cris_update_cc_op(dc, CC_OP_FLAGS, 4);
+ dc->cc_size_uptodate = -1;
+
+ /* Decode TB flags. */
+ dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
+ | X_FLAG | PFIX_FLAG);
+ dc->delayed_branch = !!(tb->flags & 7);
+ if (dc->delayed_branch) {
+ dc->jmp = JMP_INDIRECT;
+ } else {
+ dc->jmp = JMP_NOJMP;
+ }
+
+ dc->cpustate_changed = 0;
+
+ if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+ qemu_log(
+ "srch=%d pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n"
+ "pid=%x usp=%x\n"
+ "%x.%x.%x.%x\n"
+ "%x.%x.%x.%x\n"
+ "%x.%x.%x.%x\n"
+ "%x.%x.%x.%x\n",
+ search_pc, dc->pc, dc->ppc,
+ (uint64_t)tb->flags,
+ env->btarget, (unsigned)tb->flags & 7,
+ env->pregs[PR_CCS],
+ env->pregs[PR_PID], env->pregs[PR_USP],
+ env->regs[0], env->regs[1], env->regs[2], env->regs[3],
+ env->regs[4], env->regs[5], env->regs[6], env->regs[7],
+ env->regs[8], env->regs[9],
+ env->regs[10], env->regs[11],
+ env->regs[12], env->regs[13],
+ env->regs[14], env->regs[15]);
+ qemu_log("--------------\n");
+ qemu_log("IN: %s\n", lookup_symbol(pc_start));
+ }
+
+ next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
+ lj = -1;
+ num_insns = 0;
+ max_insns = tb->cflags & CF_COUNT_MASK;
+ if (max_insns == 0) {
+ max_insns = CF_COUNT_MASK;
+ }
+
+ gen_icount_start();
+ do {
+ check_breakpoint(env, dc);
+
+ if (search_pc) {
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
+ if (lj < j) {
+ lj++;
+ while (lj < j) {
+ gen_opc_instr_start[lj++] = 0;
+ }
+ }
+ if (dc->delayed_branch == 1) {
+ gen_opc_pc[lj] = dc->ppc | 1;
+ } else {
+ gen_opc_pc[lj] = dc->pc;
+ }
+ gen_opc_instr_start[lj] = 1;
+ gen_opc_icount[lj] = num_insns;
+ }
+
+ /* Pretty disas. */
+ LOG_DIS("%8.8x:\t", dc->pc);
+
+ if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
+ gen_io_start();
+ }
+ dc->clear_x = 1;
+
+ insn_len = dc->decoder(env, dc);
+ dc->ppc = dc->pc;
+ dc->pc += insn_len;
+ if (dc->clear_x) {
+ cris_clear_x_flag(dc);
+ }
+
+ num_insns++;
+ /* Check for delayed branches here. If we do it before
+ actually generating any host code, the simulator will just
+ loop doing nothing for on this program location. */
+ if (dc->delayed_branch) {
+ dc->delayed_branch--;
+ if (dc->delayed_branch == 0) {
+ if (tb->flags & 7) {
+ t_gen_mov_env_TN(dslot, tcg_const_tl(0));
+ }
+ if (dc->cpustate_changed || !dc->flagx_known
+ || (dc->flags_x != (tb->flags & X_FLAG))) {
+ cris_store_direct_jmp(dc);
+ }
+
+ if (dc->clear_locked_irq) {
+ dc->clear_locked_irq = 0;
+ t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
+ }
+
+ if (dc->jmp == JMP_DIRECT_CC) {
+ int l1;
+
+ l1 = gen_new_label();
+ cris_evaluate_flags(dc);
+
+ /* Conditional jmp. */
+ tcg_gen_brcondi_tl(TCG_COND_EQ,
+ env_btaken, 0, l1);
+ gen_goto_tb(dc, 1, dc->jmp_pc);
+ gen_set_label(l1);
+ gen_goto_tb(dc, 0, dc->pc);
+ dc->is_jmp = DISAS_TB_JUMP;
+ dc->jmp = JMP_NOJMP;
+ } else if (dc->jmp == JMP_DIRECT) {
+ cris_evaluate_flags(dc);
+ gen_goto_tb(dc, 0, dc->jmp_pc);
+ dc->is_jmp = DISAS_TB_JUMP;
+ dc->jmp = JMP_NOJMP;
+ } else {
+ t_gen_cc_jmp(env_btarget, tcg_const_tl(dc->pc));
+ dc->is_jmp = DISAS_JUMP;
+ }
+ break;
+ }
+ }
+
+ /* If we are rexecuting a branch due to exceptions on
+ delay slots dont break. */
+ if (!(tb->pc & 1) && env->singlestep_enabled) {
+ break;
+ }
+ } while (!dc->is_jmp && !dc->cpustate_changed
+ && tcg_ctx.gen_opc_ptr < gen_opc_end
+ && !singlestep
+ && (dc->pc < next_page_start)
+ && num_insns < max_insns);
+
+ if (dc->clear_locked_irq) {
+ t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
+ }
+
+ npc = dc->pc;
if (tb->cflags & CF_LAST_IO)
gen_io_end();
- /* Force an update if the per-tb cpu state has changed. */
- if (dc->is_jmp == DISAS_NEXT
- && (dc->cpustate_changed || !dc->flagx_known
- || (dc->flags_x != (tb->flags & X_FLAG)))) {
- dc->is_jmp = DISAS_UPDATE;
- tcg_gen_movi_tl(env_pc, npc);
- }
- /* Broken branch+delayslot sequence. */
- if (dc->delayed_branch == 1) {
- /* Set env->dslot to the size of the branch insn. */
- t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc));
- cris_store_direct_jmp(dc);
- }
-
- cris_evaluate_flags (dc);
-
- if (unlikely(env->singlestep_enabled)) {
- if (dc->is_jmp == DISAS_NEXT)
- tcg_gen_movi_tl(env_pc, npc);
- t_gen_raise_exception(EXCP_DEBUG);
- } else {
- switch(dc->is_jmp) {
- case DISAS_NEXT:
- gen_goto_tb(dc, 1, npc);
- break;
- default:
- case DISAS_JUMP:
- case DISAS_UPDATE:
- /* indicate that the hash table must be used
- to find the next TB */
- tcg_gen_exit_tb(0);
- break;
- case DISAS_SWI:
- case DISAS_TB_JUMP:
- /* nothing more to generate */
- break;
- }
- }
- gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
- if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
- lj++;
- while (lj <= j)
- gen_opc_instr_start[lj++] = 0;
- } else {
- tb->size = dc->pc - pc_start;
- tb->icount = num_insns;
- }
+ /* Force an update if the per-tb cpu state has changed. */
+ if (dc->is_jmp == DISAS_NEXT
+ && (dc->cpustate_changed || !dc->flagx_known
+ || (dc->flags_x != (tb->flags & X_FLAG)))) {
+ dc->is_jmp = DISAS_UPDATE;
+ tcg_gen_movi_tl(env_pc, npc);
+ }
+ /* Broken branch+delayslot sequence. */
+ if (dc->delayed_branch == 1) {
+ /* Set env->dslot to the size of the branch insn. */
+ t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc));
+ cris_store_direct_jmp(dc);
+ }
+
+ cris_evaluate_flags(dc);
+
+ if (unlikely(env->singlestep_enabled)) {
+ if (dc->is_jmp == DISAS_NEXT) {
+ tcg_gen_movi_tl(env_pc, npc);
+ }
+ t_gen_raise_exception(EXCP_DEBUG);
+ } else {
+ switch (dc->is_jmp) {
+ case DISAS_NEXT:
+ gen_goto_tb(dc, 1, npc);
+ break;
+ default:
+ case DISAS_JUMP:
+ case DISAS_UPDATE:
+ /* indicate that the hash table must be used
+ to find the next TB */
+ tcg_gen_exit_tb(0);
+ break;
+ case DISAS_SWI:
+ case DISAS_TB_JUMP:
+ /* nothing more to generate */
+ break;
+ }
+ }
+ gen_icount_end(tb, num_insns);
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
+ if (search_pc) {
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
+ lj++;
+ while (lj <= j) {
+ gen_opc_instr_start[lj++] = 0;
+ }
+ } else {
+ tb->size = dc->pc - pc_start;
+ tb->icount = num_insns;
+ }
#ifdef DEBUG_DISAS
#if !DISAS_CRIS
- if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
- log_target_disas(env, pc_start, dc->pc - pc_start,
+ if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+ log_target_disas(env, pc_start, dc->pc - pc_start,
dc->env->pregs[PR_VR]);
- qemu_log("\nisize=%d osize=%td\n",
- dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
- }
+ qemu_log("\nisize=%d osize=%td\n",
+ dc->pc - pc_start, tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf);
+ }
#endif
#endif
}
@@ -3435,41 +3471,45 @@ void gen_intermediate_code_pc (CPUCRISState *env, struct TranslationBlock *tb)
void cpu_dump_state (CPUCRISState *env, FILE *f, fprintf_function cpu_fprintf,
int flags)
{
- int i;
- uint32_t srs;
-
- if (!env || !f)
- return;
-
- cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
- "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
- env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
- env->cc_op,
- env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);
-
-
- for (i = 0; i < 16; i++) {
- cpu_fprintf(f, "%s=%8.8x ",regnames[i], env->regs[i]);
- if ((i + 1) % 4 == 0)
- cpu_fprintf(f, "\n");
- }
- cpu_fprintf(f, "\nspecial regs:\n");
- for (i = 0; i < 16; i++) {
- cpu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]);
- if ((i + 1) % 4 == 0)
- cpu_fprintf(f, "\n");
- }
- srs = env->pregs[PR_SRS];
- cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
- if (srs < ARRAY_SIZE(env->sregs)) {
- for (i = 0; i < 16; i++) {
- cpu_fprintf(f, "s%2.2d=%8.8x ",
- i, env->sregs[srs][i]);
- if ((i + 1) % 4 == 0)
- cpu_fprintf(f, "\n");
- }
- }
- cpu_fprintf(f, "\n\n");
+ int i;
+ uint32_t srs;
+
+ if (!env || !f) {
+ return;
+ }
+
+ cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
+ "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
+ env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
+ env->cc_op,
+ env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);
+
+
+ for (i = 0; i < 16; i++) {
+ cpu_fprintf(f, "%s=%8.8x ", regnames[i], env->regs[i]);
+ if ((i + 1) % 4 == 0) {
+ cpu_fprintf(f, "\n");
+ }
+ }
+ cpu_fprintf(f, "\nspecial regs:\n");
+ for (i = 0; i < 16; i++) {
+ cpu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]);
+ if ((i + 1) % 4 == 0) {
+ cpu_fprintf(f, "\n");
+ }
+ }
+ srs = env->pregs[PR_SRS];
+ cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
+ if (srs < ARRAY_SIZE(env->sregs)) {
+ for (i = 0; i < 16; i++) {
+ cpu_fprintf(f, "s%2.2d=%8.8x ",
+ i, env->sregs[srs][i]);
+ if ((i + 1) % 4 == 0) {
+ cpu_fprintf(f, "\n");
+ }
+ }
+ }
+ cpu_fprintf(f, "\n\n");
}
@@ -3478,11 +3518,11 @@ struct
uint32_t vr;
const char *name;
} cris_cores[] = {
- {8, "crisv8"},
- {9, "crisv9"},
- {10, "crisv10"},
- {11, "crisv11"},
- {32, "crisv32"},
+ {8, "crisv8"},
+ {9, "crisv9"},
+ {10, "crisv10"},
+ {11, "crisv11"},
+ {32, "crisv32"},
};
void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf)
@@ -3581,5 +3621,5 @@ CRISCPU *cpu_cris_init(const char *cpu_model)
void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb, int pc_pos)
{
- env->pc = gen_opc_pc[pc_pos];
+ env->pc = gen_opc_pc[pc_pos];
}
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 7fdb8bcbbe..8e676ba1a8 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -7962,7 +7962,7 @@ static inline void gen_intermediate_code_internal(CPUX86State *env,
cpu_ptr0 = tcg_temp_new_ptr();
cpu_ptr1 = tcg_temp_new_ptr();
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
dc->is_jmp = DISAS_NEXT;
pc_ptr = pc_start;
@@ -7984,7 +7984,7 @@ static inline void gen_intermediate_code_internal(CPUX86State *env,
}
}
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j)
@@ -8015,7 +8015,7 @@ static inline void gen_intermediate_code_internal(CPUX86State *env,
break;
}
/* if too long translation, stop generation too */
- if (gen_opc_ptr >= gen_opc_end ||
+ if (tcg_ctx.gen_opc_ptr >= gen_opc_end ||
(pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
num_insns >= max_insns) {
gen_jmp_im(pc_ptr - dc->cs_base);
@@ -8031,10 +8031,10 @@ static inline void gen_intermediate_code_internal(CPUX86State *env,
if (tb->cflags & CF_LAST_IO)
gen_io_end();
gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
/* we don't forget to fill the last values */
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j)
gen_opc_instr_start[lj++] = 0;
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 3307daaf11..af986499f2 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1018,7 +1018,7 @@ static void gen_intermediate_code_internal(CPULM32State *env,
dc->env = env;
dc->tb = tb;
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
dc->is_jmp = DISAS_NEXT;
dc->pc = pc_start;
@@ -1047,7 +1047,7 @@ static void gen_intermediate_code_internal(CPULM32State *env,
check_breakpoint(env, dc);
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j) {
@@ -1071,7 +1071,7 @@ static void gen_intermediate_code_internal(CPULM32State *env,
num_insns++;
} while (!dc->is_jmp
- && gen_opc_ptr < gen_opc_end
+ && tcg_ctx.gen_opc_ptr < gen_opc_end
&& !env->singlestep_enabled
&& !singlestep
&& (dc->pc < next_page_start)
@@ -1105,9 +1105,9 @@ static void gen_intermediate_code_internal(CPULM32State *env,
}
gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j) {
gen_opc_instr_start[lj++] = 0;
@@ -1122,7 +1122,8 @@ static void gen_intermediate_code_internal(CPULM32State *env,
qemu_log("\n");
log_target_disas(env, pc_start, dc->pc - pc_start, 0);
qemu_log("\nisize=%d osize=%td\n",
- dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
+ dc->pc - pc_start, tcg_ctx.gen_opc_ptr -
+ tcg_ctx.gen_opc_buf);
}
#endif
}
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 1430d4c991..b13be4899e 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2982,7 +2982,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
dc->tb = tb;
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
dc->env = env;
dc->is_jmp = DISAS_NEXT;
@@ -3015,7 +3015,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
break;
}
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j)
@@ -3030,7 +3030,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
dc->insn_pc = dc->pc;
disas_m68k_insn(env, dc);
num_insns++;
- } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
+ } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
!env->singlestep_enabled &&
!singlestep &&
(pc_offset) < (TARGET_PAGE_SIZE - 32) &&
@@ -3064,7 +3064,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
}
}
gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
#ifdef DEBUG_DISAS
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
@@ -3075,7 +3075,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
}
#endif
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j)
gen_opc_instr_start[lj++] = 0;
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 13fd73574b..cce4494954 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1741,7 +1741,7 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
dc->tb = tb;
org_flags = dc->synced_flags = dc->tb_flags = tb->flags;
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
dc->is_jmp = DISAS_NEXT;
dc->jmp = 0;
@@ -1784,7 +1784,7 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
check_breakpoint(env, dc);
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j)
@@ -1846,7 +1846,7 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
if (env->singlestep_enabled)
break;
} while (!dc->is_jmp && !dc->cpustate_changed
- && gen_opc_ptr < gen_opc_end
+ && tcg_ctx.gen_opc_ptr < gen_opc_end
&& !singlestep
&& (dc->pc < next_page_start)
&& num_insns < max_insns);
@@ -1897,9 +1897,9 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
}
}
gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j)
gen_opc_instr_start[lj++] = 0;
@@ -1916,7 +1916,8 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
log_target_disas(env, pc_start, dc->pc - pc_start, 0);
#endif
qemu_log("\nisize=%d osize=%td\n",
- dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
+ dc->pc - pc_start, tcg_ctx.gen_opc_ptr -
+ tcg_ctx.gen_opc_buf);
}
#endif
#endif
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 01b48fa2a2..8b438f8bb0 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15513,7 +15513,7 @@ gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
qemu_log("search pc %d\n", search_pc);
pc_start = tb->pc;
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
ctx.pc = pc_start;
ctx.saved_pc = -1;
ctx.singlestep_enabled = env->singlestep_enabled;
@@ -15549,7 +15549,7 @@ gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
}
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j)
@@ -15597,8 +15597,9 @@ gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
break;
- if (gen_opc_ptr >= gen_opc_end)
+ if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
break;
+ }
if (num_insns >= max_insns)
break;
@@ -15630,9 +15631,9 @@ gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
}
done_generating:
gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j)
gen_opc_instr_start[lj++] = 0;
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index ff2feb48db..f14da7bd1a 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1675,7 +1675,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
pc_start = tb->pc;
dc->tb = tb;
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
dc->is_jmp = DISAS_NEXT;
dc->ppc = pc_start;
dc->pc = pc_start;
@@ -1703,7 +1703,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
do {
check_breakpoint(cpu, dc);
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (k < j) {
k++;
while (k < j) {
@@ -1744,7 +1744,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
}
}
} while (!dc->is_jmp
- && gen_opc_ptr < gen_opc_end
+ && tcg_ctx.gen_opc_ptr < gen_opc_end
&& !cpu->env.singlestep_enabled
&& !singlestep
&& (dc->pc < next_page_start)
@@ -1782,9 +1782,9 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
}
gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
k++;
while (k <= j) {
gen_opc_instr_start[k++] = 0;
@@ -1799,7 +1799,8 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
qemu_log("\n");
log_target_disas(&cpu->env, pc_start, dc->pc - pc_start, 0);
qemu_log("\nisize=%d osize=%td\n",
- dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
+ dc->pc - pc_start, tcg_ctx.gen_opc_ptr -
+ tcg_ctx.gen_opc_buf);
}
#endif
}
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index f0d49eea3f..16b9c5dd57 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9624,7 +9624,7 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
int max_insns;
pc_start = tb->pc;
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
ctx.nip = pc_start;
ctx.tb = tb;
ctx.exception = POWERPC_EXCP_NONE;
@@ -9664,7 +9664,8 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
gen_icount_start();
/* Set env in case of segfault during code fetch */
- while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
+ while (ctx.exception == POWERPC_EXCP_NONE
+ && tcg_ctx.gen_opc_ptr < gen_opc_end) {
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (bp->pc == ctx.nip) {
@@ -9674,7 +9675,7 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
}
}
if (unlikely(search_pc)) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j)
@@ -9774,9 +9775,9 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
tcg_gen_exit_tb(0);
}
gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (unlikely(search_pc)) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j)
gen_opc_instr_start[lj++] = 0;
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index c6267a8769..993f20752c 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -5134,7 +5134,7 @@ static inline void gen_intermediate_code_internal(CPUS390XState *env,
dc.tb = tb;
dc.cc_op = CC_OP_DYNAMIC;
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
@@ -5156,7 +5156,7 @@ static inline void gen_intermediate_code_internal(CPUS390XState *env,
}
}
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j) {
@@ -5182,7 +5182,8 @@ static inline void gen_intermediate_code_internal(CPUS390XState *env,
if (env->singlestep_enabled) {
gen_debug(&dc);
}
- } while (!dc.is_jmp && gen_opc_ptr < gen_opc_end && dc.pc < next_page_start
+ } while (!dc.is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end
+ && dc.pc < next_page_start
&& num_insns < max_insns && !env->singlestep_enabled
&& !singlestep);
@@ -5206,9 +5207,9 @@ static inline void gen_intermediate_code_internal(CPUS390XState *env,
tcg_gen_exit_tb(0);
}
gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j) {
gen_opc_instr_start[lj++] = 0;
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 2ae7f03d35..5497dede05 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -1967,7 +1967,7 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
int max_insns;
pc_start = tb->pc;
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
ctx.pc = pc_start;
ctx.flags = (uint32_t)tb->flags;
ctx.bstate = BS_NONE;
@@ -1986,7 +1986,7 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
gen_icount_start();
- while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
+ while (ctx.bstate == BS_NONE && tcg_ctx.gen_opc_ptr < gen_opc_end) {
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (ctx.pc == bp->pc) {
@@ -1999,7 +1999,7 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
}
}
if (search_pc) {
- i = gen_opc_ptr - gen_opc_buf;
+ i = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (ii < i) {
ii++;
while (ii < i)
@@ -2056,9 +2056,9 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
}
gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
- i = gen_opc_ptr - gen_opc_buf;
+ i = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
ii++;
while (ii <= i)
gen_opc_instr_start[ii++] = 0;
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 1d8b8ad9b9..2ae803695b 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5257,7 +5257,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
dc->fpu_enabled = tb_fpu_enabled(tb->flags);
dc->address_mask_32bit = tb_am_enabled(tb->flags);
dc->singlestep = (env->singlestep_enabled || singlestep);
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
num_insns = 0;
max_insns = tb->cflags & CF_COUNT_MASK;
@@ -5279,7 +5279,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
}
if (spc) {
qemu_log("Search PC...\n");
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j)
@@ -5312,7 +5312,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
if (dc->singlestep) {
break;
}
- } while ((gen_opc_ptr < gen_opc_end) &&
+ } while ((tcg_ctx.gen_opc_ptr < gen_opc_end) &&
(dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
num_insns < max_insns);
@@ -5334,9 +5334,9 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
}
}
gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (spc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j)
gen_opc_instr_start[lj++] = 0;
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 57b18ac0c6..052bb45d70 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -1956,7 +1956,7 @@ static inline void gen_intermediate_code_internal(CPUUniCore32State *env,
dc->tb = tb;
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
dc->is_jmp = DISAS_NEXT;
dc->pc = pc_start;
@@ -1999,7 +1999,7 @@ static inline void gen_intermediate_code_internal(CPUUniCore32State *env,
}
}
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j) {
@@ -2031,7 +2031,7 @@ static inline void gen_intermediate_code_internal(CPUUniCore32State *env,
* Also stop translation when a page boundary is reached. This
* ensures prefetch aborts occur at the right place. */
num_insns++;
- } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
+ } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
!env->singlestep_enabled &&
!singlestep &&
dc->pc < next_page_start &&
@@ -2103,7 +2103,7 @@ static inline void gen_intermediate_code_internal(CPUUniCore32State *env,
done_generating:
gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
#ifdef DEBUG_DISAS
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
@@ -2114,7 +2114,7 @@ done_generating:
}
#endif
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j) {
gen_opc_instr_start[lj++] = 0;
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 3c03775a76..e5a3f49a75 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2849,7 +2849,7 @@ static void gen_intermediate_code_internal(
DisasContext dc;
int insn_count = 0;
int j, lj = -1;
- uint16_t *gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ uint16_t *gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
int max_insns = tb->cflags & CF_COUNT_MASK;
uint32_t pc_start = tb->pc;
uint32_t next_page_start =
@@ -2893,7 +2893,7 @@ static void gen_intermediate_code_internal(
check_breakpoint(env, &dc);
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j) {
@@ -2944,7 +2944,7 @@ static void gen_intermediate_code_internal(
} while (dc.is_jmp == DISAS_NEXT &&
insn_count < max_insns &&
dc.pc < next_page_start &&
- gen_opc_ptr < gen_opc_end);
+ tcg_ctx.gen_opc_ptr < gen_opc_end);
reset_litbase(&dc);
reset_sar_tracker(&dc);
@@ -2960,7 +2960,7 @@ static void gen_intermediate_code_internal(
gen_jumpi(&dc, dc.pc, 0);
}
gen_icount_end(tb, insn_count);
- *gen_opc_ptr = INDEX_op_end;
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (!search_pc) {
tb->size = dc.pc - pc_start;
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 8e5d918030..9109b813e0 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -484,10 +484,10 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
nb_globals = s->nb_globals;
memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
- nb_ops = tcg_opc_ptr - gen_opc_buf;
+ nb_ops = tcg_opc_ptr - s->gen_opc_buf;
gen_args = args;
for (op_index = 0; op_index < nb_ops; op_index++) {
- op = gen_opc_buf[op_index];
+ op = s->gen_opc_buf[op_index];
def = &tcg_op_defs[op];
/* Do copy propagation */
if (op == INDEX_op_call) {
@@ -569,7 +569,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
CASE_OP_32_64(rotr):
if (temps[args[1]].state == TCG_TEMP_CONST
&& temps[args[1]].val == 0) {
- gen_opc_buf[op_index] = op_to_movi(op);
+ s->gen_opc_buf[op_index] = op_to_movi(op);
tcg_opt_gen_movi(gen_args, args[0], 0);
args += 3;
gen_args += 2;
@@ -598,9 +598,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
if (temps[args[2]].state == TCG_TEMP_CONST
&& temps[args[2]].val == 0) {
if (temps_are_copies(args[0], args[1])) {
- gen_opc_buf[op_index] = INDEX_op_nop;
+ s->gen_opc_buf[op_index] = INDEX_op_nop;
} else {
- gen_opc_buf[op_index] = op_to_mov(op);
+ s->gen_opc_buf[op_index] = op_to_mov(op);
tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
gen_args += 2;
}
@@ -618,7 +618,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
CASE_OP_32_64(mul):
if ((temps[args[2]].state == TCG_TEMP_CONST
&& temps[args[2]].val == 0)) {
- gen_opc_buf[op_index] = op_to_movi(op);
+ s->gen_opc_buf[op_index] = op_to_movi(op);
tcg_opt_gen_movi(gen_args, args[0], 0);
args += 3;
gen_args += 2;
@@ -635,9 +635,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
CASE_OP_32_64(and):
if (temps_are_copies(args[1], args[2])) {
if (temps_are_copies(args[0], args[1])) {
- gen_opc_buf[op_index] = INDEX_op_nop;
+ s->gen_opc_buf[op_index] = INDEX_op_nop;
} else {
- gen_opc_buf[op_index] = op_to_mov(op);
+ s->gen_opc_buf[op_index] = op_to_mov(op);
tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
gen_args += 2;
}
@@ -654,7 +654,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
CASE_OP_32_64(sub):
CASE_OP_32_64(xor):
if (temps_are_copies(args[1], args[2])) {
- gen_opc_buf[op_index] = op_to_movi(op);
+ s->gen_opc_buf[op_index] = op_to_movi(op);
tcg_opt_gen_movi(gen_args, args[0], 0);
gen_args += 2;
args += 3;
@@ -672,7 +672,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
CASE_OP_32_64(mov):
if (temps_are_copies(args[0], args[1])) {
args += 2;
- gen_opc_buf[op_index] = INDEX_op_nop;
+ s->gen_opc_buf[op_index] = INDEX_op_nop;
break;
}
if (temps[args[1]].state != TCG_TEMP_CONST) {
@@ -684,7 +684,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
/* Source argument is constant. Rewrite the operation and
let movi case handle it. */
op = op_to_movi(op);
- gen_opc_buf[op_index] = op;
+ s->gen_opc_buf[op_index] = op;
args[1] = temps[args[1]].val;
/* fallthrough */
CASE_OP_32_64(movi):
@@ -702,7 +702,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
case INDEX_op_ext32s_i64:
case INDEX_op_ext32u_i64:
if (temps[args[1]].state == TCG_TEMP_CONST) {
- gen_opc_buf[op_index] = op_to_movi(op);
+ s->gen_opc_buf[op_index] = op_to_movi(op);
tmp = do_constant_folding(op, temps[args[1]].val, 0);
tcg_opt_gen_movi(gen_args, args[0], tmp);
gen_args += 2;
@@ -729,7 +729,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
CASE_OP_32_64(nor):
if (temps[args[1]].state == TCG_TEMP_CONST
&& temps[args[2]].state == TCG_TEMP_CONST) {
- gen_opc_buf[op_index] = op_to_movi(op);
+ s->gen_opc_buf[op_index] = op_to_movi(op);
tmp = do_constant_folding(op, temps[args[1]].val,
temps[args[2]].val);
tcg_opt_gen_movi(gen_args, args[0], tmp);
@@ -742,7 +742,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
CASE_OP_32_64(deposit):
if (temps[args[1]].state == TCG_TEMP_CONST
&& temps[args[2]].state == TCG_TEMP_CONST) {
- gen_opc_buf[op_index] = op_to_movi(op);
+ s->gen_opc_buf[op_index] = op_to_movi(op);
tmp = ((1ull << args[4]) - 1);
tmp = (temps[args[1]].val & ~(tmp << args[3]))
| ((temps[args[2]].val & tmp) << args[3]);
@@ -756,7 +756,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
CASE_OP_32_64(setcond):
tmp = do_constant_folding_cond(op, args[1], args[2], args[3]);
if (tmp != 2) {
- gen_opc_buf[op_index] = op_to_movi(op);
+ s->gen_opc_buf[op_index] = op_to_movi(op);
tcg_opt_gen_movi(gen_args, args[0], tmp);
gen_args += 2;
args += 4;
@@ -769,11 +769,11 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
if (tmp != 2) {
if (tmp) {
memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
- gen_opc_buf[op_index] = INDEX_op_br;
+ s->gen_opc_buf[op_index] = INDEX_op_br;
gen_args[0] = args[3];
gen_args += 1;
} else {
- gen_opc_buf[op_index] = INDEX_op_nop;
+ s->gen_opc_buf[op_index] = INDEX_op_nop;
}
args += 4;
break;
@@ -784,13 +784,13 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
tmp = do_constant_folding_cond(op, args[1], args[2], args[5]);
if (tmp != 2) {
if (temps_are_copies(args[0], args[4-tmp])) {
- gen_opc_buf[op_index] = INDEX_op_nop;
+ s->gen_opc_buf[op_index] = INDEX_op_nop;
} else if (temps[args[4-tmp]].state == TCG_TEMP_CONST) {
- gen_opc_buf[op_index] = op_to_movi(op);
+ s->gen_opc_buf[op_index] = op_to_movi(op);
tcg_opt_gen_movi(gen_args, args[0], temps[args[4-tmp]].val);
gen_args += 2;
} else {
- gen_opc_buf[op_index] = op_to_mov(op);
+ s->gen_opc_buf[op_index] = op_to_mov(op);
tcg_opt_gen_mov(s, gen_args, args[0], args[4-tmp]);
gen_args += 2;
}
@@ -820,12 +820,12 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
}
/* We emit the extra nop when we emit the add2/sub2. */
- assert(gen_opc_buf[op_index + 1] == INDEX_op_nop);
+ assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
rl = args[0];
rh = args[1];
- gen_opc_buf[op_index] = INDEX_op_movi_i32;
- gen_opc_buf[++op_index] = INDEX_op_movi_i32;
+ s->gen_opc_buf[op_index] = INDEX_op_movi_i32;
+ s->gen_opc_buf[++op_index] = INDEX_op_movi_i32;
tcg_opt_gen_movi(&gen_args[0], rl, (uint32_t)a);
tcg_opt_gen_movi(&gen_args[2], rh, (uint32_t)(a >> 32));
gen_args += 4;
@@ -843,12 +843,12 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
TCGArg rl, rh;
/* We emit the extra nop when we emit the mulu2. */
- assert(gen_opc_buf[op_index + 1] == INDEX_op_nop);
+ assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
rl = args[0];
rh = args[1];
- gen_opc_buf[op_index] = INDEX_op_movi_i32;
- gen_opc_buf[++op_index] = INDEX_op_movi_i32;
+ s->gen_opc_buf[op_index] = INDEX_op_movi_i32;
+ s->gen_opc_buf[++op_index] = INDEX_op_movi_i32;
tcg_opt_gen_movi(&gen_args[0], rl, (uint32_t)r);
tcg_opt_gen_movi(&gen_args[2], rh, (uint32_t)(r >> 32));
gen_args += 4;
@@ -862,11 +862,11 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
if (tmp != 2) {
if (tmp) {
memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
- gen_opc_buf[op_index] = INDEX_op_br;
+ s->gen_opc_buf[op_index] = INDEX_op_br;
gen_args[0] = args[5];
gen_args += 1;
} else {
- gen_opc_buf[op_index] = INDEX_op_nop;
+ s->gen_opc_buf[op_index] = INDEX_op_nop;
}
} else if ((args[4] == TCG_COND_LT || args[4] == TCG_COND_GE)
&& temps[args[2]].state == TCG_TEMP_CONST
@@ -876,7 +876,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
/* Simplify LT/GE comparisons vs zero to a single compare
vs the high word of the input. */
memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
- gen_opc_buf[op_index] = INDEX_op_brcond_i32;
+ s->gen_opc_buf[op_index] = INDEX_op_brcond_i32;
gen_args[0] = args[1];
gen_args[1] = args[3];
gen_args[2] = args[4];
@@ -891,7 +891,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
case INDEX_op_setcond2_i32:
tmp = do_constant_folding_cond2(&args[1], &args[3], args[5]);
if (tmp != 2) {
- gen_opc_buf[op_index] = INDEX_op_movi_i32;
+ s->gen_opc_buf[op_index] = INDEX_op_movi_i32;
tcg_opt_gen_movi(gen_args, args[0], tmp);
gen_args += 2;
} else if ((args[5] == TCG_COND_LT || args[5] == TCG_COND_GE)
@@ -901,7 +901,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
&& temps[args[4]].val == 0) {
/* Simplify LT/GE comparisons vs zero to a single compare
vs the high word of the input. */
- gen_opc_buf[op_index] = INDEX_op_setcond_i32;
+ s->gen_opc_buf[op_index] = INDEX_op_setcond_i32;
gen_args[0] = args[0];
gen_args[1] = args[2];
gen_args[2] = args[4];
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 8d1da2b670..0b3cb0be3a 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -27,338 +27,338 @@ int gen_new_label(void);
static inline void tcg_gen_op0(TCGOpcode opc)
{
- *gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opc_ptr++ = opc;
}
static inline void tcg_gen_op1_i32(TCGOpcode opc, TCGv_i32 arg1)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg1);
}
static inline void tcg_gen_op1_i64(TCGOpcode opc, TCGv_i64 arg1)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg1);
}
static inline void tcg_gen_op1i(TCGOpcode opc, TCGArg arg1)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = arg1;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = arg1;
}
static inline void tcg_gen_op2_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg2);
}
static inline void tcg_gen_op2_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg2);
}
static inline void tcg_gen_op2i_i32(TCGOpcode opc, TCGv_i32 arg1, TCGArg arg2)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
- *gen_opparam_ptr++ = arg2;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = arg2;
}
static inline void tcg_gen_op2i_i64(TCGOpcode opc, TCGv_i64 arg1, TCGArg arg2)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
- *gen_opparam_ptr++ = arg2;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = arg2;
}
static inline void tcg_gen_op2ii(TCGOpcode opc, TCGArg arg1, TCGArg arg2)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = arg1;
- *gen_opparam_ptr++ = arg2;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = arg1;
+ *tcg_ctx.gen_opparam_ptr++ = arg2;
}
static inline void tcg_gen_op3_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
TCGv_i32 arg3)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg3);
}
static inline void tcg_gen_op3_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
TCGv_i64 arg3)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg3);
}
static inline void tcg_gen_op3i_i32(TCGOpcode opc, TCGv_i32 arg1,
TCGv_i32 arg2, TCGArg arg3)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
- *gen_opparam_ptr++ = arg3;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = arg3;
}
static inline void tcg_gen_op3i_i64(TCGOpcode opc, TCGv_i64 arg1,
TCGv_i64 arg2, TCGArg arg3)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
- *gen_opparam_ptr++ = arg3;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = arg3;
}
static inline void tcg_gen_ldst_op_i32(TCGOpcode opc, TCGv_i32 val,
TCGv_ptr base, TCGArg offset)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(val);
- *gen_opparam_ptr++ = GET_TCGV_PTR(base);
- *gen_opparam_ptr++ = offset;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(val);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_PTR(base);
+ *tcg_ctx.gen_opparam_ptr++ = offset;
}
static inline void tcg_gen_ldst_op_i64(TCGOpcode opc, TCGv_i64 val,
TCGv_ptr base, TCGArg offset)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(val);
- *gen_opparam_ptr++ = GET_TCGV_PTR(base);
- *gen_opparam_ptr++ = offset;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(val);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_PTR(base);
+ *tcg_ctx.gen_opparam_ptr++ = offset;
}
static inline void tcg_gen_qemu_ldst_op_i64_i32(TCGOpcode opc, TCGv_i64 val,
TCGv_i32 addr, TCGArg mem_index)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(val);
- *gen_opparam_ptr++ = GET_TCGV_I32(addr);
- *gen_opparam_ptr++ = mem_index;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(val);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(addr);
+ *tcg_ctx.gen_opparam_ptr++ = mem_index;
}
static inline void tcg_gen_qemu_ldst_op_i64_i64(TCGOpcode opc, TCGv_i64 val,
TCGv_i64 addr, TCGArg mem_index)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(val);
- *gen_opparam_ptr++ = GET_TCGV_I64(addr);
- *gen_opparam_ptr++ = mem_index;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(val);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(addr);
+ *tcg_ctx.gen_opparam_ptr++ = mem_index;
}
static inline void tcg_gen_op4_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
TCGv_i32 arg3, TCGv_i32 arg4)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg4);
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg4);
}
static inline void tcg_gen_op4_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
TCGv_i64 arg3, TCGv_i64 arg4)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg4);
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg4);
}
static inline void tcg_gen_op4i_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
TCGv_i32 arg3, TCGArg arg4)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
- *gen_opparam_ptr++ = arg4;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = arg4;
}
static inline void tcg_gen_op4i_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
TCGv_i64 arg3, TCGArg arg4)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
- *gen_opparam_ptr++ = arg4;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = arg4;
}
static inline void tcg_gen_op4ii_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
TCGArg arg3, TCGArg arg4)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
- *gen_opparam_ptr++ = arg3;
- *gen_opparam_ptr++ = arg4;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = arg3;
+ *tcg_ctx.gen_opparam_ptr++ = arg4;
}
static inline void tcg_gen_op4ii_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
TCGArg arg3, TCGArg arg4)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
- *gen_opparam_ptr++ = arg3;
- *gen_opparam_ptr++ = arg4;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = arg3;
+ *tcg_ctx.gen_opparam_ptr++ = arg4;
}
static inline void tcg_gen_op5_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
TCGv_i32 arg3, TCGv_i32 arg4, TCGv_i32 arg5)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg4);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg5);
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg4);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg5);
}
static inline void tcg_gen_op5_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
TCGv_i64 arg3, TCGv_i64 arg4, TCGv_i64 arg5)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg4);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg5);
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg4);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg5);
}
static inline void tcg_gen_op5i_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
TCGv_i32 arg3, TCGv_i32 arg4, TCGArg arg5)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg4);
- *gen_opparam_ptr++ = arg5;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg4);
+ *tcg_ctx.gen_opparam_ptr++ = arg5;
}
static inline void tcg_gen_op5i_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
TCGv_i64 arg3, TCGv_i64 arg4, TCGArg arg5)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg4);
- *gen_opparam_ptr++ = arg5;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg4);
+ *tcg_ctx.gen_opparam_ptr++ = arg5;
}
static inline void tcg_gen_op5ii_i32(TCGOpcode opc, TCGv_i32 arg1,
TCGv_i32 arg2, TCGv_i32 arg3,
TCGArg arg4, TCGArg arg5)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
- *gen_opparam_ptr++ = arg4;
- *gen_opparam_ptr++ = arg5;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = arg4;
+ *tcg_ctx.gen_opparam_ptr++ = arg5;
}
static inline void tcg_gen_op5ii_i64(TCGOpcode opc, TCGv_i64 arg1,
TCGv_i64 arg2, TCGv_i64 arg3,
TCGArg arg4, TCGArg arg5)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
- *gen_opparam_ptr++ = arg4;
- *gen_opparam_ptr++ = arg5;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = arg4;
+ *tcg_ctx.gen_opparam_ptr++ = arg5;
}
static inline void tcg_gen_op6_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
TCGv_i32 arg3, TCGv_i32 arg4, TCGv_i32 arg5,
TCGv_i32 arg6)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg4);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg5);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg6);
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg4);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg5);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg6);
}
static inline void tcg_gen_op6_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
TCGv_i64 arg3, TCGv_i64 arg4, TCGv_i64 arg5,
TCGv_i64 arg6)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg4);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg5);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg6);
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg4);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg5);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg6);
}
static inline void tcg_gen_op6i_i32(TCGOpcode opc, TCGv_i32 arg1, TCGv_i32 arg2,
TCGv_i32 arg3, TCGv_i32 arg4,
TCGv_i32 arg5, TCGArg arg6)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg4);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg5);
- *gen_opparam_ptr++ = arg6;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg4);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg5);
+ *tcg_ctx.gen_opparam_ptr++ = arg6;
}
static inline void tcg_gen_op6i_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
TCGv_i64 arg3, TCGv_i64 arg4,
TCGv_i64 arg5, TCGArg arg6)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg4);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg5);
- *gen_opparam_ptr++ = arg6;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg4);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg5);
+ *tcg_ctx.gen_opparam_ptr++ = arg6;
}
static inline void tcg_gen_op6ii_i32(TCGOpcode opc, TCGv_i32 arg1,
TCGv_i32 arg2, TCGv_i32 arg3,
TCGv_i32 arg4, TCGArg arg5, TCGArg arg6)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I32(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg3);
- *gen_opparam_ptr++ = GET_TCGV_I32(arg4);
- *gen_opparam_ptr++ = arg5;
- *gen_opparam_ptr++ = arg6;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I32(arg4);
+ *tcg_ctx.gen_opparam_ptr++ = arg5;
+ *tcg_ctx.gen_opparam_ptr++ = arg6;
}
static inline void tcg_gen_op6ii_i64(TCGOpcode opc, TCGv_i64 arg1,
TCGv_i64 arg2, TCGv_i64 arg3,
TCGv_i64 arg4, TCGArg arg5, TCGArg arg6)
{
- *gen_opc_ptr++ = opc;
- *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
- *gen_opparam_ptr++ = GET_TCGV_I64(arg4);
- *gen_opparam_ptr++ = arg5;
- *gen_opparam_ptr++ = arg6;
+ *tcg_ctx.gen_opc_ptr++ = opc;
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg1);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg2);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg3);
+ *tcg_ctx.gen_opparam_ptr++ = GET_TCGV_I64(arg4);
+ *tcg_ctx.gen_opparam_ptr++ = arg5;
+ *tcg_ctx.gen_opparam_ptr++ = arg6;
}
static inline void gen_set_label(int n)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 35fba50c7f..4f756962c5 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -96,10 +96,6 @@ const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs);
static TCGRegSet tcg_target_available_regs[2];
static TCGRegSet tcg_target_call_clobber_regs;
-/* XXX: move that inside the context */
-uint16_t *gen_opc_ptr;
-TCGArg *gen_opparam_ptr;
-
static inline void tcg_out8(TCGContext *s, uint8_t v)
{
*s->code_ptr++ = v;
@@ -297,8 +293,8 @@ void tcg_func_start(TCGContext *s)
s->goto_tb_issue_mask = 0;
#endif
- gen_opc_ptr = gen_opc_buf;
- gen_opparam_ptr = gen_opparam_buf;
+ s->gen_opc_ptr = s->gen_opc_buf;
+ s->gen_opparam_ptr = s->gen_opparam_buf;
#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU)
/* Initialize qemu_ld/st labels to assist code generation at the end of TB
@@ -641,23 +637,23 @@ void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
}
#endif /* TCG_TARGET_EXTEND_ARGS */
- *gen_opc_ptr++ = INDEX_op_call;
- nparam = gen_opparam_ptr++;
+ *s->gen_opc_ptr++ = INDEX_op_call;
+ nparam = s->gen_opparam_ptr++;
if (ret != TCG_CALL_DUMMY_ARG) {
#if TCG_TARGET_REG_BITS < 64
if (sizemask & 1) {
#ifdef TCG_TARGET_WORDS_BIGENDIAN
- *gen_opparam_ptr++ = ret + 1;
- *gen_opparam_ptr++ = ret;
+ *s->gen_opparam_ptr++ = ret + 1;
+ *s->gen_opparam_ptr++ = ret;
#else
- *gen_opparam_ptr++ = ret;
- *gen_opparam_ptr++ = ret + 1;
+ *s->gen_opparam_ptr++ = ret;
+ *s->gen_opparam_ptr++ = ret + 1;
#endif
nb_rets = 2;
} else
#endif
{
- *gen_opparam_ptr++ = ret;
+ *s->gen_opparam_ptr++ = ret;
nb_rets = 1;
}
} else {
@@ -671,7 +667,7 @@ void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
#ifdef TCG_TARGET_CALL_ALIGN_ARGS
/* some targets want aligned 64 bit args */
if (real_args & 1) {
- *gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
+ *s->gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
real_args++;
}
#endif
@@ -686,28 +682,28 @@ void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
have to get more complicated to differentiate between
stack arguments and register arguments. */
#if defined(TCG_TARGET_WORDS_BIGENDIAN) != defined(TCG_TARGET_STACK_GROWSUP)
- *gen_opparam_ptr++ = args[i] + 1;
- *gen_opparam_ptr++ = args[i];
+ *s->gen_opparam_ptr++ = args[i] + 1;
+ *s->gen_opparam_ptr++ = args[i];
#else
- *gen_opparam_ptr++ = args[i];
- *gen_opparam_ptr++ = args[i] + 1;
+ *s->gen_opparam_ptr++ = args[i];
+ *s->gen_opparam_ptr++ = args[i] + 1;
#endif
real_args += 2;
continue;
}
#endif /* TCG_TARGET_REG_BITS < 64 */
- *gen_opparam_ptr++ = args[i];
+ *s->gen_opparam_ptr++ = args[i];
real_args++;
}
- *gen_opparam_ptr++ = GET_TCGV_PTR(func);
+ *s->gen_opparam_ptr++ = GET_TCGV_PTR(func);
- *gen_opparam_ptr++ = flags;
+ *s->gen_opparam_ptr++ = flags;
*nparam = (nb_rets << 16) | (real_args + 1);
/* total parameters, needed to go backward in the instruction stream */
- *gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
+ *s->gen_opparam_ptr++ = 1 + nb_rets + real_args + 3;
#if defined(TCG_TARGET_EXTEND_ARGS) && TCG_TARGET_REG_BITS == 64
for (i = 0; i < nargs; ++i) {
@@ -896,9 +892,9 @@ void tcg_dump_ops(TCGContext *s)
char buf[128];
first_insn = 1;
- opc_ptr = gen_opc_buf;
- args = gen_opparam_buf;
- while (opc_ptr < gen_opc_ptr) {
+ opc_ptr = s->gen_opc_buf;
+ args = s->gen_opparam_buf;
+ while (opc_ptr < s->gen_opc_ptr) {
c = *opc_ptr++;
def = &tcg_op_defs[c];
if (c == INDEX_op_debug_insn_start) {
@@ -1229,9 +1225,9 @@ static void tcg_liveness_analysis(TCGContext *s)
uint16_t dead_args;
uint8_t sync_args;
- gen_opc_ptr++; /* skip end */
+ s->gen_opc_ptr++; /* skip end */
- nb_ops = gen_opc_ptr - gen_opc_buf;
+ nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
s->op_sync_args = tcg_malloc(nb_ops * sizeof(uint8_t));
@@ -1240,10 +1236,10 @@ static void tcg_liveness_analysis(TCGContext *s)
mem_temps = tcg_malloc(s->nb_temps);
tcg_la_func_end(s, dead_temps, mem_temps);
- args = gen_opparam_ptr;
+ args = s->gen_opparam_ptr;
op_index = nb_ops - 1;
while (op_index >= 0) {
- op = gen_opc_buf[op_index];
+ op = s->gen_opc_buf[op_index];
def = &tcg_op_defs[op];
switch(op) {
case INDEX_op_call:
@@ -1266,7 +1262,7 @@ static void tcg_liveness_analysis(TCGContext *s)
goto do_not_remove_call;
}
}
- tcg_set_nop(s, gen_opc_buf + op_index,
+ tcg_set_nop(s, s->gen_opc_buf + op_index,
args - 1, nb_args);
} else {
do_not_remove_call:
@@ -1347,11 +1343,11 @@ static void tcg_liveness_analysis(TCGContext *s)
} else {
op = INDEX_op_sub_i32;
}
- gen_opc_buf[op_index] = op;
+ s->gen_opc_buf[op_index] = op;
args[1] = args[2];
args[2] = args[4];
- assert(gen_opc_buf[op_index + 1] == INDEX_op_nop);
- tcg_set_nop(s, gen_opc_buf + op_index + 1, args + 3, 3);
+ assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
+ tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 3);
/* Fall through and mark the single-word operation live. */
nb_iargs = 2;
nb_oargs = 1;
@@ -1367,11 +1363,11 @@ static void tcg_liveness_analysis(TCGContext *s)
if (dead_temps[args[0]] && !mem_temps[args[0]]) {
goto do_remove;
}
- gen_opc_buf[op_index] = op = INDEX_op_mul_i32;
+ s->gen_opc_buf[op_index] = op = INDEX_op_mul_i32;
args[1] = args[2];
args[2] = args[3];
- assert(gen_opc_buf[op_index + 1] == INDEX_op_nop);
- tcg_set_nop(s, gen_opc_buf + op_index + 1, args + 3, 1);
+ assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
+ tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1);
/* Fall through and mark the single-word operation live. */
nb_oargs = 1;
}
@@ -1394,7 +1390,7 @@ static void tcg_liveness_analysis(TCGContext *s)
}
}
do_remove:
- tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
+ tcg_set_nop(s, s->gen_opc_buf + op_index, args, def->nb_args);
#ifdef CONFIG_PROFILER
s->del_op_count++;
#endif
@@ -1440,15 +1436,16 @@ static void tcg_liveness_analysis(TCGContext *s)
op_index--;
}
- if (args != gen_opparam_buf)
+ if (args != s->gen_opparam_buf) {
tcg_abort();
+ }
}
#else
/* dummy liveness analysis */
static void tcg_liveness_analysis(TCGContext *s)
{
int nb_ops;
- nb_ops = gen_opc_ptr - gen_opc_buf;
+ nb_ops = s->gen_opc_ptr - s->gen_opc_buf;
s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
@@ -2221,8 +2218,8 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
#endif
#ifdef USE_TCG_OPTIMIZATIONS
- gen_opparam_ptr =
- tcg_optimize(s, gen_opc_ptr, gen_opparam_buf, tcg_op_defs);
+ s->gen_opparam_ptr =
+ tcg_optimize(s, s->gen_opc_ptr, s->gen_opparam_buf, tcg_op_defs);
#endif
#ifdef CONFIG_PROFILER
@@ -2249,11 +2246,11 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
s->code_buf = gen_code_buf;
s->code_ptr = gen_code_buf;
- args = gen_opparam_buf;
+ args = s->gen_opparam_buf;
op_index = 0;
for(;;) {
- opc = gen_opc_buf[op_index];
+ opc = s->gen_opc_buf[op_index];
#ifdef CONFIG_PROFILER
tcg_table_op_count[opc]++;
#endif
@@ -2334,7 +2331,7 @@ int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
#ifdef CONFIG_PROFILER
{
int n;
- n = (gen_opc_ptr - gen_opc_buf);
+ n = (s->gen_opc_ptr - s->gen_opc_buf);
s->op_count += n;
if (n > s->op_count_max)
s->op_count_max = n;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index c2ae873715..9481e35ab4 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -450,6 +450,12 @@ struct TCGContext {
int goto_tb_issue_mask;
#endif
+ uint16_t gen_opc_buf[OPC_BUF_SIZE];
+ TCGArg gen_opparam_buf[OPPARAM_BUF_SIZE];
+
+ uint16_t *gen_opc_ptr;
+ TCGArg *gen_opparam_ptr;
+
#if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU)
/* labels info for qemu_ld/st IRs
The labels help to generate TLB miss case codes at the end of TB */
@@ -459,10 +465,6 @@ struct TCGContext {
};
extern TCGContext tcg_ctx;
-extern uint16_t *gen_opc_ptr;
-extern TCGArg *gen_opparam_ptr;
-extern uint16_t gen_opc_buf[];
-extern TCGArg gen_opparam_buf[];
/* pool based memory allocation */
diff --git a/translate-all.c b/translate-all.c
index 5bd2d3711a..d9c2e57861 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -33,9 +33,6 @@
/* code generation context */
TCGContext tcg_ctx;
-uint16_t gen_opc_buf[OPC_BUF_SIZE];
-TCGArg gen_opparam_buf[OPPARAM_BUF_SIZE];
-
target_ulong gen_opc_pc[OPC_BUF_SIZE];
uint16_t gen_opc_icount[OPC_BUF_SIZE];
uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
diff --git a/vl.c b/vl.c
index 4f03a72e58..c8e9c782d6 100644
--- a/vl.c
+++ b/vl.c
@@ -168,6 +168,7 @@ int main(int argc, char **argv)
#include "osdep.h"
#include "ui/qemu-spice.h"
+#include "qapi/string-input-visitor.h"
//#define DEBUG_NET
//#define DEBUG_SLIRP
@@ -2476,6 +2477,53 @@ static void free_and_trace(gpointer mem)
free(mem);
}
+static int object_set_property(const char *name, const char *value, void *opaque)
+{
+ Object *obj = OBJECT(opaque);
+ StringInputVisitor *siv;
+ Error *local_err = NULL;
+
+ if (strcmp(name, "qom-type") == 0 || strcmp(name, "id") == 0) {
+ return 0;
+ }
+
+ siv = string_input_visitor_new(value);
+ object_property_set(obj, string_input_get_visitor(siv), name, &local_err);
+ string_input_visitor_cleanup(siv);
+
+ if (local_err) {
+ qerror_report_err(local_err);
+ error_free(local_err);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int object_create(QemuOpts *opts, void *opaque)
+{
+ const char *type = qemu_opt_get(opts, "qom-type");
+ const char *id = qemu_opts_id(opts);
+ Object *obj;
+
+ g_assert(type != NULL);
+
+ if (id == NULL) {
+ qerror_report(QERR_MISSING_PARAMETER, "id");
+ return -1;
+ }
+
+ obj = object_new(type);
+ if (qemu_opt_foreach(opts, object_set_property, obj, 1) < 0) {
+ return -1;
+ }
+
+ object_property_add_child(container_get(object_get_root(), "/objects"),
+ id, obj, NULL);
+
+ return 0;
+}
+
int main(int argc, char **argv, char **envp)
{
int i;
@@ -3473,6 +3521,9 @@ int main(int argc, char **argv, char **envp)
exit(1);
#endif
break;
+ case QEMU_OPTION_object:
+ opts = qemu_opts_parse(qemu_find_opts("object"), optarg, 1);
+ break;
default:
os_parse_cmd_args(popt->index, optarg);
}
@@ -3508,6 +3559,11 @@ int main(int argc, char **argv, char **envp)
qemu_set_version(machine->hw_version);
}
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create, NULL, 0) != 0) {
+ exit(1);
+ }
+
/* Init CPU def lists, based on config
* - Must be called after all the qemu_read_config_file() calls
* - Must be called before list_cpus()