From ff7ab59f40e12941530cb1d9ecc9b873d900b132 Mon Sep 17 00:00:00 2001 From: ths Date: Thu, 5 Jun 2008 21:00:28 +0000 Subject: Update documentation for qemu-img convert options, by Marc Bevand. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4671 c046a42c-6fe2-441c-8c8c-71466251a162 --- qemu-img.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu-img.texi b/qemu-img.texi index 89f912df9..44c4de874 100644 --- a/qemu-img.texi +++ b/qemu-img.texi @@ -10,7 +10,7 @@ The following commands are supported: @table @option @item create [-e] [-6] [-b @var{base_image}] [-f @var{fmt}] @var{filename} [@var{size}] @item commit [-f @var{fmt}] @var{filename} -@item convert [-c] [-e] [-6] [-f @var{fmt}] @var{filename} [-O @var{output_fmt}] @var{output_filename} +@item convert [-c] [-e] [-6] [-f @var{fmt}] [-O @var{output_fmt}] @var{filename} [@var{filename2} [...]] @var{output_filename} @item info [-f @var{fmt}] @var{filename} @end table -- cgit v1.2.3 From f58c7b354595228e10f023e86b80a7bab527186a Mon Sep 17 00:00:00 2001 From: ths Date: Thu, 5 Jun 2008 21:53:49 +0000 Subject: New qemu-img convert -B option, by Marc Bevand. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4672 c046a42c-6fe2-441c-8c8c-71466251a162 --- block.c | 27 +++++++++++++++++++++++++++ block.h | 2 ++ qemu-img.c | 47 +++++++++++++++++++++++++++++++++++++++++------ qemu-img.texi | 8 ++++++-- 4 files changed, 76 insertions(+), 8 deletions(-) diff --git a/block.c b/block.c index bd647a6f4..2aaefe832 100644 --- a/block.c +++ b/block.c @@ -884,6 +884,33 @@ void bdrv_flush(BlockDriverState *bs) bdrv_flush(bs->backing_hd); } +/* + * Returns true iff the specified sector is present in the disk image. Drivers + * not implementing the functionality are assumed to not support backing files, + * hence all their sectors are reported as allocated. + * + * 'pnum' is set to the number of sectors (including and immediately following + * the specified sector) that are known to be in the same + * allocated/unallocated state. + * + * 'nb_sectors' is the max value 'pnum' should be set to. + */ +int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, + int *pnum) +{ + int64_t n; + if (!bs->drv->bdrv_is_allocated) { + if (sector_num >= bs->total_sectors) { + *pnum = 0; + return 0; + } + n = bs->total_sectors - sector_num; + *pnum = (n < nb_sectors) ? (n) : (nb_sectors); + return 1; + } + return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum); +} + #ifndef QEMU_IMG void bdrv_info(void) { diff --git a/block.h b/block.h index b73050556..e18f4532a 100644 --- a/block.h +++ b/block.h @@ -99,6 +99,8 @@ int qemu_key_check(BlockDriverState *bs, const char *name); /* Ensure contents are flushed to disk. */ void bdrv_flush(BlockDriverState *bs); +int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, + int *pnum); #define BDRV_TYPE_HD 0 #define BDRV_TYPE_CDROM 1 diff --git a/qemu-img.c b/qemu-img.c index 309a746da..f9d8b7d99 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -55,13 +55,17 @@ static void help(void) "Command syntax:\n" " create [-e] [-6] [-b base_image] [-f fmt] filename [size]\n" " commit [-f fmt] filename\n" - " convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] filename [filename2 [...]] output_filename\n" + " convert [-c] [-e] [-6] [-f fmt] [-O output_fmt] [-B output_base_image] filename [filename2 [...]] output_filename\n" " info [-f fmt] filename\n" "\n" "Command parameters:\n" " 'filename' is a disk image filename\n" " 'base_image' is the read-only disk image which is used as base for a copy on\n" " write image; the copy on write image only stores the modified data\n" + " 'output_base_image' forces the output image to be created as a copy on write\n" + " image of the specified base image; 'output_base_image' should have the same\n" + " content as the input's base image, however the path, image format, etc may\n" + " differ\n" " 'fmt' is the disk image format. It is guessed automatically in most cases\n" " 'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n" " and 'G' (gigabyte) are supported\n" @@ -350,6 +354,13 @@ static int is_not_zero(const uint8_t *sector, int len) return 0; } +/* + * Returns true iff the first sector pointed to by 'buf' contains at least + * a non-NUL byte. + * + * 'pnum' is set to the number of sectors (including and immediately following + * the first one) that are known to be in the same allocated/unallocated state. + */ static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum) { int v, i; @@ -373,7 +384,7 @@ static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum) static int img_convert(int argc, char **argv) { int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors; - const char *fmt, *out_fmt, *out_filename; + const char *fmt, *out_fmt, *out_baseimg, *out_filename; BlockDriver *drv; BlockDriverState **bs, *out_bs; int64_t total_sectors, nb_sectors, sector_num, bs_offset; @@ -384,9 +395,10 @@ static int img_convert(int argc, char **argv) fmt = NULL; out_fmt = "raw"; + out_baseimg = NULL; flags = 0; for(;;) { - c = getopt(argc, argv, "f:O:hce6"); + c = getopt(argc, argv, "f:O:B:hce6"); if (c == -1) break; switch(c) { @@ -399,6 +411,9 @@ static int img_convert(int argc, char **argv) case 'O': out_fmt = optarg; break; + case 'B': + out_baseimg = optarg; + break; case 'c': flags |= BLOCK_FLAG_COMPRESS; break; @@ -415,6 +430,9 @@ static int img_convert(int argc, char **argv) if (bs_n < 1) help(); out_filename = argv[argc - 1]; + + if (bs_n > 1 && out_baseimg) + error("-B makes no sense when concatenating multiple input images"); bs = calloc(bs_n, sizeof(BlockDriverState *)); if (!bs) @@ -441,7 +459,7 @@ static int img_convert(int argc, char **argv) if (flags & BLOCK_FLAG_ENCRYPT && flags & BLOCK_FLAG_COMPRESS) error("Compression and encryption not supported at the same time"); - ret = bdrv_create(drv, out_filename, total_sectors, NULL, flags); + ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags); if (ret < 0) { if (ret == -ENOTSUP) { error("Formatting not supported for file format '%s'", fmt); @@ -520,7 +538,7 @@ static int img_convert(int argc, char **argv) /* signal EOF to align */ bdrv_write_compressed(out_bs, 0, NULL, 0); } else { - sector_num = 0; + sector_num = 0; // total number of sectors converted so far for(;;) { nb_sectors = total_sectors - sector_num; if (nb_sectors <= 0) @@ -543,6 +561,20 @@ static int img_convert(int argc, char **argv) if (n > bs_offset + bs_sectors - sector_num) n = bs_offset + bs_sectors - sector_num; + /* If the output image is being created as a copy on write image, + assume that sectors which are unallocated in the input image + are present in both the output's and input's base images (no + need to copy them). */ + if (out_baseimg) { + if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, n, &n1)) { + sector_num += n1; + continue; + } + /* The next 'n1' sectors are allocated in the input image. Copy + only those as they may be followed by unallocated sectors. */ + n = n1; + } + if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0) error("error while reading"); /* NOTE: at the same time we convert, we do not write zero @@ -550,7 +582,10 @@ static int img_convert(int argc, char **argv) should add a specific call to have the info to go faster */ buf1 = buf; while (n > 0) { - if (is_allocated_sectors(buf1, n, &n1)) { + /* If the output image is being created as a copy on write image, + copy all sectors even the ones containing only NUL bytes, + because they may differ from the sectors in the base image. */ + if (out_baseimg || is_allocated_sectors(buf1, n, &n1)) { if (bdrv_write(out_bs, sector_num, buf1, n1) < 0) error("error while writing"); } diff --git a/qemu-img.texi b/qemu-img.texi index 44c4de874..1c0504bcf 100644 --- a/qemu-img.texi +++ b/qemu-img.texi @@ -10,7 +10,7 @@ The following commands are supported: @table @option @item create [-e] [-6] [-b @var{base_image}] [-f @var{fmt}] @var{filename} [@var{size}] @item commit [-f @var{fmt}] @var{filename} -@item convert [-c] [-e] [-6] [-f @var{fmt}] [-O @var{output_fmt}] @var{filename} [@var{filename2} [...]] @var{output_filename} +@item convert [-c] [-e] [-6] [-f @var{fmt}] [-O @var{output_fmt}] [-B @var{output_base_image}] @var{filename} [@var{filename2} [...]] @var{output_filename} @item info [-f @var{fmt}] @var{filename} @end table @@ -21,7 +21,11 @@ Command parameters: @item base_image is the read-only disk image which is used as base for a copy on write image; the copy on write image only stores the modified data - +@item output_base_image +forces the output image to be created as a copy on write +image of the specified base image; @code{output_base_image} should have the same +content as the input's base image, however the path, image format, etc may +differ @item fmt is the disk image format. It is guessed automatically in most cases. The following formats are supported: -- cgit v1.2.3 From 5452adbee0fb19f2d0662e055e72c4128bcfb976 Mon Sep 17 00:00:00 2001 From: ths Date: Thu, 5 Jun 2008 22:00:45 +0000 Subject: Remove dead-code (else-block) from block-qcow.c, by Marc Bevand. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4673 c046a42c-6fe2-441c-8c8c-71466251a162 --- block-qcow.c | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/block-qcow.c b/block-qcow.c index 0ac2b42b4..1fecf3078 100644 --- a/block-qcow.c +++ b/block-qcow.c @@ -339,33 +339,28 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, return -1; } else { cluster_offset = bdrv_getlength(s->hd); - if (allocate == 1) { - /* round to cluster size */ - cluster_offset = (cluster_offset + s->cluster_size - 1) & - ~(s->cluster_size - 1); - bdrv_truncate(s->hd, cluster_offset + s->cluster_size); - /* if encrypted, we must initialize the cluster - content which won't be written */ - if (s->crypt_method && - (n_end - n_start) < s->cluster_sectors) { - uint64_t start_sect; - start_sect = (offset & ~(s->cluster_size - 1)) >> 9; - memset(s->cluster_data + 512, 0x00, 512); - for(i = 0; i < s->cluster_sectors; i++) { - if (i < n_start || i >= n_end) { - encrypt_sectors(s, start_sect + i, - s->cluster_data, - s->cluster_data + 512, 1, 1, - &s->aes_encrypt_key); - if (bdrv_pwrite(s->hd, cluster_offset + i * 512, - s->cluster_data, 512) != 512) - return -1; - } + /* round to cluster size */ + cluster_offset = (cluster_offset + s->cluster_size - 1) & + ~(s->cluster_size - 1); + bdrv_truncate(s->hd, cluster_offset + s->cluster_size); + /* if encrypted, we must initialize the cluster + content which won't be written */ + if (s->crypt_method && + (n_end - n_start) < s->cluster_sectors) { + uint64_t start_sect; + start_sect = (offset & ~(s->cluster_size - 1)) >> 9; + memset(s->cluster_data + 512, 0x00, 512); + for(i = 0; i < s->cluster_sectors; i++) { + if (i < n_start || i >= n_end) { + encrypt_sectors(s, start_sect + i, + s->cluster_data, + s->cluster_data + 512, 1, 1, + &s->aes_encrypt_key); + if (bdrv_pwrite(s->hd, cluster_offset + i * 512, + s->cluster_data, 512) != 512) + return -1; } } - } else { - cluster_offset |= QCOW_OFLAG_COMPRESSED | - (uint64_t)compressed_size << (63 - s->cluster_bits); } } /* update L2 table */ -- cgit v1.2.3 From cebdff772d6af6a65bf799cbbf68f86d97025495 Mon Sep 17 00:00:00 2001 From: ths Date: Thu, 5 Jun 2008 22:55:54 +0000 Subject: Fix always_inline definition for Darwin, by Andreas Faerber. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4674 c046a42c-6fe2-441c-8c8c-71466251a162 --- host-utils.h | 2 ++ osdep.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/host-utils.h b/host-utils.h index 0f7744511..b1e799ed3 100644 --- a/host-utils.h +++ b/host-utils.h @@ -23,6 +23,8 @@ * THE SOFTWARE. */ +#include "osdep.h" + #if defined(__x86_64__) #define __HAVE_FAST_MULU64__ static always_inline void mulu64 (uint64_t *plow, uint64_t *phigh, diff --git a/osdep.h b/osdep.h index 62de45704..a32242e07 100644 --- a/osdep.h +++ b/osdep.h @@ -35,9 +35,11 @@ #define always_inline inline #else #define always_inline __attribute__ (( always_inline )) __inline__ +#define inline always_inline #endif -#endif +#else #define inline always_inline +#endif #ifdef __i386__ #define REGPARM __attribute((regparm(3))) -- cgit v1.2.3 From 31a53c63b5283327db437ff053b3bfd54a6420a2 Mon Sep 17 00:00:00 2001 From: ths Date: Thu, 5 Jun 2008 23:06:46 +0000 Subject: Compile fix for Apple, by C.W. Betts. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4675 c046a42c-6fe2-441c-8c8c-71466251a162 --- dyngen-exec.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dyngen-exec.h b/dyngen-exec.h index f51d36328..92c1ae8e6 100644 --- a/dyngen-exec.h +++ b/dyngen-exec.h @@ -36,9 +36,9 @@ typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; // Linux/Sparc64 defines uint64_t -#if !(defined (__sparc_v9__) && defined(__linux__)) +#if !(defined (__sparc_v9__) && defined(__linux__)) && !(defined(__APPLE__) && defined(__x86_64__)) /* XXX may be done for all 64 bits targets ? */ -#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__) || defined(__alpha__) +#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__) || defined(__alpha__) typedef unsigned long uint64_t; #else typedef unsigned long long uint64_t; @@ -54,7 +54,7 @@ typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; // Linux/Sparc64 defines int64_t -#if !(defined (__sparc_v9__) && defined(__linux__)) +#if !(defined (__sparc_v9__) && defined(__linux__)) && !(defined(__APPLE__) && defined(__x86_64__)) #if defined (__x86_64__) || defined(__ia64) || defined(__s390x__) || defined(__alpha__) typedef signed long int64_t; #else -- cgit v1.2.3 From dcf3a079e5e09c85712cfa4c090f226049075541 Mon Sep 17 00:00:00 2001 From: ths Date: Fri, 6 Jun 2008 01:03:06 +0000 Subject: Fix compiler warning. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4676 c046a42c-6fe2-441c-8c8c-71466251a162 --- nbd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nbd.c b/nbd.c index fcf033929..c7d63d348 100644 --- a/nbd.c +++ b/nbd.c @@ -388,7 +388,7 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size, uint64_t dev_offset, o } if (len > sizeof(data)) { - LOG("len (%u) is larger than max len (%lu)", + LOG("len (%u) is larger than max len (%u)", len, sizeof(data)); errno = EINVAL; return -1; -- cgit v1.2.3 From 96768ff79c18b8eb14062bcff76677a440b7abdd Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Fri, 6 Jun 2008 10:55:02 +0000 Subject: Compile with debug. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4677 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/etraxfs_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/etraxfs_timer.c b/hw/etraxfs_timer.c index e0fde9c2c..7353d45de 100644 --- a/hw/etraxfs_timer.c +++ b/hw/etraxfs_timer.c @@ -235,7 +235,7 @@ static inline void timer_watchdog_update(struct fs_timer_t *t, uint32_t value) return; D(printf("en=%d new_key=%x oldkey=%x cmd=%d cnt=%d\n", - wd_en, new_key, wd_key, wd_cmd, wd_cnt)); + wd_en, new_key, wd_key, new_cmd, wd_cnt)); ptimer_set_freq(t->ptimer_wd, 760); if (wd_cnt == 0) -- cgit v1.2.3 From fa1bdde4a3db4b0bc21b7ae1a3c8af5678c31dcc Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Fri, 6 Jun 2008 10:58:48 +0000 Subject: ETRAX machine updates. * Move DMA_run into the dma controller to allow for multiple ETRAX/CRIS machines. * Support both ELF and kimage kernel images. * Correct emulation of the DMA RW_DATA register. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4678 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/etraxfs.c | 28 ++++++++++++---------------- hw/etraxfs_dma.c | 12 +++++++++++- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/hw/etraxfs.c b/hw/etraxfs.c index 942892c01..72482e414 100644 --- a/hw/etraxfs.c +++ b/hw/etraxfs.c @@ -44,7 +44,6 @@ void etraxfs_ser_init(CPUState *env, qemu_irq *irq, CharDriverState *chr, #define FLASH_SIZE 0x2000000 #define INTMEM_SIZE (128 * 1024) -static void *etraxfs_dmac; static uint32_t bootstrap_pc; static void main_cpu_reset(void *opaque) @@ -64,6 +63,7 @@ void bareetraxfs_init (ram_addr_t ram_size, int vga_ram_size, { CPUState *env; qemu_irq *pic; + void *etraxfs_dmac; struct etraxfs_dma_client *eth[2] = {NULL, NULL}; int kernel_size; int i; @@ -138,19 +138,20 @@ void bareetraxfs_init (ram_addr_t ram_size, int vga_ram_size, } if (kernel_filename) { -#if 1 + uint64_t entry; /* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis devboard SDK. */ kernel_size = load_elf(kernel_filename, 0, - &bootstrap_pc, NULL, NULL); -#else - /* Takes a kimage from the axis devboard SDK. */ - kernel_size = load_image(kernel_filename, phys_ram_base + 0x4000); - bootstrap_pc = 0x40004000; - /* magic for boot. */ - env->regs[8] = 0x56902387; - env->regs[9] = 0x40004000 + kernel_size; -#endif + &entry, NULL, NULL); + bootstrap_pc = entry; + if (kernel_size < 0) { + /* Takes a kimage from the axis devboard SDK. */ + kernel_size = load_image(kernel_filename, phys_ram_base + 0x4000); + bootstrap_pc = 0x40004000; + /* magic for boot. */ + env->regs[8] = 0x56902387; + env->regs[9] = 0x40004000 + kernel_size; + } } env->pc = bootstrap_pc; @@ -158,11 +159,6 @@ void bareetraxfs_init (ram_addr_t ram_size, int vga_ram_size, printf ("ram size =%ld\n", ram_size); } -void DMA_run(void) -{ - etraxfs_dmac_run(etraxfs_dmac); -} - QEMUMachine bareetraxfs_machine = { "bareetraxfs", "Bare ETRAX FS board", diff --git a/hw/etraxfs_dma.c b/hw/etraxfs_dma.c index a090a6d6b..0a5562b9c 100644 --- a/hw/etraxfs_dma.c +++ b/hw/etraxfs_dma.c @@ -273,6 +273,7 @@ static void channel_load_d(struct fs_dma_ctrl *ctrl, int c) sizeof ctrl->channels[c].current_d); D(dump_d(c, &ctrl->channels[c].current_d)); + ctrl->channels[c].regs[RW_DATA] = addr; ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = (uint32_t)ctrl->channels[c].current_d.buf; } @@ -561,7 +562,7 @@ dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) switch (addr) { case RW_DATA: - printf("RW_DATA=%x\n", value); + ctrl->channels[c].regs[addr] = value; break; case RW_CFG: @@ -658,6 +659,13 @@ void etraxfs_dmac_connect_client(void *opaque, int c, } +static void *etraxfs_dmac; +void DMA_run(void) +{ + if (etraxfs_dmac) + etraxfs_dmac_run(etraxfs_dmac); +} + void *etraxfs_dmac_init(CPUState *env, target_phys_addr_t base, int nr_channels) { @@ -686,6 +694,8 @@ void *etraxfs_dmac_init(CPUState *env, ctrl->channels[i].regmap); } + /* Hax, we only support one DMA controller at a time. */ + etraxfs_dmac = ctrl; return ctrl; err: qemu_free(ctrl->channels); -- cgit v1.2.3 From bd3a8454391bb04d515a48b9547e4fe929a852ba Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Fri, 6 Jun 2008 11:00:04 +0000 Subject: Avoid warnings. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4679 c046a42c-6fe2-441c-8c8c-71466251a162 --- tests/cris/check_swap.c | 1 + tests/cris/crisutils.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/cris/check_swap.c b/tests/cris/check_swap.c index c1eac88e5..743cfc54d 100644 --- a/tests/cris/check_swap.c +++ b/tests/cris/check_swap.c @@ -72,4 +72,5 @@ int main(void) { check_swap(); pass(); + return 0; } diff --git a/tests/cris/crisutils.h b/tests/cris/crisutils.h index 63c713897..7d1ea86f7 100644 --- a/tests/cris/crisutils.h +++ b/tests/cris/crisutils.h @@ -4,7 +4,7 @@ static char *tst_cc_loc = NULL; do { tst_cc_loc = "test_cc failed at " CURRENT_LOCATION; } while(0) /* We need a real symbol to signal error. */ -static void _err(void) { +void _err(void) { if (!tst_cc_loc) tst_cc_loc = "tst_cc_failed\n"; _fail(tst_cc_loc); -- cgit v1.2.3 From 54f25d0af585cb8d8b1288191c06a9abd193a854 Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Fri, 6 Jun 2008 11:00:58 +0000 Subject: Increase the odds for the movei test to pass in system simulation. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4680 c046a42c-6fe2-441c-8c8c-71466251a162 --- tests/cris/check_movei.s | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/cris/check_movei.s b/tests/cris/check_movei.s index 2defda5f3..bbfa63337 100644 --- a/tests/cris/check_movei.s +++ b/tests/cris/check_movei.s @@ -7,8 +7,11 @@ .include "testutils.inc" start + move.d 0, $r3 ; A write that works. Check that flags are set correspondingly. move.d d,r4 + ;; store to bring it into the tlb with the right prot bits + move.d r3,[r4] moveq -2,r5 setf c clearf p -- cgit v1.2.3 From 9012c2bf32aaf34a5ee12c3d9c8718af1530eeec Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Fri, 6 Jun 2008 11:05:18 +0000 Subject: Add a testcase for broken x arithmetic sequences. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4681 c046a42c-6fe2-441c-8c8c-71466251a162 --- tests/cris/check_xarith.s | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/cris/check_xarith.s b/tests/cris/check_xarith.s index d0356abed..80038b2ab 100644 --- a/tests/cris/check_xarith.s +++ b/tests/cris/check_xarith.s @@ -42,5 +42,31 @@ nop fail 1: + + ;; test for broken X sequence, run it several times. + moveq 8, $r0 +1: + moveq 0, $r3 + move.d $r0, $r1 + andq 1, $r1 + lslq 4, $r1 + moveq 1, $r2 + or.d $r1, $r2 + ba 2f + move $r2, $ccs +2: + addq 0, $r3 + move.d $r0, $r4 + move.d $r1, $r5 + move.d $r2, $r6 + move.d $r3, $r7 + lsrq 4, $r1 + move.d $r1, $r8 + xor $r1, $r3 + checkr3 0 + subq 1, $r0 + bne 1b + nop + pass quit -- cgit v1.2.3 From 313281198dc87984fde5cc3aceccbb002beed047 Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Fri, 6 Jun 2008 11:07:50 +0000 Subject: Make the tests run when built with experimental gcc-cris 4.4. Prettify the logs. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4682 c046a42c-6fe2-441c-8c8c-71466251a162 --- tests/cris/Makefile | 4 ++-- tests/cris/sys.c | 11 +++++++---- tests/cris/testutils.inc | 8 ++++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/tests/cris/Makefile b/tests/cris/Makefile index 69068996f..cfe494c3a 100644 --- a/tests/cris/Makefile +++ b/tests/cris/Makefile @@ -140,9 +140,9 @@ build: $(CRT) $(SYS) $(TESTCASES) check: $(CRT) $(SYS) $(TESTCASES) @echo -e "\nQEMU simulator." - @for case in $(TESTCASES); do \ + for case in $(TESTCASES); do \ echo -n "$$case "; \ - $(SIM) $$case; \ + $(SIM) ./$$case; \ done check-g: $(CRT) $(SYS) $(TESTCASES) @echo -e "\nGDB simulator." diff --git a/tests/cris/sys.c b/tests/cris/sys.c index 264ec06f3..551c5dd7c 100644 --- a/tests/cris/sys.c +++ b/tests/cris/sys.c @@ -16,7 +16,7 @@ void pass(void) { } void _fail(char *reason) { - char s[] = "failed: "; + char s[] = "\nfailed: "; int len = mystrlen(reason); write (1, s, sizeof (s) - 1); write (1, reason, len); @@ -41,8 +41,11 @@ void exit (int status) { ssize_t write (int fd, const void *buf, size_t count) { int r; - asm volatile ("moveq 4, $r9\n" /* NR_write. */ - "break 13\n" : : : "memory"); - asm volatile ("move.d $r10, %0\n" : "=r" (r)); + asm ("move.d %0, $r10\n" + "move.d %1, $r11\n" + "move.d %2, $r12\n" + "moveq 4, $r9\n" /* NR_write. */ + "break 13\n" : : "r" (fd), "r" (buf), "r" (count) : "memory"); + asm ("move.d $r10, %0\n" : "=r" (r)); return r; } diff --git a/tests/cris/testutils.inc b/tests/cris/testutils.inc index 4f434e1e4..aa1641b2e 100644 --- a/tests/cris/testutils.inc +++ b/tests/cris/testutils.inc @@ -23,7 +23,7 @@ main: .macro fail .data 99: - .asciz " checkr3 failed" + .asciz " checkr3 failed\n" .text move.d 99b, $r10 jsr _fail @@ -36,7 +36,7 @@ main: nop .data 99: - .asciz "checkr3 failed" + .asciz "checkr3 failed\n" .text move.d 99b, $r10 jsr _fail @@ -79,7 +79,7 @@ main: 9: .data 99: - .asciz "test_move_cc failed" + .asciz "test_move_cc failed\n" .text move.d 99b, $r10 jsr _fail @@ -108,7 +108,7 @@ main: 9: .data 99: - .asciz "test_move_cc failed" + .asciz "test_move_cc failed\n" .text move.d 99b, $r10 jsr _fail -- cgit v1.2.3 From bf443337130809afc7887dd59e0a29fe605155eb Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Fri, 6 Jun 2008 11:17:17 +0000 Subject: Correct P flag assertion in rfe. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4683 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-cris/op_helper.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c index ebff31a1d..21ee5ee1c 100644 --- a/target-cris/op_helper.c +++ b/target-cris/op_helper.c @@ -202,6 +202,8 @@ static void cris_ccs_rshift(CPUState *env) void helper_rfe(void) { + int rflag = env->pregs[PR_CCS] & R_FLAG; + D(fprintf(logfile, "rfe: erp=%x pid=%x ccs=%x btarget=%x\n", env->pregs[PR_ERP], env->pregs[PR_PID], env->pregs[PR_CCS], @@ -210,7 +212,7 @@ void helper_rfe(void) cris_ccs_rshift(env); /* RFE sets the P_FLAG only if the R_FLAG is not set. */ - if (!(env->pregs[PR_CCS] & R_FLAG)) + if (!rflag) env->pregs[PR_CCS] |= P_FLAG; } -- cgit v1.2.3 From 2a44f7f173649e90b6f48c85d08f009c6fe765bd Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Fri, 6 Jun 2008 11:23:28 +0000 Subject: CRIS translator updates * Improve translation of the X flag (still some corner cases missing). * First shot att P flag support and conditional stores. * Improve the jump logic. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4684 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-cris/translate.c | 315 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 212 insertions(+), 103 deletions(-) diff --git a/target-cris/translate.c b/target-cris/translate.c index 615a3fcac..3affd1cec 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -73,6 +73,7 @@ TCGv cc_op; TCGv cc_size; TCGv cc_mask; +TCGv env_btaken; TCGv env_btarget; TCGv env_pc; @@ -104,9 +105,16 @@ typedef struct DisasContext { int flags_x; int clear_x; /* Clear x after this insn? */ - int user; /* user or kernel mode. */ + int cpustate_changed; + unsigned int tb_flags; /* tb dependent flags. */ int is_jmp; +#define JMP_NOJMP 0 +#define JMP_DIRECT 1 +#define JMP_INDIRECT 2 + int jmp; /* 0=nojmp, 1=direct, 2=indirect. */ + uint32_t jmp_pc; + int delayed_branch; struct TranslationBlock *tb; @@ -207,8 +215,10 @@ static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn) tcg_gen_andi_tl(cpu_PR[r], tn, 3); else { tcg_gen_mov_tl(cpu_PR[r], tn); - if (r == PR_PID) + if (r == PR_PID) tcg_gen_helper_0_1(helper_tlb_flush_pid, tn); + else if (r == PR_CCS) + dc->cpustate_changed = 1; } } @@ -610,7 +620,7 @@ static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false) btaken = tcg_temp_new(TCG_TYPE_TL); /* Conditional jmp. */ - t_gen_mov_TN_env(btaken, btaken); + tcg_gen_mov_tl(btaken, env_btaken); tcg_gen_mov_tl(env_pc, pc_false); tcg_gen_brcondi_tl(TCG_COND_EQ, btaken, 0, l1); tcg_gen_mov_tl(env_pc, pc_true); @@ -628,7 +638,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) tcg_gen_movi_tl(env_pc, dest); tcg_gen_exit_tb((long)tb + n); } else { - tcg_gen_mov_tl(env_pc, cpu_T[0]); + tcg_gen_movi_tl(env_pc, dest); tcg_gen_exit_tb(0); } } @@ -648,6 +658,9 @@ static int sign_extend(unsigned int val, unsigned int width) static inline void cris_clear_x_flag(DisasContext *dc) { + if (dc->flagx_known && dc->flags_x) + dc->flags_uptodate = 0; + dc->flagx_known = 1; dc->flags_x = 0; } @@ -715,6 +728,15 @@ static void cris_evaluate_flags(DisasContext *dc) } break; } + if (dc->flagx_known) { + if (dc->flags_x) + tcg_gen_ori_tl(cpu_PR[PR_CCS], + cpu_PR[PR_CCS], X_FLAG); + else + tcg_gen_andi_tl(cpu_PR[PR_CCS], + cpu_PR[PR_CCS], ~X_FLAG); + } + dc->flags_uptodate = 1; } } @@ -723,6 +745,11 @@ static void cris_cc_mask(DisasContext *dc, unsigned int mask) { uint32_t ovl; + 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; @@ -732,11 +759,6 @@ static void cris_cc_mask(DisasContext *dc, unsigned int mask) } dc->cc_mask = mask; dc->update_cc = 1; - - if (mask == 0) - dc->update_cc = 0; - else - dc->flags_uptodate = 0; } static void cris_update_cc_op(DisasContext *dc, int op, int size) @@ -942,7 +964,7 @@ static int arith_cc(DisasContext *dc) static void gen_tst_cc (DisasContext *dc, int cond) { - int arith_opt; + int arith_opt, move_opt; /* TODO: optimize more condition codes. */ @@ -955,9 +977,10 @@ static void gen_tst_cc (DisasContext *dc, int cond) * code is true. */ arith_opt = arith_cc(dc) && !dc->flags_uptodate; + move_opt = (dc->cc_op == CC_OP_MOVE) && !dc->flags_uptodate; switch (cond) { case CC_EQ: - if (arith_opt) { + if (arith_opt || move_opt) { /* If cc_result is zero, T0 should be non-zero otherwise T0 should be zero. */ int l1; @@ -975,7 +998,7 @@ static void gen_tst_cc (DisasContext *dc, int cond) } break; case CC_NE: - if (arith_opt) + if (arith_opt || move_opt) tcg_gen_mov_tl(cpu_T[0], cc_result); else { cris_evaluate_flags(dc); @@ -990,8 +1013,7 @@ static void gen_tst_cc (DisasContext *dc, int cond) break; case CC_CC: cris_evaluate_flags(dc); - tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS], - C_FLAG); + tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS], C_FLAG); tcg_gen_andi_tl(cpu_T[0], cpu_T[0], C_FLAG); break; case CC_VS: @@ -1005,9 +1027,17 @@ static void gen_tst_cc (DisasContext *dc, int cond) tcg_gen_andi_tl(cpu_T[0], cpu_T[0], V_FLAG); break; case CC_PL: - if (arith_opt) - tcg_gen_shli_tl(cpu_T[0], cc_result, 31); - else { + 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(cpu_T[0], cc_result, bits); + tcg_gen_xori_tl(cpu_T[0], cpu_T[0], 1); + } else { cris_evaluate_flags(dc); tcg_gen_xori_tl(cpu_T[0], cpu_PR[PR_CCS], N_FLAG); @@ -1015,9 +1045,15 @@ static void gen_tst_cc (DisasContext *dc, int cond) } break; case CC_MI: - if (arith_opt) { - tcg_gen_shli_tl(cpu_T[0], cc_result, 31); - tcg_gen_xori_tl(cpu_T[0], cpu_T[0], 1); + 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(cpu_T[0], cc_result, 31); } else { cris_evaluate_flags(dc); @@ -1121,28 +1157,46 @@ static void gen_tst_cc (DisasContext *dc, int cond) }; } -static void cris_prepare_cc_branch (DisasContext *dc, int offset, int cond) +static void cris_store_direct_jmp(DisasContext *dc) +{ + /* Store the direct jmp state into the cpu-state. */ + if (dc->jmp == JMP_DIRECT) { + tcg_gen_movi_tl(env_btarget, dc->jmp_pc); + tcg_gen_movi_tl(env_btaken, 1); + } +} + +static void cris_prepare_cc_branch (DisasContext *dc, + 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_pc = dc->pc + offset; + if (cond != CC_A) { + dc->jmp = JMP_INDIRECT; gen_tst_cc (dc, cond); - t_gen_mov_env_TN(btaken, cpu_T[0]); - } else - t_gen_mov_env_TN(btaken, tcg_const_tl(1)); - tcg_gen_movi_tl(env_btarget, dc->pc + offset); + tcg_gen_mov_tl(env_btaken, cpu_T[0]); + tcg_gen_movi_tl(env_btarget, dc->jmp_pc); + } else { + /* Allow chaining. */ + dc->jmp = JMP_DIRECT; + } } -/* Dynamic jumps, when the dest is in a live reg for example. */ -void cris_prepare_dyn_jmp (DisasContext *dc) +/* jumps, when the dest is in a live reg for example. Direct should be set + 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; - t_gen_mov_env_TN(btaken, tcg_const_tl(1)); + dc->jmp = type; + if (type == JMP_INDIRECT) + tcg_gen_movi_tl(env_btaken, 1); } void gen_load(DisasContext *dc, TCGv dst, TCGv addr, @@ -1150,6 +1204,11 @@ void gen_load(DisasContext *dc, TCGv dst, TCGv addr, { 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); @@ -1172,6 +1231,21 @@ void gen_store (DisasContext *dc, TCGv addr, TCGv val, { 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); + + + /* 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; + } + /* Remember, operands are flipped. CRIS has reversed order. */ if (size == 1) tcg_gen_qemu_st8(val, addr, mem_index); @@ -1179,6 +1253,11 @@ void gen_store (DisasContext *dc, TCGv addr, TCGv val, 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); + } } static inline void t_gen_sext(TCGv d, TCGv s, int size) @@ -1352,6 +1431,8 @@ static unsigned int dec_bccq(DisasContext *dc) tmp = offset; offset = sign_extend(offset, 8); + DIS(fprintf (logfile, "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); @@ -1463,9 +1544,10 @@ static unsigned int dec_asrq(DisasContext *dc) DIS(fprintf (logfile, "asrq %u, $r%d\n", dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); - cris_alu(dc, CC_OP_ASR, + 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], tcg_const_tl(dc->op1), 4); + cpu_R[dc->op2], cpu_R[dc->op2], 4); return 2; } static unsigned int dec_lslq(DisasContext *dc) @@ -1475,9 +1557,11 @@ static unsigned int dec_lslq(DisasContext *dc) cris_cc_mask(dc, CC_MASK_NZ); - cris_alu(dc, CC_OP_LSL, + 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], tcg_const_tl(dc->op1), 4); + cpu_R[dc->op2], cpu_R[dc->op2], 4); return 2; } static unsigned int dec_lsrq(DisasContext *dc) @@ -1487,9 +1571,10 @@ static unsigned int dec_lsrq(DisasContext *dc) cris_cc_mask(dc, CC_MASK_NZ); - cris_alu(dc, CC_OP_LSR, + 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], tcg_const_tl(dc->op1), 4); + cpu_R[dc->op2], cpu_R[dc->op2], 4); return 2; } @@ -1962,7 +2047,6 @@ static unsigned int dec_setclrf(DisasContext *dc) flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4) | EXTRACT_FIELD(dc->ir, 0, 3); - DIS(fprintf (logfile, "set=%d flags=%x\n", set, flags)); if (set && flags == 0) { DIS(fprintf (logfile, "nop\n")); return 2; @@ -1975,13 +2059,30 @@ static unsigned int dec_setclrf(DisasContext *dc) flags)); } - if (set && (flags & X_FLAG)) { + /* User space is not allowed to touch these. Silently ignore. */ + if (dc->tb_flags & U_FLAG) { + flags &= ~(I_FLAG | U_FLAG); + } + + if (flags & X_FLAG) { dc->flagx_known = 1; - dc->flags_x = X_FLAG; - } else { - dc->flagx_known = 0; + if (set) + dc->flags_x = X_FLAG; + else + dc->flags_x = 0; } + /* Break the TB if the P flag changes. */ + if (flags & P_FLAG) { + if ((set && !(dc->tb_flags & P_FLAG)) + || (!set && (dc->tb_flags & P_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); @@ -1989,11 +2090,11 @@ static unsigned int dec_setclrf(DisasContext *dc) tcg_gen_movi_tl(cc_op, dc->cc_op); if (set) { - if (!dc->user && (flags & U_FLAG)) { + 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->is_jmp = DISAS_NEXT; + dc->cpustate_changed = 1; } tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags); } @@ -2030,7 +2131,7 @@ static unsigned int dec_move_rp(DisasContext *dc) if (dc->op2 == PR_CCS) { cris_evaluate_flags(dc); t_gen_mov_TN_reg(cpu_T[0], dc->op1); - if (dc->user) { + if (dc->tb_flags & U_FLAG) { /* User space is not allowed to touch all flags. */ tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x39f); tcg_gen_andi_tl(cpu_T[1], cpu_PR[PR_CCS], ~0x39f); @@ -2051,16 +2152,12 @@ static unsigned int dec_move_pr(DisasContext *dc) { DIS(fprintf (logfile, "move $p%u, $r%u\n", dc->op1, dc->op2)); cris_cc_mask(dc, 0); - /* Support register 0 is hardwired to zero. - Treat it specially. */ - if (dc->op2 == 0) - tcg_gen_movi_tl(cpu_T[1], 0); - else if (dc->op2 == PR_CCS) { + + if (dc->op2 == PR_CCS) cris_evaluate_flags(dc); - t_gen_mov_TN_preg(cpu_T[1], dc->op2); - } else - t_gen_mov_TN_preg(cpu_T[1], dc->op2); - cris_alu(dc, CC_OP_MOVE, + + t_gen_mov_TN_preg(cpu_T[1], dc->op2); + cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op1], cpu_R[dc->op1], cpu_T[1], preg_sizes[dc->op2]); return 2; @@ -2410,7 +2507,7 @@ static unsigned int dec_move_mp(DisasContext *dc) cris_cc_mask(dc, 0); if (dc->op2 == PR_CCS) { cris_evaluate_flags(dc); - if (dc->user) { + if (dc->tb_flags & U_FLAG) { /* User space is not allowed to touch all flags. */ tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 0x39f); tcg_gen_andi_tl(cpu_T[0], cpu_PR[PR_CCS], ~0x39f); @@ -2561,7 +2658,7 @@ static unsigned int dec_jump_p(DisasContext *dc) /* rete will often have low bit set to indicate delayslot. */ tcg_gen_andi_tl(env_btarget, cpu_T[0], ~1); cris_cc_mask(dc, 0); - cris_prepare_dyn_jmp(dc); + cris_prepare_jmp(dc, JMP_INDIRECT); return 2; } @@ -2576,7 +2673,7 @@ static unsigned int dec_jas_r(DisasContext *dc) abort(); t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4)); - cris_prepare_dyn_jmp(dc); + cris_prepare_jmp(dc, JMP_INDIRECT); return 2; } @@ -2589,9 +2686,10 @@ static unsigned int dec_jas_im(DisasContext *dc) DIS(fprintf (logfile, "jas 0x%x\n", imm)); cris_cc_mask(dc, 0); /* Store the return address in Pd. */ - tcg_gen_movi_tl(env_btarget, imm); t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8)); - cris_prepare_dyn_jmp(dc); + + dc->jmp_pc = imm; + cris_prepare_jmp(dc, JMP_DIRECT); return 6; } @@ -2604,11 +2702,10 @@ static unsigned int dec_jasc_im(DisasContext *dc) DIS(fprintf (logfile, "jasc 0x%x\n", imm)); cris_cc_mask(dc, 0); /* Store the return address in Pd. */ - tcg_gen_movi_tl(cpu_T[0], imm); - tcg_gen_mov_tl(env_btarget, cpu_T[0]); - tcg_gen_movi_tl(cpu_T[0], dc->pc + 8 + 4); - t_gen_mov_preg_TN(dc, dc->op2, cpu_T[0]); - cris_prepare_dyn_jmp(dc); + 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; } @@ -2617,11 +2714,9 @@ static unsigned int dec_jasc_r(DisasContext *dc) DIS(fprintf (logfile, "jasc_r $r%u, $p%u\n", dc->op1, dc->op2)); cris_cc_mask(dc, 0); /* Store the return address in Pd. */ - t_gen_mov_TN_reg(cpu_T[0], dc->op1); - tcg_gen_mov_tl(env_btarget, cpu_T[0]); - tcg_gen_movi_tl(cpu_T[0], dc->pc + 4 + 4); - t_gen_mov_preg_TN(dc, dc->op2, cpu_T[0]); - cris_prepare_dyn_jmp(dc); + 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; } @@ -2651,12 +2746,11 @@ static unsigned int dec_bas_im(DisasContext *dc) DIS(fprintf (logfile, "bas 0x%x, $p%u\n", dc->pc + simm, dc->op2)); cris_cc_mask(dc, 0); - /* Stor the return address in Pd. */ - tcg_gen_movi_tl(cpu_T[0], dc->pc + simm); - tcg_gen_mov_tl(env_btarget, cpu_T[0]); - tcg_gen_movi_tl(cpu_T[0], dc->pc + 8); - t_gen_mov_preg_TN(dc, dc->op2, cpu_T[0]); - cris_prepare_dyn_jmp(dc); + /* 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; } @@ -2667,12 +2761,11 @@ static unsigned int dec_basc_im(DisasContext *dc) DIS(fprintf (logfile, "basc 0x%x, $p%u\n", dc->pc + simm, dc->op2)); cris_cc_mask(dc, 0); - /* Stor the return address in Pd. */ - tcg_gen_movi_tl(cpu_T[0], dc->pc + simm); - tcg_gen_mov_tl(env_btarget, cpu_T[0]); - tcg_gen_movi_tl(cpu_T[0], dc->pc + 12); - t_gen_mov_preg_TN(dc, dc->op2, cpu_T[0]); - cris_prepare_dyn_jmp(dc); + /* 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; } @@ -2699,8 +2792,7 @@ static unsigned int dec_rfe_etc(DisasContext *dc) break; case 6: /* break. */ - tcg_gen_movi_tl(cpu_T[0], dc->pc); - t_gen_mov_env_TN(pc, cpu_T[0]); + tcg_gen_movi_tl(env_pc, dc->pc); /* Breaks start at 16 in the exception vector. */ t_gen_mov_env_TN(trap_vector, tcg_const_tl(dc->op1 + 16)); @@ -2884,8 +2976,7 @@ static void check_breakpoint(CPUState *env, DisasContext *dc) for(j = 0; j < env->nb_breakpoints; j++) { if (env->breakpoints[j] == dc->pc) { cris_evaluate_flags (dc); - tcg_gen_movi_tl(cpu_T[0], dc->pc); - t_gen_mov_env_TN(pc, cpu_T[0]); + tcg_gen_movi_tl(env_pc, dc->pc); t_gen_raise_exception(EXCP_DEBUG); dc->is_jmp = DISAS_UPDATE; } @@ -2940,6 +3031,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, struct DisasContext ctx; struct DisasContext *dc = &ctx; uint32_t next_page_start; + target_ulong npc; if (!logfile) logfile = stderr; @@ -2968,18 +3060,24 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, dc->cc_size_uptodate = -1; /* Decode TB flags. */ - dc->user = tb->flags & U_FLAG; + dc->tb_flags = tb->flags & (P_FLAG | U_FLAG | X_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 (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, - "srch=%d pc=%x %x bt=%x ds=%lld ccs=%x\n" + "srch=%d pc=%x %x flg=%llx bt=%x ds=%lld 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, + search_pc, dc->pc, dc->ppc, tb->flags, env->btarget, tb->flags & 7, env->pregs[PR_CCS], env->pregs[PR_PID], env->pregs[PR_USP], @@ -2997,9 +3095,6 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, do { check_breakpoint(env, dc); - if (dc->is_jmp == DISAS_JUMP - || dc->is_jmp == DISAS_SWI) - goto done; if (search_pc) { j = gen_opc_ptr - gen_opc_buf; @@ -3034,13 +3129,20 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, actually genereating any host code, the simulator will just loop doing nothing for on this program location. */ if (dc->delayed_branch) { - t_gen_mov_env_TN(dslot, tcg_const_tl(0)); dc->delayed_branch--; if (dc->delayed_branch == 0) { - t_gen_cc_jmp(env_btarget, - tcg_const_tl(dc->pc)); - dc->is_jmp = DISAS_JUMP; + if (tb->flags & 7) + t_gen_mov_env_TN(dslot, + tcg_const_tl(0)); + if (dc->jmp == JMP_DIRECT) { + dc->is_jmp = DISAS_NEXT; + } else { + t_gen_cc_jmp(env_btarget, + tcg_const_tl(dc->pc)); + dc->is_jmp = DISAS_JUMP; + } + break; } } @@ -3051,28 +3153,33 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && (dc->pc < next_page_start)); + npc = dc->pc; + if (dc->jmp == JMP_DIRECT && !dc->delayed_branch) + npc = dc->jmp_pc; + + /* 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)); - } - - if (!dc->is_jmp) { - D(fprintf(logfile, "!jmp pc=%x jmp=%d db=%d\n", dc->pc, - dc->is_jmp, dc->delayed_branch)); - /* T0 and env_pc should hold the new pc. */ - tcg_gen_movi_tl(cpu_T[0], dc->pc); - tcg_gen_mov_tl(env_pc, cpu_T[0]); + cris_store_direct_jmp(dc); } cris_evaluate_flags (dc); - done: + if (__builtin_expect(env->singlestep_enabled, 0)) { + 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, dc->pc); + gen_goto_tb(dc, 1, npc); break; default: case DISAS_JUMP: @@ -3207,7 +3314,9 @@ CPUCRISState *cpu_cris_init (const char *cpu_model) env_btarget = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, offsetof(CPUState, btarget), "btarget"); - + env_btaken = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, + offsetof(CPUState, btaken), + "btaken"); for (i = 0; i < 16; i++) { cpu_R[i] = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0, offsetof(CPUState, regs[i]), -- cgit v1.2.3 From 7e15e60388b38e12cf20ca0925bfff29bd61df1c Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Fri, 6 Jun 2008 11:24:33 +0000 Subject: CRIS: Add the P flag to the tb dependent flags. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4685 c046a42c-6fe2-441c-8c8c-71466251a162 --- cpu-exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu-exec.c b/cpu-exec.c index bf9bcd444..a8e67e8ad 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -217,7 +217,7 @@ static inline TranslationBlock *tb_find_fast(void) cs_base = 0; pc = env->pc; #elif defined(TARGET_CRIS) - flags = env->pregs[PR_CCS] & (U_FLAG | X_FLAG); + flags = env->pregs[PR_CCS] & (P_FLAG | U_FLAG | X_FLAG); flags |= env->dslot; cs_base = 0; pc = env->pc; -- cgit v1.2.3 From 262ffdae6fdad3f6dab855a090543f5faa77ec96 Mon Sep 17 00:00:00 2001 From: bellard Date: Fri, 6 Jun 2008 12:08:46 +0000 Subject: Fix i386 segment descriptor types on reset (Avi Kivity) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4686 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-i386/helper.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/target-i386/helper.c b/target-i386/helper.c index d3bfb9aca..856d8965d 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -383,16 +383,22 @@ void cpu_reset(CPUX86State *env) env->idt.limit = 0xffff; env->gdt.limit = 0xffff; env->ldt.limit = 0xffff; - env->ldt.flags = DESC_P_MASK; + env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT); env->tr.limit = 0xffff; - env->tr.flags = DESC_P_MASK; - - cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff, 0); - cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff, 0); - cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff, 0); - cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff, 0); - cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff, 0); - cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff, 0); + env->tr.flags = DESC_P_MASK | (11 < DESC_TYPE_SHIFT); + + cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff, + DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK | DESC_R_MASK); + cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff, + DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); + cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff, + DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); + cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff, + DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); + cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff, + DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); + cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff, + DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); env->eip = 0xfff0; env->regs[R_EDX] = env->cpuid_version; -- cgit v1.2.3 From ec9d6075b484fed47d55bf1590148f1fc081538c Mon Sep 17 00:00:00 2001 From: bellard Date: Fri, 6 Jun 2008 12:54:30 +0000 Subject: undocumented 0x82 opcode is invalid in 64 bit code git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4687 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-i386/translate.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/target-i386/translate.c b/target-i386/translate.c index 85495a9d1..14903b4df 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -3788,9 +3788,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) } break; + case 0x82: + if (CODE64(s)) + goto illegal_op; case 0x80: /* GRP1 */ case 0x81: - case 0x82: case 0x83: { int val; -- cgit v1.2.3 From c588979bfc41a0340bdf8b5e32fe4ae8f1e25aed Mon Sep 17 00:00:00 2001 From: ths Date: Sat, 7 Jun 2008 04:31:49 +0000 Subject: Allocate a register pair instead of a single register. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4688 c046a42c-6fe2-441c-8c8c-71466251a162 --- tcg/tcg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index ef4460d25..b4b8d8ea2 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -353,7 +353,7 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset, #if TCG_TARGET_REG_BITS == 32 if (type == TCG_TYPE_I64) { char buf[64]; - tcg_temp_alloc(s, s->nb_globals + 1); + tcg_temp_alloc(s, s->nb_globals + 2); ts = &s->temps[s->nb_globals]; ts->base_type = type; ts->type = TCG_TYPE_I32; -- cgit v1.2.3 From 96d19126227eb6010336f38ce4c09966964bb1f4 Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Sat, 7 Jun 2008 08:03:05 +0000 Subject: Fix Sparc32plus GDBstub support git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4689 c046a42c-6fe2-441c-8c8c-71466251a162 --- gdbstub.c | 64 ++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 5342474a5..414c3908a 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -469,40 +469,49 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) ppc_store_xer(env, tswapl(registers[101])); } #elif defined (TARGET_SPARC) +#ifdef TARGET_ABI32 +#define tswap_abi(val) tswap32(val &0xffffffff) +#else +#define tswap_abi(val) tswapl(val) +#endif static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) { +#ifdef TARGET_ABI32 + abi_ulong *registers = (abi_ulong *)mem_buf; +#else target_ulong *registers = (target_ulong *)mem_buf; +#endif int i; /* fill in g0..g7 */ for(i = 0; i < 8; i++) { - registers[i] = tswapl(env->gregs[i]); + registers[i] = tswap_abi(env->gregs[i]); } /* fill in register window */ for(i = 0; i < 24; i++) { - registers[i + 8] = tswapl(env->regwptr[i]); + registers[i + 8] = tswap_abi(env->regwptr[i]); } -#ifndef TARGET_SPARC64 +#if !defined(TARGET_SPARC64) || defined(TARGET_ABI32) /* fill in fprs */ for (i = 0; i < 32; i++) { - registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i])); + registers[i + 32] = tswap_abi(*((uint32_t *)&env->fpr[i])); } /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ - registers[64] = tswapl(env->y); + registers[64] = tswap_abi(env->y); { - target_ulong tmp; + uint32_t tmp; - tmp = GET_PSR(env); - registers[65] = tswapl(tmp); + tmp = GET_PSR(env); + registers[65] = tswap32(tmp); } - registers[66] = tswapl(env->wim); - registers[67] = tswapl(env->tbr); - registers[68] = tswapl(env->pc); - registers[69] = tswapl(env->npc); - registers[70] = tswapl(env->fsr); + registers[66] = tswap_abi(env->wim); + registers[67] = tswap_abi(env->tbr); + registers[68] = tswap_abi(env->pc); + registers[69] = tswap_abi(env->npc); + registers[70] = tswap_abi(env->fsr); registers[71] = 0; /* csr */ registers[72] = 0; - return 73 * sizeof(target_ulong); + return 73 * sizeof(uint32_t); #else /* fill in fprs */ for (i = 0; i < 64; i += 2) { @@ -527,30 +536,34 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) { +#ifdef TARGET_ABI32 + abi_ulong *registers = (abi_ulong *)mem_buf; +#else target_ulong *registers = (target_ulong *)mem_buf; +#endif int i; /* fill in g0..g7 */ for(i = 0; i < 7; i++) { - env->gregs[i] = tswapl(registers[i]); + env->gregs[i] = tswap_abi(registers[i]); } /* fill in register window */ for(i = 0; i < 24; i++) { - env->regwptr[i] = tswapl(registers[i + 8]); + env->regwptr[i] = tswap_abi(registers[i + 8]); } -#ifndef TARGET_SPARC64 +#if !defined(TARGET_SPARC64) || defined(TARGET_ABI32) /* fill in fprs */ for (i = 0; i < 32; i++) { - *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]); + *((uint32_t *)&env->fpr[i]) = tswap_abi(registers[i + 32]); } /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ - env->y = tswapl(registers[64]); - PUT_PSR(env, tswapl(registers[65])); - env->wim = tswapl(registers[66]); - env->tbr = tswapl(registers[67]); - env->pc = tswapl(registers[68]); - env->npc = tswapl(registers[69]); - env->fsr = tswapl(registers[70]); + env->y = tswap_abi(registers[64]); + PUT_PSR(env, tswap_abi(registers[65])); + env->wim = tswap_abi(registers[66]); + env->tbr = tswap_abi(registers[67]); + env->pc = tswap_abi(registers[68]); + env->npc = tswap_abi(registers[69]); + env->fsr = tswap_abi(registers[70]); #else for (i = 0; i < 64; i += 2) { uint64_t tmp; @@ -574,6 +587,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) env->y = tswapl(registers[69]); #endif } +#undef tswap_abi #elif defined (TARGET_ARM) static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) { -- cgit v1.2.3 From 1a14026e11b9baaf5050b0bed947e1b57f10ca08 Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Sat, 7 Jun 2008 08:07:37 +0000 Subject: Allow NWINDOWS selection (CPU feature with model specific defaults) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4690 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/sun4m.c | 6 +-- hw/sun4u.c | 2 +- linux-user/main.c | 28 ++++++------- target-sparc/TODO | 1 - target-sparc/cpu.h | 33 ++++++++++++--- target-sparc/helper.c | 107 +++++++++++++++++++++++++++++++++++------------ target-sparc/machine.c | 8 +++- target-sparc/op_helper.c | 24 +++++------ target-sparc/translate.c | 2 - 9 files changed, 144 insertions(+), 67 deletions(-) diff --git a/hw/sun4m.c b/hw/sun4m.c index 734b576aa..09c26270d 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -404,7 +404,7 @@ static void sun4m_hw_init(const struct hwdef *hwdef, ram_addr_t RAM_size, qemu_register_reset(secondary_cpu_reset, env); env->halted = 1; } - register_savevm("cpu", i, 3, cpu_save, cpu_load, env); + register_savevm("cpu", i, 4, cpu_save, cpu_load, env); cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS); env->prom_addr = hwdef->slavio_base; } @@ -579,7 +579,7 @@ static void sun4c_hw_init(const struct hwdef *hwdef, ram_addr_t RAM_size, cpu_sparc_set_id(env, 0); qemu_register_reset(main_cpu_reset, env); - register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); + register_savevm("cpu", 0, 4, cpu_save, cpu_load, env); cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS); env->prom_addr = hwdef->slavio_base; @@ -1391,7 +1391,7 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size, qemu_register_reset(secondary_cpu_reset, env); env->halted = 1; } - register_savevm("cpu", i, 3, cpu_save, cpu_load, env); + register_savevm("cpu", i, 4, cpu_save, cpu_load, env); cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS); env->prom_addr = hwdef->slavio_base; } diff --git a/hw/sun4u.c b/hw/sun4u.c index 0cc04f97d..6e1dee956 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -260,7 +260,7 @@ static void sun4u_init(ram_addr_t RAM_size, int vga_ram_size, bh = qemu_bh_new(hstick_irq, env); env->hstick = ptimer_init(bh); ptimer_set_period(env->hstick, 1ULL); - register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); + register_savevm("cpu", 0, 4, cpu_save, cpu_load, env); qemu_register_reset(main_cpu_reset, env); main_cpu_reset(env); diff --git a/linux-user/main.c b/linux-user/main.c index 21c2d3ba0..4bdec7e9b 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -626,11 +626,11 @@ void cpu_loop(CPUARMState *env) can be found at http://www.sics.se/~psm/sparcstack.html */ static inline int get_reg_index(CPUSPARCState *env, int cwp, int index) { - index = (index + cwp * 16) & (16 * NWINDOWS - 1); + index = (index + cwp * 16) % (16 * env->nwindows); /* wrap handling : if cwp is on the last window, then we use the registers 'after' the end */ - if (index < 8 && env->cwp == (NWINDOWS - 1)) - index += (16 * NWINDOWS); + if (index < 8 && env->cwp == env->nwindows - 1) + index += 16 * env->nwindows; return index; } @@ -656,12 +656,12 @@ static void save_window(CPUSPARCState *env) { #ifndef TARGET_SPARC64 unsigned int new_wim; - new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) & - ((1LL << NWINDOWS) - 1); - save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1)); + new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) & + ((1LL << env->nwindows) - 1); + save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2)); env->wim = new_wim; #else - save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1)); + save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2)); env->cansave++; env->canrestore--; #endif @@ -672,11 +672,11 @@ static void restore_window(CPUSPARCState *env) unsigned int new_wim, i, cwp1; abi_ulong sp_ptr; - new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) & - ((1LL << NWINDOWS) - 1); + new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) & + ((1LL << env->nwindows) - 1); /* restore the invalid window */ - cwp1 = (env->cwp + 1) & (NWINDOWS - 1); + cwp1 = cpu_cwp_inc(env, env->cwp + 1); sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)]; #if defined(DEBUG_WIN) printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n", @@ -690,8 +690,8 @@ static void restore_window(CPUSPARCState *env) env->wim = new_wim; #ifdef TARGET_SPARC64 env->canrestore++; - if (env->cleanwin < NWINDOWS - 1) - env->cleanwin++; + if (env->cleanwin < env->nwindows - 1) + env->cleanwin++; env->cansave--; #endif } @@ -703,14 +703,14 @@ static void flush_windows(CPUSPARCState *env) offset = 1; for(;;) { /* if restore would invoke restore_window(), then we can stop */ - cwp1 = (env->cwp + offset) & (NWINDOWS - 1); + cwp1 = cpu_cwp_inc(env, env->cwp + offset); if (env->wim & (1 << cwp1)) break; save_window_offset(env, cwp1); offset++; } /* set wim so that restore will reload the registers */ - cwp1 = (env->cwp + 1) & (NWINDOWS - 1); + cwp1 = cpu_cwp_inc(env, env->cwp + 1); env->wim = 1 << cwp1; #if defined(DEBUG_WIN) printf("flush_windows: nb=%d\n", offset - 1); diff --git a/target-sparc/TODO b/target-sparc/TODO index 5a4937ba0..0e998e276 100644 --- a/target-sparc/TODO +++ b/target-sparc/TODO @@ -6,7 +6,6 @@ CPU common: slot next page) - Atomical instructions - CPU features should match real CPUs (also ASI selection) - - Allow choosing of NWINDOWS (CPU model specific and as a CPU feature) - Optimizations/improvements: - Condition code/branch handling like x86, also for FPU? - Remove remaining explicit alignment checks diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index ad9aeb867..f30a606c9 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -170,8 +170,9 @@ #define PG_MODIFIED_MASK (1 << PG_MODIFIED_BIT) #define PG_CACHE_MASK (1 << PG_CACHE_BIT) -/* 2 <= NWINDOWS <= 32. In QEMU it must also be a power of two. */ -#define NWINDOWS 8 +/* 3 <= NWINDOWS <= 32. */ +#define MIN_NWINDOWS 3 +#define MAX_NWINDOWS 32 #if !defined(TARGET_SPARC64) #define NB_MMU_MODES 2 @@ -222,8 +223,9 @@ typedef struct CPUSPARCState { uint32_t mmu_cxr_mask; uint32_t mmu_sfsr_mask; uint32_t mmu_trcr_mask; + uint32_t nwindows; /* NOTE: we allow 8 more registers to handle wrapping */ - target_ulong regbase[NWINDOWS * 16 + 8]; + target_ulong regbase[MAX_NWINDOWS * 16 + 8]; CPU_COMMON @@ -330,6 +332,20 @@ void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); #ifndef NO_CPU_IO_DEFS void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); + +static inline int cpu_cwp_inc(CPUSPARCState *env1, int cwp) +{ + if (unlikely(cwp >= env1->nwindows)) + cwp -= env1->nwindows; + return cwp; +} + +static inline int cpu_cwp_dec(CPUSPARCState *env1, int cwp) +{ + if (unlikely(cwp < 0)) + cwp += env1->nwindows; + return cwp; +} #endif #define PUT_PSR(env, val) do { int _tmp = val; \ @@ -348,9 +364,14 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); env->xcc = (_tmp >> 4) << 20; \ env->psr = (_tmp & 0xf) << 20; \ } while (0) -#define GET_CWP64(env) (NWINDOWS - 1 - (env)->cwp) -#define PUT_CWP64(env, val) \ - cpu_set_cwp(env, NWINDOWS - 1 - ((val) & (NWINDOWS - 1))) +#define GET_CWP64(env) (env->nwindows - 1 - (env)->cwp) + +static inline void PUT_CWP64(CPUSPARCState *env1, int cwp) +{ + if (unlikely(cwp >= env1->nwindows || cwp < 0)) + cwp = 0; + cpu_set_cwp(env1, env1->nwindows - 1 - cwp); +} #endif diff --git a/target-sparc/helper.c b/target-sparc/helper.c index bf74c0d29..7b87d592c 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -47,6 +47,7 @@ struct sparc_def_t { uint32_t mmu_sfsr_mask; uint32_t mmu_trcr_mask; uint32_t features; + uint32_t nwindows; }; static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model); @@ -750,11 +751,11 @@ void do_interrupt(CPUState *env) change_pstate(PS_PEF | PS_PRIV | PS_AG); if (intno == TT_CLRWIN) - cpu_set_cwp(env, (env->cwp - 1) & (NWINDOWS - 1)); + cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1)); else if ((intno & 0x1c0) == TT_SPILL) - cpu_set_cwp(env, (env->cwp - env->cansave - 2) & (NWINDOWS - 1)); + cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2)); else if ((intno & 0x1c0) == TT_FILL) - cpu_set_cwp(env, (env->cwp + 1) & (NWINDOWS - 1)); + cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1)); env->tbr &= ~0x7fffULL; env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5); if (env->tl < MAXTL - 1) { @@ -853,7 +854,7 @@ void do_interrupt(CPUState *env) } #endif env->psret = 0; - cwp = (env->cwp - 1) & (NWINDOWS - 1); + cwp = cpu_cwp_dec(env, env->cwp - 1); cpu_set_cwp(env, cwp); env->regwptr[9] = env->pc; env->regwptr[10] = env->npc; @@ -887,8 +888,8 @@ void cpu_reset(CPUSPARCState *env) #if defined(CONFIG_USER_ONLY) env->user_mode_only = 1; #ifdef TARGET_SPARC64 - env->cleanwin = NWINDOWS - 2; - env->cansave = NWINDOWS - 2; + env->cleanwin = env->nwindows - 2; + env->cansave = env->nwindows - 2; env->pstate = PS_RMO | PS_PEF | PS_IE; env->asi = 0x82; // Primary no-fault #endif @@ -921,6 +922,7 @@ static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model) env->cpu_model_str = cpu_model; env->version = def->iu_version; env->fsr = def->fpu_version; + env->nwindows = def->nwindows; #if !defined(TARGET_SPARC64) env->mmu_bm = def->mmu_bm; env->mmu_ctpr_mask = def->mmu_ctpr_mask; @@ -929,6 +931,8 @@ static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model) env->mmu_trcr_mask = def->mmu_trcr_mask; env->mmuregs[0] |= def->mmu_version; cpu_sparc_set_id(env, 0); +#else + env->version |= def->nwindows - 1; #endif return 0; } @@ -970,121 +974,136 @@ static const sparc_def_t sparc_defs[] = { { .name = "Fujitsu Sparc64", .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 4, .features = CPU_DEFAULT_FEATURES, }, { .name = "Fujitsu Sparc64 III", .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 5, .features = CPU_DEFAULT_FEATURES, }, { .name = "Fujitsu Sparc64 IV", .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { .name = "Fujitsu Sparc64 V", .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { .name = "TI UltraSparc I", .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { .name = "TI UltraSparc II", .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { .name = "TI UltraSparc IIi", .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { .name = "TI UltraSparc IIe", .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { .name = "Sun UltraSparc III", .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { .name = "Sun UltraSparc III Cu", .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { .name = "Sun UltraSparc IIIi", .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { .name = "Sun UltraSparc IV", .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { .name = "Sun UltraSparc IV+", .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { .name = "Sun UltraSparc IIIi+", .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { .name = "NEC UltraSparc I", .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24) - | (MAXTL << 8) | (NWINDOWS - 1)), + | (MAXTL << 8)), .fpu_version = 0x00000000, .mmu_version = 0, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, #else @@ -1098,6 +1117,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000003f, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 7, .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD, }, { @@ -1110,6 +1130,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x000000ff, .mmu_sfsr_mask = 0x00016fff, .mmu_trcr_mask = 0x00ffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { @@ -1122,6 +1143,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x000000ff, .mmu_sfsr_mask = 0x00016fff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { @@ -1134,6 +1156,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000003f, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT | CPU_FEATURE_FSMULD, }, @@ -1147,6 +1170,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000003f, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT | CPU_FEATURE_FSMULD, }, @@ -1160,6 +1184,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000003f, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT | CPU_FEATURE_FSMULD, }, @@ -1173,6 +1198,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000ffff, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { @@ -1185,6 +1211,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000003f, .mmu_sfsr_mask = 0x00016fff, .mmu_trcr_mask = 0x0000003f, + .nwindows = 7, .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL | CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | CPU_FEATURE_FMUL, @@ -1199,6 +1226,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x000000ff, .mmu_sfsr_mask = 0x00016fff, .mmu_trcr_mask = 0x00ffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { @@ -1211,6 +1239,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x000000ff, .mmu_sfsr_mask = 0x00016bff, .mmu_trcr_mask = 0x00ffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { @@ -1223,6 +1252,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000ffff, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { @@ -1235,6 +1265,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000ffff, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { @@ -1247,6 +1278,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000ffff, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { @@ -1259,6 +1291,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000ffff, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { @@ -1271,6 +1304,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000ffff, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { @@ -1283,6 +1317,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000003f, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { @@ -1295,6 +1330,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000003f, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { @@ -1307,6 +1343,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000003f, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT | CPU_FEATURE_FSMULD, }, @@ -1320,6 +1357,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000003f, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT | CPU_FEATURE_FSMULD, }, @@ -1333,6 +1371,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000003f, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { @@ -1345,6 +1384,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000003f, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, { @@ -1357,6 +1397,7 @@ static const sparc_def_t sparc_defs[] = { .mmu_cxr_mask = 0x0000003f, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, + .nwindows = 8, .features = CPU_DEFAULT_FEATURES, }, #endif @@ -1411,7 +1452,7 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model) uint32_t plus_features = 0; uint32_t minus_features = 0; long long iu_version; - uint32_t fpu_version, mmu_version; + uint32_t fpu_version, mmu_version, nwindows; for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) { if (strcasecmp(name, sparc_defs[i].name) == 0) { @@ -1467,6 +1508,19 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model) cpu_def->mmu_version = mmu_version; #ifdef DEBUG_FEATURES fprintf(stderr, "mmu_version %llx\n", mmu_version); +#endif + } else if (!strcmp(featurestr, "nwindows")) { + char *err; + + nwindows = strtol(val, &err, 0); + if (!*val || *err || nwindows > MAX_NWINDOWS || + nwindows < MIN_NWINDOWS) { + fprintf(stderr, "bad numerical value %s\n", val); + goto error; + } + cpu_def->nwindows = nwindows; +#ifdef DEBUG_FEATURES + fprintf(stderr, "nwindows %d\n", nwindows); #endif } else { fprintf(stderr, "unrecognized feature %s\n", featurestr); @@ -1497,11 +1551,12 @@ void sparc_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) unsigned int i; for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) { - (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x ", + (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x NWINS %d ", sparc_defs[i].name, sparc_defs[i].iu_version, sparc_defs[i].fpu_version, - sparc_defs[i].mmu_version); + sparc_defs[i].mmu_version, + sparc_defs[i].nwindows); print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES & ~sparc_defs[i].features, "-"); print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES & @@ -1512,7 +1567,7 @@ void sparc_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) print_features(f, cpu_fprintf, -1, NULL); (*cpu_fprintf)(f, "\n"); (*cpu_fprintf)(f, "Numerical features (=): iu_version fpu_version " - "mmu_version\n"); + "mmu_version nwindows\n"); } #define GET_FLAG(a,b) ((env->psr & a)?b:'-') @@ -1558,7 +1613,7 @@ void cpu_dump_state(CPUState *env, FILE *f, cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d " "cleanwin %d cwp %d\n", env->cansave, env->canrestore, env->otherwin, env->wstate, - env->cleanwin, NWINDOWS - 1 - env->cwp); + env->cleanwin, env->nwindows - 1 - env->cwp); #else cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env), GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'), diff --git a/target-sparc/machine.c b/target-sparc/machine.c index 0e7a23e9f..aaac30b1e 100644 --- a/target-sparc/machine.c +++ b/target-sparc/machine.c @@ -31,7 +31,8 @@ void cpu_save(QEMUFile *f, void *opaque) for(i = 0; i < 8; i++) qemu_put_betls(f, &env->gregs[i]); - for(i = 0; i < NWINDOWS * 16; i++) + qemu_put_be32s(f, &env->nwindows); + for(i = 0; i < env->nwindows * 16; i++) qemu_put_betls(f, &env->regbase[i]); /* FPU */ @@ -65,9 +66,12 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) int i; uint32_t tmp; + if (version_id != 4) + return -EINVAL; for(i = 0; i < 8; i++) qemu_get_betls(f, &env->gregs[i]); - for(i = 0; i < NWINDOWS * 16; i++) + qemu_get_be32s(f, &env->nwindows); + for(i = 0; i < env->nwindows * 16; i++) qemu_get_betls(f, &env->regbase[i]); /* FPU */ diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index 3c04fe54f..7b28f72b8 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -2178,7 +2178,7 @@ void helper_rett(void) raise_exception(TT_ILL_INSN); env->psret = 1; - cwp = (env->cwp + 1) & (NWINDOWS - 1); + cwp = cpu_cwp_inc(env, env->cwp + 1) ; if (env->wim & (1 << cwp)) { raise_exception(TT_WIN_UNF); } @@ -2399,7 +2399,7 @@ void helper_save(void) { uint32_t cwp; - cwp = (env->cwp - 1) & (NWINDOWS - 1); + cwp = cpu_cwp_dec(env, env->cwp - 1); if (env->wim & (1 << cwp)) { raise_exception(TT_WIN_OVF); } @@ -2410,7 +2410,7 @@ void helper_restore(void) { uint32_t cwp; - cwp = (env->cwp + 1) & (NWINDOWS - 1); + cwp = cpu_cwp_inc(env, env->cwp + 1); if (env->wim & (1 << cwp)) { raise_exception(TT_WIN_UNF); } @@ -2419,7 +2419,7 @@ void helper_restore(void) void helper_wrpsr(target_ulong new_psr) { - if ((new_psr & PSR_CWP) >= NWINDOWS) + if ((new_psr & PSR_CWP) >= env->nwindows) raise_exception(TT_ILL_INSN); else PUT_PSR(env, new_psr); @@ -2437,7 +2437,7 @@ void helper_save(void) { uint32_t cwp; - cwp = (env->cwp - 1) & (NWINDOWS - 1); + cwp = cpu_cwp_dec(env, env->cwp - 1); if (env->cansave == 0) { raise_exception(TT_SPILL | (env->otherwin != 0 ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)): @@ -2458,7 +2458,7 @@ void helper_restore(void) { uint32_t cwp; - cwp = (env->cwp + 1) & (NWINDOWS - 1); + cwp = cpu_cwp_inc(env, env->cwp + 1); if (env->canrestore == 0) { raise_exception(TT_FILL | (env->otherwin != 0 ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)): @@ -2472,7 +2472,7 @@ void helper_restore(void) void helper_flushw(void) { - if (env->cansave != NWINDOWS - 2) { + if (env->cansave != env->nwindows - 2) { raise_exception(TT_SPILL | (env->otherwin != 0 ? (TT_WOTHER | ((env->wstate & 0x38) >> 1)): ((env->wstate & 0x7) << 2))); @@ -2491,7 +2491,7 @@ void helper_saved(void) void helper_restored(void) { env->canrestore++; - if (env->cleanwin < NWINDOWS - 1) + if (env->cleanwin < env->nwindows - 1) env->cleanwin++; if (env->otherwin == 0) env->cansave--; @@ -2622,12 +2622,12 @@ void helper_retry(void) void cpu_set_cwp(CPUState *env1, int new_cwp) { /* put the modified wrap registers at their proper location */ - if (env1->cwp == (NWINDOWS - 1)) - memcpy32(env1->regbase, env1->regbase + NWINDOWS * 16); + if (env1->cwp == env->nwindows - 1) + memcpy32(env1->regbase, env1->regbase + env->nwindows * 16); env1->cwp = new_cwp; /* put the wrap registers at their temporary location */ - if (new_cwp == (NWINDOWS - 1)) - memcpy32(env1->regbase + NWINDOWS * 16, env1->regbase); + if (new_cwp == env->nwindows - 1) + memcpy32(env1->regbase + env->nwindows * 16, env1->regbase); env1->regwptr = env1->regbase + (new_cwp * 16); } diff --git a/target-sparc/translate.c b/target-sparc/translate.c index eb0ab3343..999378a6d 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -3442,8 +3442,6 @@ static void disas_sparc_insn(DisasContext * dc) goto illegal_insn; } #else - tcg_gen_andi_tl(cpu_dst, cpu_dst, - ((1 << NWINDOWS) - 1)); tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wim)); -- cgit v1.2.3 From 0a878c4760718e1604e2cfe423252729716110ad Mon Sep 17 00:00:00 2001 From: malc Date: Sat, 7 Jun 2008 20:31:33 +0000 Subject: PPC TCG Fixes * Fix typo in aliased div2 * "Optimize" aliased div2/divu2 * Fix two remaining branch retranslation problems (Kudos to Andrzej Zaborowski) * Rework goto_tb and set_jmp_target1 * Use correct size when flushing icache * Use correct register selection for ORI (Was harmless since in both cases srcreg was equal to dstreg) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4691 c046a42c-6fe2-441c-8c8c-71466251a162 --- exec-all.h | 35 ++++++++++++++++++++--------------- tcg/ppc/tcg-target.c | 50 +++++++++++++++++--------------------------------- 2 files changed, 37 insertions(+), 48 deletions(-) diff --git a/exec-all.h b/exec-all.h index 8c52b796a..ba6f6da5a 100644 --- a/exec-all.h +++ b/exec-all.h @@ -184,32 +184,37 @@ extern int code_gen_max_blocks; #if defined(USE_DIRECT_JUMP) #if defined(__powerpc__) +static inline void flush_icache_range(unsigned long start, unsigned long stop); static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr) { - uint32_t val, *ptr; + /* This must be in concord with INDEX_op_goto_tb inside tcg_out_op */ + uint32_t *ptr; long disp = addr - jmp_addr; + unsigned long patch_size; ptr = (uint32_t *)jmp_addr; - val = *ptr; if ((disp << 6) >> 6 != disp) { - uint16_t *p1; - - p1 = (uint16_t *) ptr; - *ptr = (val & ~0x03fffffc) | 4; - p1[3] = addr >> 16; - p1[5] = addr & 0xffff; + ptr[0] = 0x3c000000 | (addr >> 16); /* lis 0,addr@ha */ + ptr[1] = 0x60000000 | (addr & 0xffff); /* la 0,addr@l(0) */ + ptr[2] = 0x7c0903a6; /* mtctr 0 */ + ptr[3] = 0x4e800420; /* brctr */ + patch_size = 16; } else { /* patch the branch destination */ - val = (val & ~0x03fffffc) | (disp & 0x03fffffc); - *ptr = val; + if (disp != 16) { + *ptr = 0x48000000 | (disp & 0x03fffffc); /* b disp */ + patch_size = 4; + } else { + ptr[0] = 0x60000000; /* nop */ + ptr[1] = 0x60000000; + ptr[2] = 0x60000000; + ptr[3] = 0x60000000; + patch_size = 16; + } } /* flush icache */ - asm volatile ("dcbst 0,%0" : : "r"(ptr) : "memory"); - asm volatile ("sync" : : : "memory"); - asm volatile ("icbi 0,%0" : : "r"(ptr) : "memory"); - asm volatile ("sync" : : : "memory"); - asm volatile ("isync" : : : "memory"); + flush_icache_range(jmp_addr, jmp_addr + patch_size); } #elif defined(__i386__) || defined(__x86_64__) static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr) diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 6d955c949..ffac342e3 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -388,7 +388,7 @@ static void tcg_out_movi(TCGContext *s, TCGType type, else { tcg_out32 (s, ADDIS | RT (ret) | RA (0) | ((arg >> 16) & 0xffff)); if (arg & 0xffff) - tcg_out32 (s, ORI | RT (ret) | RA (ret) | (arg & 0xffff)); + tcg_out32 (s, ORI | RS (ret) | RA (ret) | (arg & 0xffff)); } } @@ -939,18 +939,14 @@ static void tcg_out_brcond(TCGContext *s, int cond, tcg_out32 (s, op | RA (arg1) | RB (arg2)); } - if (l->has_value) { - tcg_target_long disp; - - disp = (tcg_target_long) s->code_ptr - l->u.value; - if (disp != (int16_t) disp) - tcg_abort (); - + if (l->has_value) tcg_out32 (s, tcg_to_bc[cond] | reloc_pc14_val (s->code_ptr, l->u.value)); - } else { - tcg_out32 (s, tcg_to_bc[cond]); + uint16_t val = *(uint16_t *) &s->code_ptr[2]; + + /* Thanks to Andrzej Zaborowski */ + tcg_out32 (s, tcg_to_bc[cond] | (val & 0xfffc)); tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0); } } @@ -1029,24 +1025,9 @@ static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, case INDEX_op_goto_tb: if (s->tb_jmp_offset) { /* direct jump method */ - uint32_t val; - uint16_t *p; s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf; - /* Thanks to Andrzej Zaborowski for this */ - val = *(uint32_t *) s->code_ptr & 0x3fffffc; - - tcg_out32 (s, B | val); - - /* For branches outside of LL range - This must be in concord with tb_set_jmp_target1 */ - p = (uint16_t *) s->code_ptr; - p[0] = (ADDIS | RT (0) | RA (0)) >> 16; - p[2] = (ORI | RT (0) | RA (0)) >> 16; - s->code_ptr += 8; - - tcg_out32 (s, MTSPR | RS (0) | CTR); - tcg_out32 (s, BCCTR | BO_ALWAYS); + s->code_ptr += 16; } else { tcg_abort (); @@ -1061,7 +1042,10 @@ static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, tcg_out_b (s, 0, l->u.value); } else { - tcg_out32 (s, B); + uint32_t val = *(uint32_t *) s->code_ptr; + + /* Thanks to Andrzej Zaborowski */ + tcg_out32 (s, B | (val & 0x3fffffc)); tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0); } } @@ -1222,10 +1206,10 @@ static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, case INDEX_op_div2_i32: if (args[0] == args[2] || args[0] == args[3]) { tcg_out32 (s, DIVW | TAB (0, args[2], args[3])); + tcg_out32 (s, MTSPR | RS (0) | CTR); tcg_out32 (s, MULLW | TAB (0, 0, args[3])); - tcg_out32 (s, SUBF | TAB (0, 0, args[2])); - tcg_out32 (s, DIVW | TAB (args[0], args[2], args[3])); - tcg_out_mov (s, args[1], 0); + tcg_out32 (s, SUBF | TAB (args[1], 0, args[2])); + tcg_out32 (s, MFSPR | RT (args[0]) | CTR); } else { tcg_out32 (s, DIVW | TAB (args[0], args[2], args[3])); @@ -1236,10 +1220,10 @@ static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, case INDEX_op_divu2_i32: if (args[0] == args[2] || args[0] == args[3]) { tcg_out32 (s, DIVWU | TAB (0, args[2], args[3])); + tcg_out32 (s, MTSPR | RS (0) | CTR); tcg_out32 (s, MULLW | TAB (0, 0, args[3])); - tcg_out32 (s, SUBF | TAB (0, 0, args[2])); - tcg_out32 (s, DIVWU | TAB (args[0], args[2], args[3])); - tcg_out_mov (s, args[1], 0); + tcg_out32 (s, SUBF | TAB (args[1], 0, args[2])); + tcg_out32 (s, MFSPR | RT (args[0]) | CTR); } else { tcg_out32 (s, DIVWU | TAB (args[0], args[2], args[3])); -- cgit v1.2.3 From d597536303d762c4209cbab7e379819b8eb14536 Mon Sep 17 00:00:00 2001 From: pbrook Date: Sat, 7 Jun 2008 20:50:51 +0000 Subject: Multithreaded locking fixes. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4692 c046a42c-6fe2-441c-8c8c-71466251a162 --- cpu-defs.h | 1 + cpu-exec.c | 25 +++--- exec-all.h | 212 +------------------------------------------ exec.c | 13 ++- linux-user/elfload.c | 4 +- linux-user/main.c | 146 ++++++++++++++++++++++++++++-- linux-user/mmap.c | 16 ++++ linux-user/qemu.h | 14 ++- linux-user/signal.c | 4 +- qemu-lock.h | 249 +++++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 447 insertions(+), 237 deletions(-) create mode 100644 qemu-lock.h diff --git a/cpu-defs.h b/cpu-defs.h index f7f5f1730..5804521a7 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -166,6 +166,7 @@ typedef struct CPUTLBEntry { \ void *next_cpu; /* next CPU sharing TB cache */ \ int cpu_index; /* CPU index (informative) */ \ + int running; /* Nonzero if cpu is currently running(usermode). */ \ /* user data */ \ void *opaque; \ \ diff --git a/cpu-exec.c b/cpu-exec.c index a8e67e8ad..3a1ff4e07 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -44,7 +44,6 @@ #endif int tb_invalidated_flag; -static unsigned long next_tb; //#define DEBUG_EXEC //#define DEBUG_SIGNAL @@ -93,8 +92,6 @@ static TranslationBlock *tb_find_slow(target_ulong pc, target_ulong phys_pc, phys_page1, phys_page2, virt_page2; uint8_t *tc_ptr; - spin_lock(&tb_lock); - tb_invalidated_flag = 0; regs_to_env(); /* XXX: do it just before cpu_gen_code() */ @@ -155,7 +152,6 @@ static TranslationBlock *tb_find_slow(target_ulong pc, found: /* we add the TB in the virtual pc hash table */ env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb; - spin_unlock(&tb_lock); return tb; } @@ -228,14 +224,6 @@ static inline TranslationBlock *tb_find_fast(void) if (__builtin_expect(!tb || tb->pc != pc || tb->cs_base != cs_base || tb->flags != flags, 0)) { tb = tb_find_slow(pc, cs_base, flags); - /* Note: we do it here to avoid a gcc bug on Mac OS X when - doing it in tb_find_slow */ - if (tb_invalidated_flag) { - /* as some TB could have been invalidated because - of memory exceptions while generating the code, we - must recompute the hash index here */ - next_tb = 0; - } } return tb; } @@ -249,6 +237,7 @@ int cpu_exec(CPUState *env1) int ret, interrupt_request; TranslationBlock *tb; uint8_t *tc_ptr; + unsigned long next_tb; if (cpu_halted(env1) == EXCP_HALTED) return EXCP_HALTED; @@ -577,7 +566,16 @@ int cpu_exec(CPUState *env1) #endif } #endif + spin_lock(&tb_lock); tb = tb_find_fast(); + /* Note: we do it here to avoid a gcc bug on Mac OS X when + doing it in tb_find_slow */ + if (tb_invalidated_flag) { + /* as some TB could have been invalidated because + of memory exceptions while generating the code, we + must recompute the hash index here */ + next_tb = 0; + } #ifdef DEBUG_EXEC if ((loglevel & CPU_LOG_EXEC)) { fprintf(logfile, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n", @@ -594,11 +592,10 @@ int cpu_exec(CPUState *env1) (env->kqemu_enabled != 2) && #endif tb->page_addr[1] == -1) { - spin_lock(&tb_lock); tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb); - spin_unlock(&tb_lock); } } + spin_unlock(&tb_lock); tc_ptr = tb->tc_ptr; env->current_tb = tb; /* execute the generated code */ diff --git a/exec-all.h b/exec-all.h index ba6f6da5a..62a939487 100644 --- a/exec-all.h +++ b/exec-all.h @@ -302,217 +302,7 @@ extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; -#if defined(__hppa__) - -typedef int spinlock_t[4]; - -#define SPIN_LOCK_UNLOCKED { 1, 1, 1, 1 } - -static inline void resetlock (spinlock_t *p) -{ - (*p)[0] = (*p)[1] = (*p)[2] = (*p)[3] = 1; -} - -#else - -typedef int spinlock_t; - -#define SPIN_LOCK_UNLOCKED 0 - -static inline void resetlock (spinlock_t *p) -{ - *p = SPIN_LOCK_UNLOCKED; -} - -#endif - -#if defined(__powerpc__) -static inline int testandset (int *p) -{ - int ret; - __asm__ __volatile__ ( - "0: lwarx %0,0,%1\n" - " xor. %0,%3,%0\n" - " bne 1f\n" - " stwcx. %2,0,%1\n" - " bne- 0b\n" - "1: " - : "=&r" (ret) - : "r" (p), "r" (1), "r" (0) - : "cr0", "memory"); - return ret; -} -#elif defined(__i386__) -static inline int testandset (int *p) -{ - long int readval = 0; - - __asm__ __volatile__ ("lock; cmpxchgl %2, %0" - : "+m" (*p), "+a" (readval) - : "r" (1) - : "cc"); - return readval; -} -#elif defined(__x86_64__) -static inline int testandset (int *p) -{ - long int readval = 0; - - __asm__ __volatile__ ("lock; cmpxchgl %2, %0" - : "+m" (*p), "+a" (readval) - : "r" (1) - : "cc"); - return readval; -} -#elif defined(__s390__) -static inline int testandset (int *p) -{ - int ret; - - __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" - " jl 0b" - : "=&d" (ret) - : "r" (1), "a" (p), "0" (*p) - : "cc", "memory" ); - return ret; -} -#elif defined(__alpha__) -static inline int testandset (int *p) -{ - int ret; - unsigned long one; - - __asm__ __volatile__ ("0: mov 1,%2\n" - " ldl_l %0,%1\n" - " stl_c %2,%1\n" - " beq %2,1f\n" - ".subsection 2\n" - "1: br 0b\n" - ".previous" - : "=r" (ret), "=m" (*p), "=r" (one) - : "m" (*p)); - return ret; -} -#elif defined(__sparc__) -static inline int testandset (int *p) -{ - int ret; - - __asm__ __volatile__("ldstub [%1], %0" - : "=r" (ret) - : "r" (p) - : "memory"); - - return (ret ? 1 : 0); -} -#elif defined(__arm__) -static inline int testandset (int *spinlock) -{ - register unsigned int ret; - __asm__ __volatile__("swp %0, %1, [%2]" - : "=r"(ret) - : "0"(1), "r"(spinlock)); - - return ret; -} -#elif defined(__mc68000) -static inline int testandset (int *p) -{ - char ret; - __asm__ __volatile__("tas %1; sne %0" - : "=r" (ret) - : "m" (p) - : "cc","memory"); - return ret; -} -#elif defined(__hppa__) - -/* Because malloc only guarantees 8-byte alignment for malloc'd data, - and GCC only guarantees 8-byte alignment for stack locals, we can't - be assured of 16-byte alignment for atomic lock data even if we - specify "__attribute ((aligned(16)))" in the type declaration. So, - we use a struct containing an array of four ints for the atomic lock - type and dynamically select the 16-byte aligned int from the array - for the semaphore. */ -#define __PA_LDCW_ALIGNMENT 16 -static inline void *ldcw_align (void *p) { - unsigned long a = (unsigned long)p; - a = (a + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); - return (void *)a; -} - -static inline int testandset (spinlock_t *p) -{ - unsigned int ret; - p = ldcw_align(p); - __asm__ __volatile__("ldcw 0(%1),%0" - : "=r" (ret) - : "r" (p) - : "memory" ); - return !ret; -} - -#elif defined(__ia64) - -#include - -static inline int testandset (int *p) -{ - return __sync_lock_test_and_set (p, 1); -} -#elif defined(__mips__) -static inline int testandset (int *p) -{ - int ret; - - __asm__ __volatile__ ( - " .set push \n" - " .set noat \n" - " .set mips2 \n" - "1: li $1, 1 \n" - " ll %0, %1 \n" - " sc $1, %1 \n" - " beqz $1, 1b \n" - " .set pop " - : "=r" (ret), "+R" (*p) - : - : "memory"); - - return ret; -} -#else -#error unimplemented CPU support -#endif - -#if defined(CONFIG_USER_ONLY) -static inline void spin_lock(spinlock_t *lock) -{ - while (testandset(lock)); -} - -static inline void spin_unlock(spinlock_t *lock) -{ - resetlock(lock); -} - -static inline int spin_trylock(spinlock_t *lock) -{ - return !testandset(lock); -} -#else -static inline void spin_lock(spinlock_t *lock) -{ -} - -static inline void spin_unlock(spinlock_t *lock) -{ -} - -static inline int spin_trylock(spinlock_t *lock) -{ - return 1; -} -#endif +#include "qemu-lock.h" extern spinlock_t tb_lock; diff --git a/exec.c b/exec.c index 4480dfa17..ffe4cc9da 100644 --- a/exec.c +++ b/exec.c @@ -1341,10 +1341,20 @@ void cpu_set_log_filename(const char *filename) /* mask must never be zero, except for A20 change call */ void cpu_interrupt(CPUState *env, int mask) { +#if !defined(USE_NPTL) TranslationBlock *tb; static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED; +#endif + /* FIXME: This is probably not threadsafe. A different thread could + be in the mittle of a read-modify-write operation. */ env->interrupt_request |= mask; +#if defined(USE_NPTL) + /* FIXME: TB unchaining isn't SMP safe. For now just ignore the + problem and hope the cpu will stop of its own accord. For userspace + emulation this often isn't actually as bad as it sounds. Often + signals are used primarily to interrupt blocking syscalls. */ +#else /* if the cpu is currently executing code, we must unlink it and all the potentially executing TB */ tb = env->current_tb; @@ -1353,6 +1363,7 @@ void cpu_interrupt(CPUState *env, int mask) tb_reset_jump_recursive(tb); resetlock(&interrupt_lock); } +#endif } void cpu_reset_interrupt(CPUState *env, int mask) @@ -2015,7 +2026,6 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) end = TARGET_PAGE_ALIGN(end); if (flags & PAGE_WRITE) flags |= PAGE_WRITE_ORG; - spin_lock(&tb_lock); for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) { p = page_find_alloc(addr >> TARGET_PAGE_BITS); /* if the write protection is set, then we invalidate the code @@ -2027,7 +2037,6 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) } p->flags = flags; } - spin_unlock(&tb_lock); } int page_check_range(target_ulong start, target_ulong len, int flags) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index ca0023e62..67b7535d4 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -89,7 +89,7 @@ enum { static const char *get_elf_platform(void) { static char elf_platform[] = "i386"; - int family = (global_env->cpuid_version >> 8) & 0xff; + int family = (thread_env->cpuid_version >> 8) & 0xff; if (family > 6) family = 6; if (family >= 3) @@ -101,7 +101,7 @@ static const char *get_elf_platform(void) static uint32_t get_elf_hwcap(void) { - return global_env->cpuid_features; + return thread_env->cpuid_features; } #ifdef TARGET_X86_64 diff --git a/linux-user/main.c b/linux-user/main.c index 4bdec7e9b..1f68766f0 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -26,6 +26,8 @@ #include "qemu.h" #include "qemu-common.h" +/* For tb_lock */ +#include "exec-all.h" #define DEBUG_LOGFILE "/tmp/qemu.log" @@ -123,6 +125,135 @@ int64_t cpu_get_real_ticks(void) #endif +#if defined(USE_NPTL) +/***********************************************************/ +/* Helper routines for implementing atomic operations. */ + +/* To implement exclusive operations we force all cpus to syncronise. + We don't require a full sync, only that no cpus are executing guest code. + The alternative is to map target atomic ops onto host equivalents, + which requires quite a lot of per host/target work. */ +static pthread_mutex_t exclusive_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t exclusive_cond = PTHREAD_COND_INITIALIZER; +static pthread_cond_t exclusive_resume = PTHREAD_COND_INITIALIZER; +static int pending_cpus; + +/* Make sure everything is in a consistent state for calling fork(). */ +void fork_start(void) +{ + mmap_fork_start(); + pthread_mutex_lock(&tb_lock); + pthread_mutex_lock(&exclusive_lock); +} + +void fork_end(int child) +{ + if (child) { + /* Child processes created by fork() only have a single thread. + Discard information about the parent threads. */ + first_cpu = thread_env; + thread_env->next_cpu = NULL; + pending_cpus = 0; + pthread_mutex_init(&exclusive_lock, NULL); + pthread_cond_init(&exclusive_cond, NULL); + pthread_cond_init(&exclusive_resume, NULL); + pthread_mutex_init(&tb_lock, NULL); + } else { + pthread_mutex_unlock(&exclusive_lock); + pthread_mutex_unlock(&tb_lock); + } + mmap_fork_end(child); +} + +/* Wait for pending exclusive operations to complete. The exclusive lock + must be held. */ +static inline void exclusive_idle(void) +{ + while (pending_cpus) { + pthread_cond_wait(&exclusive_resume, &exclusive_lock); + } +} + +/* Start an exclusive operation. + Must only be called from outside cpu_arm_exec. */ +static inline void start_exclusive(void) +{ + CPUState *other; + pthread_mutex_lock(&exclusive_lock); + exclusive_idle(); + + pending_cpus = 1; + /* Make all other cpus stop executing. */ + for (other = first_cpu; other; other = other->next_cpu) { + if (other->running) { + pending_cpus++; + cpu_interrupt(other, CPU_INTERRUPT_EXIT); + } + } + if (pending_cpus > 1) { + pthread_cond_wait(&exclusive_cond, &exclusive_lock); + } +} + +/* Finish an exclusive operation. */ +static inline void end_exclusive(void) +{ + pending_cpus = 0; + pthread_cond_broadcast(&exclusive_resume); + pthread_mutex_unlock(&exclusive_lock); +} + +/* Wait for exclusive ops to finish, and begin cpu execution. */ +static inline void cpu_exec_start(CPUState *env) +{ + pthread_mutex_lock(&exclusive_lock); + exclusive_idle(); + env->running = 1; + pthread_mutex_unlock(&exclusive_lock); +} + +/* Mark cpu as not executing, and release pending exclusive ops. */ +static inline void cpu_exec_end(CPUState *env) +{ + pthread_mutex_lock(&exclusive_lock); + env->running = 0; + if (pending_cpus > 1) { + pending_cpus--; + if (pending_cpus == 1) { + pthread_cond_signal(&exclusive_cond); + } + } + exclusive_idle(); + pthread_mutex_unlock(&exclusive_lock); +} +#else /* if !USE_NPTL */ +/* These are no-ops because we are not threadsafe. */ +static inline void cpu_exec_start(CPUState *env) +{ +} + +static inline void cpu_exec_end(CPUState *env) +{ +} + +static inline void start_exclusive(void) +{ +} + +static inline void end_exclusive(void) +{ +} + +void fork_start(void) +{ +} + +void fork_end(int child) +{ +} +#endif + + #ifdef TARGET_I386 /***********************************************************/ /* CPUX86 core interface */ @@ -378,8 +509,11 @@ do_kernel_trap(CPUARMState *env) /* ??? No-op. Will need to do better for SMP. */ break; case 0xffff0fc0: /* __kernel_cmpxchg */ - /* ??? This is not really atomic. However we don't support - threads anyway, so it doesn't realy matter. */ + /* XXX: This only works between threads, not between processes. + It's probably possible to implement this with native host + operations. However things like ldrex/strex are much harder so + there's not much point trying. */ + start_exclusive(); cpsr = cpsr_read(env); addr = env->regs[2]; /* FIXME: This should SEGV if the access fails. */ @@ -396,6 +530,7 @@ do_kernel_trap(CPUARMState *env) cpsr &= ~CPSR_C; } cpsr_write(env, cpsr, CPSR_C); + end_exclusive(); break; case 0xffff0fe0: /* __kernel_get_tls */ env->regs[0] = env->cp15.c13_tls2; @@ -422,7 +557,9 @@ void cpu_loop(CPUARMState *env) uint32_t addr; for(;;) { + cpu_exec_start(env); trapnr = cpu_arm_exec(env); + cpu_exec_end(env); switch(trapnr) { case EXCP_UDEF: { @@ -2044,8 +2181,7 @@ void usage(void) _exit(1); } -/* XXX: currently only used for async signals (see signal.c) */ -CPUState *global_env; +THREAD CPUState *thread_env; void init_task_state(TaskState *ts) { @@ -2203,7 +2339,7 @@ int main(int argc, char **argv) fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } - global_env = env; + thread_env = env; if (getenv("QEMU_STRACE")) { do_strace = 1; diff --git a/linux-user/mmap.c b/linux-user/mmap.c index c0821386d..b4ca1074b 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -46,6 +46,22 @@ void mmap_unlock(void) pthread_mutex_unlock(&mmap_mutex); } } + +/* Grab lock to make sure things are in a consistent state after fork(). */ +void mmap_fork_start(void) +{ + if (mmap_lock_count) + abort(); + pthread_mutex_lock(&mmap_mutex); +} + +void mmap_fork_end(int child) +{ + if (child) + pthread_mutex_init(&mmap_mutex, NULL); + else + pthread_mutex_unlock(&mmap_mutex); +} #else /* We aren't threadsafe to start with, so no need to worry about locking. */ void mmap_lock(void) diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 81f7fb290..d3a3c3c20 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -37,6 +37,12 @@ typedef target_long abi_long; #include "target_signal.h" #include "gdbstub.h" +#if defined(USE_NPTL) +#define THREAD __thread +#else +#define THREAD +#endif + /* This struct is used to hold certain information about the image. * Basically, it replicates in user space what would be certain * task_struct fields in the kernel @@ -184,12 +190,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6); void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2))); -extern CPUState *global_env; +extern THREAD CPUState *thread_env; void cpu_loop(CPUState *env); void init_paths(const char *prefix); const char *path(const char *pathname); char *target_strerror(int err); int get_osversion(void); +void fork_start(void); +void fork_end(int child); extern int loglevel; extern FILE *logfile; @@ -235,6 +243,10 @@ int target_msync(abi_ulong start, abi_ulong len, int flags); extern unsigned long last_brk; void mmap_lock(void); void mmap_unlock(void); +#if defined(USE_NPTL) +void mmap_fork_start(void); +void mmap_fork_end(int child); +#endif /* user access */ diff --git a/linux-user/signal.c b/linux-user/signal.c index e6e1a0826..623a5e31c 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -424,9 +424,9 @@ static void host_signal_handler(int host_signum, siginfo_t *info, fprintf(stderr, "qemu: got signal %d\n", sig); #endif host_to_target_siginfo_noswap(&tinfo, info); - if (queue_signal(global_env, sig, &tinfo) == 1) { + if (queue_signal(thread_env, sig, &tinfo) == 1) { /* interrupt the virtual CPU as soon as possible */ - cpu_interrupt(global_env, CPU_INTERRUPT_EXIT); + cpu_interrupt(thread_env, CPU_INTERRUPT_EXIT); } } diff --git a/qemu-lock.h b/qemu-lock.h new file mode 100644 index 000000000..fdd8da943 --- /dev/null +++ b/qemu-lock.h @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* Locking primitives. Most of this code should be redundant - + system emulation doesn't need/use locking, NPTL userspace uses + pthread mutexes, and non-NPTL userspace isn't threadsafe anyway. + In either case a spinlock is probably the wrong kind of lock. + Spinlocks are only good if you know annother CPU has the lock and is + likely to release it soon. In environments where you have more threads + than physical CPUs (the extreme case being a single CPU host) a spinlock + simply wastes CPU until the OS decides to preempt it. */ +#if defined(USE_NPTL) + +#include +#define spin_lock pthread_mutex_lock +#define spin_unlock pthread_mutex_unlock +#define spinlock_t pthread_mutex_t +#define SPIN_LOCK_UNLOCKED PTHREAD_MUTEX_INITIALIZER + +#else + +#if defined(__hppa__) + +typedef int spinlock_t[4]; + +#define SPIN_LOCK_UNLOCKED { 1, 1, 1, 1 } + +static inline void resetlock (spinlock_t *p) +{ + (*p)[0] = (*p)[1] = (*p)[2] = (*p)[3] = 1; +} + +#else + +typedef int spinlock_t; + +#define SPIN_LOCK_UNLOCKED 0 + +static inline void resetlock (spinlock_t *p) +{ + *p = SPIN_LOCK_UNLOCKED; +} + +#endif + +#if defined(__powerpc__) +static inline int testandset (int *p) +{ + int ret; + __asm__ __volatile__ ( + "0: lwarx %0,0,%1\n" + " xor. %0,%3,%0\n" + " bne 1f\n" + " stwcx. %2,0,%1\n" + " bne- 0b\n" + "1: " + : "=&r" (ret) + : "r" (p), "r" (1), "r" (0) + : "cr0", "memory"); + return ret; +} +#elif defined(__i386__) +static inline int testandset (int *p) +{ + long int readval = 0; + + __asm__ __volatile__ ("lock; cmpxchgl %2, %0" + : "+m" (*p), "+a" (readval) + : "r" (1) + : "cc"); + return readval; +} +#elif defined(__x86_64__) +static inline int testandset (int *p) +{ + long int readval = 0; + + __asm__ __volatile__ ("lock; cmpxchgl %2, %0" + : "+m" (*p), "+a" (readval) + : "r" (1) + : "cc"); + return readval; +} +#elif defined(__s390__) +static inline int testandset (int *p) +{ + int ret; + + __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n" + " jl 0b" + : "=&d" (ret) + : "r" (1), "a" (p), "0" (*p) + : "cc", "memory" ); + return ret; +} +#elif defined(__alpha__) +static inline int testandset (int *p) +{ + int ret; + unsigned long one; + + __asm__ __volatile__ ("0: mov 1,%2\n" + " ldl_l %0,%1\n" + " stl_c %2,%1\n" + " beq %2,1f\n" + ".subsection 2\n" + "1: br 0b\n" + ".previous" + : "=r" (ret), "=m" (*p), "=r" (one) + : "m" (*p)); + return ret; +} +#elif defined(__sparc__) +static inline int testandset (int *p) +{ + int ret; + + __asm__ __volatile__("ldstub [%1], %0" + : "=r" (ret) + : "r" (p) + : "memory"); + + return (ret ? 1 : 0); +} +#elif defined(__arm__) +static inline int testandset (int *spinlock) +{ + register unsigned int ret; + __asm__ __volatile__("swp %0, %1, [%2]" + : "=r"(ret) + : "0"(1), "r"(spinlock)); + + return ret; +} +#elif defined(__mc68000) +static inline int testandset (int *p) +{ + char ret; + __asm__ __volatile__("tas %1; sne %0" + : "=r" (ret) + : "m" (p) + : "cc","memory"); + return ret; +} +#elif defined(__hppa__) + +/* Because malloc only guarantees 8-byte alignment for malloc'd data, + and GCC only guarantees 8-byte alignment for stack locals, we can't + be assured of 16-byte alignment for atomic lock data even if we + specify "__attribute ((aligned(16)))" in the type declaration. So, + we use a struct containing an array of four ints for the atomic lock + type and dynamically select the 16-byte aligned int from the array + for the semaphore. */ +#define __PA_LDCW_ALIGNMENT 16 +static inline void *ldcw_align (void *p) { + unsigned long a = (unsigned long)p; + a = (a + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); + return (void *)a; +} + +static inline int testandset (spinlock_t *p) +{ + unsigned int ret; + p = ldcw_align(p); + __asm__ __volatile__("ldcw 0(%1),%0" + : "=r" (ret) + : "r" (p) + : "memory" ); + return !ret; +} + +#elif defined(__ia64) + +#include + +static inline int testandset (int *p) +{ + return __sync_lock_test_and_set (p, 1); +} +#elif defined(__mips__) +static inline int testandset (int *p) +{ + int ret; + + __asm__ __volatile__ ( + " .set push \n" + " .set noat \n" + " .set mips2 \n" + "1: li $1, 1 \n" + " ll %0, %1 \n" + " sc $1, %1 \n" + " beqz $1, 1b \n" + " .set pop " + : "=r" (ret), "+R" (*p) + : + : "memory"); + + return ret; +} +#else +#error unimplemented CPU support +#endif + +#if defined(CONFIG_USER_ONLY) +static inline void spin_lock(spinlock_t *lock) +{ + while (testandset(lock)); +} + +static inline void spin_unlock(spinlock_t *lock) +{ + resetlock(lock); +} + +static inline int spin_trylock(spinlock_t *lock) +{ + return !testandset(lock); +} +#else +static inline void spin_lock(spinlock_t *lock) +{ +} + +static inline void spin_unlock(spinlock_t *lock) +{ +} + +static inline int spin_trylock(spinlock_t *lock) +{ + return 1; +} +#endif + +#endif -- cgit v1.2.3 From d865bab55244797cce4f67a2a8196cbb0ceabc47 Mon Sep 17 00:00:00 2001 From: pbrook Date: Sat, 7 Jun 2008 22:12:17 +0000 Subject: Implement thread creation. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4693 c046a42c-6fe2-441c-8c8c-71466251a162 --- linux-user/syscall.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 137 insertions(+), 11 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 25b9e5a65..d02022887 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -74,6 +74,11 @@ #if defined(USE_NPTL) #include +#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \ + CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID) +#else +/* XXX: Hardcode the above values. */ +#define CLONE_NPTL_FLAGS2 0 #endif //#define DEBUG @@ -2706,6 +2711,48 @@ abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr) #endif /* defined(TARGET_I386) */ +#if defined(USE_NPTL) + +#define NEW_STACK_SIZE PTHREAD_STACK_MIN + +static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER; +typedef struct { + CPUState *env; + pthread_mutex_t mutex; + pthread_cond_t cond; + pthread_t thread; + uint32_t tid; + abi_ulong child_tidptr; + abi_ulong parent_tidptr; + sigset_t sigmask; +} new_thread_info; + +static void *clone_func(void *arg) +{ + new_thread_info *info = arg; + CPUState *env; + + env = info->env; + thread_env = env; + info->tid = gettid(); + if (info->child_tidptr) + put_user_u32(info->tid, info->child_tidptr); + if (info->parent_tidptr) + put_user_u32(info->tid, info->parent_tidptr); + /* Enable signals. */ + sigprocmask(SIG_SETMASK, &info->sigmask, NULL); + /* Signal to the parent that we're ready. */ + pthread_mutex_lock(&info->mutex); + pthread_cond_broadcast(&info->cond); + pthread_mutex_unlock(&info->mutex); + /* Wait until the parent has finshed initializing the tls state. */ + pthread_mutex_lock(&clone_lock); + pthread_mutex_unlock(&clone_lock); + cpu_loop(env); + /* never exits */ + return NULL; +} +#else /* this stack is the equivalent of the kernel stack associated with a thread/process */ #define NEW_STACK_SIZE 8192 @@ -2717,24 +2764,27 @@ static int clone_func(void *arg) /* never exits */ return 0; } +#endif /* do_fork() Must return host values and target errnos (unlike most do_*() functions). */ -int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp) +static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, + abi_ulong parent_tidptr, target_ulong newtls, + abi_ulong child_tidptr) { int ret; TaskState *ts; uint8_t *new_stack; CPUState *new_env; +#if defined(USE_NPTL) + unsigned int nptl_flags; + sigset_t sigmask; +#endif if (flags & CLONE_VM) { #if defined(USE_NPTL) - /* qemu is not threadsafe. Bail out immediately if application - tries to create a thread. */ - if (!(flags & CLONE_VFORK)) { - gemu_log ("clone(CLONE_VM) not supported\n"); - return -EINVAL; - } + new_thread_info info; + pthread_attr_t attr; #endif ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); init_task_state(ts); @@ -2744,19 +2794,94 @@ int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp) /* Init regs that differ from the parent. */ cpu_clone_regs(new_env, newsp); new_env->opaque = ts; +#if defined(USE_NPTL) + nptl_flags = flags; + flags &= ~CLONE_NPTL_FLAGS2; + + /* TODO: Implement CLONE_CHILD_CLEARTID. */ + if (nptl_flags & CLONE_SETTLS) + cpu_set_tls (new_env, newtls); + + /* Grab a mutex so that thread setup appears atomic. */ + pthread_mutex_lock(&clone_lock); + + memset(&info, 0, sizeof(info)); + pthread_mutex_init(&info.mutex, NULL); + pthread_mutex_lock(&info.mutex); + pthread_cond_init(&info.cond, NULL); + info.env = new_env; + if (nptl_flags & CLONE_CHILD_SETTID) + info.child_tidptr = child_tidptr; + if (nptl_flags & CLONE_PARENT_SETTID) + info.parent_tidptr = parent_tidptr; + + ret = pthread_attr_init(&attr); + ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE); + /* It is not safe to deliver signals until the child has finished + initializing, so temporarily block all signals. */ + sigfillset(&sigmask); + sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask); + + ret = pthread_create(&info.thread, &attr, clone_func, &info); + + sigprocmask(SIG_SETMASK, &info.sigmask, NULL); + pthread_attr_destroy(&attr); + if (ret == 0) { + /* Wait for the child to initialize. */ + pthread_cond_wait(&info.cond, &info.mutex); + ret = info.tid; + if (flags & CLONE_PARENT_SETTID) + put_user_u32(ret, parent_tidptr); + } else { + ret = -1; + } + pthread_mutex_unlock(&info.mutex); + pthread_cond_destroy(&info.cond); + pthread_mutex_destroy(&info.mutex); + pthread_mutex_unlock(&clone_lock); +#else + if (flags & CLONE_NPTL_FLAGS2) + return -EINVAL; + /* This is probably going to die very quickly, but do it anyway. */ #ifdef __ia64__ ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); #else ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); +#endif #endif } else { /* if no CLONE_VM, we consider it is a fork */ - if ((flags & ~CSIGNAL) != 0) + if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) return -EINVAL; + fork_start(); ret = fork(); +#if defined(USE_NPTL) + /* There is a race condition here. The parent process could + theoretically read the TID in the child process before the child + tid is set. This would require using either ptrace + (not implemented) or having *_tidptr to point at a shared memory + mapping. We can't repeat the spinlock hack used above because + the child process gets its own copy of the lock. */ + if (ret == 0) { + cpu_clone_regs(env, newsp); + fork_end(1); + /* Child Process. */ + if (flags & CLONE_CHILD_SETTID) + put_user_u32(gettid(), child_tidptr); + if (flags & CLONE_PARENT_SETTID) + put_user_u32(gettid(), parent_tidptr); + ts = (TaskState *)env->opaque; + if (flags & CLONE_SETTLS) + cpu_set_tls (env, newtls); + /* TODO: Implement CLONE_CHILD_CLEARTID. */ + } else { + fork_end(0); + } +#else if (ret == 0) { cpu_clone_regs(env, newsp); } +#endif } return ret; } @@ -3153,7 +3278,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = do_brk(arg1); break; case TARGET_NR_fork: - ret = get_errno(do_fork(cpu_env, SIGCHLD, 0)); + ret = get_errno(do_fork(cpu_env, SIGCHLD, 0, 0, 0, 0)); break; #ifdef TARGET_NR_waitpid case TARGET_NR_waitpid: @@ -4531,7 +4656,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = get_errno(fsync(arg1)); break; case TARGET_NR_clone: - ret = get_errno(do_fork(cpu_env, arg1, arg2)); + ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5)); break; #ifdef __NR_exit_group /* new thread calls */ @@ -4967,7 +5092,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_vfork case TARGET_NR_vfork: - ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0)); + ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, + 0, 0, 0, 0)); break; #endif #ifdef TARGET_NR_ugetrlimit -- cgit v1.2.3 From 2c44375d649910677dd9cdcf170f4dbaafa3f193 Mon Sep 17 00:00:00 2001 From: malc Date: Sun, 8 Jun 2008 01:07:48 +0000 Subject: Do not scare users with ominous error messages from AUD_open* Apparently Windows Server 2003 sets the frequency for either mc or pi voice to zero, which in turn triggers a call to audio_bug from this chain: open_voice -> AUD_open_in -> audio_bug (audio_validate_settings): A bug was just triggered in AUD_open_in ... Context: audio: frequency=0 nchannels=2 fmt=S16 endianness=little But since no attempt by the said OS is made to actually use the voice with zero frequency this can be considered normal behavior. Hence if zero freqency situation is encountered - close current voice, and make noises if the guest tries to use it. Reported by simon@...ve git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4694 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/ac97.c | 91 +++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 60 insertions(+), 31 deletions(-) diff --git a/hw/ac97.c b/hw/ac97.c index ba4ea1e51..83b438308 100644 --- a/hw/ac97.c +++ b/hw/ac97.c @@ -158,6 +158,7 @@ typedef struct AC97LinkState { SWVoiceIn *voice_pi; SWVoiceOut *voice_po; SWVoiceIn *voice_mc; + int invalid_freq[3]; uint8_t silence[128]; uint32_t base[2]; int bup_flag; @@ -360,39 +361,61 @@ static void open_voice (AC97LinkState *s, int index, int freq) as.fmt = AUD_FMT_S16; as.endianness = 0; - switch (index) { - case PI_INDEX: - s->voice_pi = AUD_open_in ( - &s->card, - s->voice_pi, - "ac97.pi", - s, - pi_callback, - &as - ); - break; + if (freq > 0) { + s->invalid_freq[index] = 0; + switch (index) { + case PI_INDEX: + s->voice_pi = AUD_open_in ( + &s->card, + s->voice_pi, + "ac97.pi", + s, + pi_callback, + &as + ); + break; - case PO_INDEX: - s->voice_po = AUD_open_out ( - &s->card, - s->voice_po, - "ac97.po", - s, - po_callback, - &as - ); - break; + case PO_INDEX: + s->voice_po = AUD_open_out ( + &s->card, + s->voice_po, + "ac97.po", + s, + po_callback, + &as + ); + break; - case MC_INDEX: - s->voice_mc = AUD_open_in ( - &s->card, - s->voice_mc, - "ac97.mc", - s, - mc_callback, - &as - ); - break; + case MC_INDEX: + s->voice_mc = AUD_open_in ( + &s->card, + s->voice_mc, + "ac97.mc", + s, + mc_callback, + &as + ); + break; + } + } + else { + s->invalid_freq[index] = freq; + switch (index) { + case PI_INDEX: + AUD_close_in (&s->card, s->voice_pi); + s->voice_pi = NULL; + break; + + case PO_INDEX: + AUD_close_out (&s->card, s->voice_po); + s->voice_po = NULL; + break; + + case MC_INDEX: + AUD_close_in (&s->card, s->voice_mc); + s->voice_mc = NULL; + break; + } } } @@ -1065,6 +1088,12 @@ static void transfer_audio (AC97LinkState *s, int index, int elapsed) AC97BusMasterRegs *r = &s->bm_regs[index]; int written = 0, stop = 0; + if (s->invalid_freq[index]) { + AUD_log ("ac97", "attempt to use voice %d with invalid frequency %d\n", + index, s->invalid_freq[index]); + return; + } + if (r->sr & SR_DCH) { if (r->cr & CR_RPBM) { switch (index) { -- cgit v1.2.3 From e2eef1703b536d42b89f8046faf7adeaa0e42ba1 Mon Sep 17 00:00:00 2001 From: pbrook Date: Sun, 8 Jun 2008 01:09:01 +0000 Subject: Remove dead and bitrotten "qemu-fast" code. Only build softmmu+MMIO handlers for system emulation. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4695 c046a42c-6fe2-441c-8c8c-71466251a162 --- exec.c | 138 ++++-------------------------------------------- target-cris/op_helper.c | 8 ++- 2 files changed, 16 insertions(+), 130 deletions(-) diff --git a/exec.c b/exec.c index ffe4cc9da..2cf0a6a5e 100644 --- a/exec.c +++ b/exec.c @@ -95,11 +95,13 @@ unsigned long code_gen_buffer_size; unsigned long code_gen_buffer_max_size; uint8_t *code_gen_ptr; +#if !defined(CONFIG_USER_ONLY) ram_addr_t phys_ram_size; int phys_ram_fd; uint8_t *phys_ram_base; uint8_t *phys_ram_dirty; static ram_addr_t phys_ram_alloc_offset = 0; +#endif CPUState *first_cpu; /* current CPU in the current thread. It is only valid inside @@ -137,8 +139,6 @@ typedef struct PhysPageDesc { #define L1_SIZE (1 << L1_BITS) #define L2_SIZE (1 << L2_BITS) -static void io_mem_init(void); - unsigned long qemu_real_host_page_size; unsigned long qemu_host_page_bits; unsigned long qemu_host_page_size; @@ -148,12 +148,14 @@ unsigned long qemu_host_page_mask; static PageDesc *l1_map[L1_SIZE]; PhysPageDesc **l1_phys_map; +#if !defined(CONFIG_USER_ONLY) +static void io_mem_init(void); + /* io memory support */ CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; void *io_mem_opaque[IO_MEM_NB_ENTRIES]; static int io_mem_nb; -#if defined(CONFIG_SOFTMMU) static int io_mem_watch; #endif @@ -408,7 +410,9 @@ void cpu_exec_init_all(unsigned long tb_size) code_gen_alloc(tb_size); code_gen_ptr = code_gen_buffer; page_init(); +#if !defined(CONFIG_USER_ONLY) io_mem_init(); +#endif } void cpu_exec_init(CPUState *env) @@ -1536,9 +1540,6 @@ void tlb_flush(CPUState *env, int flush_global) memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *)); -#if !defined(CONFIG_SOFTMMU) - munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START); -#endif #ifdef USE_KQEMU if (env->kqemu_enabled) { kqemu_flush(env, flush_global); @@ -1585,10 +1586,6 @@ void tlb_flush_page(CPUState *env, target_ulong addr) tlb_flush_jmp_cache(env, addr); -#if !defined(CONFIG_SOFTMMU) - if (addr < MMAP_AREA_END) - munmap((void *)addr, TARGET_PAGE_SIZE); -#endif #ifdef USE_KQEMU if (env->kqemu_enabled) { kqemu_flush_page(env, addr); @@ -1674,34 +1671,6 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, #endif #endif } - -#if !defined(CONFIG_SOFTMMU) - /* XXX: this is expensive */ - { - VirtPageDesc *p; - int j; - target_ulong addr; - - for(i = 0; i < L1_SIZE; i++) { - p = l1_virt_map[i]; - if (p) { - addr = i << (TARGET_PAGE_BITS + L2_BITS); - for(j = 0; j < L2_SIZE; j++) { - if (p->valid_tag == virt_valid_tag && - p->phys_addr >= start && p->phys_addr < end && - (p->prot & PROT_WRITE)) { - if (addr < MMAP_AREA_END) { - mprotect((void *)addr, TARGET_PAGE_SIZE, - p->prot & ~PROT_WRITE); - } - } - addr += TARGET_PAGE_SIZE; - p++; - } - } - } - } -#endif } static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry) @@ -1795,9 +1764,6 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, #endif ret = 0; -#if !defined(CONFIG_SOFTMMU) - if (is_softmmu) -#endif { if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { /* IO memory case */ @@ -1857,92 +1823,9 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, te->addr_write = -1; } } -#if !defined(CONFIG_SOFTMMU) - else { - if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) { - /* IO access: no mapping is done as it will be handled by the - soft MMU */ - if (!(env->hflags & HF_SOFTMMU_MASK)) - ret = 2; - } else { - void *map_addr; - - if (vaddr >= MMAP_AREA_END) { - ret = 2; - } else { - if (prot & PROT_WRITE) { - if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM || -#if defined(TARGET_HAS_SMC) || 1 - first_tb || -#endif - ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && - !cpu_physical_memory_is_dirty(pd))) { - /* ROM: we do as if code was inside */ - /* if code is present, we only map as read only and save the - original mapping */ - VirtPageDesc *vp; - - vp = virt_page_find_alloc(vaddr >> TARGET_PAGE_BITS, 1); - vp->phys_addr = pd; - vp->prot = prot; - vp->valid_tag = virt_valid_tag; - prot &= ~PAGE_WRITE; - } - } - map_addr = mmap((void *)vaddr, TARGET_PAGE_SIZE, prot, - MAP_SHARED | MAP_FIXED, phys_ram_fd, (pd & TARGET_PAGE_MASK)); - if (map_addr == MAP_FAILED) { - cpu_abort(env, "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n", - paddr, vaddr); - } - } - } - } -#endif return ret; } -/* called from signal handler: invalidate the code and unprotect the - page. Return TRUE if the fault was succesfully handled. */ -int page_unprotect(target_ulong addr, unsigned long pc, void *puc) -{ -#if !defined(CONFIG_SOFTMMU) - VirtPageDesc *vp; - -#if defined(DEBUG_TLB) - printf("page_unprotect: addr=0x%08x\n", addr); -#endif - addr &= TARGET_PAGE_MASK; - - /* if it is not mapped, no need to worry here */ - if (addr >= MMAP_AREA_END) - return 0; - vp = virt_page_find(addr >> TARGET_PAGE_BITS); - if (!vp) - return 0; - /* NOTE: in this case, validate_tag is _not_ tested as it - validates only the code TLB */ - if (vp->valid_tag != virt_valid_tag) - return 0; - if (!(vp->prot & PAGE_WRITE)) - return 0; -#if defined(DEBUG_TLB) - printf("page_unprotect: addr=0x%08x phys_addr=0x%08x prot=%x\n", - addr, vp->phys_addr, vp->prot); -#endif - if (mprotect((void *)addr, TARGET_PAGE_SIZE, vp->prot) < 0) - cpu_abort(cpu_single_env, "error mprotect addr=0x%lx prot=%d\n", - (unsigned long)addr, vp->prot); - /* set the dirty bit */ - phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 0xff; - /* flush the code inside */ - tb_invalidate_phys_page(vp->phys_addr, pc, puc); - return 1; -#else - return 0; -#endif -} - #else void tlb_flush(CPUState *env, int flush_global) @@ -2130,6 +2013,7 @@ static inline void tlb_set_dirty(CPUState *env, } #endif /* defined(CONFIG_USER_ONLY) */ +#if !defined(CONFIG_USER_ONLY) static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, ram_addr_t memory); static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, @@ -2387,7 +2271,6 @@ static CPUWriteMemoryFunc *notdirty_mem_write[3] = { notdirty_mem_writel, }; -#if defined(CONFIG_SOFTMMU) /* Watchpoint access routines. Watchpoints are inserted using TLB tricks, so these check for a hit then pass through to the normal out-of-line phys routines. */ @@ -2463,7 +2346,6 @@ static CPUWriteMemoryFunc *watch_mem_write[3] = { watch_mem_writew, watch_mem_writel, }; -#endif static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr, unsigned int len) @@ -2619,10 +2501,8 @@ static void io_mem_init(void) cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read, notdirty_mem_write, NULL); io_mem_nb = 5; -#if defined(CONFIG_SOFTMMU) io_mem_watch = cpu_register_io_memory(-1, watch_mem_read, watch_mem_write, NULL); -#endif /* alloc dirty bits array */ phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS); memset(phys_ram_dirty, 0xff, phys_ram_size >> TARGET_PAGE_BITS); @@ -2672,6 +2552,8 @@ CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index) return io_mem_read[io_index >> IO_MEM_SHIFT]; } +#endif /* !defined(CONFIG_USER_ONLY) */ + /* physical memory access (slow version, mainly for debug) */ #if defined(CONFIG_USER_ONLY) void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c index 21ee5ee1c..f5c0ed191 100644 --- a/target-cris/op_helper.c +++ b/target-cris/op_helper.c @@ -24,6 +24,10 @@ #include "mmu.h" #include "helper.h" +#define D(x) + +#if !defined(CONFIG_USER_ONLY) + #define MMUSUFFIX _mmu #define SHIFT 0 @@ -38,8 +42,6 @@ #define SHIFT 3 #include "softmmu_template.h" -#define D(x) - /* Try to fill the TLB and return an exception if error. If retaddr is NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ @@ -78,6 +80,8 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr) env = saved_env; } +#endif + void helper_raise_exception(uint32_t index) { env->exception_index = index; -- cgit v1.2.3 From 731ba0cec2ae7071da75902a8071ac718c86cb14 Mon Sep 17 00:00:00 2001 From: malc Date: Sun, 8 Jun 2008 01:42:47 +0000 Subject: Fix some signedness issues caught by gcc 4.3 git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4696 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/gus.c | 4 ++-- hw/gusemu.h | 4 +++- hw/gusemu_mixer.c | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/hw/gus.c b/hw/gus.c index 57753a7f5..c7a88463f 100644 --- a/hw/gus.c +++ b/hw/gus.c @@ -58,7 +58,7 @@ typedef struct GUSState { QEMUSoundCard card; int freq; int pos, left, shift, irqs; - uint16_t *mixbuf; + GUSsample *mixbuf; uint8_t himem[1024 * 1024 + 32 + 4096]; int samples; SWVoiceOut *voice; @@ -198,7 +198,7 @@ void GUS_dmarequest (GUSEmuState *der) int GUS_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len) { GUSState *s = opaque; - int8_t tmpbuf[4096]; + char tmpbuf[4096]; int pos = dma_pos, mode, left = dma_len - dma_pos; ldebug ("read DMA %#x %d\n", dma_pos, dma_len); diff --git a/hw/gusemu.h b/hw/gusemu.h index 2e9c1c0c7..a64300a09 100644 --- a/hw/gusemu.h +++ b/hw/gusemu.h @@ -32,12 +32,14 @@ typedef unsigned short GUSword; typedef unsigned int GUSdword; typedef signed char GUSchar; + typedef signed short GUSsample; #else #include typedef int8_t GUSchar; typedef uint8_t GUSbyte; typedef uint16_t GUSword; typedef uint32_t GUSdword; + typedef int16_t GUSsample; #endif typedef struct _GUSEmuState @@ -91,7 +93,7 @@ void gus_dma_transferdata(GUSEmuState *state, char *dma_addr, unsigned int count /* If the interrupts are asynchronous, it may be needed to use a separate thread mixing into a temporary */ /* audio buffer in order to avoid quality loss caused by large numsamples and elapsed_time values. */ -void gus_mixvoices(GUSEmuState *state, unsigned int playback_freq, unsigned int numsamples, short *bufferpos); +void gus_mixvoices(GUSEmuState *state, unsigned int playback_freq, unsigned int numsamples, GUSsample *bufferpos); /* recommended range: 10 < numsamples < 100 */ /* lower values may result in increased rounding error, higher values often cause audible timing delays */ diff --git a/hw/gusemu_mixer.c b/hw/gusemu_mixer.c index b3b5aa5d7..6d8d9ced1 100644 --- a/hw/gusemu_mixer.c +++ b/hw/gusemu_mixer.c @@ -33,7 +33,7 @@ /* samples are always 16bit stereo (4 bytes each, first right then left interleaved) */ void gus_mixvoices(GUSEmuState * state, unsigned int playback_freq, unsigned int numsamples, - short *bufferpos) + GUSsample *bufferpos) { /* note that byte registers are stored in the upper half of each voice register! */ GUSbyte *gusptr; @@ -170,8 +170,8 @@ void gus_mixvoices(GUSEmuState * state, unsigned int playback_freq, unsigned int } /* mix samples into buffer */ - *(bufferpos + 2 * sample) += (short) ((sample1 * PanningPos) >> 4); /* right */ - *(bufferpos + 2 * sample + 1) += (short) ((sample1 * (15 - PanningPos)) >> 4); /* left */ + *(bufferpos + 2 * sample) += (GUSsample) ((sample1 * PanningPos) >> 4); /* right */ + *(bufferpos + 2 * sample + 1) += (GUSsample) ((sample1 * (15 - PanningPos)) >> 4); /* left */ } /* write back voice and volume */ GUSvoice(wVSRCurrVol) = Volume32 / 32; -- cgit v1.2.3 From 0e6745890ccfaaf1cfb591d3ad230a99a4e3c660 Mon Sep 17 00:00:00 2001 From: malc Date: Sun, 8 Jun 2008 01:55:07 +0000 Subject: Update git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4697 c046a42c-6fe2-441c-8c8c-71466251a162 --- Changelog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Changelog b/Changelog index 0ed5bcbc0..44c79942c 100644 --- a/Changelog +++ b/Changelog @@ -2,6 +2,8 @@ - Braille support (Samuel Thibault) - Freecom MusicPal system emulation (Jan Kiszka) - OMAP242x and Nokia N800, N810 machines (Andrzej Zaborowski) + - EsounD audio driver (Frederick Reeve) + - Gravis Ultrasound GF1 sound card (Tibor "TS" Schütz) version 0.9.1: -- cgit v1.2.3 From 7fb2a862f40a9615f8ae5bc3f8c0c2d33ee8db91 Mon Sep 17 00:00:00 2001 From: malc Date: Sun, 8 Jun 2008 01:55:09 +0000 Subject: Fix error reporting under Win32 (CreateFile does not set errno) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4698 c046a42c-6fe2-441c-8c8c-71466251a162 --- kqemu.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kqemu.c b/kqemu.c index 540aa3cc5..4783aa2a0 100644 --- a/kqemu.c +++ b/kqemu.c @@ -166,14 +166,19 @@ int kqemu_init(CPUState *env) FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (kqemu_fd == KQEMU_INVALID_FD) { + fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %lu\n", + KQEMU_DEVICE, GetLastError()); + return -1; + } #else kqemu_fd = open(KQEMU_DEVICE, O_RDWR); -#endif if (kqemu_fd == KQEMU_INVALID_FD) { fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %s\n", KQEMU_DEVICE, strerror(errno)); return -1; } +#endif version = 0; #ifdef _WIN32 DeviceIoControl(kqemu_fd, KQEMU_GET_VERSION, NULL, 0, -- cgit v1.2.3 From 29ddf27b72960d6e6b115cd69812c9c57b2a7b13 Mon Sep 17 00:00:00 2001 From: malc Date: Sun, 8 Jun 2008 04:27:56 +0000 Subject: Check the returned audio_buf_info fields At least on one system zero is returned in either fragsize or fragstotal (reported by Dave Scott), this results in an audio_calloc failing the audio_bug check and another ominous error message. Fail early and blame the system. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4699 c046a42c-6fe2-441c-8c8c-71466251a162 --- audio/ossaudio.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/audio/ossaudio.c b/audio/ossaudio.c index 2a300c21d..a29b4bc17 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -254,6 +254,12 @@ static int oss_open (int in, struct oss_params *req, goto err; } + if (!abinfo.fragstotal || !abinfo.fragsize) { + AUD_log (AUDIO_CAP, "Returned bogus buffer information(%d, %d) for %s\n", + abinfo.fragstotal, abinfo.fragsize, typ); + goto err; + } + obt->fmt = fmt; obt->nchannels = nchannels; obt->freq = freq; -- cgit v1.2.3 From 7dd9e556e396a6c12a1d31e53ba98a2a90c4e73d Mon Sep 17 00:00:00 2001 From: ths Date: Sun, 8 Jun 2008 07:42:23 +0000 Subject: Register helper functions. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4700 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/helper.h | 20 +++++++++++++------- target-mips/translate.c | 5 +++++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/target-mips/helper.h b/target-mips/helper.h index 98a97c9be..cee92fc82 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -1,8 +1,14 @@ -void do_raise_exception_err(int excp, int err); -void do_raise_exception(int excp); -void do_interrupt_restart (void); +#ifndef DEF_HELPER +#define DEF_HELPER(ret, name, params) ret name params; +#endif -void do_clo (void); -void do_clz (void); -void do_dclo (void); -void do_dclz (void); +DEF_HELPER(void, do_raise_exception_err, (int excp, int err)) +DEF_HELPER(void, do_raise_exception, (int excp)) +DEF_HELPER(void, do_interrupt_restart, (void)) + +DEF_HELPER(void, do_clo, (void)) +DEF_HELPER(void, do_clz, (void)) +#ifdef TARGET_MIPS64 +DEF_HELPER(void, do_dclo, (void)) +DEF_HELPER(void, do_dclz, (void)) +#endif diff --git a/target-mips/translate.c b/target-mips/translate.c index f0dc14d82..e6b3f547c 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -7476,6 +7476,11 @@ static void mips_tcg_init(void) cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1"); #endif + /* register helpers */ +#undef DEF_HELPER +#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name); +#include "helper.h" + inited = 1; } -- cgit v1.2.3 From c8256f9d23bba4fac3b0b6a9e6e3dc12362cbe0b Mon Sep 17 00:00:00 2001 From: balrog Date: Sun, 8 Jun 2008 22:45:01 +0000 Subject: Enhance sendkey with key hold time (Jan Kiszka). Current key injection via the monitor basically generates no key hold time. This is fine for keyboard emulations that have their own queues, but it causes troubles for those how don't (like the MusicPal - it simply does not work with injected keys). Moreover, I would like to use this mechanism to simulate pressed buttons during power-up. Therefore, this patch enhances the key injection with a configurable release delay (by default 100 virtual milliseconds). This feature allows to get rid of the initial sleep() in musicpal_init because one can now simply start qemu with -S and issue "sendkey m 1000" and "continue" in the monitor to achieve the desired effect of a pressed menu button during power-up. So there is no need for a per-musicpal or even qemu-wide "-hold-button" switch. Signed-off-by: Jan Kiszka git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4701 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/musicpal.c | 6 ------ monitor.c | 58 +++++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/hw/musicpal.c b/hw/musicpal.c index 211c84936..b0fcee25b 100644 --- a/hw/musicpal.c +++ b/hw/musicpal.c @@ -1504,12 +1504,6 @@ static void musicpal_init(ram_addr_t ram_size, int vga_ram_size, qemu_add_kbd_event_handler(musicpal_key_event, pic[MP_GPIO_IRQ]); - /* - * Wait a bit to catch menu button during U-Boot start-up - * (to trigger emergency update). - */ - sleep(1); - mv88w8618_eth_init(&nd_table[0], MP_ETH_BASE, pic[MP_ETH_IRQ]); mixer_i2c = musicpal_audio_init(MP_AUDIO_BASE, pic[MP_AUDIO_IRQ]); diff --git a/monitor.c b/monitor.c index e6abcdd72..002fc0286 100644 --- a/monitor.c +++ b/monitor.c @@ -35,10 +35,7 @@ #include "audio/audio.h" #include "disas.h" #include - -#ifdef CONFIG_PROFILER -#include "qemu-timer.h" /* for ticks_per_sec */ -#endif +#include "qemu-timer.h" //#define DEBUG //#define DEBUG_COMPLETION @@ -920,14 +917,37 @@ static int get_keycode(const char *key) return -1; } -static void do_sendkey(const char *string) +#define MAX_KEYCODES 16 +static uint8_t keycodes[MAX_KEYCODES]; +static int nb_pending_keycodes; +static QEMUTimer *key_timer; + +static void release_keys(void *opaque) +{ + int keycode; + + while (nb_pending_keycodes > 0) { + nb_pending_keycodes--; + keycode = keycodes[nb_pending_keycodes]; + if (keycode & 0x80) + kbd_put_keycode(0xe0); + kbd_put_keycode(keycode | 0x80); + } +} + +static void do_sendkey(const char *string, int has_hold_time, int hold_time) { - uint8_t keycodes[16]; - int nb_keycodes = 0; char keyname_buf[16]; char *separator; int keyname_len, keycode, i; + if (nb_pending_keycodes > 0) { + qemu_del_timer(key_timer); + release_keys(NULL); + } + if (!has_hold_time) + hold_time = 100; + i = 0; while (1) { separator = strchr(string, '-'); keyname_len = separator ? separator - string : strlen(string); @@ -937,7 +957,7 @@ static void do_sendkey(const char *string) term_printf("invalid key: '%s...'\n", keyname_buf); return; } - if (nb_keycodes == sizeof(keycodes)) { + if (i == MAX_KEYCODES) { term_printf("too many keys\n"); return; } @@ -947,26 +967,23 @@ static void do_sendkey(const char *string) term_printf("unknown key: '%s'\n", keyname_buf); return; } - keycodes[nb_keycodes++] = keycode; + keycodes[i++] = keycode; } if (!separator) break; string = separator + 1; } + nb_pending_keycodes = i; /* key down events */ - for(i = 0; i < nb_keycodes; i++) { + for (i = 0; i < nb_pending_keycodes; i++) { keycode = keycodes[i]; if (keycode & 0x80) kbd_put_keycode(0xe0); kbd_put_keycode(keycode & 0x7f); } - /* key up events */ - for(i = nb_keycodes - 1; i >= 0; i--) { - keycode = keycodes[i]; - if (keycode & 0x80) - kbd_put_keycode(0xe0); - kbd_put_keycode(keycode | 0x80); - } + /* delayed key up events */ + qemu_mod_timer(key_timer, + qemu_get_clock(vm_clock) + ticks_per_sec * hold_time); } static int mouse_button_state; @@ -1353,8 +1370,8 @@ static term_cmd_t term_cmds[] = { { "i", "/ii.", do_ioport_read, "/fmt addr", "I/O port read" }, - { "sendkey", "s", do_sendkey, - "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" }, + { "sendkey", "si?", do_sendkey, + "keys [hold_ms]", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms)" }, { "system_reset", "", do_system_reset, "", "reset the system" }, { "system_powerdown", "", do_system_powerdown, @@ -2638,6 +2655,9 @@ void monitor_init(CharDriverState *hd, int show_banner) int i; if (is_first_init) { + key_timer = qemu_new_timer(vm_clock, release_keys, NULL); + if (!key_timer) + return; for (i = 0; i < MAX_MON; i++) { monitor_hd[i] = NULL; } -- cgit v1.2.3 From 88d2c950b002a3976cd5673b0214006e72cae191 Mon Sep 17 00:00:00 2001 From: balrog Date: Mon, 9 Jun 2008 00:03:13 +0000 Subject: TC6393XB system features (Dmitry Baryshkov). Add basic support for TC6393XB system features. No support for GPIO input though. Signed-off-by: Dmitry Baryshkov git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4702 c046a42c-6fe2-441c-8c8c-71466251a162 --- Makefile.target | 2 +- hw/devices.h | 7 ++ hw/tc6393xb.c | 291 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/tosa.c | 38 +------- 4 files changed, 301 insertions(+), 37 deletions(-) create mode 100644 hw/tc6393xb.c diff --git a/Makefile.target b/Makefile.target index e06a99e50..e1cd403eb 100644 --- a/Makefile.target +++ b/Makefile.target @@ -585,7 +585,7 @@ OBJS+= arm-semi.o OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o OBJS+= pflash_cfi01.o gumstix.o -OBJS+= zaurus.o ide.o serial.o nand.o ecc.o spitz.o tosa.o +OBJS+= zaurus.o ide.o serial.o nand.o ecc.o spitz.o tosa.o tc6393xb.o OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o OBJS+= omap2.o omap_dss.o OBJS+= palm.o tsc210x.o diff --git a/hw/devices.h b/hw/devices.h index 948abc5fa..45fead9c2 100644 --- a/hw/devices.h +++ b/hw/devices.h @@ -64,4 +64,11 @@ int tusb6010_sync_io(struct tusb_s *s); int tusb6010_async_io(struct tusb_s *s); void tusb6010_power(struct tusb_s *s, int on); +/* tc6393xb.c */ +struct tc6393xb_s; +struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq); +void tc6393xb_gpio_out_set(struct tc6393xb_s *s, int line, + qemu_irq handler); +qemu_irq *tc6393xb_gpio_in_get(struct tc6393xb_s *s); + #endif diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c new file mode 100644 index 000000000..189369467 --- /dev/null +++ b/hw/tc6393xb.c @@ -0,0 +1,291 @@ +/* vim:set shiftwidth=4 ts=4 et: */ +#include "hw.h" +#include "pxa.h" +#include "devices.h" + +#define TC6393XB_GPIOS 16 + +#define SCR_REVID 0x08 /* b Revision ID */ +#define SCR_ISR 0x50 /* b Interrupt Status */ +#define SCR_IMR 0x52 /* b Interrupt Mask */ +#define SCR_IRR 0x54 /* b Interrupt Routing */ +#define SCR_GPER 0x60 /* w GP Enable */ +#define SCR_GPI_SR(i) (0x64 + (i)) /* b3 GPI Status */ +#define SCR_GPI_IMR(i) (0x68 + (i)) /* b3 GPI INT Mask */ +#define SCR_GPI_EDER(i) (0x6c + (i)) /* b3 GPI Edge Detect Enable */ +#define SCR_GPI_LIR(i) (0x70 + (i)) /* b3 GPI Level Invert */ +#define SCR_GPO_DSR(i) (0x78 + (i)) /* b3 GPO Data Set */ +#define SCR_GPO_DOECR(i) (0x7c + (i)) /* b3 GPO Data OE Control */ +#define SCR_GP_IARCR(i) (0x80 + (i)) /* b3 GP Internal Active Register Control */ +#define SCR_GP_IARLCR(i) (0x84 + (i)) /* b3 GP INTERNAL Active Register Level Control */ +#define SCR_GPI_BCR(i) (0x88 + (i)) /* b3 GPI Buffer Control */ +#define SCR_GPA_IARCR 0x8c /* w GPa Internal Active Register Control */ +#define SCR_GPA_IARLCR 0x90 /* w GPa Internal Active Register Level Control */ +#define SCR_GPA_BCR 0x94 /* w GPa Buffer Control */ +#define SCR_CCR 0x98 /* w Clock Control */ +#define SCR_PLL2CR 0x9a /* w PLL2 Control */ +#define SCR_PLL1CR 0x9c /* l PLL1 Control */ +#define SCR_DIARCR 0xa0 /* b Device Internal Active Register Control */ +#define SCR_DBOCR 0xa1 /* b Device Buffer Off Control */ +#define SCR_FER 0xe0 /* b Function Enable */ +#define SCR_MCR 0xe4 /* w Mode Control */ +#define SCR_CONFIG 0xfc /* b Configuration Control */ +#define SCR_DEBUG 0xff /* b Debug */ + +struct tc6393xb_s { + target_phys_addr_t target_base; + struct { + uint8_t ISR; + uint8_t IMR; + uint8_t IRR; + uint16_t GPER; + uint8_t GPI_SR[3]; + uint8_t GPI_IMR[3]; + uint8_t GPI_EDER[3]; + uint8_t GPI_LIR[3]; + uint8_t GP_IARCR[3]; + uint8_t GP_IARLCR[3]; + uint8_t GPI_BCR[3]; + uint16_t GPA_IARCR; + uint16_t GPA_IARLCR; + uint16_t CCR; + uint16_t PLL2CR; + uint32_t PLL1CR; + uint8_t DIARCR; + uint8_t DBOCR; + uint8_t FER; + uint16_t MCR; + uint8_t CONFIG; + uint8_t DEBUG; + } scr; + uint32_t gpio_dir; + uint32_t gpio_level; + uint32_t prev_level; + qemu_irq handler[TC6393XB_GPIOS]; + qemu_irq *gpio_in; +}; + +qemu_irq *tc6393xb_gpio_in_get(struct tc6393xb_s *s) +{ + return s->gpio_in; +} + +static void tc6393xb_gpio_set(void *opaque, int line, int level) +{ +// struct tc6393xb_s *s = opaque; + + if (line > TC6393XB_GPIOS) { + printf("%s: No GPIO pin %i\n", __FUNCTION__, line); + return; + } + + // FIXME: how does the chip reflect the GPIO input level change? +} + +void tc6393xb_gpio_out_set(struct tc6393xb_s *s, int line, + qemu_irq handler) +{ + if (line >= TC6393XB_GPIOS) { + fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line); + return; + } + + s->handler[line] = handler; +} + +static void tc6393xb_gpio_handler_update(struct tc6393xb_s *s) +{ + uint32_t level, diff; + int bit; + + level = s->gpio_level & s->gpio_dir; + + for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) { + bit = ffs(diff) - 1; + qemu_set_irq(s->handler[bit], (level >> bit) & 1); + } + + s->prev_level = level; +} + +#define SCR_REG_B(N) \ + case SCR_ ##N: return s->scr.N +#define SCR_REG_W(N) \ + case SCR_ ##N: return s->scr.N; \ + case SCR_ ##N + 1: return s->scr.N >> 8; +#define SCR_REG_L(N) \ + case SCR_ ##N: return s->scr.N; \ + case SCR_ ##N + 1: return s->scr.N >> 8; \ + case SCR_ ##N + 2: return s->scr.N >> 16; \ + case SCR_ ##N + 3: return s->scr.N >> 24; +#define SCR_REG_A(N) \ + case SCR_ ##N(0): return s->scr.N[0]; \ + case SCR_ ##N(1): return s->scr.N[1]; \ + case SCR_ ##N(2): return s->scr.N[2] + +static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) +{ + struct tc6393xb_s *s = opaque; + addr -= s->target_base; + switch (addr) { + case SCR_REVID: + return 3; + case SCR_REVID+1: + return 0; + SCR_REG_B(ISR); + SCR_REG_B(IMR); + SCR_REG_B(IRR); + SCR_REG_W(GPER); + SCR_REG_A(GPI_SR); + SCR_REG_A(GPI_IMR); + SCR_REG_A(GPI_EDER); + SCR_REG_A(GPI_LIR); + case SCR_GPO_DSR(0): + case SCR_GPO_DSR(1): + case SCR_GPO_DSR(2): + return (s->gpio_level >> ((addr - SCR_GPO_DSR(0)) * 8)) & 0xff; + case SCR_GPO_DOECR(0): + case SCR_GPO_DOECR(1): + case SCR_GPO_DOECR(2): + return (s->gpio_dir >> ((addr - SCR_GPO_DOECR(0)) * 8)) & 0xff; + SCR_REG_A(GP_IARCR); + SCR_REG_A(GP_IARLCR); + SCR_REG_A(GPI_BCR); + SCR_REG_W(GPA_IARCR); + SCR_REG_W(GPA_IARLCR); + SCR_REG_W(CCR); + SCR_REG_W(PLL2CR); + SCR_REG_L(PLL1CR); + SCR_REG_B(DIARCR); + SCR_REG_B(DBOCR); + SCR_REG_B(FER); + SCR_REG_W(MCR); + SCR_REG_B(CONFIG); + SCR_REG_B(DEBUG); + } + fprintf(stderr, "tc6393xb: unhandled read at %08x\n", (uint32_t) addr); + return 0; +} +#undef SCR_REG_B +#undef SCR_REG_W +#undef SCR_REG_L +#undef SCR_REG_A + +#define SCR_REG_B(N) \ + case SCR_ ##N: s->scr.N = value; break; +#define SCR_REG_W(N) \ + case SCR_ ##N: s->scr.N = (s->scr.N & ~0xff) | (value & 0xff); break; \ + case SCR_ ##N + 1: s->scr.N = (s->scr.N & 0xff) | (value << 8); break +#define SCR_REG_L(N) \ + case SCR_ ##N: s->scr.N = (s->scr.N & ~0xff) | (value & 0xff); break; \ + case SCR_ ##N + 1: s->scr.N = (s->scr.N & ~(0xff << 8)) | (value & (0xff << 8)); break; \ + case SCR_ ##N + 2: s->scr.N = (s->scr.N & ~(0xff << 16)) | (value & (0xff << 16)); break; \ + case SCR_ ##N + 3: s->scr.N = (s->scr.N & ~(0xff << 24)) | (value & (0xff << 24)); break; +#define SCR_REG_A(N) \ + case SCR_ ##N(0): s->scr.N[0] = value; break; \ + case SCR_ ##N(1): s->scr.N[1] = value; break; \ + case SCR_ ##N(2): s->scr.N[2] = value; break + +static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr, uint32_t value) +{ + struct tc6393xb_s *s = opaque; + addr -= s->target_base; + switch (addr) { + SCR_REG_B(ISR); + SCR_REG_B(IMR); + SCR_REG_B(IRR); + SCR_REG_W(GPER); + SCR_REG_A(GPI_SR); + SCR_REG_A(GPI_IMR); + SCR_REG_A(GPI_EDER); + SCR_REG_A(GPI_LIR); + case SCR_GPO_DSR(0): + case SCR_GPO_DSR(1): + case SCR_GPO_DSR(2): + s->gpio_level = (s->gpio_level & ~(0xff << ((addr - SCR_GPO_DSR(0))*8))) | ((value & 0xff) << ((addr - SCR_GPO_DSR(0))*8)); + tc6393xb_gpio_handler_update(s); + break; + case SCR_GPO_DOECR(0): + case SCR_GPO_DOECR(1): + case SCR_GPO_DOECR(2): + s->gpio_dir = (s->gpio_dir & ~(0xff << ((addr - SCR_GPO_DOECR(0))*8))) | ((value & 0xff) << ((addr - SCR_GPO_DOECR(0))*8)); + tc6393xb_gpio_handler_update(s); + break; + SCR_REG_A(GP_IARCR); + SCR_REG_A(GP_IARLCR); + SCR_REG_A(GPI_BCR); + SCR_REG_W(GPA_IARCR); + SCR_REG_W(GPA_IARLCR); + SCR_REG_W(CCR); + SCR_REG_W(PLL2CR); + SCR_REG_L(PLL1CR); + SCR_REG_B(DIARCR); + SCR_REG_B(DBOCR); + SCR_REG_B(FER); + SCR_REG_W(MCR); + SCR_REG_B(CONFIG); + SCR_REG_B(DEBUG); + default: + fprintf(stderr, "tc6393xb: unhandled write at %08x: %02x\n", + (uint32_t) addr, value & 0xff); + break; + } +} +#undef SCR_REG_B +#undef SCR_REG_W +#undef SCR_REG_L +#undef SCR_REG_A + +static uint32_t tc6393xb_readw(void *opaque, target_phys_addr_t addr) +{ + return (tc6393xb_readb(opaque, addr) & 0xff) | + (tc6393xb_readb(opaque, addr + 1) << 8); +} + +static uint32_t tc6393xb_readl(void *opaque, target_phys_addr_t addr) +{ + return (tc6393xb_readb(opaque, addr) & 0xff) | + ((tc6393xb_readb(opaque, addr + 1) & 0xff) << 8) | + ((tc6393xb_readb(opaque, addr + 2) & 0xff) << 16) | + ((tc6393xb_readb(opaque, addr + 3) & 0xff) << 24); +} + +static void tc6393xb_writew(void *opaque, target_phys_addr_t addr, uint32_t value) +{ + tc6393xb_writeb(opaque, addr, value); + tc6393xb_writeb(opaque, addr + 1, value >> 8); +} + +static void tc6393xb_writel(void *opaque, target_phys_addr_t addr, uint32_t value) +{ + tc6393xb_writeb(opaque, addr, value); + tc6393xb_writeb(opaque, addr + 1, value >> 8); + tc6393xb_writeb(opaque, addr + 2, value >> 16); + tc6393xb_writeb(opaque, addr + 3, value >> 24); +} + +struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq) +{ + int iomemtype; + struct tc6393xb_s *s; + CPUReadMemoryFunc *tc6393xb_readfn[] = { + tc6393xb_readb, + tc6393xb_readw, + tc6393xb_readl, + }; + CPUWriteMemoryFunc *tc6393xb_writefn[] = { + tc6393xb_writeb, + tc6393xb_writew, + tc6393xb_writel, + }; + + s = (struct tc6393xb_s *) qemu_mallocz(sizeof(struct tc6393xb_s)); + s->target_base = base; + s->gpio_in = qemu_allocate_irqs(tc6393xb_gpio_set, s, TC6393XB_GPIOS); + + iomemtype = cpu_register_io_memory(0, tc6393xb_readfn, + tc6393xb_writefn, s); + cpu_register_physical_memory(s->target_base, 0x200000, iomemtype); + + return s; +} diff --git a/hw/tosa.c b/hw/tosa.c index 97d41ece8..f67d67e19 100644 --- a/hw/tosa.c +++ b/hw/tosa.c @@ -12,6 +12,7 @@ #include "pxa.h" #include "arm-misc.h" #include "sysemu.h" +#include "devices.h" #include "sharpsl.h" #include "pcmcia.h" #include "block.h" @@ -31,41 +32,6 @@ #define TOSA_GPIO_SD_WP (TOSA_SCOOP_GPIO_BASE + 3) #define TOSA_GPIO_PWR_ON (TOSA_SCOOP_GPIO_BASE + 4) -struct tc6393xb_s { - target_phys_addr_t target_base; -}; - -static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) -{ - return 3; -} -static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr, - uint32_t value) -{ -} -static void tosa_tc6393xb_register(struct pxa2xx_state_s *cpu) -{ - int iomemtype; - struct tc6393xb_s *s; - CPUReadMemoryFunc *tc6393xb_readfn[] = { - tc6393xb_readb, - tc6393xb_readb, - tc6393xb_readb, - }; - CPUWriteMemoryFunc *tc6393xb_writefn[] = { - tc6393xb_writeb, - tc6393xb_writeb, - tc6393xb_writeb, - }; - - s = (struct tc6393xb_s *) qemu_mallocz(sizeof(struct tc6393xb_s)); - s->target_base = 0x10000000; - - iomemtype = cpu_register_io_memory(0, tc6393xb_readfn, - tc6393xb_writefn, s); - cpu_register_physical_memory(s->target_base, 0x200000, iomemtype); -} - static void tosa_microdrive_attach(struct pxa2xx_state_s *cpu) { struct pcmcia_card_s *md; @@ -132,7 +98,7 @@ static void tosa_init(ram_addr_t ram_size, int vga_ram_size, cpu_register_physical_memory(0, TOSA_ROM, qemu_ram_alloc(TOSA_ROM) | IO_MEM_ROM); - tosa_tc6393xb_register(cpu); + tc6393xb_init(0x10000000, NULL); scp0 = scoop_init(cpu, 0, 0x08800000); scp1 = scoop_init(cpu, 1, 0x14800040); -- cgit v1.2.3 From f227f17d1b4f21b681c94efce859b9094482b7e6 Mon Sep 17 00:00:00 2001 From: balrog Date: Mon, 9 Jun 2008 00:03:47 +0000 Subject: Fix the sendkey hold time calculation (Jan Kiszka). git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4703 c046a42c-6fe2-441c-8c8c-71466251a162 --- monitor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monitor.c b/monitor.c index 002fc0286..1eb8be1ed 100644 --- a/monitor.c +++ b/monitor.c @@ -982,8 +982,8 @@ static void do_sendkey(const char *string, int has_hold_time, int hold_time) kbd_put_keycode(keycode & 0x7f); } /* delayed key up events */ - qemu_mod_timer(key_timer, - qemu_get_clock(vm_clock) + ticks_per_sec * hold_time); + qemu_mod_timer(key_timer, qemu_get_clock(vm_clock) + + muldiv64(ticks_per_sec, hold_time, 1000)); } static int mouse_button_state; -- cgit v1.2.3 From 0f459d16c378128a586cf161526721a81b629405 Mon Sep 17 00:00:00 2001 From: pbrook Date: Mon, 9 Jun 2008 00:20:13 +0000 Subject: Clean up MMIO TLB handling. The IO index is now stored in its own field, instead of being wedged into the vaddr field. This eliminates the ROMD and watchpoint host pointer weirdness. The IO index space is expanded by 1 bit, and several additional bits are made available in the TLB vaddr field. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4704 c046a42c-6fe2-441c-8c8c-71466251a162 --- cpu-all.h | 27 +++++-- cpu-defs.h | 12 +-- exec.c | 232 ++++++++++++++++++++++++++--------------------------- gdbstub.c | 32 ++++++-- hw/pflash_cfi01.c | 8 +- hw/pflash_cfi02.c | 12 +-- softmmu_template.h | 48 ++++++----- 7 files changed, 195 insertions(+), 176 deletions(-) diff --git a/cpu-all.h b/cpu-all.h index 06dc6d7b1..6a1612536 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -797,7 +797,7 @@ extern CPUState *cpu_single_env; void cpu_interrupt(CPUState *s, int mask); void cpu_reset_interrupt(CPUState *env, int mask); -int cpu_watchpoint_insert(CPUState *env, target_ulong addr); +int cpu_watchpoint_insert(CPUState *env, target_ulong addr, int type); int cpu_watchpoint_remove(CPUState *env, target_ulong addr); void cpu_watchpoint_remove_all(CPUState *env); int cpu_breakpoint_insert(CPUState *env, target_ulong pc); @@ -868,21 +868,34 @@ extern uint8_t *phys_ram_dirty; extern ram_addr_t ram_size; /* physical memory access */ -#define TLB_INVALID_MASK (1 << 3) -#define IO_MEM_SHIFT 4 + +/* MMIO pages are identified by a combination of an IO device index and + 3 flags. The ROMD code stores the page ram offset in iotlb entry, + so only a limited number of ids are avaiable. */ + +#define IO_MEM_SHIFT 3 #define IO_MEM_NB_ENTRIES (1 << (TARGET_PAGE_BITS - IO_MEM_SHIFT)) #define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */ #define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */ #define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT) -#define IO_MEM_NOTDIRTY (4 << IO_MEM_SHIFT) /* used internally, never use directly */ -/* acts like a ROM when read and like a device when written. As an - exception, the write memory callback gets the ram offset instead of - the physical address */ +#define IO_MEM_NOTDIRTY (3 << IO_MEM_SHIFT) + +/* Acts like a ROM when read and like a device when written. */ #define IO_MEM_ROMD (1) #define IO_MEM_SUBPAGE (2) #define IO_MEM_SUBWIDTH (4) +/* Flags stored in the low bits of the TLB virtual address. These are + defined so that fast path ram access is all zeros. */ +/* Zero if TLB entry is valid. */ +#define TLB_INVALID_MASK (1 << 3) +/* Set if TLB entry references a clean RAM page. The iotlb entry will + contain the page physical address. */ +#define TLB_NOTDIRTY (1 << 4) +/* Set if TLB entry is an IO callback. */ +#define TLB_MMIO (1 << 5) + typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value); typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr); diff --git a/cpu-defs.h b/cpu-defs.h index 5804521a7..e19768604 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -106,16 +106,17 @@ typedef uint64_t target_phys_addr_t; #endif typedef struct CPUTLBEntry { - /* bit 31 to TARGET_PAGE_BITS : virtual address - bit TARGET_PAGE_BITS-1..IO_MEM_SHIFT : if non zero, memory io - zone number + /* bit TARGET_LONG_BITS to TARGET_PAGE_BITS : virtual address + bit TARGET_PAGE_BITS-1..4 : Nonzero for accesses that should not + go directly to ram. bit 3 : indicates that the entry is invalid bit 2..0 : zero */ target_ulong addr_read; target_ulong addr_write; target_ulong addr_code; - /* addend to virtual address to get physical address */ + /* Addend to virtual address to get physical address. IO accesses + use the correcponding iotlb value. */ #if TARGET_PHYS_ADDR_BITS == 64 /* on i386 Linux make sure it is aligned */ target_phys_addr_t addend __attribute__((aligned(8))); @@ -143,6 +144,7 @@ typedef struct CPUTLBEntry { int halted; /* TRUE if the CPU is in suspend state */ \ /* The meaning of the MMU modes is defined in the target code. */ \ CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE]; \ + target_phys_addr_t iotlb[NB_MMU_MODES][CPU_TLB_SIZE]; \ struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \ /* buffer for temporaries in the code generator */ \ long temp_buf[CPU_TEMP_BUF_NLONGS]; \ @@ -155,7 +157,7 @@ typedef struct CPUTLBEntry { \ struct { \ target_ulong vaddr; \ - target_phys_addr_t addend; \ + int type; /* PAGE_READ/PAGE_WRITE */ \ } watchpoint[MAX_WATCHPOINTS]; \ int nb_watchpoints; \ int watchpoint_hit; \ diff --git a/exec.c b/exec.c index 2cf0a6a5e..64287e20c 100644 --- a/exec.c +++ b/exec.c @@ -121,7 +121,7 @@ typedef struct PageDesc { } PageDesc; typedef struct PhysPageDesc { - /* offset in host memory of the page + io_index in the low 12 bits */ + /* offset in host memory of the page + io_index in the low bits */ ram_addr_t phys_offset; } PhysPageDesc; @@ -1188,7 +1188,7 @@ static void breakpoint_invalidate(CPUState *env, target_ulong pc) #endif /* Add a watchpoint. */ -int cpu_watchpoint_insert(CPUState *env, target_ulong addr) +int cpu_watchpoint_insert(CPUState *env, target_ulong addr, int type) { int i; @@ -1201,6 +1201,7 @@ int cpu_watchpoint_insert(CPUState *env, target_ulong addr) i = env->nb_watchpoints++; env->watchpoint[i].vaddr = addr; + env->watchpoint[i].type = type; tlb_flush_page(env, addr); /* FIXME: This flush is needed because of the hack to make memory ops terminate the TB. It can be removed once the proper IO trap and @@ -1617,7 +1618,7 @@ static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) { addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend; if ((addr - start) < length) { - tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY; + tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | TLB_NOTDIRTY; } } } @@ -1681,7 +1682,7 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry) ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend - (unsigned long)phys_ram_base; if (!cpu_physical_memory_is_dirty(ram_addr)) { - tlb_entry->addr_write |= IO_MEM_NOTDIRTY; + tlb_entry->addr_write |= TLB_NOTDIRTY; } } } @@ -1704,33 +1705,26 @@ void cpu_tlb_update_dirty(CPUState *env) #endif } -static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, - unsigned long start) +static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, target_ulong vaddr) { - unsigned long addr; - if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) { - addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend; - if (addr == start) { - tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_RAM; - } - } + if (tlb_entry->addr_write == (vaddr | TLB_NOTDIRTY)) + tlb_entry->addr_write = vaddr; } -/* update the TLB corresponding to virtual page vaddr and phys addr - addr so that it is no longer dirty */ -static inline void tlb_set_dirty(CPUState *env, - unsigned long addr, target_ulong vaddr) +/* update the TLB corresponding to virtual page vaddr + so that it is no longer dirty */ +static inline void tlb_set_dirty(CPUState *env, target_ulong vaddr) { int i; - addr &= TARGET_PAGE_MASK; + vaddr &= TARGET_PAGE_MASK; i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); - tlb_set_dirty1(&env->tlb_table[0][i], addr); - tlb_set_dirty1(&env->tlb_table[1][i], addr); + tlb_set_dirty1(&env->tlb_table[0][i], vaddr); + tlb_set_dirty1(&env->tlb_table[1][i], vaddr); #if (NB_MMU_MODES >= 3) - tlb_set_dirty1(&env->tlb_table[2][i], addr); + tlb_set_dirty1(&env->tlb_table[2][i], vaddr); #if (NB_MMU_MODES == 4) - tlb_set_dirty1(&env->tlb_table[3][i], addr); + tlb_set_dirty1(&env->tlb_table[3][i], vaddr); #endif #endif } @@ -1747,10 +1741,12 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, unsigned long pd; unsigned int index; target_ulong address; + target_ulong code_address; target_phys_addr_t addend; int ret; CPUTLBEntry *te; int i; + target_phys_addr_t iotlb; p = phys_page_find(paddr >> TARGET_PAGE_BITS); if (!p) { @@ -1764,64 +1760,69 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, #endif ret = 0; - { - if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { - /* IO memory case */ - address = vaddr | pd; - addend = paddr; - } else { - /* standard memory */ - address = vaddr; - addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK); - } - - /* Make accesses to pages with watchpoints go via the - watchpoint trap routines. */ - for (i = 0; i < env->nb_watchpoints; i++) { - if (vaddr == (env->watchpoint[i].vaddr & TARGET_PAGE_MASK)) { - if (address & ~TARGET_PAGE_MASK) { - env->watchpoint[i].addend = 0; - address = vaddr | io_mem_watch; - } else { - env->watchpoint[i].addend = pd - paddr + - (unsigned long) phys_ram_base; - /* TODO: Figure out how to make read watchpoints coexist - with code. */ - pd = (pd & TARGET_PAGE_MASK) | io_mem_watch | IO_MEM_ROMD; - } - } + address = vaddr; + if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { + /* IO memory case (romd handled later) */ + address |= TLB_MMIO; + } + addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK); + if ((pd & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) { + /* Normal RAM. */ + iotlb = pd & TARGET_PAGE_MASK; + if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM) + iotlb |= IO_MEM_NOTDIRTY; + else + iotlb |= IO_MEM_ROM; + } else { + /* IO handlers are currently passed a phsical address. + It would be nice to pass an offset from the base address + of that region. This would avoid having to special case RAM, + and avoid full address decoding in every device. + We can't use the high bits of pd for this because + IO_MEM_ROMD uses these as a ram address. */ + iotlb = (pd & ~TARGET_PAGE_MASK) + paddr; + } + + code_address = address; + /* Make accesses to pages with watchpoints go via the + watchpoint trap routines. */ + for (i = 0; i < env->nb_watchpoints; i++) { + if (vaddr == (env->watchpoint[i].vaddr & TARGET_PAGE_MASK)) { + iotlb = io_mem_watch + paddr; + /* TODO: The memory case can be optimized by not trapping + reads of pages with a write breakpoint. */ + address |= TLB_MMIO; } + } - index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); - addend -= vaddr; - te = &env->tlb_table[mmu_idx][index]; - te->addend = addend; - if (prot & PAGE_READ) { - te->addr_read = address; - } else { - te->addr_read = -1; - } + index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + env->iotlb[mmu_idx][index] = iotlb - vaddr; + te = &env->tlb_table[mmu_idx][index]; + te->addend = addend - vaddr; + if (prot & PAGE_READ) { + te->addr_read = address; + } else { + te->addr_read = -1; + } - if (prot & PAGE_EXEC) { - te->addr_code = address; - } else { - te->addr_code = -1; - } - if (prot & PAGE_WRITE) { - if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM || - (pd & IO_MEM_ROMD)) { - /* write access calls the I/O callback */ - te->addr_write = vaddr | - (pd & ~(TARGET_PAGE_MASK | IO_MEM_ROMD)); - } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && - !cpu_physical_memory_is_dirty(pd)) { - te->addr_write = vaddr | IO_MEM_NOTDIRTY; - } else { - te->addr_write = address; - } + if (prot & PAGE_EXEC) { + te->addr_code = code_address; + } else { + te->addr_code = -1; + } + if (prot & PAGE_WRITE) { + if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM || + (pd & IO_MEM_ROMD)) { + /* Write access calls the I/O callback. */ + te->addr_write = address | TLB_MMIO; + } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && + !cpu_physical_memory_is_dirty(pd)) { + te->addr_write = address | TLB_NOTDIRTY; } else { - te->addr_write = -1; + te->addr_write = address; } + } else { + te->addr_write = -1; } return ret; } @@ -2181,11 +2182,10 @@ static CPUWriteMemoryFunc *unassigned_mem_write[3] = { unassigned_mem_writeb, }; -static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) +static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr, + uint32_t val) { - unsigned long ram_addr; int dirty_flags; - ram_addr = addr - (unsigned long)phys_ram_base; dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS]; if (!(dirty_flags & CODE_DIRTY_FLAG)) { #if !defined(CONFIG_USER_ONLY) @@ -2193,7 +2193,7 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS]; #endif } - stb_p((uint8_t *)(long)addr, val); + stb_p(phys_ram_base + ram_addr, val); #ifdef USE_KQEMU if (cpu_single_env->kqemu_enabled && (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK) @@ -2204,14 +2204,13 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t /* we remove the notdirty callback only if the code has been flushed */ if (dirty_flags == 0xff) - tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr); + tlb_set_dirty(cpu_single_env, cpu_single_env->mem_write_vaddr); } -static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) +static void notdirty_mem_writew(void *opaque, target_phys_addr_t ram_addr, + uint32_t val) { - unsigned long ram_addr; int dirty_flags; - ram_addr = addr - (unsigned long)phys_ram_base; dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS]; if (!(dirty_flags & CODE_DIRTY_FLAG)) { #if !defined(CONFIG_USER_ONLY) @@ -2219,7 +2218,7 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS]; #endif } - stw_p((uint8_t *)(long)addr, val); + stw_p(phys_ram_base + ram_addr, val); #ifdef USE_KQEMU if (cpu_single_env->kqemu_enabled && (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK) @@ -2230,14 +2229,13 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t /* we remove the notdirty callback only if the code has been flushed */ if (dirty_flags == 0xff) - tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr); + tlb_set_dirty(cpu_single_env, cpu_single_env->mem_write_vaddr); } -static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) +static void notdirty_mem_writel(void *opaque, target_phys_addr_t ram_addr, + uint32_t val) { - unsigned long ram_addr; int dirty_flags; - ram_addr = addr - (unsigned long)phys_ram_base; dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS]; if (!(dirty_flags & CODE_DIRTY_FLAG)) { #if !defined(CONFIG_USER_ONLY) @@ -2245,7 +2243,7 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS]; #endif } - stl_p((uint8_t *)(long)addr, val); + stl_p(phys_ram_base + ram_addr, val); #ifdef USE_KQEMU if (cpu_single_env->kqemu_enabled && (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK) @@ -2256,7 +2254,7 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t /* we remove the notdirty callback only if the code has been flushed */ if (dirty_flags == 0xff) - tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr); + tlb_set_dirty(cpu_single_env, cpu_single_env->mem_write_vaddr); } static CPUReadMemoryFunc *error_mem_read[3] = { @@ -2271,67 +2269,63 @@ static CPUWriteMemoryFunc *notdirty_mem_write[3] = { notdirty_mem_writel, }; +/* Generate a debug exception if a watchpoint has been hit. */ +static void check_watchpoint(int offset, int flags) +{ + CPUState *env = cpu_single_env; + target_ulong vaddr; + int i; + + vaddr = (env->mem_write_vaddr & TARGET_PAGE_MASK) + offset; + for (i = 0; i < env->nb_watchpoints; i++) { + if (vaddr == env->watchpoint[i].vaddr + && (env->watchpoint[i].type & flags)) { + env->watchpoint_hit = i + 1; + cpu_interrupt(env, CPU_INTERRUPT_DEBUG); + break; + } + } +} + /* Watchpoint access routines. Watchpoints are inserted using TLB tricks, so these check for a hit then pass through to the normal out-of-line phys routines. */ static uint32_t watch_mem_readb(void *opaque, target_phys_addr_t addr) { + check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_READ); return ldub_phys(addr); } static uint32_t watch_mem_readw(void *opaque, target_phys_addr_t addr) { + check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_READ); return lduw_phys(addr); } static uint32_t watch_mem_readl(void *opaque, target_phys_addr_t addr) { + check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_READ); return ldl_phys(addr); } -/* Generate a debug exception if a watchpoint has been hit. - Returns the real physical address of the access. addr will be a host - address in case of a RAM location. */ -static target_ulong check_watchpoint(target_phys_addr_t addr) -{ - CPUState *env = cpu_single_env; - target_ulong watch; - target_ulong retaddr; - int i; - - retaddr = addr; - for (i = 0; i < env->nb_watchpoints; i++) { - watch = env->watchpoint[i].vaddr; - if (((env->mem_write_vaddr ^ watch) & TARGET_PAGE_MASK) == 0) { - retaddr = addr - env->watchpoint[i].addend; - if (((addr ^ watch) & ~TARGET_PAGE_MASK) == 0) { - cpu_single_env->watchpoint_hit = i + 1; - cpu_interrupt(cpu_single_env, CPU_INTERRUPT_DEBUG); - break; - } - } - } - return retaddr; -} - static void watch_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) { - addr = check_watchpoint(addr); + check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_WRITE); stb_phys(addr, val); } static void watch_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) { - addr = check_watchpoint(addr); + check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_WRITE); stw_phys(addr, val); } static void watch_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) { - addr = check_watchpoint(addr); + check_watchpoint(addr & ~TARGET_PAGE_MASK, PAGE_WRITE); stl_phys(addr, val); } @@ -2501,7 +2495,7 @@ static void io_mem_init(void) cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read, notdirty_mem_write, NULL); io_mem_nb = 5; - io_mem_watch = cpu_register_io_memory(-1, watch_mem_read, + io_mem_watch = cpu_register_io_memory(0, watch_mem_read, watch_mem_write, NULL); /* alloc dirty bits array */ phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS); diff --git a/gdbstub.c b/gdbstub.c index 414c3908a..d4ca6f3c9 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1117,21 +1117,37 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) if (*p == ',') p++; len = strtoull(p, (char **)&p, 16); - if (type == 0 || type == 1) { + switch (type) { + case 0: + case 1: if (cpu_breakpoint_insert(env, addr) < 0) goto breakpoint_error; put_packet(s, "OK"); + break; #ifndef CONFIG_USER_ONLY - } else if (type == 2) { - if (cpu_watchpoint_insert(env, addr) < 0) + case 2: + type = PAGE_WRITE; + goto insert_watchpoint; + case 3: + type = PAGE_READ; + goto insert_watchpoint; + case 4: + type = PAGE_READ | PAGE_WRITE; + insert_watchpoint: + if (cpu_watchpoint_insert(env, addr, type) < 0) goto breakpoint_error; put_packet(s, "OK"); + break; #endif - } else { - breakpoint_error: - put_packet(s, "E22"); + default: + put_packet(s, ""); + break; } break; + breakpoint_error: + put_packet(s, "E22"); + break; + case 'z': type = strtoul(p, (char **)&p, 16); if (*p == ',') @@ -1144,12 +1160,12 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf) cpu_breakpoint_remove(env, addr); put_packet(s, "OK"); #ifndef CONFIG_USER_ONLY - } else if (type == 2) { + } else if (type >= 2 || type <= 4) { cpu_watchpoint_remove(env, addr); put_packet(s, "OK"); #endif } else { - goto breakpoint_error; + put_packet(s, ""); } break; case 'q': diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c index c360179c3..771ea854d 100644 --- a/hw/pflash_cfi01.c +++ b/hw/pflash_cfi01.c @@ -202,14 +202,8 @@ static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value, uint8_t *p; uint8_t cmd; - /* WARNING: when the memory area is in ROMD mode, the offset is a - ram offset, not a physical address */ cmd = value; - - if (pfl->wcycle == 0) - offset -= (target_ulong)(long)pfl->storage; - else - offset -= pfl->base; + offset -= pfl->base; DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d wcycle 0x%x\n", __func__, offset, value, width, pfl->wcycle); diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c index 1daaac3d8..5530841bf 100644 --- a/hw/pflash_cfi02.c +++ b/hw/pflash_cfi02.c @@ -112,13 +112,12 @@ static uint32_t pflash_read (pflash_t *pfl, uint32_t offset, int width) DPRINTF("%s: offset " TARGET_FMT_lx "\n", __func__, offset); ret = -1; + offset -= pfl->base; if (pfl->rom_mode) { - offset -= (uint32_t)(long)pfl->storage; /* Lazy reset of to ROMD mode */ if (pfl->wcycle == 0) pflash_register_memory(pfl, 1); - } else - offset -= pfl->base; + } offset &= pfl->chip_len - 1; boff = offset & 0xFF; if (pfl->width == 2) @@ -242,12 +241,7 @@ static void pflash_write (pflash_t *pfl, uint32_t offset, uint32_t value, } DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d %d\n", __func__, offset, value, width, pfl->wcycle); - /* WARNING: when the memory area is in ROMD mode, the offset is a - ram offset, not a physical address */ - if (pfl->rom_mode) - offset -= (uint32_t)(long)pfl->storage; - else - offset -= pfl->base; + offset -= pfl->base; offset &= pfl->chip_len - 1; DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d\n", __func__, diff --git a/softmmu_template.h b/softmmu_template.h index 0a4bc7e0c..934df5286 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -51,12 +51,13 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, int mmu_idx, void *retaddr); static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr, - target_ulong tlb_addr) + target_ulong addr) { DATA_TYPE res; int index; + index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); + physaddr = (physaddr & TARGET_PAGE_MASK) + addr; - index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); #if SHIFT <= 2 res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr); #else @@ -81,7 +82,7 @@ DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE res; int index; target_ulong tlb_addr; - target_phys_addr_t physaddr; + target_phys_addr_t addend; void *retaddr; /* test if there is match for unaligned or IO access */ @@ -90,12 +91,12 @@ DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, redo: tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = addr + env->tlb_table[mmu_idx][index].addend; if (tlb_addr & ~TARGET_PAGE_MASK) { /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) goto do_unaligned_access; - res = glue(io_read, SUFFIX)(physaddr, tlb_addr); + addend = env->iotlb[mmu_idx][index]; + res = glue(io_read, SUFFIX)(addend, addr); } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { /* slow unaligned access (it spans two pages or IO) */ do_unaligned_access: @@ -113,7 +114,8 @@ DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); } #endif - res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr); + addend = env->tlb_table[mmu_idx][index].addend; + res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend)); } } else { /* the page is not in the TLB : fill it */ @@ -135,19 +137,19 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, { DATA_TYPE res, res1, res2; int index, shift; - target_phys_addr_t physaddr; + target_phys_addr_t addend; target_ulong tlb_addr, addr1, addr2; index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); redo: tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = addr + env->tlb_table[mmu_idx][index].addend; if (tlb_addr & ~TARGET_PAGE_MASK) { /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) goto do_unaligned_access; - res = glue(io_read, SUFFIX)(physaddr, tlb_addr); + addend = env->iotlb[mmu_idx][index]; + res = glue(io_read, SUFFIX)(addend, addr); } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { do_unaligned_access: /* slow unaligned access (it spans two pages) */ @@ -166,7 +168,8 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, res = (DATA_TYPE)res; } else { /* unaligned/aligned access in the same page */ - res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr); + addend = env->tlb_table[mmu_idx][index].addend; + res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend)); } } else { /* the page is not in the TLB : fill it */ @@ -185,13 +188,14 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr, DATA_TYPE val, - target_ulong tlb_addr, + target_ulong addr, void *retaddr) { int index; + index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); + physaddr = (physaddr & TARGET_PAGE_MASK) + addr; - index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); - env->mem_write_vaddr = tlb_addr; + env->mem_write_vaddr = addr; env->mem_write_pc = (unsigned long)retaddr; #if SHIFT <= 2 io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val); @@ -213,7 +217,7 @@ void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE val, int mmu_idx) { - target_phys_addr_t physaddr; + target_phys_addr_t addend; target_ulong tlb_addr; void *retaddr; int index; @@ -222,13 +226,13 @@ void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, redo: tlb_addr = env->tlb_table[mmu_idx][index].addr_write; if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = addr + env->tlb_table[mmu_idx][index].addend; if (tlb_addr & ~TARGET_PAGE_MASK) { /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) goto do_unaligned_access; retaddr = GETPC(); - glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr); + addend = env->iotlb[mmu_idx][index]; + glue(io_write, SUFFIX)(addend, val, addr, retaddr); } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { do_unaligned_access: retaddr = GETPC(); @@ -245,7 +249,8 @@ void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, do_unaligned_access(addr, 1, mmu_idx, retaddr); } #endif - glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val); + addend = env->tlb_table[mmu_idx][index].addend; + glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val); } } else { /* the page is not in the TLB : fill it */ @@ -265,7 +270,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, int mmu_idx, void *retaddr) { - target_phys_addr_t physaddr; + target_phys_addr_t addend; target_ulong tlb_addr; int index, i; @@ -273,12 +278,12 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, redo: tlb_addr = env->tlb_table[mmu_idx][index].addr_write; if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = addr + env->tlb_table[mmu_idx][index].addend; if (tlb_addr & ~TARGET_PAGE_MASK) { /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) goto do_unaligned_access; - glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr); + addend = env->iotlb[mmu_idx][index]; + glue(io_write, SUFFIX)(addend, val, addr, retaddr); } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { do_unaligned_access: /* XXX: not efficient, but simple */ @@ -295,7 +300,8 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, } } else { /* aligned/unaligned access in the same page */ - glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val); + addend = env->tlb_table[mmu_idx][index].addend; + glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val); } } else { /* the page is not in the TLB : fill it */ -- cgit v1.2.3 From 398ce98e4f4286370d97a7e51b01bf6334c3b65e Mon Sep 17 00:00:00 2001 From: malc Date: Mon, 9 Jun 2008 06:06:25 +0000 Subject: Fix div[u]2. Previous code assummed 32 by 32 bit divmod operation, and survived x86_64 test only by sheer luck. MIPS wasn't so forgiving. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4705 c046a42c-6fe2-441c-8c8c-71466251a162 --- tcg/ppc/tcg-target.c | 91 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 26 deletions(-) diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index ffac342e3..6c4e37523 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -198,6 +198,10 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) ct_str = *pct_str; switch (ct_str[0]) { + case 'A': case 'B': case 'C': case 'D': + ct->ct |= TCG_CT_REG; + tcg_regset_set_reg(ct->u.regs, 3 + ct_str[0] - 'A'); + break; case 'r': ct->ct |= TCG_CT_REG; tcg_regset_set32(ct->u.regs, 0, 0xffffffff); @@ -1014,6 +1018,63 @@ static void tcg_out_brcond2(TCGContext *s, tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr); } +static uint64_t __attribute ((used)) ppc_udiv_helper (uint64_t a, uint32_t b) +{ + uint64_t rem, quo; + quo = a / b; + rem = a % b; + return (rem << 32) | (uint32_t) quo; +} + +static uint64_t __attribute ((used)) ppc_div_helper (int64_t a, int32_t b) +{ + int64_t rem, quo; + quo = a / b; + rem = a % b; + return (rem << 32) | (uint32_t) quo; +} + +#define MAKE_TRAMPOLINE(name) \ +extern void name##_trampoline (void); \ +asm (#name "_trampoline:\n" \ + " mflr 0\n" \ + " addi 1,1,-112\n" \ + " mr 4,6\n" \ + " stmw 7,0(1)\n" \ + " stw 0,108(0)\n" \ + " bl ppc_" #name "_helper\n" \ + " lmw 7,0(1)\n" \ + " lwz 0,108(0)\n" \ + " addi 1,1,112\n" \ + " mtlr 0\n" \ + " blr\n" \ + ) + +MAKE_TRAMPOLINE (div); +MAKE_TRAMPOLINE (udiv); + +static void tcg_out_div2 (TCGContext *s, int uns) +{ + void *label1_ptr, *label2_ptr; + + tcg_out32 (s, CMPLI | BF (7) | RA (3)); + label1_ptr = s->code_ptr; + tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE); + + tcg_out_b (s, LK, (tcg_target_long) (uns ? udiv_trampoline : div_trampoline)); + + label2_ptr = s->code_ptr; + tcg_out32 (s, B); + + reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr); + + tcg_out32 (s, (uns ? DIVWU : DIVW) | TAB (6, 4, 5)); + tcg_out32 (s, MULLW | TAB (0, 6, 5)); + tcg_out32 (s, SUBF | TAB (3, 0, 4)); + + reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr); +} + static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, const int *const_args) { @@ -1204,32 +1265,10 @@ static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, } break; case INDEX_op_div2_i32: - if (args[0] == args[2] || args[0] == args[3]) { - tcg_out32 (s, DIVW | TAB (0, args[2], args[3])); - tcg_out32 (s, MTSPR | RS (0) | CTR); - tcg_out32 (s, MULLW | TAB (0, 0, args[3])); - tcg_out32 (s, SUBF | TAB (args[1], 0, args[2])); - tcg_out32 (s, MFSPR | RT (args[0]) | CTR); - } - else { - tcg_out32 (s, DIVW | TAB (args[0], args[2], args[3])); - tcg_out32 (s, MULLW | TAB (0, args[0], args[3])); - tcg_out32 (s, SUBF | TAB (args[1], 0, args[2])); - } + tcg_out_div2 (s, 0); break; case INDEX_op_divu2_i32: - if (args[0] == args[2] || args[0] == args[3]) { - tcg_out32 (s, DIVWU | TAB (0, args[2], args[3])); - tcg_out32 (s, MTSPR | RS (0) | CTR); - tcg_out32 (s, MULLW | TAB (0, 0, args[3])); - tcg_out32 (s, SUBF | TAB (args[1], 0, args[2])); - tcg_out32 (s, MFSPR | RT (args[0]) | CTR); - } - else { - tcg_out32 (s, DIVWU | TAB (args[0], args[2], args[3])); - tcg_out32 (s, MULLW | TAB (0, args[0], args[3])); - tcg_out32 (s, SUBF | TAB (args[1], 0, args[2])); - } + tcg_out_div2 (s, 1); break; case INDEX_op_shl_i32: @@ -1372,8 +1411,8 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_add_i32, { "r", "r", "ri" } }, { INDEX_op_mul_i32, { "r", "r", "ri" } }, { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } }, - { INDEX_op_div2_i32, { "r", "r", "r", "r", "r" } }, - { INDEX_op_divu2_i32, { "r", "r", "r", "r", "r" } }, + { INDEX_op_div2_i32, { "D", "A", "B", "1", "C" } }, + { INDEX_op_divu2_i32, { "D", "A", "B", "1", "C" } }, { INDEX_op_sub_i32, { "r", "r", "ri" } }, { INDEX_op_and_i32, { "r", "r", "ri" } }, { INDEX_op_or_i32, { "r", "r", "ri" } }, -- cgit v1.2.3 From 5be1676206f83dc603a8746de8026b3f966b1b97 Mon Sep 17 00:00:00 2001 From: malc Date: Mon, 9 Jun 2008 06:06:28 +0000 Subject: R_PPC_REL24 safety net git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4706 c046a42c-6fe2-441c-8c8c-71466251a162 --- dyngen.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dyngen.c b/dyngen.c index c38d12386..880d641a5 100644 --- a/dyngen.c +++ b/dyngen.c @@ -1963,6 +1963,14 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, break; case R_PPC_REL24: /* warning: must be at 32 MB distancy */ + fprintf(outfile, "{\n" + " long disp = (%s - (long)(gen_code_ptr + %d) + %d);\n" + " if ((disp << 6) >> 6 != disp) {;\n" + " fprintf(stderr, \"Branch target is too far away\\n\");" + " abort();\n" + " }\n" + "}\n", + relname, reloc_offset, addend); fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n", reloc_offset, reloc_offset, relname, reloc_offset, addend); break; -- cgit v1.2.3 From 176a4f299899210d550b3d9ddb83eae7df2ff485 Mon Sep 17 00:00:00 2001 From: malc Date: Mon, 9 Jun 2008 06:06:30 +0000 Subject: Add -mlongcall for PPC host (needed for MIPS for instance) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4707 c046a42c-6fe2-441c-8c8c-71466251a162 --- Makefile.target | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.target b/Makefile.target index e1cd403eb..ab60677b6 100644 --- a/Makefile.target +++ b/Makefile.target @@ -106,6 +106,7 @@ endif ifeq ($(ARCH),ppc) CPPFLAGS+= -D__powerpc__ +OP_CFLAGS+= -mlongcall endif ifeq ($(ARCH),sparc) -- cgit v1.2.3 From f1aa63203d53945faa708c821c9d4491e5cc8a27 Mon Sep 17 00:00:00 2001 From: ths Date: Mon, 9 Jun 2008 07:13:38 +0000 Subject: Switch remaining CP0 instructions to TCG or helper functions. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4708 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/exec.h | 35 +- target-mips/helper.h | 118 ++++++ target-mips/op.c | 954 ------------------------------------------------ target-mips/op_helper.c | 792 +++++++++++++++++++++++++++++++++++++++- target-mips/translate.c | 516 +++++++++++++------------- 5 files changed, 1179 insertions(+), 1236 deletions(-) diff --git a/target-mips/exec.h b/target-mips/exec.h index f10a35df0..c92700572 100644 --- a/target-mips/exec.h +++ b/target-mips/exec.h @@ -48,28 +48,6 @@ register target_ulong T1 asm(AREG2); #include "softmmu_exec.h" #endif /* !defined(CONFIG_USER_ONLY) */ -#if defined(TARGET_MIPS64) -#if TARGET_LONG_BITS > HOST_LONG_BITS -void do_dsll (void); -void do_dsll32 (void); -void do_dsra (void); -void do_dsra32 (void); -void do_dsrl (void); -void do_dsrl32 (void); -void do_drotr (void); -void do_drotr32 (void); -void do_dsllv (void); -void do_dsrav (void); -void do_dsrlv (void); -void do_drotrv (void); -void do_dclo (void); -void do_dclz (void); -#endif -#endif - -#if HOST_LONG_BITS < 64 -void do_div (void); -#endif #if TARGET_LONG_BITS > HOST_LONG_BITS void do_mult (void); void do_multu (void); @@ -92,15 +70,7 @@ void do_mulhiu (void); void do_mulshi (void); void do_mulshiu (void); #endif -#if defined(TARGET_MIPS64) -void do_ddiv (void); -#if TARGET_LONG_BITS > HOST_LONG_BITS -void do_ddivu (void); -#endif -#endif -void do_mfc0_random(void); -void do_mfc0_count(void); -void do_mtc0_entryhi(uint32_t in); + void do_mtc0_status_debug(uint32_t old, uint32_t val); void do_mtc0_status_irqraise_debug(void); void dump_fpu(CPUState *env); @@ -133,9 +103,6 @@ void cpu_mips_update_irq (CPUState *env); void cpu_mips_clock_init (CPUState *env); void cpu_mips_tlb_flush (CPUState *env, int flush_global); -void do_cfc1 (int reg); -void do_ctc1 (int reg); - #define FOP_PROTO(op) \ void do_float_ ## op ## _s(void); \ void do_float_ ## op ## _d(void); diff --git a/target-mips/helper.h b/target-mips/helper.h index cee92fc82..ddc82f1df 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -12,3 +12,121 @@ DEF_HELPER(void, do_clz, (void)) DEF_HELPER(void, do_dclo, (void)) DEF_HELPER(void, do_dclz, (void)) #endif + +/* CP0 helpers */ +#ifndef CONFIG_USER_ONLY +DEF_HELPER(void, do_mfc0_mvpcontrol, (void)) +DEF_HELPER(void, do_mfc0_mvpconf0, (void)) +DEF_HELPER(void, do_mfc0_mvpconf1, (void)) +DEF_HELPER(void, do_mfc0_random, (void)) +DEF_HELPER(void, do_mfc0_tcstatus, (void)) +DEF_HELPER(void, do_mftc0_tcstatus, (void)) +DEF_HELPER(void, do_mfc0_tcbind, (void)) +DEF_HELPER(void, do_mftc0_tcbind, (void)) +DEF_HELPER(void, do_mfc0_tcrestart, (void)) +DEF_HELPER(void, do_mftc0_tcrestart, (void)) +DEF_HELPER(void, do_mfc0_tchalt, (void)) +DEF_HELPER(void, do_mftc0_tchalt, (void)) +DEF_HELPER(void, do_mfc0_tccontext, (void)) +DEF_HELPER(void, do_mftc0_tccontext, (void)) +DEF_HELPER(void, do_mfc0_tcschedule, (void)) +DEF_HELPER(void, do_mftc0_tcschedule, (void)) +DEF_HELPER(void, do_mfc0_tcschefback, (void)) +DEF_HELPER(void, do_mftc0_tcschefback, (void)) +DEF_HELPER(void, do_mfc0_count, (void)) +DEF_HELPER(void, do_mftc0_entryhi, (void)) +DEF_HELPER(void, do_mftc0_status, (void)) +DEF_HELPER(void, do_mfc0_lladdr, (void)) +DEF_HELPER(void, do_mfc0_watchlo, (uint32_t sel)) +DEF_HELPER(void, do_mfc0_watchhi, (uint32_t sel)) +DEF_HELPER(void, do_mfc0_debug, (void)) +DEF_HELPER(void, do_mftc0_debug, (void)) +#ifdef TARGET_MIPS64 +DEF_HELPER(void, do_dmfc0_tcrestart, (void)) +DEF_HELPER(void, do_dmfc0_tchalt, (void)) +DEF_HELPER(void, do_dmfc0_tccontext, (void)) +DEF_HELPER(void, do_dmfc0_tcschedule, (void)) +DEF_HELPER(void, do_dmfc0_tcschefback, (void)) +DEF_HELPER(void, do_dmfc0_lladdr, (void)) +DEF_HELPER(void, do_dmfc0_watchlo, (uint32_t sel)) +#endif /* TARGET_MIPS64 */ + +DEF_HELPER(void, do_mtc0_index, (void)) +DEF_HELPER(void, do_mtc0_mvpcontrol, (void)) +DEF_HELPER(void, do_mtc0_vpecontrol, (void)) +DEF_HELPER(void, do_mtc0_vpeconf0, (void)) +DEF_HELPER(void, do_mtc0_vpeconf1, (void)) +DEF_HELPER(void, do_mtc0_yqmask, (void)) +DEF_HELPER(void, do_mtc0_vpeopt, (void)) +DEF_HELPER(void, do_mtc0_entrylo0, (void)) +DEF_HELPER(void, do_mtc0_tcstatus, (void)) +DEF_HELPER(void, do_mttc0_tcstatus, (void)) +DEF_HELPER(void, do_mtc0_tcbind, (void)) +DEF_HELPER(void, do_mttc0_tcbind, (void)) +DEF_HELPER(void, do_mtc0_tcrestart, (void)) +DEF_HELPER(void, do_mttc0_tcrestart, (void)) +DEF_HELPER(void, do_mtc0_tchalt, (void)) +DEF_HELPER(void, do_mttc0_tchalt, (void)) +DEF_HELPER(void, do_mtc0_tccontext, (void)) +DEF_HELPER(void, do_mttc0_tccontext, (void)) +DEF_HELPER(void, do_mtc0_tcschedule, (void)) +DEF_HELPER(void, do_mttc0_tcschedule, (void)) +DEF_HELPER(void, do_mtc0_tcschefback, (void)) +DEF_HELPER(void, do_mttc0_tcschefback, (void)) +DEF_HELPER(void, do_mtc0_entrylo1, (void)) +DEF_HELPER(void, do_mtc0_context, (void)) +DEF_HELPER(void, do_mtc0_pagemask, (void)) +DEF_HELPER(void, do_mtc0_pagegrain, (void)) +DEF_HELPER(void, do_mtc0_wired, (void)) +DEF_HELPER(void, do_mtc0_srsconf0, (void)) +DEF_HELPER(void, do_mtc0_srsconf1, (void)) +DEF_HELPER(void, do_mtc0_srsconf2, (void)) +DEF_HELPER(void, do_mtc0_srsconf3, (void)) +DEF_HELPER(void, do_mtc0_srsconf4, (void)) +DEF_HELPER(void, do_mtc0_hwrena, (void)) +DEF_HELPER(void, do_mtc0_count, (void)) +DEF_HELPER(void, do_mtc0_entryhi, (void)) +DEF_HELPER(void, do_mttc0_entryhi, (void)) +DEF_HELPER(void, do_mtc0_compare, (void)) +DEF_HELPER(void, do_mtc0_status, (void)) +DEF_HELPER(void, do_mttc0_status, (void)) +DEF_HELPER(void, do_mtc0_intctl, (void)) +DEF_HELPER(void, do_mtc0_srsctl, (void)) +DEF_HELPER(void, do_mtc0_cause, (void)) +DEF_HELPER(void, do_mtc0_ebase, (void)) +DEF_HELPER(void, do_mtc0_config0, (void)) +DEF_HELPER(void, do_mtc0_config2, (void)) +DEF_HELPER(void, do_mtc0_watchlo, (uint32_t sel)) +DEF_HELPER(void, do_mtc0_watchhi, (uint32_t sel)) +DEF_HELPER(void, do_mtc0_xcontext, (void)) +DEF_HELPER(void, do_mtc0_framemask, (void)) +DEF_HELPER(void, do_mtc0_debug, (void)) +DEF_HELPER(void, do_mttc0_debug, (void)) +DEF_HELPER(void, do_mtc0_performance0, (void)) +DEF_HELPER(void, do_mtc0_taglo, (void)) +DEF_HELPER(void, do_mtc0_datalo, (void)) +DEF_HELPER(void, do_mtc0_taghi, (void)) +DEF_HELPER(void, do_mtc0_datahi, (void)) +#endif /* !CONFIG_USER_ONLY */ + +/* MIPS MT functions */ +DEF_HELPER(void, do_mftgpr, (uint32_t sel)) +DEF_HELPER(void, do_mftlo, (uint32_t sel)) +DEF_HELPER(void, do_mfthi, (uint32_t sel)) +DEF_HELPER(void, do_mftacx, (uint32_t sel)) +DEF_HELPER(void, do_mftdsp, (void)) +DEF_HELPER(void, do_mttgpr, (uint32_t sel)) +DEF_HELPER(void, do_mttlo, (uint32_t sel)) +DEF_HELPER(void, do_mtthi, (uint32_t sel)) +DEF_HELPER(void, do_mttacx, (uint32_t sel)) +DEF_HELPER(void, do_mttdsp, (void)) +DEF_HELPER(void, do_dmt, (void)) +DEF_HELPER(void, do_emt, (void)) +DEF_HELPER(void, do_dvpe, (void)) +DEF_HELPER(void, do_evpe, (void)) +DEF_HELPER(void, do_fork, (void)) +DEF_HELPER(void, do_yield, (void)) + +/* CP1 functions */ +DEF_HELPER(void, do_cfc1, (uint32_t reg)) +DEF_HELPER(void, do_ctc1, (uint32_t reg)) diff --git a/target-mips/op.c b/target-mips/op.c index f09c2a451..ff5aed968 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -460,946 +460,6 @@ void op_dmultu (void) } #endif -/* CP0 functions */ -void op_mfc0_mvpcontrol (void) -{ - T0 = env->mvp->CP0_MVPControl; - FORCE_RET(); -} - -void op_mfc0_mvpconf0 (void) -{ - T0 = env->mvp->CP0_MVPConf0; - FORCE_RET(); -} - -void op_mfc0_mvpconf1 (void) -{ - T0 = env->mvp->CP0_MVPConf1; - FORCE_RET(); -} - -void op_mfc0_random (void) -{ - CALL_FROM_TB0(do_mfc0_random); - FORCE_RET(); -} - -void op_mfc0_tcstatus (void) -{ - T0 = env->CP0_TCStatus[env->current_tc]; - FORCE_RET(); -} - -void op_mftc0_tcstatus(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->CP0_TCStatus[other_tc]; - FORCE_RET(); -} - -void op_mfc0_tcbind (void) -{ - T0 = env->CP0_TCBind[env->current_tc]; - FORCE_RET(); -} - -void op_mftc0_tcbind(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->CP0_TCBind[other_tc]; - FORCE_RET(); -} - -void op_mfc0_tcrestart (void) -{ - T0 = env->PC[env->current_tc]; - FORCE_RET(); -} - -void op_mftc0_tcrestart(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->PC[other_tc]; - FORCE_RET(); -} - -void op_mfc0_tchalt (void) -{ - T0 = env->CP0_TCHalt[env->current_tc]; - FORCE_RET(); -} - -void op_mftc0_tchalt(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->CP0_TCHalt[other_tc]; - FORCE_RET(); -} - -void op_mfc0_tccontext (void) -{ - T0 = env->CP0_TCContext[env->current_tc]; - FORCE_RET(); -} - -void op_mftc0_tccontext(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->CP0_TCContext[other_tc]; - FORCE_RET(); -} - -void op_mfc0_tcschedule (void) -{ - T0 = env->CP0_TCSchedule[env->current_tc]; - FORCE_RET(); -} - -void op_mftc0_tcschedule(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->CP0_TCSchedule[other_tc]; - FORCE_RET(); -} - -void op_mfc0_tcschefback (void) -{ - T0 = env->CP0_TCScheFBack[env->current_tc]; - FORCE_RET(); -} - -void op_mftc0_tcschefback(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->CP0_TCScheFBack[other_tc]; - FORCE_RET(); -} - -void op_mfc0_count (void) -{ - CALL_FROM_TB0(do_mfc0_count); - FORCE_RET(); -} - -void op_mftc0_entryhi(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff); - FORCE_RET(); -} - -void op_mftc0_status(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - uint32_t tcstatus = env->CP0_TCStatus[other_tc]; - - T0 = env->CP0_Status & ~0xf1000018; - T0 |= tcstatus & (0xf << CP0TCSt_TCU0); - T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX); - T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU); - FORCE_RET(); -} - -void op_mfc0_lladdr (void) -{ - T0 = (int32_t)env->CP0_LLAddr >> 4; - FORCE_RET(); -} - -void op_mfc0_watchlo (void) -{ - T0 = (int32_t)env->CP0_WatchLo[PARAM1]; - FORCE_RET(); -} - -void op_mfc0_watchhi (void) -{ - T0 = env->CP0_WatchHi[PARAM1]; - FORCE_RET(); -} - -void op_mfc0_debug (void) -{ - T0 = env->CP0_Debug; - if (env->hflags & MIPS_HFLAG_DM) - T0 |= 1 << CP0DB_DM; - FORCE_RET(); -} - -void op_mftc0_debug(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - /* XXX: Might be wrong, check with EJTAG spec. */ - T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | - (env->CP0_Debug_tcstatus[other_tc] & - ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); - FORCE_RET(); -} - -void op_mtc0_index (void) -{ - int num = 1; - unsigned int tmp = env->tlb->nb_tlb; - - do { - tmp >>= 1; - num <<= 1; - } while (tmp); - env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1)); - FORCE_RET(); -} - -void op_mtc0_mvpcontrol (void) -{ - uint32_t mask = 0; - uint32_t newval; - - if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) - mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) | - (1 << CP0MVPCo_EVP); - if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) - mask |= (1 << CP0MVPCo_STLB); - newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask); - - // TODO: Enable/disable shared TLB, enable/disable VPEs. - - env->mvp->CP0_MVPControl = newval; - FORCE_RET(); -} - -void op_mtc0_vpecontrol (void) -{ - uint32_t mask; - uint32_t newval; - - mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) | - (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC); - newval = (env->CP0_VPEControl & ~mask) | (T0 & mask); - - /* Yield scheduler intercept not implemented. */ - /* Gating storage scheduler intercept not implemented. */ - - // TODO: Enable/disable TCs. - - env->CP0_VPEControl = newval; - FORCE_RET(); -} - -void op_mtc0_vpeconf0 (void) -{ - uint32_t mask = 0; - uint32_t newval; - - if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) { - if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA)) - mask |= (0xff << CP0VPEC0_XTC); - mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA); - } - newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask); - - // TODO: TC exclusive handling due to ERL/EXL. - - env->CP0_VPEConf0 = newval; - FORCE_RET(); -} - -void op_mtc0_vpeconf1 (void) -{ - uint32_t mask = 0; - uint32_t newval; - - if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) - mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) | - (0xff << CP0VPEC1_NCP1); - newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask); - - /* UDI not implemented. */ - /* CP2 not implemented. */ - - // TODO: Handle FPU (CP1) binding. - - env->CP0_VPEConf1 = newval; - FORCE_RET(); -} - -void op_mtc0_yqmask (void) -{ - /* Yield qualifier inputs not implemented. */ - env->CP0_YQMask = 0x00000000; - FORCE_RET(); -} - -void op_mtc0_vpeschedule (void) -{ - env->CP0_VPESchedule = T0; - FORCE_RET(); -} - -void op_mtc0_vpeschefback (void) -{ - env->CP0_VPEScheFBack = T0; - FORCE_RET(); -} - -void op_mtc0_vpeopt (void) -{ - env->CP0_VPEOpt = T0 & 0x0000ffff; - FORCE_RET(); -} - -void op_mtc0_entrylo0 (void) -{ - /* Large physaddr (PABITS) not implemented */ - /* 1k pages not implemented */ - env->CP0_EntryLo0 = T0 & 0x3FFFFFFF; - FORCE_RET(); -} - -void op_mtc0_tcstatus (void) -{ - uint32_t mask = env->CP0_TCStatus_rw_bitmask; - uint32_t newval; - - newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask); - - // TODO: Sync with CP0_Status. - - env->CP0_TCStatus[env->current_tc] = newval; - FORCE_RET(); -} - -void op_mttc0_tcstatus (void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - // TODO: Sync with CP0_Status. - - env->CP0_TCStatus[other_tc] = T0; - FORCE_RET(); -} - -void op_mtc0_tcbind (void) -{ - uint32_t mask = (1 << CP0TCBd_TBE); - uint32_t newval; - - if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) - mask |= (1 << CP0TCBd_CurVPE); - newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask); - env->CP0_TCBind[env->current_tc] = newval; - FORCE_RET(); -} - -void op_mttc0_tcbind (void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - uint32_t mask = (1 << CP0TCBd_TBE); - uint32_t newval; - - if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) - mask |= (1 << CP0TCBd_CurVPE); - newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask); - env->CP0_TCBind[other_tc] = newval; - FORCE_RET(); -} - -void op_mtc0_tcrestart (void) -{ - env->PC[env->current_tc] = T0; - env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS); - env->CP0_LLAddr = 0ULL; - /* MIPS16 not implemented. */ - FORCE_RET(); -} - -void op_mttc0_tcrestart (void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - env->PC[other_tc] = T0; - env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS); - env->CP0_LLAddr = 0ULL; - /* MIPS16 not implemented. */ - FORCE_RET(); -} - -void op_mtc0_tchalt (void) -{ - env->CP0_TCHalt[env->current_tc] = T0 & 0x1; - - // TODO: Halt TC / Restart (if allocated+active) TC. - - FORCE_RET(); -} - -void op_mttc0_tchalt (void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - // TODO: Halt TC / Restart (if allocated+active) TC. - - env->CP0_TCHalt[other_tc] = T0; - FORCE_RET(); -} - -void op_mtc0_tccontext (void) -{ - env->CP0_TCContext[env->current_tc] = T0; - FORCE_RET(); -} - -void op_mttc0_tccontext (void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - env->CP0_TCContext[other_tc] = T0; - FORCE_RET(); -} - -void op_mtc0_tcschedule (void) -{ - env->CP0_TCSchedule[env->current_tc] = T0; - FORCE_RET(); -} - -void op_mttc0_tcschedule (void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - env->CP0_TCSchedule[other_tc] = T0; - FORCE_RET(); -} - -void op_mtc0_tcschefback (void) -{ - env->CP0_TCScheFBack[env->current_tc] = T0; - FORCE_RET(); -} - -void op_mttc0_tcschefback (void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - env->CP0_TCScheFBack[other_tc] = T0; - FORCE_RET(); -} - -void op_mtc0_entrylo1 (void) -{ - /* Large physaddr (PABITS) not implemented */ - /* 1k pages not implemented */ - env->CP0_EntryLo1 = T0 & 0x3FFFFFFF; - FORCE_RET(); -} - -void op_mtc0_context (void) -{ - env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF); - FORCE_RET(); -} - -void op_mtc0_pagemask (void) -{ - /* 1k pages not implemented */ - env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1)); - FORCE_RET(); -} - -void op_mtc0_pagegrain (void) -{ - /* SmartMIPS not implemented */ - /* Large physaddr (PABITS) not implemented */ - /* 1k pages not implemented */ - env->CP0_PageGrain = 0; - FORCE_RET(); -} - -void op_mtc0_wired (void) -{ - env->CP0_Wired = T0 % env->tlb->nb_tlb; - FORCE_RET(); -} - -void op_mtc0_srsconf0 (void) -{ - env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask; - FORCE_RET(); -} - -void op_mtc0_srsconf1 (void) -{ - env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask; - FORCE_RET(); -} - -void op_mtc0_srsconf2 (void) -{ - env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask; - FORCE_RET(); -} - -void op_mtc0_srsconf3 (void) -{ - env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask; - FORCE_RET(); -} - -void op_mtc0_srsconf4 (void) -{ - env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask; - FORCE_RET(); -} - -void op_mtc0_hwrena (void) -{ - env->CP0_HWREna = T0 & 0x0000000F; - FORCE_RET(); -} - -void op_mtc0_count (void) -{ - CALL_FROM_TB2(cpu_mips_store_count, env, T0); - FORCE_RET(); -} - -void op_mtc0_entryhi (void) -{ - target_ulong old, val; - - /* 1k pages not implemented */ - val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF); -#if defined(TARGET_MIPS64) - val &= env->SEGMask; -#endif - old = env->CP0_EntryHi; - env->CP0_EntryHi = val; - if (env->CP0_Config3 & (1 << CP0C3_MT)) { - uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff; - env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff); - } - /* If the ASID changes, flush qemu's TLB. */ - if ((old & 0xFF) != (val & 0xFF)) - CALL_FROM_TB2(cpu_mips_tlb_flush, env, 1); - FORCE_RET(); -} - -void op_mttc0_entryhi(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff); - env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff); - FORCE_RET(); -} - -void op_mtc0_compare (void) -{ - CALL_FROM_TB2(cpu_mips_store_compare, env, T0); - FORCE_RET(); -} - -void op_mtc0_status (void) -{ - uint32_t val, old; - uint32_t mask = env->CP0_Status_rw_bitmask; - - val = T0 & mask; - old = env->CP0_Status; - env->CP0_Status = (env->CP0_Status & ~mask) | val; - CALL_FROM_TB1(compute_hflags, env); - if (loglevel & CPU_LOG_EXEC) - CALL_FROM_TB2(do_mtc0_status_debug, old, val); - CALL_FROM_TB1(cpu_mips_update_irq, env); - FORCE_RET(); -} - -void op_mttc0_status(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - uint32_t tcstatus = env->CP0_TCStatus[other_tc]; - - env->CP0_Status = T0 & ~0xf1000018; - tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0)); - tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX)); - tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU)); - env->CP0_TCStatus[other_tc] = tcstatus; - FORCE_RET(); -} - -void op_mtc0_intctl (void) -{ - /* vectored interrupts not implemented, no performance counters. */ - env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0); - FORCE_RET(); -} - -void op_mtc0_srsctl (void) -{ - uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS); - env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask); - FORCE_RET(); -} - -void op_mtc0_srsmap (void) -{ - env->CP0_SRSMap = T0; - FORCE_RET(); -} - -void op_mtc0_cause (void) -{ - uint32_t mask = 0x00C00300; - uint32_t old = env->CP0_Cause; - - if (env->insn_flags & ISA_MIPS32R2) - mask |= 1 << CP0Ca_DC; - - env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask); - - if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) { - if (env->CP0_Cause & (1 << CP0Ca_DC)) - CALL_FROM_TB1(cpu_mips_stop_count, env); - else - CALL_FROM_TB1(cpu_mips_start_count, env); - } - - /* Handle the software interrupt as an hardware one, as they - are very similar */ - if (T0 & CP0Ca_IP_mask) { - CALL_FROM_TB1(cpu_mips_update_irq, env); - } - FORCE_RET(); -} - -void op_mtc0_epc (void) -{ - env->CP0_EPC = T0; - FORCE_RET(); -} - -void op_mtc0_ebase (void) -{ - /* vectored interrupts not implemented */ - /* Multi-CPU not implemented */ - env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000); - FORCE_RET(); -} - -void op_mtc0_config0 (void) -{ - env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007); - FORCE_RET(); -} - -void op_mtc0_config2 (void) -{ - /* tertiary/secondary caches not implemented */ - env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF); - FORCE_RET(); -} - -void op_mtc0_watchlo (void) -{ - /* Watch exceptions for instructions, data loads, data stores - not implemented. */ - env->CP0_WatchLo[PARAM1] = (T0 & ~0x7); - FORCE_RET(); -} - -void op_mtc0_watchhi (void) -{ - env->CP0_WatchHi[PARAM1] = (T0 & 0x40FF0FF8); - env->CP0_WatchHi[PARAM1] &= ~(env->CP0_WatchHi[PARAM1] & T0 & 0x7); - FORCE_RET(); -} - -void op_mtc0_xcontext (void) -{ - target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1; - env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask); - FORCE_RET(); -} - -void op_mtc0_framemask (void) -{ - env->CP0_Framemask = T0; /* XXX */ - FORCE_RET(); -} - -void op_mtc0_debug (void) -{ - env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120); - if (T0 & (1 << CP0DB_DM)) - env->hflags |= MIPS_HFLAG_DM; - else - env->hflags &= ~MIPS_HFLAG_DM; - FORCE_RET(); -} - -void op_mttc0_debug(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - /* XXX: Might be wrong, check with EJTAG spec. */ - env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)); - env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | - (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); - FORCE_RET(); -} - -void op_mtc0_depc (void) -{ - env->CP0_DEPC = T0; - FORCE_RET(); -} - -void op_mtc0_performance0 (void) -{ - env->CP0_Performance0 = T0 & 0x000007ff; - FORCE_RET(); -} - -void op_mtc0_taglo (void) -{ - env->CP0_TagLo = T0 & 0xFFFFFCF6; - FORCE_RET(); -} - -void op_mtc0_datalo (void) -{ - env->CP0_DataLo = T0; /* XXX */ - FORCE_RET(); -} - -void op_mtc0_taghi (void) -{ - env->CP0_TagHi = T0; /* XXX */ - FORCE_RET(); -} - -void op_mtc0_datahi (void) -{ - env->CP0_DataHi = T0; /* XXX */ - FORCE_RET(); -} - -void op_mtc0_errorepc (void) -{ - env->CP0_ErrorEPC = T0; - FORCE_RET(); -} - -void op_mtc0_desave (void) -{ - env->CP0_DESAVE = T0; - FORCE_RET(); -} - -#if defined(TARGET_MIPS64) -void op_dmfc0_tcrestart (void) -{ - T0 = env->PC[env->current_tc]; - FORCE_RET(); -} - -void op_dmfc0_tchalt (void) -{ - T0 = env->CP0_TCHalt[env->current_tc]; - FORCE_RET(); -} - -void op_dmfc0_tccontext (void) -{ - T0 = env->CP0_TCContext[env->current_tc]; - FORCE_RET(); -} - -void op_dmfc0_tcschedule (void) -{ - T0 = env->CP0_TCSchedule[env->current_tc]; - FORCE_RET(); -} - -void op_dmfc0_tcschefback (void) -{ - T0 = env->CP0_TCScheFBack[env->current_tc]; - FORCE_RET(); -} - -void op_dmfc0_lladdr (void) -{ - T0 = env->CP0_LLAddr >> 4; - FORCE_RET(); -} - -void op_dmfc0_watchlo (void) -{ - T0 = env->CP0_WatchLo[PARAM1]; - FORCE_RET(); -} -#endif /* TARGET_MIPS64 */ - -/* MIPS MT functions */ -void op_mftgpr(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->gpr[other_tc][PARAM1]; - FORCE_RET(); -} - -void op_mftlo(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->LO[other_tc][PARAM1]; - FORCE_RET(); -} - -void op_mfthi(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->HI[other_tc][PARAM1]; - FORCE_RET(); -} - -void op_mftacx(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->ACX[other_tc][PARAM1]; - FORCE_RET(); -} - -void op_mftdsp(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->DSPControl[other_tc]; - FORCE_RET(); -} - -void op_mttgpr(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->gpr[other_tc][PARAM1]; - FORCE_RET(); -} - -void op_mttlo(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->LO[other_tc][PARAM1]; - FORCE_RET(); -} - -void op_mtthi(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->HI[other_tc][PARAM1]; - FORCE_RET(); -} - -void op_mttacx(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->ACX[other_tc][PARAM1]; - FORCE_RET(); -} - -void op_mttdsp(void) -{ - int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - - T0 = env->DSPControl[other_tc]; - FORCE_RET(); -} - - -void op_dmt(void) -{ - // TODO - T0 = 0; - // rt = T0 - FORCE_RET(); -} - -void op_emt(void) -{ - // TODO - T0 = 0; - // rt = T0 - FORCE_RET(); -} - -void op_dvpe(void) -{ - // TODO - T0 = 0; - // rt = T0 - FORCE_RET(); -} - -void op_evpe(void) -{ - // TODO - T0 = 0; - // rt = T0 - FORCE_RET(); -} - -void op_fork(void) -{ - // T0 = rt, T1 = rs - T0 = 0; - // TODO: store to TC register - FORCE_RET(); -} - -void op_yield(void) -{ - if (T0 < 0) { - /* No scheduling policy implemented. */ - if (T0 != -2) { - if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) && - env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) { - env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT); - env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT; - CALL_FROM_TB1(do_raise_exception, EXCP_THREAD); - } - } - } else if (T0 == 0) { - if (0 /* TODO: TC underflow */) { - env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT); - CALL_FROM_TB1(do_raise_exception, EXCP_THREAD); - } else { - // TODO: Deallocate TC - } - } else if (T0 > 0) { - /* Yield qualifier inputs not implemented. */ - env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT); - env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT; - CALL_FROM_TB1(do_raise_exception, EXCP_THREAD); - } - T0 = env->CP0_YQMask; - FORCE_RET(); -} - /* CP1 functions */ #if 0 # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env) @@ -1407,20 +467,6 @@ void op_yield(void) # define DEBUG_FPU_STATE() do { } while(0) #endif -void op_cfc1 (void) -{ - CALL_FROM_TB1(do_cfc1, PARAM1); - DEBUG_FPU_STATE(); - FORCE_RET(); -} - -void op_ctc1 (void) -{ - CALL_FROM_TB1(do_ctc1, PARAM1); - DEBUG_FPU_STATE(); - FORCE_RET(); -} - void op_mfc1 (void) { T0 = (int32_t)WT0; diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 2020e9efe..ae91acdb0 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -306,7 +306,7 @@ void do_mulshiu (void) } #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ -#if defined(CONFIG_USER_ONLY) +#ifdef CONFIG_USER_ONLY void do_mfc0_random (void) { cpu_abort(env, "mfc0 random\n"); @@ -360,16 +360,662 @@ void cpu_mips_tlb_flush (CPUState *env, int flush_global) #else /* CP0 helpers */ +void do_mfc0_mvpcontrol (void) +{ + T0 = env->mvp->CP0_MVPControl; +} + +void do_mfc0_mvpconf0 (void) +{ + T0 = env->mvp->CP0_MVPConf0; +} + +void do_mfc0_mvpconf1 (void) +{ + T0 = env->mvp->CP0_MVPConf1; +} + void do_mfc0_random (void) { T0 = (int32_t)cpu_mips_get_random(env); } +void do_mfc0_tcstatus (void) +{ + T0 = env->CP0_TCStatus[env->current_tc]; +} + +void do_mftc0_tcstatus(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->CP0_TCStatus[other_tc]; +} + +void do_mfc0_tcbind (void) +{ + T0 = env->CP0_TCBind[env->current_tc]; +} + +void do_mftc0_tcbind(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->CP0_TCBind[other_tc]; +} + +void do_mfc0_tcrestart (void) +{ + T0 = env->PC[env->current_tc]; +} + +void do_mftc0_tcrestart(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->PC[other_tc]; +} + +void do_mfc0_tchalt (void) +{ + T0 = env->CP0_TCHalt[env->current_tc]; +} + +void do_mftc0_tchalt(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->CP0_TCHalt[other_tc]; +} + +void do_mfc0_tccontext (void) +{ + T0 = env->CP0_TCContext[env->current_tc]; +} + +void do_mftc0_tccontext(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->CP0_TCContext[other_tc]; +} + +void do_mfc0_tcschedule (void) +{ + T0 = env->CP0_TCSchedule[env->current_tc]; +} + +void do_mftc0_tcschedule(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->CP0_TCSchedule[other_tc]; +} + +void do_mfc0_tcschefback (void) +{ + T0 = env->CP0_TCScheFBack[env->current_tc]; +} + +void do_mftc0_tcschefback(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->CP0_TCScheFBack[other_tc]; +} + void do_mfc0_count (void) { T0 = (int32_t)cpu_mips_get_count(env); } +void do_mftc0_entryhi(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff); +} + +void do_mftc0_status(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + uint32_t tcstatus = env->CP0_TCStatus[other_tc]; + + T0 = env->CP0_Status & ~0xf1000018; + T0 |= tcstatus & (0xf << CP0TCSt_TCU0); + T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX); + T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU); +} + +void do_mfc0_lladdr (void) +{ + T0 = (int32_t)env->CP0_LLAddr >> 4; +} + +void do_mfc0_watchlo (uint32_t sel) +{ + T0 = (int32_t)env->CP0_WatchLo[sel]; +} + +void do_mfc0_watchhi (uint32_t sel) +{ + T0 = env->CP0_WatchHi[sel]; +} + +void do_mfc0_debug (void) +{ + T0 = env->CP0_Debug; + if (env->hflags & MIPS_HFLAG_DM) + T0 |= 1 << CP0DB_DM; +} + +void do_mftc0_debug(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + /* XXX: Might be wrong, check with EJTAG spec. */ + T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | + (env->CP0_Debug_tcstatus[other_tc] & + ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); +} + +#if defined(TARGET_MIPS64) +void do_dmfc0_tcrestart (void) +{ + T0 = env->PC[env->current_tc]; +} + +void do_dmfc0_tchalt (void) +{ + T0 = env->CP0_TCHalt[env->current_tc]; +} + +void do_dmfc0_tccontext (void) +{ + T0 = env->CP0_TCContext[env->current_tc]; +} + +void do_dmfc0_tcschedule (void) +{ + T0 = env->CP0_TCSchedule[env->current_tc]; +} + +void do_dmfc0_tcschefback (void) +{ + T0 = env->CP0_TCScheFBack[env->current_tc]; +} + +void do_dmfc0_lladdr (void) +{ + T0 = env->CP0_LLAddr >> 4; +} + +void do_dmfc0_watchlo (uint32_t sel) +{ + T0 = env->CP0_WatchLo[sel]; +} +#endif /* TARGET_MIPS64 */ + +void do_mtc0_index (void) +{ + int num = 1; + unsigned int tmp = env->tlb->nb_tlb; + + do { + tmp >>= 1; + num <<= 1; + } while (tmp); + env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1)); +} + +void do_mtc0_mvpcontrol (void) +{ + uint32_t mask = 0; + uint32_t newval; + + if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) + mask |= (1 << CP0MVPCo_CPA) | (1 << CP0MVPCo_VPC) | + (1 << CP0MVPCo_EVP); + if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) + mask |= (1 << CP0MVPCo_STLB); + newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask); + + // TODO: Enable/disable shared TLB, enable/disable VPEs. + + env->mvp->CP0_MVPControl = newval; +} + +void do_mtc0_vpecontrol (void) +{ + uint32_t mask; + uint32_t newval; + + mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) | + (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC); + newval = (env->CP0_VPEControl & ~mask) | (T0 & mask); + + /* Yield scheduler intercept not implemented. */ + /* Gating storage scheduler intercept not implemented. */ + + // TODO: Enable/disable TCs. + + env->CP0_VPEControl = newval; +} + +void do_mtc0_vpeconf0 (void) +{ + uint32_t mask = 0; + uint32_t newval; + + if (env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) { + if (env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA)) + mask |= (0xff << CP0VPEC0_XTC); + mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA); + } + newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask); + + // TODO: TC exclusive handling due to ERL/EXL. + + env->CP0_VPEConf0 = newval; +} + +void do_mtc0_vpeconf1 (void) +{ + uint32_t mask = 0; + uint32_t newval; + + if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) + mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) | + (0xff << CP0VPEC1_NCP1); + newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask); + + /* UDI not implemented. */ + /* CP2 not implemented. */ + + // TODO: Handle FPU (CP1) binding. + + env->CP0_VPEConf1 = newval; +} + +void do_mtc0_yqmask (void) +{ + /* Yield qualifier inputs not implemented. */ + env->CP0_YQMask = 0x00000000; +} + +void do_mtc0_vpeopt (void) +{ + env->CP0_VPEOpt = T0 & 0x0000ffff; +} + +void do_mtc0_entrylo0 (void) +{ + /* Large physaddr (PABITS) not implemented */ + /* 1k pages not implemented */ + env->CP0_EntryLo0 = T0 & 0x3FFFFFFF; +} + +void do_mtc0_tcstatus (void) +{ + uint32_t mask = env->CP0_TCStatus_rw_bitmask; + uint32_t newval; + + newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask); + + // TODO: Sync with CP0_Status. + + env->CP0_TCStatus[env->current_tc] = newval; +} + +void do_mttc0_tcstatus (void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + // TODO: Sync with CP0_Status. + + env->CP0_TCStatus[other_tc] = T0; +} + +void do_mtc0_tcbind (void) +{ + uint32_t mask = (1 << CP0TCBd_TBE); + uint32_t newval; + + if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) + mask |= (1 << CP0TCBd_CurVPE); + newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask); + env->CP0_TCBind[env->current_tc] = newval; +} + +void do_mttc0_tcbind (void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + uint32_t mask = (1 << CP0TCBd_TBE); + uint32_t newval; + + if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) + mask |= (1 << CP0TCBd_CurVPE); + newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask); + env->CP0_TCBind[other_tc] = newval; +} + +void do_mtc0_tcrestart (void) +{ + env->PC[env->current_tc] = T0; + env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS); + env->CP0_LLAddr = 0ULL; + /* MIPS16 not implemented. */ +} + +void do_mttc0_tcrestart (void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + env->PC[other_tc] = T0; + env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS); + env->CP0_LLAddr = 0ULL; + /* MIPS16 not implemented. */ +} + +void do_mtc0_tchalt (void) +{ + env->CP0_TCHalt[env->current_tc] = T0 & 0x1; + + // TODO: Halt TC / Restart (if allocated+active) TC. +} + +void do_mttc0_tchalt (void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + // TODO: Halt TC / Restart (if allocated+active) TC. + + env->CP0_TCHalt[other_tc] = T0; +} + +void do_mtc0_tccontext (void) +{ + env->CP0_TCContext[env->current_tc] = T0; +} + +void do_mttc0_tccontext (void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + env->CP0_TCContext[other_tc] = T0; +} + +void do_mtc0_tcschedule (void) +{ + env->CP0_TCSchedule[env->current_tc] = T0; +} + +void do_mttc0_tcschedule (void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + env->CP0_TCSchedule[other_tc] = T0; +} + +void do_mtc0_tcschefback (void) +{ + env->CP0_TCScheFBack[env->current_tc] = T0; +} + +void do_mttc0_tcschefback (void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + env->CP0_TCScheFBack[other_tc] = T0; +} + +void do_mtc0_entrylo1 (void) +{ + /* Large physaddr (PABITS) not implemented */ + /* 1k pages not implemented */ + env->CP0_EntryLo1 = T0 & 0x3FFFFFFF; +} + +void do_mtc0_context (void) +{ + env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF); +} + +void do_mtc0_pagemask (void) +{ + /* 1k pages not implemented */ + env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1)); +} + +void do_mtc0_pagegrain (void) +{ + /* SmartMIPS not implemented */ + /* Large physaddr (PABITS) not implemented */ + /* 1k pages not implemented */ + env->CP0_PageGrain = 0; +} + +void do_mtc0_wired (void) +{ + env->CP0_Wired = T0 % env->tlb->nb_tlb; +} + +void do_mtc0_srsconf0 (void) +{ + env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask; +} + +void do_mtc0_srsconf1 (void) +{ + env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask; +} + +void do_mtc0_srsconf2 (void) +{ + env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask; +} + +void do_mtc0_srsconf3 (void) +{ + env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask; +} + +void do_mtc0_srsconf4 (void) +{ + env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask; +} + +void do_mtc0_hwrena (void) +{ + env->CP0_HWREna = T0 & 0x0000000F; +} + +void do_mtc0_count (void) +{ + cpu_mips_store_count(env, T0); +} + +void do_mtc0_entryhi (void) +{ + target_ulong old, val; + + /* 1k pages not implemented */ + val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF); +#if defined(TARGET_MIPS64) + val &= env->SEGMask; +#endif + old = env->CP0_EntryHi; + env->CP0_EntryHi = val; + if (env->CP0_Config3 & (1 << CP0C3_MT)) { + uint32_t tcst = env->CP0_TCStatus[env->current_tc] & ~0xff; + env->CP0_TCStatus[env->current_tc] = tcst | (val & 0xff); + } + /* If the ASID changes, flush qemu's TLB. */ + if ((old & 0xFF) != (val & 0xFF)) + cpu_mips_tlb_flush(env, 1); +} + +void do_mttc0_entryhi(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff); + env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff); +} + +void do_mtc0_compare (void) +{ + cpu_mips_store_compare(env, T0); +} + +void do_mtc0_status (void) +{ + uint32_t val, old; + uint32_t mask = env->CP0_Status_rw_bitmask; + + val = T0 & mask; + old = env->CP0_Status; + env->CP0_Status = (env->CP0_Status & ~mask) | val; + compute_hflags(env); + if (loglevel & CPU_LOG_EXEC) + do_mtc0_status_debug(old, val); + cpu_mips_update_irq(env); +} + +void do_mttc0_status(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + uint32_t tcstatus = env->CP0_TCStatus[other_tc]; + + env->CP0_Status = T0 & ~0xf1000018; + tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0)); + tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX)); + tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU)); + env->CP0_TCStatus[other_tc] = tcstatus; +} + +void do_mtc0_intctl (void) +{ + /* vectored interrupts not implemented, no performance counters. */ + env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0); +} + +void do_mtc0_srsctl (void) +{ + uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS); + env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask); +} + +void do_mtc0_cause (void) +{ + uint32_t mask = 0x00C00300; + uint32_t old = env->CP0_Cause; + + if (env->insn_flags & ISA_MIPS32R2) + mask |= 1 << CP0Ca_DC; + + env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask); + + if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) { + if (env->CP0_Cause & (1 << CP0Ca_DC)) + cpu_mips_stop_count(env); + else + cpu_mips_start_count(env); + } + + /* Handle the software interrupt as an hardware one, as they + are very similar */ + if (T0 & CP0Ca_IP_mask) { + cpu_mips_update_irq(env); + } +} + +void do_mtc0_ebase (void) +{ + /* vectored interrupts not implemented */ + /* Multi-CPU not implemented */ + env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000); +} + +void do_mtc0_config0 (void) +{ + env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007); +} + +void do_mtc0_config2 (void) +{ + /* tertiary/secondary caches not implemented */ + env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF); +} + +void do_mtc0_watchlo (uint32_t sel) +{ + /* Watch exceptions for instructions, data loads, data stores + not implemented. */ + env->CP0_WatchLo[sel] = (T0 & ~0x7); +} + +void do_mtc0_watchhi (uint32_t sel) +{ + env->CP0_WatchHi[sel] = (T0 & 0x40FF0FF8); + env->CP0_WatchHi[sel] &= ~(env->CP0_WatchHi[sel] & T0 & 0x7); +} + +void do_mtc0_xcontext (void) +{ + target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1; + env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask); +} + +void do_mtc0_framemask (void) +{ + env->CP0_Framemask = T0; /* XXX */ +} + +void do_mtc0_debug (void) +{ + env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120); + if (T0 & (1 << CP0DB_DM)) + env->hflags |= MIPS_HFLAG_DM; + else + env->hflags &= ~MIPS_HFLAG_DM; +} + +void do_mttc0_debug(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + /* XXX: Might be wrong, check with EJTAG spec. */ + env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)); + env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | + (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); +} + +void do_mtc0_performance0 (void) +{ + env->CP0_Performance0 = T0 & 0x000007ff; +} + +void do_mtc0_taglo (void) +{ + env->CP0_TagLo = T0 & 0xFFFFFCF6; +} + +void do_mtc0_datalo (void) +{ + env->CP0_DataLo = T0; /* XXX */ +} + +void do_mtc0_taghi (void) +{ + env->CP0_TagHi = T0; /* XXX */ +} + +void do_mtc0_datahi (void) +{ + env->CP0_DataHi = T0; /* XXX */ +} + void do_mtc0_status_debug(uint32_t old, uint32_t val) { fprintf(logfile, "Status %08x (%08x) => %08x (%08x) Cause %08x", @@ -388,7 +1034,144 @@ void do_mtc0_status_irqraise_debug(void) { fprintf(logfile, "Raise pending IRQs\n"); } +#endif /* !CONFIG_USER_ONLY */ + +/* MIPS MT functions */ +void do_mftgpr(uint32_t sel) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->gpr[other_tc][sel]; +} + +void do_mftlo(uint32_t sel) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->LO[other_tc][sel]; +} + +void do_mfthi(uint32_t sel) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->HI[other_tc][sel]; +} + +void do_mftacx(uint32_t sel) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->ACX[other_tc][sel]; +} + +void do_mftdsp(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->DSPControl[other_tc]; +} +void do_mttgpr(uint32_t sel) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->gpr[other_tc][sel]; +} + +void do_mttlo(uint32_t sel) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->LO[other_tc][sel]; +} + +void do_mtthi(uint32_t sel) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->HI[other_tc][sel]; +} + +void do_mttacx(uint32_t sel) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->ACX[other_tc][sel]; +} + +void do_mttdsp(void) +{ + int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + + T0 = env->DSPControl[other_tc]; +} + +/* MIPS MT functions */ +void do_dmt(void) +{ + // TODO + T0 = 0; + // rt = T0 +} + +void do_emt(void) +{ + // TODO + T0 = 0; + // rt = T0 +} + +void do_dvpe(void) +{ + // TODO + T0 = 0; + // rt = T0 +} + +void do_evpe(void) +{ + // TODO + T0 = 0; + // rt = T0 +} + +void do_fork(void) +{ + // T0 = rt, T1 = rs + T0 = 0; + // TODO: store to TC register +} + +void do_yield(void) +{ + if (T0 < 0) { + /* No scheduling policy implemented. */ + if (T0 != -2) { + if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) && + env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) { + env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT); + env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT; + do_raise_exception(EXCP_THREAD); + } + } + } else if (T0 == 0) { + if (0 /* TODO: TC underflow */) { + env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT); + do_raise_exception(EXCP_THREAD); + } else { + // TODO: Deallocate TC + } + } else if (T0 > 0) { + /* Yield qualifier inputs not implemented. */ + env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT); + env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT; + do_raise_exception(EXCP_THREAD); + } + T0 = env->CP0_YQMask; +} + +/* CP1 functions */ void fpu_handle_exception(void) { #ifdef CONFIG_SOFTFLOAT @@ -426,6 +1209,7 @@ void fpu_handle_exception(void) #endif } +#ifndef CONFIG_USER_ONLY /* TLB management */ void cpu_mips_tlb_flush (CPUState *env, int flush_global) { @@ -679,7 +1463,7 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, else do_raise_exception(EXCP_DBE); } -#endif +#endif /* !CONFIG_USER_ONLY */ /* Complex FPU operations which may need stack space. */ @@ -703,7 +1487,7 @@ unsigned int ieee_rm[] = { #define RESTORE_ROUNDING_MODE \ set_float_rounding_mode(ieee_rm[env->fpu->fcr31 & 3], &env->fpu->fp_status) -void do_cfc1 (int reg) +void do_cfc1 (uint32_t reg) { switch (reg) { case 0: @@ -724,7 +1508,7 @@ void do_cfc1 (int reg) } } -void do_ctc1 (int reg) +void do_ctc1 (uint32_t reg) { switch(reg) { case 25: diff --git a/target-mips/translate.c b/target-mips/translate.c index e6b3f547c..c744c9afb 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -2583,6 +2583,7 @@ fail: } /* CP0 (MMU and control) */ +#ifndef CONFIG_USER_ONLY static inline void gen_mfc0_load32 (TCGv t, target_ulong off) { TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); @@ -2601,6 +2602,24 @@ static inline void gen_mfc0_load64 (TCGv t, target_ulong off) tcg_temp_free(r_tmp); } +static inline void gen_mtc0_store32 (TCGv t, target_ulong off) +{ + TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); + + tcg_gen_trunc_tl_i32(r_tmp, t); + tcg_gen_st_i32(r_tmp, cpu_env, off); + tcg_temp_free(r_tmp); +} + +static inline void gen_mtc0_store64 (TCGv t, target_ulong off) +{ + TCGv r_tmp = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ext_tl_i64(r_tmp, t); + tcg_gen_st_i64(r_tmp, cpu_env, off); + tcg_temp_free(r_tmp); +} + static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) { const char *rn = "invalid"; @@ -2617,17 +2636,17 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_mvpcontrol(); + tcg_gen_helper_0_0(do_mfc0_mvpcontrol); rn = "MVPControl"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_mvpconf0(); + tcg_gen_helper_0_0(do_mfc0_mvpconf0); rn = "MVPConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_mvpconf1(); + tcg_gen_helper_0_0(do_mfc0_mvpconf1); rn = "MVPConf1"; break; default: @@ -2637,7 +2656,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 1: switch (sel) { case 0: - gen_op_mfc0_random(); + tcg_gen_helper_0_0(do_mfc0_random); rn = "Random"; break; case 1: @@ -2688,37 +2707,37 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tcstatus(); + tcg_gen_helper_0_0(do_mfc0_tcstatus); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tcbind(); + tcg_gen_helper_0_0(do_mfc0_tcbind); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tcrestart(); + tcg_gen_helper_0_0(do_mfc0_tcrestart); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tchalt(); + tcg_gen_helper_0_0(do_mfc0_tchalt); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tccontext(); + tcg_gen_helper_0_0(do_mfc0_tccontext); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tcschedule(); + tcg_gen_helper_0_0(do_mfc0_tcschedule); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tcschefback(); + tcg_gen_helper_0_0(do_mfc0_tcschefback); rn = "TCScheFBack"; break; default: @@ -2744,7 +2763,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Context"; break; case 1: -// gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */ +// tcg_gen_helper_0_0(do_mfc0_contextconfig); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -2826,7 +2845,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - gen_op_mfc0_count(); + tcg_gen_helper_0_0(do_mfc0_count); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -2952,7 +2971,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 17: switch (sel) { case 0: - gen_op_mfc0_lladdr(); + tcg_gen_helper_0_0(do_mfc0_lladdr); rn = "LLAddr"; break; default: @@ -2962,7 +2981,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - gen_op_mfc0_watchlo(sel); + tcg_gen_helper_0_1i(do_mfc0_watchlo, sel); rn = "WatchLo"; break; default: @@ -2972,7 +2991,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ...7: - gen_op_mfc0_watchhi(sel); + tcg_gen_helper_0_1i(do_mfc0_watchhi, sel); rn = "WatchHi"; break; default: @@ -3011,23 +3030,23 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - gen_op_mfc0_debug(); /* EJTAG support */ + tcg_gen_helper_0_0(do_mfc0_debug); /* EJTAG support */ rn = "Debug"; break; case 1: -// gen_op_mfc0_tracecontrol(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_mfc0_tracecontrol); /* PDtrace support */ rn = "TraceControl"; // break; case 2: -// gen_op_mfc0_tracecontrol2(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_mfc0_tracecontrol2); /* PDtrace support */ rn = "TraceControl2"; // break; case 3: -// gen_op_mfc0_usertracedata(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_mfc0_usertracedata); /* PDtrace support */ rn = "UserTraceData"; // break; case 4: -// gen_op_mfc0_debug(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_mfc0_debug); /* PDtrace support */ rn = "TraceBPC"; // break; default: @@ -3053,31 +3072,31 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Performance0"; break; case 1: -// gen_op_mfc0_performance1(); +// tcg_gen_helper_0_0(do_mfc0_performance1); rn = "Performance1"; // break; case 2: -// gen_op_mfc0_performance2(); +// tcg_gen_helper_0_0(do_mfc0_performance2); rn = "Performance2"; // break; case 3: -// gen_op_mfc0_performance3(); +// tcg_gen_helper_0_0(do_mfc0_performance3); rn = "Performance3"; // break; case 4: -// gen_op_mfc0_performance4(); +// tcg_gen_helper_0_0(do_mfc0_performance4); rn = "Performance4"; // break; case 5: -// gen_op_mfc0_performance5(); +// tcg_gen_helper_0_0(do_mfc0_performance5); rn = "Performance5"; // break; case 6: -// gen_op_mfc0_performance6(); +// tcg_gen_helper_0_0(do_mfc0_performance6); rn = "Performance6"; // break; case 7: -// gen_op_mfc0_performance7(); +// tcg_gen_helper_0_0(do_mfc0_performance7); rn = "Performance7"; // break; default: @@ -3191,12 +3210,12 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: switch (sel) { case 0: - gen_op_mtc0_index(); + tcg_gen_helper_0_0(do_mtc0_index); rn = "Index"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_mvpcontrol(); + tcg_gen_helper_0_0(do_mtc0_mvpcontrol); rn = "MVPControl"; break; case 2: @@ -3221,37 +3240,37 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpecontrol(); + tcg_gen_helper_0_0(do_mtc0_vpecontrol); rn = "VPEControl"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeconf0(); + tcg_gen_helper_0_0(do_mtc0_vpeconf0); rn = "VPEConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeconf1(); + tcg_gen_helper_0_0(do_mtc0_vpeconf1); rn = "VPEConf1"; break; case 4: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_yqmask(); + tcg_gen_helper_0_0(do_mtc0_yqmask); rn = "YQMask"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeschedule(); + gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_VPESchedule)); rn = "VPESchedule"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeschefback(); + gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_VPEScheFBack)); rn = "VPEScheFBack"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeopt(); + tcg_gen_helper_0_0(do_mtc0_vpeopt); rn = "VPEOpt"; break; default: @@ -3261,42 +3280,42 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: switch (sel) { case 0: - gen_op_mtc0_entrylo0(); + tcg_gen_helper_0_0(do_mtc0_entrylo0); rn = "EntryLo0"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcstatus(); + tcg_gen_helper_0_0(do_mtc0_tcstatus); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcbind(); + tcg_gen_helper_0_0(do_mtc0_tcbind); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcrestart(); + tcg_gen_helper_0_0(do_mtc0_tcrestart); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tchalt(); + tcg_gen_helper_0_0(do_mtc0_tchalt); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tccontext(); + tcg_gen_helper_0_0(do_mtc0_tccontext); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcschedule(); + tcg_gen_helper_0_0(do_mtc0_tcschedule); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcschefback(); + tcg_gen_helper_0_0(do_mtc0_tcschefback); rn = "TCScheFBack"; break; default: @@ -3306,7 +3325,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: switch (sel) { case 0: - gen_op_mtc0_entrylo1(); + tcg_gen_helper_0_0(do_mtc0_entrylo1); rn = "EntryLo1"; break; default: @@ -3316,11 +3335,11 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 4: switch (sel) { case 0: - gen_op_mtc0_context(); + tcg_gen_helper_0_0(do_mtc0_context); rn = "Context"; break; case 1: -// gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */ +// tcg_gen_helper_0_0(do_mtc0_contextconfig); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -3330,12 +3349,12 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 5: switch (sel) { case 0: - gen_op_mtc0_pagemask(); + tcg_gen_helper_0_0(do_mtc0_pagemask); rn = "PageMask"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_pagegrain(); + tcg_gen_helper_0_0(do_mtc0_pagegrain); rn = "PageGrain"; break; default: @@ -3345,32 +3364,32 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 6: switch (sel) { case 0: - gen_op_mtc0_wired(); + tcg_gen_helper_0_0(do_mtc0_wired); rn = "Wired"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf0(); + tcg_gen_helper_0_0(do_mtc0_srsconf0); rn = "SRSConf0"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf1(); + tcg_gen_helper_0_0(do_mtc0_srsconf1); rn = "SRSConf1"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf2(); + tcg_gen_helper_0_0(do_mtc0_srsconf2); rn = "SRSConf2"; break; case 4: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf3(); + tcg_gen_helper_0_0(do_mtc0_srsconf3); rn = "SRSConf3"; break; case 5: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf4(); + tcg_gen_helper_0_0(do_mtc0_srsconf4); rn = "SRSConf4"; break; default: @@ -3381,7 +3400,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_hwrena(); + tcg_gen_helper_0_0(do_mtc0_hwrena); rn = "HWREna"; break; default: @@ -3395,7 +3414,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - gen_op_mtc0_count(); + tcg_gen_helper_0_0(do_mtc0_count); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -3408,7 +3427,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 10: switch (sel) { case 0: - gen_op_mtc0_entryhi(); + tcg_gen_helper_0_0(do_mtc0_entryhi); rn = "EntryHi"; break; default: @@ -3418,7 +3437,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 11: switch (sel) { case 0: - gen_op_mtc0_compare(); + tcg_gen_helper_0_0(do_mtc0_compare); rn = "Compare"; break; /* 6,7 are implementation dependent */ @@ -3431,7 +3450,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 12: switch (sel) { case 0: - gen_op_mtc0_status(); + tcg_gen_helper_0_0(do_mtc0_status); /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; @@ -3439,21 +3458,21 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_intctl(); + tcg_gen_helper_0_0(do_mtc0_intctl); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "IntCtl"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsctl(); + tcg_gen_helper_0_0(do_mtc0_srsctl); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSCtl"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsmap(); + gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_SRSMap)); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSMap"; @@ -3465,7 +3484,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 13: switch (sel) { case 0: - gen_op_mtc0_cause(); + tcg_gen_helper_0_0(do_mtc0_cause); rn = "Cause"; break; default: @@ -3477,7 +3496,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 14: switch (sel) { case 0: - gen_op_mtc0_epc(); + gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_EPC)); rn = "EPC"; break; default: @@ -3492,7 +3511,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_ebase(); + tcg_gen_helper_0_0(do_mtc0_ebase); rn = "EBase"; break; default: @@ -3502,7 +3521,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 16: switch (sel) { case 0: - gen_op_mtc0_config0(); + tcg_gen_helper_0_0(do_mtc0_config0); rn = "Config"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -3512,7 +3531,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Config1"; break; case 2: - gen_op_mtc0_config2(); + tcg_gen_helper_0_0(do_mtc0_config2); rn = "Config2"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -3549,7 +3568,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - gen_op_mtc0_watchlo(sel); + tcg_gen_helper_0_1i(do_mtc0_watchlo, sel); rn = "WatchLo"; break; default: @@ -3559,7 +3578,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ... 7: - gen_op_mtc0_watchhi(sel); + tcg_gen_helper_0_1i(do_mtc0_watchhi, sel); rn = "WatchHi"; break; default: @@ -3571,7 +3590,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: #if defined(TARGET_MIPS64) check_insn(env, ctx, ISA_MIPS3); - gen_op_mtc0_xcontext(); + tcg_gen_helper_0_0(do_mtc0_xcontext); rn = "XContext"; break; #endif @@ -3583,7 +3602,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) /* Officially reserved, but sel 0 is used for R1x000 framemask */ switch (sel) { case 0: - gen_op_mtc0_framemask(); + tcg_gen_helper_0_0(do_mtc0_framemask); rn = "Framemask"; break; default: @@ -3597,20 +3616,20 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - gen_op_mtc0_debug(); /* EJTAG support */ + tcg_gen_helper_0_0(do_mtc0_debug); /* EJTAG support */ /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; rn = "Debug"; break; case 1: -// gen_op_mtc0_tracecontrol(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_mtc0_tracecontrol); /* PDtrace support */ rn = "TraceControl"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; // break; case 2: -// gen_op_mtc0_tracecontrol2(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_mtc0_tracecontrol2); /* PDtrace support */ rn = "TraceControl2"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -3618,13 +3637,13 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; -// gen_op_mtc0_usertracedata(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_mtc0_usertracedata); /* PDtrace support */ rn = "UserTraceData"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; // break; case 4: -// gen_op_mtc0_debug(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_mtc0_debug); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceBPC"; @@ -3636,7 +3655,8 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 24: switch (sel) { case 0: - gen_op_mtc0_depc(); /* EJTAG support */ + /* EJTAG support */ + gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_DEPC)); rn = "DEPC"; break; default: @@ -3646,35 +3666,35 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 25: switch (sel) { case 0: - gen_op_mtc0_performance0(); + tcg_gen_helper_0_0(do_mtc0_performance0); rn = "Performance0"; break; case 1: -// gen_op_mtc0_performance1(); +// tcg_gen_helper_0_0(do_mtc0_performance1); rn = "Performance1"; // break; case 2: -// gen_op_mtc0_performance2(); +// tcg_gen_helper_0_0(do_mtc0_performance2); rn = "Performance2"; // break; case 3: -// gen_op_mtc0_performance3(); +// tcg_gen_helper_0_0(do_mtc0_performance3); rn = "Performance3"; // break; case 4: -// gen_op_mtc0_performance4(); +// tcg_gen_helper_0_0(do_mtc0_performance4); rn = "Performance4"; // break; case 5: -// gen_op_mtc0_performance5(); +// tcg_gen_helper_0_0(do_mtc0_performance5); rn = "Performance5"; // break; case 6: -// gen_op_mtc0_performance6(); +// tcg_gen_helper_0_0(do_mtc0_performance6); rn = "Performance6"; // break; case 7: -// gen_op_mtc0_performance7(); +// tcg_gen_helper_0_0(do_mtc0_performance7); rn = "Performance7"; // break; default: @@ -3701,14 +3721,14 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_op_mtc0_taglo(); + tcg_gen_helper_0_0(do_mtc0_taglo); rn = "TagLo"; break; case 1: case 3: case 5: case 7: - gen_op_mtc0_datalo(); + tcg_gen_helper_0_0(do_mtc0_datalo); rn = "DataLo"; break; default: @@ -3721,14 +3741,14 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_op_mtc0_taghi(); + tcg_gen_helper_0_0(do_mtc0_taghi); rn = "TagHi"; break; case 1: case 3: case 5: case 7: - gen_op_mtc0_datahi(); + tcg_gen_helper_0_0(do_mtc0_datahi); rn = "DataHi"; break; default: @@ -3739,7 +3759,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 30: switch (sel) { case 0: - gen_op_mtc0_errorepc(); + gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_ErrorEPC)); rn = "ErrorEPC"; break; default: @@ -3749,7 +3769,8 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 31: switch (sel) { case 0: - gen_op_mtc0_desave(); /* EJTAG support */ + /* EJTAG support */ + gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_DESAVE)); rn = "DESAVE"; break; default: @@ -3796,17 +3817,17 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_mvpcontrol(); + tcg_gen_helper_0_0(do_mfc0_mvpcontrol); rn = "MVPControl"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_mvpconf0(); + tcg_gen_helper_0_0(do_mfc0_mvpconf0); rn = "MVPConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_mvpconf1(); + tcg_gen_helper_0_0(do_mfc0_mvpconf1); rn = "MVPConf1"; break; default: @@ -3816,7 +3837,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 1: switch (sel) { case 0: - gen_op_mfc0_random(); + tcg_gen_helper_0_0(do_mfc0_random); rn = "Random"; break; case 1: @@ -3866,37 +3887,37 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tcstatus(); + tcg_gen_helper_0_0(do_mfc0_tcstatus); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mfc0_tcbind(); + tcg_gen_helper_0_0(do_mfc0_tcbind); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_dmfc0_tcrestart(); + tcg_gen_helper_0_0(do_dmfc0_tcrestart); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - gen_op_dmfc0_tchalt(); + tcg_gen_helper_0_0(do_dmfc0_tchalt); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_op_dmfc0_tccontext(); + tcg_gen_helper_0_0(do_dmfc0_tccontext); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_op_dmfc0_tcschedule(); + tcg_gen_helper_0_0(do_dmfc0_tcschedule); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_op_dmfc0_tcschefback(); + tcg_gen_helper_0_0(do_dmfc0_tcschefback); rn = "TCScheFBack"; break; default: @@ -3920,7 +3941,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Context"; break; case 1: -// gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */ +// tcg_gen_helper_0_0(do_dmfc0_contextconfig); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -4001,7 +4022,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - gen_op_mfc0_count(); + tcg_gen_helper_0_0(do_mfc0_count); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -4124,7 +4145,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 17: switch (sel) { case 0: - gen_op_dmfc0_lladdr(); + tcg_gen_helper_0_0(do_dmfc0_lladdr); rn = "LLAddr"; break; default: @@ -4134,7 +4155,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - gen_op_dmfc0_watchlo(sel); + tcg_gen_helper_0_1i(do_dmfc0_watchlo, sel); rn = "WatchLo"; break; default: @@ -4144,7 +4165,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ... 7: - gen_op_mfc0_watchhi(sel); + tcg_gen_helper_0_1i(do_mfc0_watchhi, sel); rn = "WatchHi"; break; default: @@ -4180,23 +4201,23 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - gen_op_mfc0_debug(); /* EJTAG support */ + tcg_gen_helper_0_0(do_mfc0_debug); /* EJTAG support */ rn = "Debug"; break; case 1: -// gen_op_dmfc0_tracecontrol(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_dmfc0_tracecontrol); /* PDtrace support */ rn = "TraceControl"; // break; case 2: -// gen_op_dmfc0_tracecontrol2(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_dmfc0_tracecontrol2); /* PDtrace support */ rn = "TraceControl2"; // break; case 3: -// gen_op_dmfc0_usertracedata(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_dmfc0_usertracedata); /* PDtrace support */ rn = "UserTraceData"; // break; case 4: -// gen_op_dmfc0_debug(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_dmfc0_debug); /* PDtrace support */ rn = "TraceBPC"; // break; default: @@ -4221,31 +4242,31 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Performance0"; break; case 1: -// gen_op_dmfc0_performance1(); +// tcg_gen_helper_0_0(do_dmfc0_performance1); rn = "Performance1"; // break; case 2: -// gen_op_dmfc0_performance2(); +// tcg_gen_helper_0_0(do_dmfc0_performance2); rn = "Performance2"; // break; case 3: -// gen_op_dmfc0_performance3(); +// tcg_gen_helper_0_0(do_dmfc0_performance3); rn = "Performance3"; // break; case 4: -// gen_op_dmfc0_performance4(); +// tcg_gen_helper_0_0(do_dmfc0_performance4); rn = "Performance4"; // break; case 5: -// gen_op_dmfc0_performance5(); +// tcg_gen_helper_0_0(do_dmfc0_performance5); rn = "Performance5"; // break; case 6: -// gen_op_dmfc0_performance6(); +// tcg_gen_helper_0_0(do_dmfc0_performance6); rn = "Performance6"; // break; case 7: -// gen_op_dmfc0_performance7(); +// tcg_gen_helper_0_0(do_dmfc0_performance7); rn = "Performance7"; // break; default: @@ -4358,12 +4379,12 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: switch (sel) { case 0: - gen_op_mtc0_index(); + tcg_gen_helper_0_0(do_mtc0_index); rn = "Index"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_mvpcontrol(); + tcg_gen_helper_0_0(do_mtc0_mvpcontrol); rn = "MVPControl"; break; case 2: @@ -4388,37 +4409,37 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpecontrol(); + tcg_gen_helper_0_0(do_mtc0_vpecontrol); rn = "VPEControl"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeconf0(); + tcg_gen_helper_0_0(do_mtc0_vpeconf0); rn = "VPEConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeconf1(); + tcg_gen_helper_0_0(do_mtc0_vpeconf1); rn = "VPEConf1"; break; case 4: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_yqmask(); + tcg_gen_helper_0_0(do_mtc0_yqmask); rn = "YQMask"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeschedule(); + tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule)); rn = "VPESchedule"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeschefback(); + tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack)); rn = "VPEScheFBack"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_vpeopt(); + tcg_gen_helper_0_0(do_mtc0_vpeopt); rn = "VPEOpt"; break; default: @@ -4428,42 +4449,42 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: switch (sel) { case 0: - gen_op_mtc0_entrylo0(); + tcg_gen_helper_0_0(do_mtc0_entrylo0); rn = "EntryLo0"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcstatus(); + tcg_gen_helper_0_0(do_mtc0_tcstatus); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcbind(); + tcg_gen_helper_0_0(do_mtc0_tcbind); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcrestart(); + tcg_gen_helper_0_0(do_mtc0_tcrestart); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tchalt(); + tcg_gen_helper_0_0(do_mtc0_tchalt); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tccontext(); + tcg_gen_helper_0_0(do_mtc0_tccontext); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcschedule(); + tcg_gen_helper_0_0(do_mtc0_tcschedule); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_op_mtc0_tcschefback(); + tcg_gen_helper_0_0(do_mtc0_tcschefback); rn = "TCScheFBack"; break; default: @@ -4473,7 +4494,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: switch (sel) { case 0: - gen_op_mtc0_entrylo1(); + tcg_gen_helper_0_0(do_mtc0_entrylo1); rn = "EntryLo1"; break; default: @@ -4483,11 +4504,11 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 4: switch (sel) { case 0: - gen_op_mtc0_context(); + tcg_gen_helper_0_0(do_mtc0_context); rn = "Context"; break; case 1: -// gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */ +// tcg_gen_helper_0_0(do_mtc0_contextconfig); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -4497,12 +4518,12 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 5: switch (sel) { case 0: - gen_op_mtc0_pagemask(); + tcg_gen_helper_0_0(do_mtc0_pagemask); rn = "PageMask"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_pagegrain(); + tcg_gen_helper_0_0(do_mtc0_pagegrain); rn = "PageGrain"; break; default: @@ -4512,32 +4533,32 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 6: switch (sel) { case 0: - gen_op_mtc0_wired(); + tcg_gen_helper_0_0(do_mtc0_wired); rn = "Wired"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf0(); + tcg_gen_helper_0_0(do_mtc0_srsconf0); rn = "SRSConf0"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf1(); + tcg_gen_helper_0_0(do_mtc0_srsconf1); rn = "SRSConf1"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf2(); + tcg_gen_helper_0_0(do_mtc0_srsconf2); rn = "SRSConf2"; break; case 4: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf3(); + tcg_gen_helper_0_0(do_mtc0_srsconf3); rn = "SRSConf3"; break; case 5: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsconf4(); + tcg_gen_helper_0_0(do_mtc0_srsconf4); rn = "SRSConf4"; break; default: @@ -4548,7 +4569,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_hwrena(); + tcg_gen_helper_0_0(do_mtc0_hwrena); rn = "HWREna"; break; default: @@ -4562,7 +4583,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - gen_op_mtc0_count(); + tcg_gen_helper_0_0(do_mtc0_count); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -4575,7 +4596,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 10: switch (sel) { case 0: - gen_op_mtc0_entryhi(); + tcg_gen_helper_0_0(do_mtc0_entryhi); rn = "EntryHi"; break; default: @@ -4585,7 +4606,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 11: switch (sel) { case 0: - gen_op_mtc0_compare(); + tcg_gen_helper_0_0(do_mtc0_compare); rn = "Compare"; break; /* 6,7 are implementation dependent */ @@ -4598,7 +4619,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 12: switch (sel) { case 0: - gen_op_mtc0_status(); + tcg_gen_helper_0_0(do_mtc0_status); /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; @@ -4606,21 +4627,21 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_intctl(); + tcg_gen_helper_0_0(do_mtc0_intctl); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "IntCtl"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsctl(); + tcg_gen_helper_0_0(do_mtc0_srsctl); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSCtl"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_srsmap(); + gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_SRSMap)); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSMap"; @@ -4632,7 +4653,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 13: switch (sel) { case 0: - gen_op_mtc0_cause(); + tcg_gen_helper_0_0(do_mtc0_cause); rn = "Cause"; break; default: @@ -4644,7 +4665,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 14: switch (sel) { case 0: - gen_op_mtc0_epc(); + tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC)); rn = "EPC"; break; default: @@ -4659,7 +4680,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_op_mtc0_ebase(); + tcg_gen_helper_0_0(do_mtc0_ebase); rn = "EBase"; break; default: @@ -4669,7 +4690,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 16: switch (sel) { case 0: - gen_op_mtc0_config0(); + tcg_gen_helper_0_0(do_mtc0_config0); rn = "Config"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -4679,7 +4700,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Config1"; break; case 2: - gen_op_mtc0_config2(); + tcg_gen_helper_0_0(do_mtc0_config2); rn = "Config2"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -4707,7 +4728,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - gen_op_mtc0_watchlo(sel); + tcg_gen_helper_0_1i(do_mtc0_watchlo, sel); rn = "WatchLo"; break; default: @@ -4717,7 +4738,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ... 7: - gen_op_mtc0_watchhi(sel); + tcg_gen_helper_0_1i(do_mtc0_watchhi, sel); rn = "WatchHi"; break; default: @@ -4728,7 +4749,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS3); - gen_op_mtc0_xcontext(); + tcg_gen_helper_0_0(do_mtc0_xcontext); rn = "XContext"; break; default: @@ -4739,7 +4760,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) /* Officially reserved, but sel 0 is used for R1x000 framemask */ switch (sel) { case 0: - gen_op_mtc0_framemask(); + tcg_gen_helper_0_0(do_mtc0_framemask); rn = "Framemask"; break; default: @@ -4753,32 +4774,32 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - gen_op_mtc0_debug(); /* EJTAG support */ + tcg_gen_helper_0_0(do_mtc0_debug); /* EJTAG support */ /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; rn = "Debug"; break; case 1: -// gen_op_mtc0_tracecontrol(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_mtc0_tracecontrol); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceControl"; // break; case 2: -// gen_op_mtc0_tracecontrol2(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_mtc0_tracecontrol2); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceControl2"; // break; case 3: -// gen_op_mtc0_usertracedata(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_mtc0_usertracedata); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "UserTraceData"; // break; case 4: -// gen_op_mtc0_debug(); /* PDtrace support */ +// tcg_gen_helper_0_0(do_mtc0_debug); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceBPC"; @@ -4790,7 +4811,8 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 24: switch (sel) { case 0: - gen_op_mtc0_depc(); /* EJTAG support */ + /* EJTAG support */ + tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC)); rn = "DEPC"; break; default: @@ -4800,35 +4822,35 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 25: switch (sel) { case 0: - gen_op_mtc0_performance0(); + tcg_gen_helper_0_0(do_mtc0_performance0); rn = "Performance0"; break; case 1: -// gen_op_mtc0_performance1(); +// tcg_gen_helper_0_0(do_mtc0_performance1); rn = "Performance1"; // break; case 2: -// gen_op_mtc0_performance2(); +// tcg_gen_helper_0_0(do_mtc0_performance2); rn = "Performance2"; // break; case 3: -// gen_op_mtc0_performance3(); +// tcg_gen_helper_0_0(do_mtc0_performance3); rn = "Performance3"; // break; case 4: -// gen_op_mtc0_performance4(); +// tcg_gen_helper_0_0(do_mtc0_performance4); rn = "Performance4"; // break; case 5: -// gen_op_mtc0_performance5(); +// tcg_gen_helper_0_0(do_mtc0_performance5); rn = "Performance5"; // break; case 6: -// gen_op_mtc0_performance6(); +// tcg_gen_helper_0_0(do_mtc0_performance6); rn = "Performance6"; // break; case 7: -// gen_op_mtc0_performance7(); +// tcg_gen_helper_0_0(do_mtc0_performance7); rn = "Performance7"; // break; default: @@ -4855,14 +4877,14 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_op_mtc0_taglo(); + tcg_gen_helper_0_0(do_mtc0_taglo); rn = "TagLo"; break; case 1: case 3: case 5: case 7: - gen_op_mtc0_datalo(); + tcg_gen_helper_0_0(do_mtc0_datalo); rn = "DataLo"; break; default: @@ -4875,14 +4897,14 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_op_mtc0_taghi(); + tcg_gen_helper_0_0(do_mtc0_taghi); rn = "TagHi"; break; case 1: case 3: case 5: case 7: - gen_op_mtc0_datahi(); + tcg_gen_helper_0_0(do_mtc0_datahi); rn = "DataHi"; break; default: @@ -4893,7 +4915,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 30: switch (sel) { case 0: - gen_op_mtc0_errorepc(); + tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC)); rn = "ErrorEPC"; break; default: @@ -4903,7 +4925,8 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 31: switch (sel) { case 0: - gen_op_mtc0_desave(); /* EJTAG support */ + /* EJTAG support */ + gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_DESAVE)); rn = "DESAVE"; break; default: @@ -4951,25 +4974,25 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, case 2: switch (sel) { case 1: - gen_op_mftc0_tcstatus(); + tcg_gen_helper_0_0(do_mftc0_tcstatus); break; case 2: - gen_op_mftc0_tcbind(); + tcg_gen_helper_0_0(do_mftc0_tcbind); break; case 3: - gen_op_mftc0_tcrestart(); + tcg_gen_helper_0_0(do_mftc0_tcrestart); break; case 4: - gen_op_mftc0_tchalt(); + tcg_gen_helper_0_0(do_mftc0_tchalt); break; case 5: - gen_op_mftc0_tccontext(); + tcg_gen_helper_0_0(do_mftc0_tccontext); break; case 6: - gen_op_mftc0_tcschedule(); + tcg_gen_helper_0_0(do_mftc0_tcschedule); break; case 7: - gen_op_mftc0_tcschefback(); + tcg_gen_helper_0_0(do_mftc0_tcschefback); break; default: gen_mfc0(env, ctx, rt, sel); @@ -4979,7 +5002,7 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, case 10: switch (sel) { case 0: - gen_op_mftc0_entryhi(); + tcg_gen_helper_0_0(do_mftc0_entryhi); break; default: gen_mfc0(env, ctx, rt, sel); @@ -4988,7 +5011,7 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, case 12: switch (sel) { case 0: - gen_op_mftc0_status(); + tcg_gen_helper_0_0(do_mftc0_status); break; default: gen_mfc0(env, ctx, rt, sel); @@ -4997,7 +5020,7 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, case 23: switch (sel) { case 0: - gen_op_mftc0_debug(); + tcg_gen_helper_0_0(do_mftc0_debug); break; default: gen_mfc0(env, ctx, rt, sel); @@ -5010,49 +5033,49 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, } else switch (sel) { /* GPR registers. */ case 0: - gen_op_mftgpr(rt); + tcg_gen_helper_0_1i(do_mftgpr, rt); break; /* Auxiliary CPU registers */ case 1: switch (rt) { case 0: - gen_op_mftlo(0); + tcg_gen_helper_0_1i(do_mftlo, 0); break; case 1: - gen_op_mfthi(0); + tcg_gen_helper_0_1i(do_mfthi, 0); break; case 2: - gen_op_mftacx(0); + tcg_gen_helper_0_1i(do_mftacx, 0); break; case 4: - gen_op_mftlo(1); + tcg_gen_helper_0_1i(do_mftlo, 1); break; case 5: - gen_op_mfthi(1); + tcg_gen_helper_0_1i(do_mfthi, 1); break; case 6: - gen_op_mftacx(1); + tcg_gen_helper_0_1i(do_mftacx, 1); break; case 8: - gen_op_mftlo(2); + tcg_gen_helper_0_1i(do_mftlo, 2); break; case 9: - gen_op_mfthi(2); + tcg_gen_helper_0_1i(do_mfthi, 2); break; case 10: - gen_op_mftacx(2); + tcg_gen_helper_0_1i(do_mftacx, 2); break; case 12: - gen_op_mftlo(3); + tcg_gen_helper_0_1i(do_mftlo, 3); break; case 13: - gen_op_mfthi(3); + tcg_gen_helper_0_1i(do_mfthi, 3); break; case 14: - gen_op_mftacx(3); + tcg_gen_helper_0_1i(do_mftacx, 3); break; case 16: - gen_op_mftdsp(); + tcg_gen_helper_0_0(do_mftdsp); break; default: goto die; @@ -5071,7 +5094,7 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, break; case 3: /* XXX: For now we support only a single FPU context. */ - gen_op_cfc1(rt); + tcg_gen_helper_0_1i(do_cfc1, rt); break; /* COP2: Not implemented. */ case 4: @@ -5115,25 +5138,25 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, case 2: switch (sel) { case 1: - gen_op_mttc0_tcstatus(); + tcg_gen_helper_0_0(do_mttc0_tcstatus); break; case 2: - gen_op_mttc0_tcbind(); + tcg_gen_helper_0_0(do_mttc0_tcbind); break; case 3: - gen_op_mttc0_tcrestart(); + tcg_gen_helper_0_0(do_mttc0_tcrestart); break; case 4: - gen_op_mttc0_tchalt(); + tcg_gen_helper_0_0(do_mttc0_tchalt); break; case 5: - gen_op_mttc0_tccontext(); + tcg_gen_helper_0_0(do_mttc0_tccontext); break; case 6: - gen_op_mttc0_tcschedule(); + tcg_gen_helper_0_0(do_mttc0_tcschedule); break; case 7: - gen_op_mttc0_tcschefback(); + tcg_gen_helper_0_0(do_mttc0_tcschefback); break; default: gen_mtc0(env, ctx, rd, sel); @@ -5143,7 +5166,7 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, case 10: switch (sel) { case 0: - gen_op_mttc0_entryhi(); + tcg_gen_helper_0_0(do_mttc0_entryhi); break; default: gen_mtc0(env, ctx, rd, sel); @@ -5152,7 +5175,7 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, case 12: switch (sel) { case 0: - gen_op_mttc0_status(); + tcg_gen_helper_0_0(do_mttc0_status); break; default: gen_mtc0(env, ctx, rd, sel); @@ -5161,7 +5184,7 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, case 23: switch (sel) { case 0: - gen_op_mttc0_debug(); + tcg_gen_helper_0_0(do_mttc0_debug); break; default: gen_mtc0(env, ctx, rd, sel); @@ -5174,49 +5197,49 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, } else switch (sel) { /* GPR registers. */ case 0: - gen_op_mttgpr(rd); + tcg_gen_helper_0_1i(do_mttgpr, rd); break; /* Auxiliary CPU registers */ case 1: switch (rd) { case 0: - gen_op_mttlo(0); + tcg_gen_helper_0_1i(do_mttlo, 0); break; case 1: - gen_op_mtthi(0); + tcg_gen_helper_0_1i(do_mtthi, 0); break; case 2: - gen_op_mttacx(0); + tcg_gen_helper_0_1i(do_mttacx, 0); break; case 4: - gen_op_mttlo(1); + tcg_gen_helper_0_1i(do_mttlo, 1); break; case 5: - gen_op_mtthi(1); + tcg_gen_helper_0_1i(do_mtthi, 1); break; case 6: - gen_op_mttacx(1); + tcg_gen_helper_0_1i(do_mttacx, 1); break; case 8: - gen_op_mttlo(2); + tcg_gen_helper_0_1i(do_mttlo, 2); break; case 9: - gen_op_mtthi(2); + tcg_gen_helper_0_1i(do_mtthi, 2); break; case 10: - gen_op_mttacx(2); + tcg_gen_helper_0_1i(do_mttacx, 2); break; case 12: - gen_op_mttlo(3); + tcg_gen_helper_0_1i(do_mttlo, 3); break; case 13: - gen_op_mtthi(3); + tcg_gen_helper_0_1i(do_mtthi, 3); break; case 14: - gen_op_mttacx(3); + tcg_gen_helper_0_1i(do_mttacx, 3); break; case 16: - gen_op_mttdsp(); + tcg_gen_helper_0_0(do_mttdsp); break; default: goto die; @@ -5235,7 +5258,7 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, break; case 3: /* XXX: For now we support only a single FPU context. */ - gen_op_ctc1(rd); + tcg_gen_helper_0_1i(do_ctc1, rd); break; /* COP2: Not implemented. */ case 4: @@ -5380,6 +5403,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int } MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd); } +#endif /* !CONFIG_USER_ONLY */ /* CP1 Branches (before delay slot) */ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, @@ -5464,13 +5488,13 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) opn = "mtc1"; break; case OPC_CFC1: - gen_op_cfc1(fs); + tcg_gen_helper_0_1i(do_cfc1, fs); gen_store_gpr(cpu_T[0], rt); opn = "cfc1"; break; case OPC_CTC1: gen_load_gpr(cpu_T[0], rt); - gen_op_ctc1(fs); + tcg_gen_helper_0_1i(do_ctc1, fs); opn = "ctc1"; break; case OPC_DMFC1: @@ -6846,12 +6870,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx) check_insn(env, ctx, ASE_MT); gen_load_gpr(cpu_T[0], rt); gen_load_gpr(cpu_T[1], rs); - gen_op_fork(); + tcg_gen_helper_0_0(do_fork); break; case OPC_YIELD: check_insn(env, ctx, ASE_MT); gen_load_gpr(cpu_T[0], rs); - gen_op_yield(); + tcg_gen_helper_0_0(do_yield); gen_store_gpr(cpu_T[0], rd); break; #if defined(TARGET_MIPS64) @@ -6921,29 +6945,33 @@ static void decode_opc (CPUState *env, DisasContext *ctx) case OPC_DMFC0: case OPC_DMTC0: #endif +#ifndef CONFIG_USER_ONLY gen_cp0(env, ctx, op1, rt, rd); +#endif break; case OPC_C0_FIRST ... OPC_C0_LAST: +#ifndef CONFIG_USER_ONLY gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); +#endif break; case OPC_MFMC0: op2 = MASK_MFMC0(ctx->opcode); switch (op2) { case OPC_DMT: check_insn(env, ctx, ASE_MT); - gen_op_dmt(); + tcg_gen_helper_0_0(do_dmt); break; case OPC_EMT: check_insn(env, ctx, ASE_MT); - gen_op_emt(); + tcg_gen_helper_0_0(do_emt); break; case OPC_DVPE: check_insn(env, ctx, ASE_MT); - gen_op_dvpe(); + tcg_gen_helper_0_0(do_dvpe); break; case OPC_EVPE: check_insn(env, ctx, ASE_MT); - gen_op_evpe(); + tcg_gen_helper_0_0(do_evpe); break; case OPC_DI: check_insn(env, ctx, ISA_MIPS32R2); -- cgit v1.2.3 From 82e671d9ecdf1422780e56182e9c228071493a22 Mon Sep 17 00:00:00 2001 From: pbrook Date: Mon, 9 Jun 2008 12:10:22 +0000 Subject: Despite what the documentation says/implies, PTHREAD_STACK_MIN is often not defined by pthread.h. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4709 c046a42c-6fe2-441c-8c8c-71466251a162 --- linux-user/syscall.c | 1 + 1 file changed, 1 insertion(+) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index d02022887..b6e9778a8 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From 17e2377abf16c3951d7d34521ceade4d7dc31d01 Mon Sep 17 00:00:00 2001 From: pbrook Date: Mon, 9 Jun 2008 13:47:45 +0000 Subject: Prevent guest reusing host memory allocations. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4710 c046a42c-6fe2-441c-8c8c-71466251a162 --- Makefile | 2 +- Makefile.target | 4 ++-- cutils.c | 35 --------------------------------- exec.c | 28 ++++++++++++++++++++++++-- linux-user/mmap.c | 46 +++++++++++++++++++++++++++++++++++++++++++ qemu-malloc.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 134 insertions(+), 40 deletions(-) create mode 100644 qemu-malloc.c diff --git a/Makefile b/Makefile index d227f911b..fc56a4b6e 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ recurse-all: $(SUBDIR_RULES) ####################################################################### # BLOCK_OBJS is code used by both qemu system emulation and qemu-img -BLOCK_OBJS=cutils.o +BLOCK_OBJS=cutils.o qemu-malloc.o BLOCK_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o BLOCK_OBJS+=block-dmg.o block-bochs.o block-vpc.o block-vvfat.o BLOCK_OBJS+=block-qcow2.o block-parallels.o diff --git a/Makefile.target b/Makefile.target index ab60677b6..50f8c1b5c 100644 --- a/Makefile.target +++ b/Makefile.target @@ -387,7 +387,7 @@ LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH)el.ld endif endif -OBJS= main.o syscall.o strace.o mmap.o signal.o path.o osdep.o thunk.o \ +OBJS= main.o syscall.o strace.o mmap.o signal.o path.o thunk.o \ elfload.o linuxload.o uaccess.o LIBS+= $(AIOLIBS) ifdef TARGET_HAS_BFLT @@ -444,7 +444,7 @@ LDFLAGS+=-Wl,-segaddr,__STD_PROG_ZONE,0x1000 -image_base 0x0e000000 LIBS+=-lmx -OBJS= main.o commpage.o machload.o mmap.o osdep.o signal.o syscall.o thunk.o +OBJS= main.o commpage.o machload.o mmap.o signal.o syscall.o thunk.o OBJS+= libqemu.a diff --git a/cutils.c b/cutils.c index 738d5265d..9ef2fa627 100644 --- a/cutils.c +++ b/cutils.c @@ -95,38 +95,3 @@ time_t mktimegm(struct tm *tm) t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec; return t; } - -void *get_mmap_addr(unsigned long size) -{ - return NULL; -} - -void qemu_free(void *ptr) -{ - free(ptr); -} - -void *qemu_malloc(size_t size) -{ - return malloc(size); -} - -void *qemu_mallocz(size_t size) -{ - void *ptr; - ptr = qemu_malloc(size); - if (!ptr) - return NULL; - memset(ptr, 0, size); - return ptr; -} - -char *qemu_strdup(const char *str) -{ - char *ptr; - ptr = qemu_malloc(strlen(str) + 1); - if (!ptr) - return NULL; - strcpy(ptr, str); - return ptr; -} diff --git a/exec.c b/exec.c index 64287e20c..18f8f5f55 100644 --- a/exec.c +++ b/exec.c @@ -263,13 +263,33 @@ static inline PageDesc *page_find_alloc(target_ulong index) { PageDesc **lp, *p; +#if TARGET_LONG_BITS > 32 + /* Host memory outside guest VM. For 32-bit targets we have already + excluded high addresses. */ + if (index > ((target_ulong)L2_SIZE * L1_SIZE * TARGET_PAGE_SIZE)) + return NULL; +#endif lp = &l1_map[index >> L2_BITS]; p = *lp; if (!p) { /* allocate if not found */ - p = qemu_malloc(sizeof(PageDesc) * L2_SIZE); - memset(p, 0, sizeof(PageDesc) * L2_SIZE); +#if defined(CONFIG_USER_ONLY) + unsigned long addr; + size_t len = sizeof(PageDesc) * L2_SIZE; + /* Don't use qemu_malloc because it may recurse. */ + p = mmap(0, len, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + *lp = p; + addr = h2g(p); + if (addr == (target_ulong)addr) { + page_set_flags(addr & TARGET_PAGE_MASK, + TARGET_PAGE_ALIGN(addr + len), + PAGE_RESERVED); + } +#else + p = qemu_mallocz(sizeof(PageDesc) * L2_SIZE); *lp = p; +#endif } return p + (index & (L2_SIZE - 1)); } @@ -1912,6 +1932,10 @@ void page_set_flags(target_ulong start, target_ulong end, int flags) flags |= PAGE_WRITE_ORG; for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) { p = page_find_alloc(addr >> TARGET_PAGE_BITS); + /* We may be called for host regions that are outside guest + address space. */ + if (!p) + return; /* if the write protection is set, then we invalidate the code inside */ if (!(p->flags & PAGE_WRITE) && diff --git a/linux-user/mmap.c b/linux-user/mmap.c index b4ca1074b..be1ddb9f2 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -73,6 +73,52 @@ void mmap_unlock(void) } #endif +void *qemu_vmalloc(size_t size) +{ + void *p; + unsigned long addr; + mmap_lock(); + /* Use map and mark the pages as used. */ + p = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + addr = (unsigned long)p; + if (addr == (target_ulong) addr) { + /* Allocated region overlaps guest address space. + This may recurse. */ + page_set_flags(addr & TARGET_PAGE_MASK, TARGET_PAGE_ALIGN(addr + size), + PAGE_RESERVED); + } + + mmap_unlock(); + return p; +} + +void *qemu_malloc(size_t size) +{ + char * p; + size += 16; + p = qemu_vmalloc(size); + *(size_t *)p = size; + return p + 16; +} + +/* We use map, which is always zero initialized. */ +void * qemu_mallocz(size_t size) +{ + return qemu_malloc(size); +} + +void qemu_free(void *ptr) +{ + /* FIXME: We should unmark the reserved pages here. However this gets + complicated when one target page spans multiple host pages, so we + don't bother. */ + size_t *p; + p = (size_t *)((char *)ptr - 16); + munmap(p, *p); +} + /* NOTE: all the constants are the HOST ones, but addresses are target. */ int target_mprotect(abi_ulong start, abi_ulong len, int prot) { diff --git a/qemu-malloc.c b/qemu-malloc.c new file mode 100644 index 000000000..16d3c2e1f --- /dev/null +++ b/qemu-malloc.c @@ -0,0 +1,59 @@ +/* + * malloc-like functions for system emulation. + * + * Copyright (c) 2006 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "qemu-common.h" + +void *get_mmap_addr(unsigned long size) +{ + return NULL; +} + +void qemu_free(void *ptr) +{ + free(ptr); +} + +void *qemu_malloc(size_t size) +{ + return malloc(size); +} + +void *qemu_mallocz(size_t size) +{ + void *ptr; + ptr = qemu_malloc(size); + if (!ptr) + return NULL; + memset(ptr, 0, size); + return ptr; +} + +char *qemu_strdup(const char *str) +{ + char *ptr; + ptr = qemu_malloc(strlen(str) + 1); + if (!ptr) + return NULL; + strcpy(ptr, str); + return ptr; +} -- cgit v1.2.3 From b2a7081acb46b0cdcbec0346672d86fc77ebfeb5 Mon Sep 17 00:00:00 2001 From: pbrook Date: Mon, 9 Jun 2008 13:57:23 +0000 Subject: Use qemu_mallocz. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4711 c046a42c-6fe2-441c-8c8c-71466251a162 --- exec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/exec.c b/exec.c index 18f8f5f55..48600e49a 100644 --- a/exec.c +++ b/exec.c @@ -721,10 +721,9 @@ static void build_page_bitmap(PageDesc *p) int n, tb_start, tb_end; TranslationBlock *tb; - p->code_bitmap = qemu_malloc(TARGET_PAGE_SIZE / 8); + p->code_bitmap = qemu_mallocz(TARGET_PAGE_SIZE / 8); if (!p->code_bitmap) return; - memset(p->code_bitmap, 0, TARGET_PAGE_SIZE / 8); tb = p->first_tb; while (tb != NULL) { -- cgit v1.2.3 From c3a928338e7878ddd9f5eeab17d05d52c92c9198 Mon Sep 17 00:00:00 2001 From: pbrook Date: Mon, 9 Jun 2008 14:02:50 +0000 Subject: Use qemu_mallocz to allocate new thread state. Remove redundant memset. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4712 c046a42c-6fe2-441c-8c8c-71466251a162 --- linux-user/main.c | 2 +- linux-user/syscall.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 1f68766f0..6b4d8d72c 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2183,11 +2183,11 @@ void usage(void) THREAD CPUState *thread_env; +/* Assumes contents are already zeroed. */ void init_task_state(TaskState *ts) { int i; - memset(ts, 0, sizeof(TaskState)); ts->used = 1; ts->first_free = ts->sigqueue_table; for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) { diff --git a/linux-user/syscall.c b/linux-user/syscall.c index b6e9778a8..c99c5ffe2 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2787,7 +2787,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, new_thread_info info; pthread_attr_t attr; #endif - ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE); + ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE); init_task_state(ts); new_stack = ts->stack; /* we create a new CPU instance. */ -- cgit v1.2.3 From 7880febd2c77ea65d9a7989e48760cb6d8a4ce6c Mon Sep 17 00:00:00 2001 From: pbrook Date: Mon, 9 Jun 2008 14:31:18 +0000 Subject: Add proper file header. Signed-off-by: Dmitry Baryshkov git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4713 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/tc6393xb.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c index 189369467..6db6dcb33 100644 --- a/hw/tc6393xb.c +++ b/hw/tc6393xb.c @@ -1,4 +1,12 @@ -/* vim:set shiftwidth=4 ts=4 et: */ +/* + * Toshiba TC6393XB I/O Controller. + * Found in Sharp Zaurus SL-6000 (tosa) or some + * Toshiba e-Series PDAs. + * + * Most features are currently unsupported!!! + * + * This code is licensed under the GNU GPL v2. + */ #include "hw.h" #include "pxa.h" #include "devices.h" -- cgit v1.2.3 From 5d794885a2eb55a52214f1a31dada29f0c55862d Mon Sep 17 00:00:00 2001 From: malc Date: Mon, 9 Jun 2008 19:57:27 +0000 Subject: Fix test for signed div fast path git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4714 c046a42c-6fe2-441c-8c8c-71466251a162 --- tcg/ppc/tcg-target.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 6c4e37523..205cd2bad 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -1057,7 +1057,13 @@ static void tcg_out_div2 (TCGContext *s, int uns) { void *label1_ptr, *label2_ptr; - tcg_out32 (s, CMPLI | BF (7) | RA (3)); + if (uns) + tcg_out32 (s, CMPLI | BF (7) | RA (3)); + else { + tcg_out32 (s, SRAWI | RS (4) | RA (0) | 31); + tcg_out32 (s, CMPL | BF (7) | RA (3) | RB (4)); + } + label1_ptr = s->code_ptr; tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE); -- cgit v1.2.3 From fa4fbfb98ad09b1a5bde2c78db5cb1c13363bdf2 Mon Sep 17 00:00:00 2001 From: malc Date: Mon, 9 Jun 2008 19:57:36 +0000 Subject: Emit trampolines manually in prologue git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4715 c046a42c-6fe2-441c-8c8c-71466251a162 --- tcg/ppc/tcg-target.c | 118 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 38 deletions(-) diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 205cd2bad..9b5c6d622 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -23,6 +23,8 @@ */ static uint8_t *tb_ret_addr; +static uint8_t *udiv_addr; +static uint8_t *div_addr; #define FAST_PATH #if TARGET_PHYS_ADDR_BITS <= 32 @@ -118,7 +120,7 @@ static const int tcg_target_call_oarg_regs[2] = { }; static const int tcg_target_callee_save_regs[] = { - TCG_REG_R13, /* sould r13 be saved? */ + TCG_REG_R13, /* should r13 be saved? */ TCG_REG_R14, TCG_REG_R15, TCG_REG_R16, @@ -135,6 +137,22 @@ static const int tcg_target_callee_save_regs[] = { TCG_REG_R31 }; +static const int div_save_regs[] = { + TCG_REG_R4, + TCG_REG_R5, + TCG_REG_R7, + TCG_REG_R8, + TCG_REG_R9, + TCG_REG_R10, + TCG_REG_R11, + TCG_REG_R12, + TCG_REG_R13, /* should r13 be saved? */ + TCG_REG_R24, + TCG_REG_R25, + TCG_REG_R26, + TCG_REG_R27, +}; + static uint32_t reloc_pc24_val (void *pc, tcg_target_long target) { tcg_target_long disp; @@ -799,9 +817,25 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) #endif } +static uint64_t ppc_udiv_helper (uint64_t a, uint32_t b) +{ + uint64_t rem, quo; + quo = a / b; + rem = a % b; + return (rem << 32) | (uint32_t) quo; +} + +static uint64_t ppc_div_helper (int64_t a, int32_t b) +{ + int64_t rem, quo; + quo = a / b; + rem = a % b; + return (rem << 32) | (uint32_t) quo; +} + void tcg_target_qemu_prologue (TCGContext *s) { - int i, frame_size; + int i, j, frame_size; frame_size = 0 + 4 /* back chain */ @@ -837,6 +871,49 @@ void tcg_target_qemu_prologue (TCGContext *s) tcg_out32 (s, MTSPR | RS (0) | LR); tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size); tcg_out32 (s, BCLR | BO_ALWAYS); + + /* div trampolines */ + for (j = 0; j < 2; ++j) { + tcg_target_long target; + + frame_size = 8 + ARRAY_SIZE (div_save_regs) * 4; + frame_size = (frame_size + 15) & ~15; + + if (j == 0) { + target = (tcg_target_long) ppc_udiv_helper; + udiv_addr = s->code_ptr; + } + else { + target = (tcg_target_long) ppc_div_helper; + div_addr = s->code_ptr; + } + + tcg_out32 (s, MFSPR | RT (0) | LR); + tcg_out32 (s, STWU | RS (1) | RA (1) | (-frame_size & 0xffff)); + for (i = 0; i < ARRAY_SIZE (div_save_regs); ++i) + tcg_out32 (s, (STW + | RS (div_save_regs[i]) + | RA (1) + | (i * 4 + 8) + ) + ); + tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size - 4)); + tcg_out_mov (s, 4, 6); + tcg_out_b (s, LK, target); + tcg_out_mov (s, 6, 4); + + for (i = 0; i < ARRAY_SIZE (div_save_regs); ++i) + tcg_out32 (s, (LWZ + | RT (div_save_regs[i]) + | RA (1) + | (i * 4 + 8) + ) + ); + tcg_out32 (s, LWZ | RT (0) | RA (1) | (frame_size - 4)); + tcg_out32 (s, MTSPR | RS (0) | LR); + tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size); + tcg_out32 (s, BCLR | BO_ALWAYS); + } } static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1, @@ -1018,41 +1095,6 @@ static void tcg_out_brcond2(TCGContext *s, tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr); } -static uint64_t __attribute ((used)) ppc_udiv_helper (uint64_t a, uint32_t b) -{ - uint64_t rem, quo; - quo = a / b; - rem = a % b; - return (rem << 32) | (uint32_t) quo; -} - -static uint64_t __attribute ((used)) ppc_div_helper (int64_t a, int32_t b) -{ - int64_t rem, quo; - quo = a / b; - rem = a % b; - return (rem << 32) | (uint32_t) quo; -} - -#define MAKE_TRAMPOLINE(name) \ -extern void name##_trampoline (void); \ -asm (#name "_trampoline:\n" \ - " mflr 0\n" \ - " addi 1,1,-112\n" \ - " mr 4,6\n" \ - " stmw 7,0(1)\n" \ - " stw 0,108(0)\n" \ - " bl ppc_" #name "_helper\n" \ - " lmw 7,0(1)\n" \ - " lwz 0,108(0)\n" \ - " addi 1,1,112\n" \ - " mtlr 0\n" \ - " blr\n" \ - ) - -MAKE_TRAMPOLINE (div); -MAKE_TRAMPOLINE (udiv); - static void tcg_out_div2 (TCGContext *s, int uns) { void *label1_ptr, *label2_ptr; @@ -1067,7 +1109,7 @@ static void tcg_out_div2 (TCGContext *s, int uns) label1_ptr = s->code_ptr; tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE); - tcg_out_b (s, LK, (tcg_target_long) (uns ? udiv_trampoline : div_trampoline)); + tcg_out_b (s, LK, (tcg_target_long) (uns ? udiv_addr : div_addr)); label2_ptr = s->code_ptr; tcg_out32 (s, B); -- cgit v1.2.3 From e72210e194498c34358028d2236915c7856f1da9 Mon Sep 17 00:00:00 2001 From: bellard Date: Mon, 9 Jun 2008 20:44:19 +0000 Subject: SVM: Fix segment attribute clobbering (Alexander Graf) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4716 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-i386/op_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c index ebeeebdec..730ec8169 100644 --- a/target-i386/op_helper.c +++ b/target-i386/op_helper.c @@ -4767,7 +4767,7 @@ static inline void svm_save_seg(target_phys_addr_t addr, stl_phys(addr + offsetof(struct vmcb_seg, limit), sc->limit); stw_phys(addr + offsetof(struct vmcb_seg, attrib), - (sc->flags >> 8) | ((sc->flags >> 12) & 0x0f00)); + ((sc->flags >> 8) & 0xff) | ((sc->flags >> 12) & 0x0f00)); } static inline void svm_load_seg(target_phys_addr_t addr, SegmentCache *sc) -- cgit v1.2.3 From a7cfbba0cf90e3a42f2fc05556dd5b1d614f4cad Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Mon, 9 Jun 2008 23:06:31 +0000 Subject: CRIS: Translator updates. * RFN (Return From NMI) insn. * Avoid unnecessary T0 transfers. * Dont do tcg related init more than once. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4717 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-cris/translate.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/target-cris/translate.c b/target-cris/translate.c index 3affd1cec..cd0c2e15f 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -735,7 +735,7 @@ static void cris_evaluate_flags(DisasContext *dc) else tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~X_FLAG); - } + } dc->flags_uptodate = 1; } @@ -1530,7 +1530,6 @@ static unsigned int dec_btstq(DisasContext *dc) cris_cc_mask(dc, CC_MASK_NZ); - t_gen_mov_TN_reg(cpu_T[0], dc->op2); cris_alu(dc, CC_OP_BTST, cpu_T[0], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4); cris_update_cc_op(dc, CC_OP_FLAGS, 4); @@ -1968,11 +1967,10 @@ static unsigned int dec_movs_r(DisasContext *dc) dc->op1, dc->op2)); cris_cc_mask(dc, CC_MASK_NZ); - t_gen_mov_TN_reg(cpu_T[0], dc->op1); /* Size can only be qi or hi. */ t_gen_sext(cpu_T[1], cpu_R[dc->op1], size); cris_alu(dc, CC_OP_MOVE, - cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4); + cpu_R[dc->op2], cpu_R[dc->op1], cpu_T[1], 4); return 2; } @@ -2788,7 +2786,9 @@ static unsigned int dec_rfe_etc(DisasContext *dc) break; case 5: /* rfn. */ - BUG(); + cris_evaluate_flags(dc); + tcg_gen_helper_0_0(helper_rfn); + dc->is_jmp = DISAS_UPDATE; break; case 6: /* break. */ @@ -3271,12 +3271,20 @@ void cpu_dump_state (CPUState *env, FILE *f, CPUCRISState *cpu_cris_init (const char *cpu_model) { CPUCRISState *env; + static int tcg_initialized = 0; int i; env = qemu_mallocz(sizeof(CPUCRISState)); if (!env) return NULL; + cpu_exec_init(env); + cpu_reset(env); + + if (tcg_initialized) + return env; + + tcg_initialized = 1; cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env"); #if TARGET_LONG_BITS > HOST_LONG_BITS @@ -3337,6 +3345,7 @@ CPUCRISState *cpu_cris_init (const char *cpu_model) TCG_HELPER(helper_movl_sreg_reg); TCG_HELPER(helper_movl_reg_sreg); TCG_HELPER(helper_rfe); + TCG_HELPER(helper_rfn); TCG_HELPER(helper_evaluate_flags_muls); TCG_HELPER(helper_evaluate_flags_mulu); @@ -3346,8 +3355,6 @@ CPUCRISState *cpu_cris_init (const char *cpu_model) TCG_HELPER(helper_evaluate_flags_move_2); TCG_HELPER(helper_evaluate_flags); TCG_HELPER(helper_top_evaluate_flags); - - cpu_reset(env); return env; } -- cgit v1.2.3 From 5bf8f1aba1ab727713edf4084e7bc841dd1e6732 Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Mon, 9 Jun 2008 23:07:50 +0000 Subject: CRIS: Support RFN insn. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4718 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-cris/helper.h | 1 + target-cris/op_helper.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/target-cris/helper.h b/target-cris/helper.h index 34f6831f4..4c96f0487 100644 --- a/target-cris/helper.h +++ b/target-cris/helper.h @@ -5,6 +5,7 @@ void TCG_HELPER_PROTO helper_tlb_flush_pid(uint32_t pid); void TCG_HELPER_PROTO helper_dump(uint32_t a0, uint32_t a1, uint32_t a2); void TCG_HELPER_PROTO helper_dummy(void); void TCG_HELPER_PROTO helper_rfe(void); +void TCG_HELPER_PROTO helper_rfn(void); void TCG_HELPER_PROTO helper_store(uint32_t a0); void TCG_HELPER_PROTO helper_movl_sreg_reg (uint32_t sreg, uint32_t reg); diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c index f5c0ed191..0e7d3c37f 100644 --- a/target-cris/op_helper.c +++ b/target-cris/op_helper.c @@ -220,6 +220,25 @@ void helper_rfe(void) env->pregs[PR_CCS] |= P_FLAG; } +void helper_rfn(void) +{ + int rflag = env->pregs[PR_CCS] & R_FLAG; + + D(fprintf(logfile, "rfn: erp=%x pid=%x ccs=%x btarget=%x\n", + env->pregs[PR_ERP], env->pregs[PR_PID], + env->pregs[PR_CCS], + env->btarget)); + + cris_ccs_rshift(env); + + /* Set the P_FLAG only if the R_FLAG is not set. */ + if (!rflag) + env->pregs[PR_CCS] |= P_FLAG; + + /* Always set the M flag. */ + env->pregs[PR_CCS] |= M_FLAG; +} + void helper_store(uint32_t a0) { if (env->pregs[PR_CCS] & P_FLAG ) -- cgit v1.2.3 From 1b1a38b0aaf3a24b9b8162d8aef9e700a42f8d43 Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Mon, 9 Jun 2008 23:18:06 +0000 Subject: CRIS: Emulate NMIs. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4719 c046a42c-6fe2-441c-8c8c-71466251a162 --- cpu-exec.c | 10 +++++++++- target-cris/cpu.h | 15 ++++++++------- target-cris/helper.c | 19 +++++++++++-------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 3a1ff4e07..b8c208b41 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -501,7 +501,15 @@ int cpu_exec(CPUState *env1) next_tb = 0; } #elif defined(TARGET_CRIS) - if (interrupt_request & CPU_INTERRUPT_HARD) { + if (interrupt_request & CPU_INTERRUPT_HARD + && (env->pregs[PR_CCS] & I_FLAG)) { + env->exception_index = EXCP_IRQ; + do_interrupt(env); + next_tb = 0; + } + if (interrupt_request & CPU_INTERRUPT_NMI + && (env->pregs[PR_CCS] & M_FLAG)) { + env->exception_index = EXCP_NMI; do_interrupt(env); next_tb = 0; } diff --git a/target-cris/cpu.h b/target-cris/cpu.h index a4f016f12..447e780b2 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -29,12 +29,11 @@ #define ELF_MACHINE EM_CRIS -#define EXCP_MMU_EXEC 0 -#define EXCP_MMU_READ 1 -#define EXCP_MMU_WRITE 2 -#define EXCP_MMU_FLUSH 3 -#define EXCP_MMU_FAULT 4 -#define EXCP_BREAK 16 /* trap. */ +#define EXCP_NMI 1 +#define EXCP_GURU 2 +#define EXCP_BUSFAULT 3 +#define EXCP_IRQ 4 +#define EXCP_BREAK 5 /* Register aliases. R0 - R15 */ #define R_FP 8 @@ -54,11 +53,14 @@ #define PR_EBP 9 #define PR_ERP 10 #define PR_SRP 11 +#define PR_NRP 12 #define PR_CCS 13 #define PR_USP 14 #define PR_SPC 15 /* CPU flags. */ +#define Q_FLAG 0x80000000 +#define M_FLAG 0x40000000 #define S_FLAG 0x200 #define R_FLAG 0x100 #define P_FLAG 0x80 @@ -154,7 +156,6 @@ typedef struct CPUCRISState { uint32_t lo; } tlbsets[2][4][16]; - int features; int user_mode_only; CPU_COMMON diff --git a/target-cris/helper.c b/target-cris/helper.c index c16a58a3b..a29e55c05 100644 --- a/target-cris/helper.c +++ b/target-cris/helper.c @@ -78,13 +78,13 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, miss = cris_mmu_translate(&res, env, address, rw, mmu_idx); if (miss) { - if (env->exception_index == EXCP_MMU_FAULT) + if (env->exception_index == EXCP_BUSFAULT) cpu_abort(env, "CRIS: Illegal recursive bus fault." "addr=%x rw=%d\n", address, rw); - env->exception_index = EXCP_MMU_FAULT; + env->exception_index = EXCP_BUSFAULT; env->fault_vector = res.bf_vec; r = 1; } @@ -120,17 +120,20 @@ void do_interrupt(CPUState *env) env->pregs[PR_ERP] = env->pc + 2; break; - case EXCP_MMU_FAULT: + case EXCP_NMI: + /* NMI is hardwired to vector zero. */ + ex_vec = 0; + env->pregs[PR_CCS] &= ~M_FLAG; + env->pregs[PR_NRP] = env->pc; + break; + + case EXCP_BUSFAULT: ex_vec = env->fault_vector; env->pregs[PR_ERP] = env->pc; break; default: - /* Is the core accepting interrupts? */ - if (!(env->pregs[PR_CCS] & I_FLAG)) - return; - /* The interrupt controller gives us the - vector. */ + /* The interrupt controller gives us the vector. */ ex_vec = env->interrupt_vector; /* Normal interrupts are taken between TB's. env->pc is valid here. */ -- cgit v1.2.3 From 5ef98b4742a291c732080c313051b1b36da1707d Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Mon, 9 Jun 2008 23:33:30 +0000 Subject: ETRAX: Add NMI support to the watchdog and the interrupt controller. * Add NMI and GURU exceptions to teh interrupt controller. * Teach the watchdog timer to signal an NMI before reseting the chip. * Add etraxfs.h to hold api for etrax device models. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4720 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/etraxfs.c | 25 ++++++++----------------- hw/etraxfs.h | 42 ++++++++++++++++++++++++++++++++++++++++++ hw/etraxfs_pic.c | 53 ++++++++++++++++++++++++++++++++++++++++++++--------- hw/etraxfs_timer.c | 29 +++++++++++++++++++++++++---- 4 files changed, 119 insertions(+), 30 deletions(-) create mode 100644 hw/etraxfs.h diff --git a/hw/etraxfs.c b/hw/etraxfs.c index 72482e414..4348151c3 100644 --- a/hw/etraxfs.c +++ b/hw/etraxfs.c @@ -30,16 +30,7 @@ #include "devices.h" #include "boards.h" -#include "etraxfs_dma.h" - -/* Init functions for different blocks. */ -extern qemu_irq *etraxfs_pic_init(CPUState *env, target_phys_addr_t base); -void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, - target_phys_addr_t base); -void *etraxfs_eth_init(NICInfo *nd, CPUState *env, - qemu_irq *irq, target_phys_addr_t base); -void etraxfs_ser_init(CPUState *env, qemu_irq *irq, CharDriverState *chr, - target_phys_addr_t base); +#include "etraxfs.h" #define FLASH_SIZE 0x2000000 #define INTMEM_SIZE (128 * 1024) @@ -62,7 +53,7 @@ void bareetraxfs_init (ram_addr_t ram_size, int vga_ram_size, const char *initrd_filename, const char *cpu_model) { CPUState *env; - qemu_irq *pic; + struct etraxfs_pic *pic; void *etraxfs_dmac; struct etraxfs_dma_client *eth[2] = {NULL, NULL}; int kernel_size; @@ -110,13 +101,13 @@ void bareetraxfs_init (ram_addr_t ram_size, int vga_ram_size, etraxfs_dmac = etraxfs_dmac_init(env, 0xb0000000, 10); for (i = 0; i < 10; i++) { /* On ETRAX, odd numbered channels are inputs. */ - etraxfs_dmac_connect(etraxfs_dmac, i, pic + 7 + i, i & 1); + etraxfs_dmac_connect(etraxfs_dmac, i, pic->irq + 7 + i, i & 1); } /* Add the two ethernet blocks. */ - eth[0] = etraxfs_eth_init(&nd_table[0], env, pic + 25, 0xb0034000); + eth[0] = etraxfs_eth_init(&nd_table[0], env, pic->irq + 25, 0xb0034000); if (nb_nics > 1) - eth[1] = etraxfs_eth_init(&nd_table[1], env, pic + 26, 0xb0036000); + eth[1] = etraxfs_eth_init(&nd_table[1], env, pic->irq + 26, 0xb0036000); /* The DMA Connector block is missing, hardwire things for now. */ etraxfs_dmac_connect_client(etraxfs_dmac, 0, eth[0]); @@ -127,12 +118,12 @@ void bareetraxfs_init (ram_addr_t ram_size, int vga_ram_size, } /* 2 timers. */ - etraxfs_timer_init(env, pic + 0x1b, 0xb001e000); - etraxfs_timer_init(env, pic + 0x1b, 0xb005e000); + etraxfs_timer_init(env, pic->irq + 0x1b, pic->nmi + 1, 0xb001e000); + etraxfs_timer_init(env, pic->irq + 0x1b, pic->nmi + 1, 0xb005e000); for (i = 0; i < 4; i++) { if (serial_hds[i]) { - etraxfs_ser_init(env, pic + 0x14 + i, + etraxfs_ser_init(env, pic->irq + 0x14 + i, serial_hds[i], 0xb0026000 + i * 0x2000); } } diff --git a/hw/etraxfs.h b/hw/etraxfs.h new file mode 100644 index 000000000..0c9fdbb60 --- /dev/null +++ b/hw/etraxfs.h @@ -0,0 +1,42 @@ +/* + * QEMU ETRAX System Emulator + * + * Copyright (c) 2008 Edgar E. Iglesias, Axis Communications AB. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "etraxfs_dma.h" + +struct etraxfs_pic +{ + qemu_irq *irq; + qemu_irq *nmi; + qemu_irq *guru; + + void *internal; +}; + +struct etraxfs_pic *etraxfs_pic_init(CPUState *env, target_phys_addr_t base); +void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, qemu_irq *nmi, + target_phys_addr_t base); +void *etraxfs_eth_init(NICInfo *nd, CPUState *env, + qemu_irq *irq, target_phys_addr_t base); +void etraxfs_ser_init(CPUState *env, qemu_irq *irq, CharDriverState *chr, + target_phys_addr_t base); diff --git a/hw/etraxfs_pic.c b/hw/etraxfs_pic.c index 7022c9953..d145bec17 100644 --- a/hw/etraxfs_pic.c +++ b/hw/etraxfs_pic.c @@ -24,6 +24,7 @@ #include #include "hw.h" +#include "etraxfs.h" #define D(x) @@ -143,7 +144,7 @@ void irq_info(void) { } -static void etraxfs_pic_handler(void *opaque, int irq, int level) +static void irq_handler(void *opaque, int irq, int level) { struct fs_pic_state_t *fs = (void *)opaque; CPUState *env = fs->env; @@ -187,22 +188,56 @@ static void etraxfs_pic_handler(void *opaque, int irq, int level) } } -qemu_irq *etraxfs_pic_init(CPUState *env, target_phys_addr_t base) +static void nmi_handler(void *opaque, int irq, int level) +{ + struct fs_pic_state_t *fs = (void *)opaque; + CPUState *env = fs->env; + uint32_t mask; + + mask = 1 << irq; + if (level) + fs->r_nmi |= mask; + else + fs->r_nmi &= ~mask; + + if (fs->r_nmi) + cpu_interrupt(env, CPU_INTERRUPT_NMI); + else + cpu_reset_interrupt(env, CPU_INTERRUPT_NMI); +} + +static void guru_handler(void *opaque, int irq, int level) +{ + struct fs_pic_state_t *fs = (void *)opaque; + CPUState *env = fs->env; + cpu_abort(env, "%s unsupported exception\n", __func__); + +} + + +struct etraxfs_pic *etraxfs_pic_init(CPUState *env, target_phys_addr_t base) { - struct fs_pic_state_t *fs; - qemu_irq *pic; + struct fs_pic_state_t *fs = NULL; + struct etraxfs_pic *pic = NULL; int intr_vect_regs; - fs = qemu_mallocz(sizeof *fs); - if (!fs) - return NULL; - fs->env = env; + pic = qemu_mallocz(sizeof *pic); + pic->internal = fs = qemu_mallocz(sizeof *fs); + if (!fs || !pic) + goto err; - pic = qemu_allocate_irqs(etraxfs_pic_handler, fs, 30); + fs->env = env; + pic->irq = qemu_allocate_irqs(irq_handler, fs, 30); + pic->nmi = qemu_allocate_irqs(nmi_handler, fs, 2); + pic->guru = qemu_allocate_irqs(guru_handler, fs, 1); intr_vect_regs = cpu_register_io_memory(0, pic_read, pic_write, fs); cpu_register_physical_memory(base, 0x14, intr_vect_regs); fs->base = base; return pic; + err: + free(pic); + free(fs); + return NULL; } diff --git a/hw/etraxfs_timer.c b/hw/etraxfs_timer.c index 7353d45de..e996c57f6 100644 --- a/hw/etraxfs_timer.c +++ b/hw/etraxfs_timer.c @@ -46,6 +46,7 @@ struct fs_timer_t { CPUState *env; qemu_irq *irq; + qemu_irq *nmi; target_phys_addr_t base; QEMUBH *bh_t0; @@ -56,6 +57,8 @@ struct fs_timer_t { ptimer_state *ptimer_wd; struct timeval last; + int wd_hits; + /* Control registers. */ uint32_t rw_tmr0_div; uint32_t r_tmr0_data; @@ -129,6 +132,7 @@ static void update_ctrl(struct fs_timer_t *t, int tnum) unsigned int freq_hz; unsigned int div; uint32_t ctrl; + ptimer_state *timer; if (tnum == 0) { @@ -163,8 +167,8 @@ static void update_ctrl(struct fs_timer_t *t, int tnum) D(printf ("freq_hz=%d div=%d\n", freq_hz, div)); div = div * TIMER_SLOWDOWN; - div >>= 15; - freq_hz >>= 15; + div >>= 10; + freq_hz >>= 10; ptimer_set_freq(timer, freq_hz); ptimer_set_limit(timer, div, 0); @@ -216,7 +220,18 @@ static void timer1_hit(void *opaque) static void watchdog_hit(void *opaque) { - qemu_system_reset_request(); + struct fs_timer_t *t = opaque; + if (t->wd_hits == 0) { + /* real hw gives a single tick before reseting but we are + a bit friendlier to compensate for our slower execution. */ + ptimer_set_count(t->ptimer_wd, 10); + ptimer_run(t->ptimer_wd, 1); + qemu_irq_raise(t->nmi[0]); + } + else + qemu_system_reset_request(); + + t->wd_hits++; } static inline void timer_watchdog_update(struct fs_timer_t *t, uint32_t value) @@ -237,6 +252,11 @@ static inline void timer_watchdog_update(struct fs_timer_t *t, uint32_t value) D(printf("en=%d new_key=%x oldkey=%x cmd=%d cnt=%d\n", wd_en, new_key, wd_key, new_cmd, wd_cnt)); + if (t->wd_hits) + qemu_irq_lower(t->nmi[0]); + + t->wd_hits = 0; + ptimer_set_freq(t->ptimer_wd, 760); if (wd_cnt == 0) wd_cnt = 256; @@ -320,7 +340,7 @@ static void etraxfs_timer_reset(void *opaque) qemu_irq_lower(t->irq[0]); } -void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, +void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, qemu_irq *nmi, target_phys_addr_t base) { static struct fs_timer_t *t; @@ -337,6 +357,7 @@ void etraxfs_timer_init(CPUState *env, qemu_irq *irqs, t->ptimer_t1 = ptimer_init(t->bh_t1); t->ptimer_wd = ptimer_init(t->bh_wd); t->irq = irqs; + t->nmi = nmi; t->env = env; t->base = base; -- cgit v1.2.3 From 877d8ad78bfeade699af313e1f7793743dc48a08 Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Mon, 9 Jun 2008 23:44:20 +0000 Subject: CRIS: Add (untested) cpu-state save/load. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4721 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/etraxfs.c | 2 +- target-cris/machine.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/hw/etraxfs.c b/hw/etraxfs.c index 4348151c3..0efcd831f 100644 --- a/hw/etraxfs.c +++ b/hw/etraxfs.c @@ -67,7 +67,7 @@ void bareetraxfs_init (ram_addr_t ram_size, int vga_ram_size, cpu_model = "crisv32"; } env = cpu_init(cpu_model); -/* register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); */ + register_savevm("cpu", 0, 1, cpu_save, cpu_load, env); qemu_register_reset(main_cpu_reset, env); /* allocate RAM */ diff --git a/target-cris/machine.c b/target-cris/machine.c index cbfa645b4..3e152e9fb 100644 --- a/target-cris/machine.c +++ b/target-cris/machine.c @@ -5,3 +5,91 @@ void register_machines(void) { qemu_register_machine(&bareetraxfs_machine); } + +void cpu_save(QEMUFile *f, void *opaque) +{ + CPUCRISState *env = opaque; + int i; + int s; + int mmu; + + for (i = 0; i < 16; i++) + qemu_put_be32(f, env->regs[i]); + for (i = 0; i < 16; i++) + qemu_put_be32(f, env->pregs[i]); + + qemu_put_be32(f, env->pc); + qemu_put_be32(f, env->ksp); + + qemu_put_be32(f, env->dslot); + qemu_put_be32(f, env->btaken); + qemu_put_be32(f, env->btarget); + + qemu_put_be32(f, env->cc_op); + qemu_put_be32(f, env->cc_mask); + qemu_put_be32(f, env->cc_dest); + qemu_put_be32(f, env->cc_src); + qemu_put_be32(f, env->cc_result); + qemu_put_be32(f, env->cc_size); + qemu_put_be32(f, env->cc_x); + + for (s = 0; s < 4; i++) { + for (i = 0; i < 16; i++) + qemu_put_be32(f, env->sregs[s][i]); + } + + qemu_put_be32(f, env->mmu_rand_lfsr); + for (mmu = 0; mmu < 2; mmu++) { + for (s = 0; s < 4; i++) { + for (i = 0; i < 16; i++) { + qemu_put_be32(f, env->tlbsets[mmu][s][i].lo); + qemu_put_be32(f, env->tlbsets[mmu][s][i].hi); + } + } + } +} + +int cpu_load(QEMUFile *f, void *opaque, int version_id) +{ + CPUCRISState *env = opaque; + int i; + int s; + int mmu; + + for (i = 0; i < 16; i++) + env->regs[i] = qemu_get_be32(f); + for (i = 0; i < 16; i++) + env->pregs[i] = qemu_get_be32(f); + + env->pc = qemu_get_be32(f); + env->ksp = qemu_get_be32(f); + + env->dslot = qemu_get_be32(f); + env->btaken = qemu_get_be32(f); + env->btarget = qemu_get_be32(f); + + env->cc_op = qemu_get_be32(f); + env->cc_mask = qemu_get_be32(f); + env->cc_dest = qemu_get_be32(f); + env->cc_src = qemu_get_be32(f); + env->cc_result = qemu_get_be32(f); + env->cc_size = qemu_get_be32(f); + env->cc_x = qemu_get_be32(f); + + for (s = 0; s < 4; i++) { + for (i = 0; i < 16; i++) + env->sregs[s][i] = qemu_get_be32(f); + } + + env->mmu_rand_lfsr = qemu_get_be32(f); + for (mmu = 0; mmu < 2; mmu++) { + for (s = 0; s < 4; i++) { + for (i = 0; i < 16; i++) { + env->tlbsets[mmu][s][i].lo = qemu_get_be32(f); + env->tlbsets[mmu][s][i].hi = qemu_get_be32(f); + } + } + } + + return 0; +} -- cgit v1.2.3 From 77b73de67632ed04acad4d816741ba27427cadac Mon Sep 17 00:00:00 2001 From: malc Date: Mon, 9 Jun 2008 23:44:44 +0000 Subject: Use rem/div[u]_i32 drop div[u]2_i32 git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4722 c046a42c-6fe2-441c-8c8c-71466251a162 --- tcg/ppc/tcg-target.c | 138 ++++++++++----------------------------------------- tcg/ppc/tcg-target.h | 1 + 2 files changed, 26 insertions(+), 113 deletions(-) diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 9b5c6d622..0fd8e4b87 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -23,8 +23,6 @@ */ static uint8_t *tb_ret_addr; -static uint8_t *udiv_addr; -static uint8_t *div_addr; #define FAST_PATH #if TARGET_PHYS_ADDR_BITS <= 32 @@ -137,22 +135,6 @@ static const int tcg_target_callee_save_regs[] = { TCG_REG_R31 }; -static const int div_save_regs[] = { - TCG_REG_R4, - TCG_REG_R5, - TCG_REG_R7, - TCG_REG_R8, - TCG_REG_R9, - TCG_REG_R10, - TCG_REG_R11, - TCG_REG_R12, - TCG_REG_R13, /* should r13 be saved? */ - TCG_REG_R24, - TCG_REG_R25, - TCG_REG_R26, - TCG_REG_R27, -}; - static uint32_t reloc_pc24_val (void *pc, tcg_target_long target) { tcg_target_long disp; @@ -817,22 +799,6 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) #endif } -static uint64_t ppc_udiv_helper (uint64_t a, uint32_t b) -{ - uint64_t rem, quo; - quo = a / b; - rem = a % b; - return (rem << 32) | (uint32_t) quo; -} - -static uint64_t ppc_div_helper (int64_t a, int32_t b) -{ - int64_t rem, quo; - quo = a / b; - rem = a % b; - return (rem << 32) | (uint32_t) quo; -} - void tcg_target_qemu_prologue (TCGContext *s) { int i, j, frame_size; @@ -871,49 +837,6 @@ void tcg_target_qemu_prologue (TCGContext *s) tcg_out32 (s, MTSPR | RS (0) | LR); tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size); tcg_out32 (s, BCLR | BO_ALWAYS); - - /* div trampolines */ - for (j = 0; j < 2; ++j) { - tcg_target_long target; - - frame_size = 8 + ARRAY_SIZE (div_save_regs) * 4; - frame_size = (frame_size + 15) & ~15; - - if (j == 0) { - target = (tcg_target_long) ppc_udiv_helper; - udiv_addr = s->code_ptr; - } - else { - target = (tcg_target_long) ppc_div_helper; - div_addr = s->code_ptr; - } - - tcg_out32 (s, MFSPR | RT (0) | LR); - tcg_out32 (s, STWU | RS (1) | RA (1) | (-frame_size & 0xffff)); - for (i = 0; i < ARRAY_SIZE (div_save_regs); ++i) - tcg_out32 (s, (STW - | RS (div_save_regs[i]) - | RA (1) - | (i * 4 + 8) - ) - ); - tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size - 4)); - tcg_out_mov (s, 4, 6); - tcg_out_b (s, LK, target); - tcg_out_mov (s, 6, 4); - - for (i = 0; i < ARRAY_SIZE (div_save_regs); ++i) - tcg_out32 (s, (LWZ - | RT (div_save_regs[i]) - | RA (1) - | (i * 4 + 8) - ) - ); - tcg_out32 (s, LWZ | RT (0) | RA (1) | (frame_size - 4)); - tcg_out32 (s, MTSPR | RS (0) | LR); - tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size); - tcg_out32 (s, BCLR | BO_ALWAYS); - } } static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1, @@ -1095,34 +1018,6 @@ static void tcg_out_brcond2(TCGContext *s, tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr); } -static void tcg_out_div2 (TCGContext *s, int uns) -{ - void *label1_ptr, *label2_ptr; - - if (uns) - tcg_out32 (s, CMPLI | BF (7) | RA (3)); - else { - tcg_out32 (s, SRAWI | RS (4) | RA (0) | 31); - tcg_out32 (s, CMPL | BF (7) | RA (3) | RB (4)); - } - - label1_ptr = s->code_ptr; - tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE); - - tcg_out_b (s, LK, (tcg_target_long) (uns ? udiv_addr : div_addr)); - - label2_ptr = s->code_ptr; - tcg_out32 (s, B); - - reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr); - - tcg_out32 (s, (uns ? DIVWU : DIVW) | TAB (6, 4, 5)); - tcg_out32 (s, MULLW | TAB (0, 6, 5)); - tcg_out32 (s, SUBF | TAB (3, 0, 4)); - - reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr); -} - static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, const int *const_args) { @@ -1301,6 +1196,27 @@ static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, else tcg_out32 (s, MULLW | TAB (args[0], args[1], args[2])); break; + + case INDEX_op_div_i32: + tcg_out32 (s, DIVW | TAB (args[0], args[1], args[2])); + break; + + case INDEX_op_divu_i32: + tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2])); + break; + + case INDEX_op_rem_i32: + tcg_out32 (s, DIVW | TAB (0, args[1], args[2])); + tcg_out32 (s, MULLW | TAB (0, 0, args[2])); + tcg_out32 (s, SUBF | TAB (args[0], 0, args[1])); + break; + + case INDEX_op_remu_i32: + tcg_out32 (s, DIVWU | TAB (0, args[1], args[2])); + tcg_out32 (s, MULLW | TAB (0, 0, args[2])); + tcg_out32 (s, SUBF | TAB (args[0], 0, args[1])); + break; + case INDEX_op_mulu2_i32: if (args[0] == args[2] || args[0] == args[3]) { tcg_out32 (s, MULLW | TAB (0, args[2], args[3])); @@ -1312,12 +1228,6 @@ static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, tcg_out32 (s, MULHWU | TAB (args[1], args[2], args[3])); } break; - case INDEX_op_div2_i32: - tcg_out_div2 (s, 0); - break; - case INDEX_op_divu2_i32: - tcg_out_div2 (s, 1); - break; case INDEX_op_shl_i32: if (const_args[2]) { @@ -1458,9 +1368,11 @@ static const TCGTargetOpDef ppc_op_defs[] = { { INDEX_op_add_i32, { "r", "r", "ri" } }, { INDEX_op_mul_i32, { "r", "r", "ri" } }, + { INDEX_op_div_i32, { "r", "r", "r" } }, + { INDEX_op_divu_i32, { "r", "r", "r" } }, + { INDEX_op_rem_i32, { "r", "r", "r" } }, + { INDEX_op_remu_i32, { "r", "r", "r" } }, { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } }, - { INDEX_op_div2_i32, { "D", "A", "B", "1", "C" } }, - { INDEX_op_divu2_i32, { "D", "A", "B", "1", "C" } }, { INDEX_op_sub_i32, { "r", "r", "ri" } }, { INDEX_op_and_i32, { "r", "r", "ri" } }, { INDEX_op_or_i32, { "r", "r", "ri" } }, diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h index e7a1c2a0d..db1b12170 100644 --- a/tcg/ppc/tcg-target.h +++ b/tcg/ppc/tcg-target.h @@ -70,6 +70,7 @@ enum { /* optional instructions */ #define TCG_TARGET_HAS_neg_i32 +#define TCG_TARGET_HAS_div_i32 #define TCG_AREG0 TCG_REG_R27 #define TCG_AREG1 TCG_REG_R24 -- cgit v1.2.3 From a8303d18e044b9c808c27a9c48888c6e639a321d Mon Sep 17 00:00:00 2001 From: edgar_igl Date: Tue, 10 Jun 2008 00:11:48 +0000 Subject: ETRAX: More DMA context level related fixes. * When hitting EOL (end of list) at the data descriptor level, the DMA should mark the current context-descriptor as disabled and perform a context-store so software can see whats goin on. * Context loads update RW_SAVED_DATA_BUF, data loads dont. This fixes an issue with ethernet bootstrapping. * Reorder the logic for processing out channels to be more like the one for input channels. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4723 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/etraxfs_dma.c | 110 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 40 deletions(-) diff --git a/hw/etraxfs_dma.c b/hw/etraxfs_dma.c index 0a5562b9c..776cfb9cf 100644 --- a/hw/etraxfs_dma.c +++ b/hw/etraxfs_dma.c @@ -267,23 +267,33 @@ static void channel_load_d(struct fs_dma_ctrl *ctrl, int c) target_phys_addr_t addr = channel_reg(ctrl, c, RW_SAVED_DATA); /* Load and decode. FIXME: handle endianness. */ - D(printf("%s addr=%x\n", __func__, addr)); + D(printf("%s ch=%d addr=%x\n", __func__, c, addr)); cpu_physical_memory_read (addr, (void *) &ctrl->channels[c].current_d, sizeof ctrl->channels[c].current_d); D(dump_d(c, &ctrl->channels[c].current_d)); ctrl->channels[c].regs[RW_DATA] = addr; - ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = - (uint32_t)ctrl->channels[c].current_d.buf; +} + +static void channel_store_c(struct fs_dma_ctrl *ctrl, int c) +{ + target_phys_addr_t addr = channel_reg(ctrl, c, RW_GROUP_DOWN); + + /* Encode and store. FIXME: handle endianness. */ + D(printf("%s ch=%d addr=%x\n", __func__, c, addr)); + D(dump_d(c, &ctrl->channels[c].current_d)); + cpu_physical_memory_write (addr, + (void *) &ctrl->channels[c].current_c, + sizeof ctrl->channels[c].current_c); } static void channel_store_d(struct fs_dma_ctrl *ctrl, int c) { target_phys_addr_t addr = channel_reg(ctrl, c, RW_SAVED_DATA); - /* Load and decode. FIXME: handle endianness. */ - D(printf("%s addr=%x\n", __func__, addr)); + /* Encode and store. FIXME: handle endianness. */ + D(printf("%s ch=%d addr=%x\n", __func__, c, addr)); cpu_physical_memory_write (addr, (void *) &ctrl->channels[c].current_d, sizeof ctrl->channels[c].current_d); @@ -326,20 +336,23 @@ static void channel_continue(struct fs_dma_ctrl *ctrl, int c) /* If the current descriptor cleared the eol flag and we had already reached eol state, do the continue. */ if (!ctrl->channels[c].current_d.eol && ctrl->channels[c].eol) { - D(printf("continue %d ok %x\n", c, + D(printf("continue %d ok %p\n", c, ctrl->channels[c].current_d.next)); ctrl->channels[c].regs[RW_SAVED_DATA] = (uint32_t) ctrl->channels[c].current_d.next; channel_load_d(ctrl, c); channel_start(ctrl, c); } + ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = + (uint32_t) ctrl->channels[c].current_d.buf; } static void channel_stream_cmd(struct fs_dma_ctrl *ctrl, int c, uint32_t v) { unsigned int cmd = v & ((1 << 10) - 1); - D(printf("%s cmd=%x\n", __func__, cmd)); + D(printf("%s ch=%d cmd=%x pc=%x\n", + __func__, c, cmd, ctrl->env->pc)); if (cmd & regk_dma_load_d) { channel_load_d(ctrl, c); if (cmd & regk_dma_burst) @@ -348,6 +361,7 @@ static void channel_stream_cmd(struct fs_dma_ctrl *ctrl, int c, uint32_t v) if (cmd & regk_dma_load_c) { channel_load_c(ctrl, c); + channel_start(ctrl, c); } } @@ -382,11 +396,30 @@ static void channel_out_run(struct fs_dma_ctrl *ctrl, int c) saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF); - D(printf("buf=%x after=%x saved_data_buf=%x\n", + D(fprintf(logfile, "ch=%d buf=%x after=%x saved_data_buf=%x\n", + c, (uint32_t)ctrl->channels[c].current_d.buf, (uint32_t)ctrl->channels[c].current_d.after, saved_data_buf)); + len = (uint32_t) ctrl->channels[c].current_d.after; + len -= saved_data_buf; + + if (len > sizeof buf) + len = sizeof buf; + cpu_physical_memory_read (saved_data_buf, buf, len); + + D(printf("channel %d pushes %x %u bytes\n", c, + saved_data_buf, len)); + + if (ctrl->channels[c].client->client.push) + ctrl->channels[c].client->client.push( + ctrl->channels[c].client->client.opaque, buf, len); + else + printf("WARNING: DMA ch%d dataloss, no attached client.\n", c); + + saved_data_buf += len; + if (saved_data_buf == (uint32_t)ctrl->channels[c].current_d.after) { /* Done. Step to next. */ if (ctrl->channels[c].current_d.out_eop) { @@ -403,36 +436,26 @@ static void channel_out_run(struct fs_dma_ctrl *ctrl, int c) if (ctrl->channels[c].current_d.eol) { D(printf("channel %d EOL\n", c)); ctrl->channels[c].eol = 1; + + /* Mark the context as disabled. */ + ctrl->channels[c].current_c.dis = 1; + channel_store_c(ctrl, c); + channel_stop(ctrl, c); } else { ctrl->channels[c].regs[RW_SAVED_DATA] = (uint32_t) ctrl->channels[c].current_d.next; /* Load new descriptor. */ channel_load_d(ctrl, c); + saved_data_buf = (uint32_t) + ctrl->channels[c].current_d.buf; } channel_store_d(ctrl, c); + ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf; D(dump_d(c, &ctrl->channels[c].current_d)); - return; } - - len = (uint32_t) ctrl->channels[c].current_d.after; - len -= saved_data_buf; - - if (len > sizeof buf) - len = sizeof buf; - cpu_physical_memory_read (saved_data_buf, buf, len); - - D(printf("channel %d pushes %x %u bytes\n", c, - saved_data_buf, len)); - /* TODO: Push content. */ - if (ctrl->channels[c].client->client.push) - ctrl->channels[c].client->client.push( - ctrl->channels[c].client->client.opaque, buf, len); - else - printf("WARNING: DMA ch%d dataloss, no attached client.\n", c); - - ctrl->channels[c].regs[RW_SAVED_DATA_BUF] += len; + ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf; } static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, @@ -483,14 +506,19 @@ static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, if (ctrl->channels[c].current_d.eol) { D(printf("channel %d EOL\n", c)); ctrl->channels[c].eol = 1; + + /* Mark the context as disabled. */ + ctrl->channels[c].current_c.dis = 1; + channel_store_c(ctrl, c); + channel_stop(ctrl, c); } else { ctrl->channels[c].regs[RW_SAVED_DATA] = (uint32_t) ctrl->channels[c].current_d.next; /* Load new descriptor. */ channel_load_d(ctrl, c); - saved_data_buf = - ctrl->channels[c].regs[RW_SAVED_DATA_BUF]; + saved_data_buf = (uint32_t) + ctrl->channels[c].current_d.buf; } } @@ -523,21 +551,21 @@ dma_readl (void *opaque, target_phys_addr_t addr) /* Make addr relative to this instances base. */ c = fs_channel(ctrl->base, addr); - addr &= 0x1fff; + addr &= 0x1fff; switch (addr) - { + { case RW_STAT: r = ctrl->channels[c].state & 7; r |= ctrl->channels[c].eol << 5; r |= ctrl->channels[c].stream_cmd_src << 8; break; - default: + default: r = ctrl->channels[c].regs[addr]; D(printf ("%s c=%d addr=%x pc=%x\n", - __func__, c, addr, env->pc)); - break; - } + __func__, c, addr, ctrl->env->pc)); + break; + } return r; } @@ -560,7 +588,7 @@ dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) c = fs_channel(ctrl->base, addr); addr &= 0x1fff; switch (addr) - { + { case RW_DATA: ctrl->channels[c].regs[addr] = value; break; @@ -591,13 +619,15 @@ dma_writel (void *opaque, target_phys_addr_t addr, uint32_t value) case RW_STREAM_CMD: ctrl->channels[c].regs[addr] = value; + D(printf("stream_cmd ch=%d pc=%x\n", + c, ctrl->env->pc)); channel_stream_cmd(ctrl, c, value); break; - default: - D(printf ("%s c=%d %x %x pc=%x\n", - __func__, c, addr, value, env->pc)); - break; + default: + D(printf ("%s c=%d %x %x pc=%x\n", + __func__, c, addr, value, ctrl->env->pc)); + break; } } -- cgit v1.2.3 From 2c2435bdd498ab177469bec25a44e915a4d4a63a Mon Sep 17 00:00:00 2001 From: ths Date: Tue, 10 Jun 2008 01:18:32 +0000 Subject: Fix data type mixup, spotted by malc. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4724 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/translate.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index c744c9afb..0bd6fd9a6 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -2595,11 +2595,8 @@ static inline void gen_mfc0_load32 (TCGv t, target_ulong off) static inline void gen_mfc0_load64 (TCGv t, target_ulong off) { - TCGv r_tmp = tcg_temp_new(TCG_TYPE_I64); - - tcg_gen_ld_i64(r_tmp, cpu_env, off); - tcg_gen_trunc_i64_tl(t, r_tmp); - tcg_temp_free(r_tmp); + tcg_gen_ld_tl(t, cpu_env, off); + tcg_gen_ext32s_tl(t, t); } static inline void gen_mtc0_store32 (TCGv t, target_ulong off) @@ -2613,11 +2610,8 @@ static inline void gen_mtc0_store32 (TCGv t, target_ulong off) static inline void gen_mtc0_store64 (TCGv t, target_ulong off) { - TCGv r_tmp = tcg_temp_new(TCG_TYPE_I64); - - tcg_gen_ext_tl_i64(r_tmp, t); - tcg_gen_st_i64(r_tmp, cpu_env, off); - tcg_temp_free(r_tmp); + tcg_gen_ext32s_tl(t, t); + tcg_gen_st_tl(t, cpu_env, off); } static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) -- cgit v1.2.3 From 0d5bd3631f56bfed85db2896daa3c8ce932c5859 Mon Sep 17 00:00:00 2001 From: malc Date: Tue, 10 Jun 2008 01:47:17 +0000 Subject: Remove stray variable git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4725 c046a42c-6fe2-441c-8c8c-71466251a162 --- tcg/ppc/tcg-target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 0fd8e4b87..f27f096ed 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -801,7 +801,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) void tcg_target_qemu_prologue (TCGContext *s) { - int i, j, frame_size; + int i, frame_size; frame_size = 0 + 4 /* back chain */ -- cgit v1.2.3 From af325d36e02e83ea60046225dc0ae6c2402abfac Mon Sep 17 00:00:00 2001 From: ths Date: Tue, 10 Jun 2008 15:29:15 +0000 Subject: Fix typo, by Laurent Desnogues. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4726 c046a42c-6fe2-441c-8c8c-71466251a162 --- linux-user/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index c99c5ffe2..cd90946ae 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3070,7 +3070,7 @@ void syscall_init(void) #if TARGET_ABI_BITS == 32 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1) { -#ifdef TARGET_WORDS_BIG_ENDIAN +#ifdef TARGET_WORDS_BIGENDIAN return ((uint64_t)word0 << 32) | word1; #else return ((uint64_t)word1 << 32) | word0; -- cgit v1.2.3 From ae45d3693b49de05b472c00fbe0d6e3ff5d16ecc Mon Sep 17 00:00:00 2001 From: bellard Date: Wed, 11 Jun 2008 09:44:44 +0000 Subject: using strncpy is *always* a bad idea git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4727 c046a42c-6fe2-441c-8c8c-71466251a162 --- vl.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/vl.c b/vl.c index 18ddcce1f..671b7a41d 100644 --- a/vl.c +++ b/vl.c @@ -3394,8 +3394,7 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, #ifndef _WIN32 if (is_unix) { char path[109]; - strncpy(path, uaddr.sun_path, 108); - path[108] = 0; + pstrcpy(path, sizeof(path), uaddr.sun_path); unlink(path); } else #endif @@ -5075,7 +5074,7 @@ static int drive_init(struct drive_opt *arg, int snapshot, } if (get_param_value(buf, sizeof(buf), "if", str)) { - strncpy(devname, buf, sizeof(devname)); + pstrcpy(devname, sizeof(devname), buf); if (!strcmp(buf, "ide")) { type = IF_IDE; max_devs = MAX_IDE_DEVS; -- cgit v1.2.3 From 764dfc3fa03f08457bb584720650c8899df82d57 Mon Sep 17 00:00:00 2001 From: ths Date: Wed, 11 Jun 2008 10:39:48 +0000 Subject: Move FP TNs to cpu env. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4728 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/cpu.h | 11 ++++++----- target-mips/exec.h | 36 ++++++++++++++++++------------------ target-mips/translate.c | 6 +++--- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 964a560fa..874ecee5e 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -70,11 +70,6 @@ typedef struct CPUMIPSFPUContext CPUMIPSFPUContext; struct CPUMIPSFPUContext { /* Floating point registers */ fpr_t fpr[32]; -#ifndef USE_HOST_FLOAT_REGS - fpr_t ft0; - fpr_t ft1; - fpr_t ft2; -#endif float_status fp_status; /* fpu implementation/revision register (fir) */ uint32_t fcr0; @@ -148,6 +143,12 @@ struct CPUMIPSState { #if TARGET_LONG_BITS > HOST_LONG_BITS target_ulong t0; target_ulong t1; +#endif + /* temporary hack for FP globals */ +#ifndef USE_HOST_FLOAT_REGS + fpr_t ft0; + fpr_t ft1; + fpr_t ft2; #endif target_ulong HI[MIPS_TC_MAX][MIPS_DSP_ACC]; target_ulong LO[MIPS_TC_MAX][MIPS_DSP_ACC]; diff --git a/target-mips/exec.h b/target-mips/exec.h index c92700572..90f0a0269 100644 --- a/target-mips/exec.h +++ b/target-mips/exec.h @@ -21,24 +21,24 @@ register target_ulong T1 asm(AREG2); #if defined (USE_HOST_FLOAT_REGS) #error "implement me." #else -#define FDT0 (env->fpu->ft0.fd) -#define FDT1 (env->fpu->ft1.fd) -#define FDT2 (env->fpu->ft2.fd) -#define FST0 (env->fpu->ft0.fs[FP_ENDIAN_IDX]) -#define FST1 (env->fpu->ft1.fs[FP_ENDIAN_IDX]) -#define FST2 (env->fpu->ft2.fs[FP_ENDIAN_IDX]) -#define FSTH0 (env->fpu->ft0.fs[!FP_ENDIAN_IDX]) -#define FSTH1 (env->fpu->ft1.fs[!FP_ENDIAN_IDX]) -#define FSTH2 (env->fpu->ft2.fs[!FP_ENDIAN_IDX]) -#define DT0 (env->fpu->ft0.d) -#define DT1 (env->fpu->ft1.d) -#define DT2 (env->fpu->ft2.d) -#define WT0 (env->fpu->ft0.w[FP_ENDIAN_IDX]) -#define WT1 (env->fpu->ft1.w[FP_ENDIAN_IDX]) -#define WT2 (env->fpu->ft2.w[FP_ENDIAN_IDX]) -#define WTH0 (env->fpu->ft0.w[!FP_ENDIAN_IDX]) -#define WTH1 (env->fpu->ft1.w[!FP_ENDIAN_IDX]) -#define WTH2 (env->fpu->ft2.w[!FP_ENDIAN_IDX]) +#define FDT0 (env->ft0.fd) +#define FDT1 (env->ft1.fd) +#define FDT2 (env->ft2.fd) +#define FST0 (env->ft0.fs[FP_ENDIAN_IDX]) +#define FST1 (env->ft1.fs[FP_ENDIAN_IDX]) +#define FST2 (env->ft2.fs[FP_ENDIAN_IDX]) +#define FSTH0 (env->ft0.fs[!FP_ENDIAN_IDX]) +#define FSTH1 (env->ft1.fs[!FP_ENDIAN_IDX]) +#define FSTH2 (env->ft2.fs[!FP_ENDIAN_IDX]) +#define DT0 (env->ft0.d) +#define DT1 (env->ft1.d) +#define DT2 (env->ft2.d) +#define WT0 (env->ft0.w[FP_ENDIAN_IDX]) +#define WT1 (env->ft1.w[FP_ENDIAN_IDX]) +#define WT2 (env->ft2.w[FP_ENDIAN_IDX]) +#define WTH0 (env->ft0.w[!FP_ENDIAN_IDX]) +#define WTH1 (env->ft1.w[!FP_ENDIAN_IDX]) +#define WTH2 (env->ft2.w[!FP_ENDIAN_IDX]) #endif #include "cpu.h" diff --git a/target-mips/translate.c b/target-mips/translate.c index 0bd6fd9a6..7c54982d0 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -7386,9 +7386,9 @@ void fpu_dump_state(CPUState *env, FILE *f, fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n", env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status, get_float_exception_flags(&env->fpu->fp_status)); - fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0); - fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1); - fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2); + fpu_fprintf(f, "FT0: "); printfpr(&env->ft0); + fpu_fprintf(f, "FT1: "); printfpr(&env->ft1); + fpu_fprintf(f, "FT2: "); printfpr(&env->ft2); for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) { fpu_fprintf(f, "%3s: ", fregnames[i]); printfpr(&env->fpu->fpr[i]); -- cgit v1.2.3 From 9843a0d2c62d683c1940cfd2d7c6533837b56bb2 Mon Sep 17 00:00:00 2001 From: ths Date: Wed, 11 Jun 2008 10:40:33 +0000 Subject: Free some more temporaries. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4729 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/translate.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 7c54982d0..2f6679b68 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -840,21 +840,15 @@ static inline void gen_op_addr_add (void) See the MIPS64 PRA manual, section 4.10. */ { int l1 = gen_new_label(); - - { - TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); - - tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags)); - tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU); - tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1); - } - { - TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); - - tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status)); - tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX)); - tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1); - } + TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32); + + tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags)); + tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU); + tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1); + tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status)); + tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX)); + tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1); + tcg_temp_free(r_tmp); tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]); gen_set_label(l1); } @@ -5542,13 +5536,14 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) gen_load_gpr(cpu_T[1], rs); { TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR); - TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); + TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32); tcg_gen_ld_ptr(r_ptr, cpu_env, offsetof(CPUState, fpu)); tcg_gen_ld_i32(r_tmp, r_ptr, offsetof(CPUMIPSFPUContext, fcr31)); tcg_temp_free(r_ptr); tcg_gen_andi_i32(r_tmp, r_tmp, ccbit); tcg_gen_brcondi_i32(cond, r_tmp, 0, l1); + tcg_temp_free(r_tmp); } tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); -- cgit v1.2.3 From 8df1ca4ba51fc3bfccc3d901584b316ae2e60bb9 Mon Sep 17 00:00:00 2001 From: ths Date: Wed, 11 Jun 2008 11:03:34 +0000 Subject: Allocate register pair for 64-bit registers on 32-bit host. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4730 c046a42c-6fe2-441c-8c8c-71466251a162 --- tcg/tcg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index b4b8d8ea2..e97605411 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -423,7 +423,7 @@ TCGv tcg_temp_new_internal(TCGType type, int temp_local) idx = s->nb_temps; #if TCG_TARGET_REG_BITS == 32 if (type == TCG_TYPE_I64) { - tcg_temp_alloc(s, s->nb_temps + 1); + tcg_temp_alloc(s, s->nb_temps + 2); ts = &s->temps[s->nb_temps]; ts->base_type = type; ts->type = TCG_TYPE_I32; @@ -1961,7 +1961,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, break; } args += def->nb_args; - next: ; + next: if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) { return op_index; } -- cgit v1.2.3 From faf7aaa9183d5f2029ada291837a8716e9be127b Mon Sep 17 00:00:00 2001 From: ths Date: Wed, 11 Jun 2008 12:26:29 +0000 Subject: Avoid gen_opc_buf overflow. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4731 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/translate.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 2f6679b68..8a00336ed 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -7229,7 +7229,8 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, fprintf (logfile, "search pc %d\n", search_pc); pc_start = tb->pc; - gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; + /* Leave some spare opc slots for branch handling. */ + gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16; ctx.pc = pc_start; ctx.saved_pc = -1; ctx.tb = tb; @@ -7254,7 +7255,7 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, fprintf(logfile, "\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags); #endif - while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) { + while (ctx.bstate == BS_NONE) { if (env->nb_breakpoints > 0) { for(j = 0; j < env->nb_breakpoints; j++) { if (env->breakpoints[j] == ctx.pc) { @@ -7290,6 +7291,9 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) break; + if (gen_opc_ptr >= gen_opc_end) + break; + #if defined (MIPS_SINGLE_STEP) break; #endif -- cgit v1.2.3 From aa0bf00b659111905887269775f1f611c8cda74b Mon Sep 17 00:00:00 2001 From: ths Date: Wed, 11 Jun 2008 13:02:57 +0000 Subject: Switch most MIPS FP load/stores to TCG. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4732 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/op.c | 139 -------- target-mips/op_mem.c | 20 -- target-mips/translate.c | 854 ++++++++++++++++++++++++------------------------ 3 files changed, 426 insertions(+), 587 deletions(-) diff --git a/target-mips/op.c b/target-mips/op.c index ff5aed968..3d594aa98 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -48,103 +48,6 @@ func(arg0, arg1, arg2, arg3) #endif -#define FREG 0 -#include "fop_template.c" -#undef FREG -#define FREG 1 -#include "fop_template.c" -#undef FREG -#define FREG 2 -#include "fop_template.c" -#undef FREG -#define FREG 3 -#include "fop_template.c" -#undef FREG -#define FREG 4 -#include "fop_template.c" -#undef FREG -#define FREG 5 -#include "fop_template.c" -#undef FREG -#define FREG 6 -#include "fop_template.c" -#undef FREG -#define FREG 7 -#include "fop_template.c" -#undef FREG -#define FREG 8 -#include "fop_template.c" -#undef FREG -#define FREG 9 -#include "fop_template.c" -#undef FREG -#define FREG 10 -#include "fop_template.c" -#undef FREG -#define FREG 11 -#include "fop_template.c" -#undef FREG -#define FREG 12 -#include "fop_template.c" -#undef FREG -#define FREG 13 -#include "fop_template.c" -#undef FREG -#define FREG 14 -#include "fop_template.c" -#undef FREG -#define FREG 15 -#include "fop_template.c" -#undef FREG -#define FREG 16 -#include "fop_template.c" -#undef FREG -#define FREG 17 -#include "fop_template.c" -#undef FREG -#define FREG 18 -#include "fop_template.c" -#undef FREG -#define FREG 19 -#include "fop_template.c" -#undef FREG -#define FREG 20 -#include "fop_template.c" -#undef FREG -#define FREG 21 -#include "fop_template.c" -#undef FREG -#define FREG 22 -#include "fop_template.c" -#undef FREG -#define FREG 23 -#include "fop_template.c" -#undef FREG -#define FREG 24 -#include "fop_template.c" -#undef FREG -#define FREG 25 -#include "fop_template.c" -#undef FREG -#define FREG 26 -#include "fop_template.c" -#undef FREG -#define FREG 27 -#include "fop_template.c" -#undef FREG -#define FREG 28 -#include "fop_template.c" -#undef FREG -#define FREG 29 -#include "fop_template.c" -#undef FREG -#define FREG 30 -#include "fop_template.c" -#undef FREG -#define FREG 31 -#include "fop_template.c" -#undef FREG - /* Load and store */ #define MEMSUFFIX _raw #include "op_mem.c" @@ -467,48 +370,6 @@ void op_dmultu (void) # define DEBUG_FPU_STATE() do { } while(0) #endif -void op_mfc1 (void) -{ - T0 = (int32_t)WT0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} - -void op_mtc1 (void) -{ - WT0 = T0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} - -void op_dmfc1 (void) -{ - T0 = DT0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} - -void op_dmtc1 (void) -{ - DT0 = T0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} - -void op_mfhc1 (void) -{ - T0 = (int32_t)WTH0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} - -void op_mthc1 (void) -{ - WTH0 = T0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} - /* Float support. Single precition routines have a "s" suffix, double precision a "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps", diff --git a/target-mips/op_mem.c b/target-mips/op_mem.c index 4b889a88d..cb60d06be 100644 --- a/target-mips/op_mem.c +++ b/target-mips/op_mem.c @@ -268,26 +268,6 @@ void glue(op_sdr, MEMSUFFIX) (void) } #endif /* TARGET_MIPS64 */ -void glue(op_lwc1, MEMSUFFIX) (void) -{ - WT0 = glue(ldl, MEMSUFFIX)(T0); - FORCE_RET(); -} -void glue(op_swc1, MEMSUFFIX) (void) -{ - glue(stl, MEMSUFFIX)(T0, WT0); - FORCE_RET(); -} -void glue(op_ldc1, MEMSUFFIX) (void) -{ - DT0 = glue(ldq, MEMSUFFIX)(T0); - FORCE_RET(); -} -void glue(op_sdc1, MEMSUFFIX) (void) -{ - glue(stq, MEMSUFFIX)(T0, DT0); - FORCE_RET(); -} void glue(op_luxc1, MEMSUFFIX) (void) { DT0 = glue(ldq, MEMSUFFIX)(T0 & ~0x7); diff --git a/target-mips/translate.c b/target-mips/translate.c index 8a00336ed..757e12bbd 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -423,7 +423,10 @@ enum { }; /* global register indices */ -static TCGv cpu_env, current_tc_gprs, current_tc_hi, cpu_T[2]; +static TCGv cpu_env, current_tc_gprs, current_tc_hi, current_fpu, cpu_T[2]; + +/* FPU TNs, global for now. */ +static TCGv fpu32_T[3], fpu64_T[3], fpu32h_T[3]; static inline void tcg_gen_helper_0_1i(void *func, TCGv arg) { @@ -572,58 +575,60 @@ static inline void gen_store_srsgpr (TCGv t, int reg) } /* Floating point register moves. */ -#define FGEN32(func, NAME) \ -static GenOpFunc *NAME ## _table [32] = { \ -NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \ -NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \ -NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \ -NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \ -NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \ -NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \ -NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \ -NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \ -}; \ -static always_inline void func(int n) \ -{ \ - NAME ## _table[n](); \ +static inline void gen_load_fpr32 (TCGv t, int reg) +{ + tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX); } -FGEN32(gen_op_load_fpr_WT0, gen_op_load_fpr_WT0_fpr); -FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr); - -FGEN32(gen_op_load_fpr_WT1, gen_op_load_fpr_WT1_fpr); -FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr); - -FGEN32(gen_op_load_fpr_WT2, gen_op_load_fpr_WT2_fpr); -FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr); - -FGEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fpr); -FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr); - -FGEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fpr); -FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr); - -FGEN32(gen_op_load_fpr_DT2, gen_op_load_fpr_DT2_fpr); -FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr); +static inline void gen_store_fpr32 (TCGv t, int reg) +{ + tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX); +} -FGEN32(gen_op_load_fpr_WTH0, gen_op_load_fpr_WTH0_fpr); -FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr); +static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg) +{ + if (ctx->hflags & MIPS_HFLAG_F64) { + tcg_gen_ld_i64(t, current_fpu, 8 * reg); + } else { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX); + tcg_gen_extu_i32_i64(t, r_tmp1); + tcg_gen_shli_i64(t, t, 32); + tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX); + tcg_gen_extu_i32_i64(r_tmp2, r_tmp1); + tcg_gen_or_i64(t, t, r_tmp2); + tcg_temp_free(r_tmp1); + tcg_temp_free(r_tmp2); + } +} -FGEN32(gen_op_load_fpr_WTH1, gen_op_load_fpr_WTH1_fpr); -FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr); +static inline void gen_store_fpr64 (DisasContext *ctx, TCGv t, int reg) +{ + if (ctx->hflags & MIPS_HFLAG_F64) { + tcg_gen_st_i64(t, current_fpu, 8 * reg); + } else { + TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); -FGEN32(gen_op_load_fpr_WTH2, gen_op_load_fpr_WTH2_fpr); -FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr); + tcg_gen_trunc_i64_i32(r_tmp, t); + tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX); + tcg_gen_shri_i64(t, t, 32); + tcg_gen_trunc_i64_i32(r_tmp, t); + tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX); + tcg_temp_free(r_tmp); + } +} -#define GEN_LOAD_FREG_FTN(FTn, Fn) \ -do { \ - glue(gen_op_load_fpr_, FTn)(Fn); \ -} while (0) +static inline void gen_load_fpr32h (TCGv t, int reg) +{ + tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX); +} -#define GEN_STORE_FTN_FREG(Fn, FTn) \ -do { \ - glue(gen_op_store_fpr_, FTn)(Fn); \ -} while (0) +static inline void gen_store_fpr32h (TCGv t, int reg) +{ + tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX); +} #define FOP_CONDS(type, fmt) \ static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = { \ @@ -950,10 +955,6 @@ OP_LD_TABLE(wl); OP_LD_TABLE(wr); OP_ST_TABLE(wl); OP_ST_TABLE(wr); -OP_LD_TABLE(wc1); -OP_ST_TABLE(wc1); -OP_LD_TABLE(dc1); -OP_ST_TABLE(dc1); OP_LD_TABLE(uxc1); OP_ST_TABLE(uxc1); @@ -1028,26 +1029,6 @@ OP_ST_ATOMIC(scd,st64,0x7); #endif #undef OP_ST_ATOMIC -void inline op_ldst_lwc1(DisasContext *ctx) -{ - op_ldst(lwc1); -} - -void inline op_ldst_ldc1(DisasContext *ctx) -{ - op_ldst(ldc1); -} - -void inline op_ldst_swc1(DisasContext *ctx) -{ - op_ldst(swc1); -} - -void inline op_ldst_sdc1(DisasContext *ctx) -{ - op_ldst(sdc1); -} - /* Load and store */ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, int base, int16_t offset) @@ -1218,23 +1199,23 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, memory access. */ switch (opc) { case OPC_LWC1: - op_ldst_lwc1(ctx); - GEN_STORE_FTN_FREG(ft, WT0); + tcg_gen_qemu_ld32s(fpu32_T[0], cpu_T[0], ctx->mem_idx); + gen_store_fpr32(fpu32_T[0], ft); opn = "lwc1"; break; case OPC_SWC1: - GEN_LOAD_FREG_FTN(WT0, ft); - op_ldst_swc1(ctx); + gen_load_fpr32(fpu32_T[0], ft); + tcg_gen_qemu_st32(fpu32_T[0], cpu_T[0], ctx->mem_idx); opn = "swc1"; break; case OPC_LDC1: - op_ldst_ldc1(ctx); - GEN_STORE_FTN_FREG(ft, DT0); + tcg_gen_qemu_ld64(fpu64_T[0], cpu_T[0], ctx->mem_idx); + gen_store_fpr64(ctx, fpu64_T[0], ft); opn = "ldc1"; break; case OPC_SDC1: - GEN_LOAD_FREG_FTN(DT0, ft); - op_ldst_sdc1(ctx); + gen_load_fpr64(ctx, fpu64_T[0], ft); + tcg_gen_qemu_st64(fpu64_T[0], cpu_T[0], ctx->mem_idx); opn = "sdc1"; break; default: @@ -5073,11 +5054,11 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, case 2: /* XXX: For now we support only a single FPU context. */ if (h == 0) { - GEN_LOAD_FREG_FTN(WT0, rt); - gen_op_mfc1(); + gen_load_fpr32(fpu32_T[0], rt); + tcg_gen_ext_i32_tl(cpu_T[0], fpu32_T[0]); } else { - GEN_LOAD_FREG_FTN(WTH0, rt); - gen_op_mfhc1(); + gen_load_fpr32h(fpu32h_T[0], rt); + tcg_gen_ext_i32_tl(cpu_T[0], fpu32h_T[0]); } break; case 3: @@ -5237,11 +5218,11 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, case 2: /* XXX: For now we support only a single FPU context. */ if (h == 0) { - gen_op_mtc1(); - GEN_STORE_FTN_FREG(rd, WT0); + tcg_gen_trunc_tl_i32(fpu32_T[0], cpu_T[0]); + gen_store_fpr32(fpu32_T[0], rd); } else { - gen_op_mthc1(); - GEN_STORE_FTN_FREG(rd, WTH0); + tcg_gen_trunc_tl_i32(fpu32h_T[0], cpu_T[0]); + gen_store_fpr32h(fpu32h_T[0], rd); } break; case 3: @@ -5464,15 +5445,15 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) switch (opc) { case OPC_MFC1: - GEN_LOAD_FREG_FTN(WT0, fs); - gen_op_mfc1(); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_ext_i32_tl(cpu_T[0], fpu32_T[0]); gen_store_gpr(cpu_T[0], rt); opn = "mfc1"; break; case OPC_MTC1: gen_load_gpr(cpu_T[0], rt); - gen_op_mtc1(); - GEN_STORE_FTN_FREG(fs, WT0); + tcg_gen_trunc_tl_i32(fpu32_T[0], cpu_T[0]); + gen_store_fpr32(fpu32_T[0], fs); opn = "mtc1"; break; case OPC_CFC1: @@ -5486,27 +5467,27 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) opn = "ctc1"; break; case OPC_DMFC1: - GEN_LOAD_FREG_FTN(DT0, fs); - gen_op_dmfc1(); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_mov_tl(cpu_T[0], fpu64_T[0]); gen_store_gpr(cpu_T[0], rt); opn = "dmfc1"; break; case OPC_DMTC1: gen_load_gpr(cpu_T[0], rt); - gen_op_dmtc1(); - GEN_STORE_FTN_FREG(fs, DT0); + tcg_gen_mov_tl(fpu64_T[0], cpu_T[0]); + gen_store_fpr64(ctx, fpu64_T[0], fs); opn = "dmtc1"; break; case OPC_MFHC1: - GEN_LOAD_FREG_FTN(WTH0, fs); - gen_op_mfhc1(); + gen_load_fpr32h(fpu32h_T[0], fs); + tcg_gen_ext_i32_tl(cpu_T[0], fpu32h_T[0]); gen_store_gpr(cpu_T[0], rt); opn = "mfhc1"; break; case OPC_MTHC1: gen_load_gpr(cpu_T[0], rt); - gen_op_mthc1(); - GEN_STORE_FTN_FREG(fs, WTH0); + tcg_gen_trunc_tl_i32(fpu32h_T[0], cpu_T[0]); + gen_store_fpr32h(fpu32h_T[0], fs); opn = "mthc1"; break; default: @@ -5614,207 +5595,207 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, switch (ctx->opcode & FOP(0x3f, 0x1f)) { case FOP(0, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); gen_op_float_add_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "add.s"; optype = BINOP; break; case FOP(1, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); gen_op_float_sub_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "sub.s"; optype = BINOP; break; case FOP(2, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); gen_op_float_mul_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "mul.s"; optype = BINOP; break; case FOP(3, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); gen_op_float_div_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "div.s"; optype = BINOP; break; case FOP(4, 16): - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_sqrt_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "sqrt.s"; break; case FOP(5, 16): - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_abs_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "abs.s"; break; case FOP(6, 16): - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_mov_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "mov.s"; break; case FOP(7, 16): - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_chs_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "neg.s"; break; case FOP(8, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_roundl_s(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "round.l.s"; break; case FOP(9, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_truncl_s(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "trunc.l.s"; break; case FOP(10, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_ceill_s(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "ceil.l.s"; break; case FOP(11, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_floorl_s(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "floor.l.s"; break; case FOP(12, 16): - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_roundw_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "round.w.s"; break; case FOP(13, 16): - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_truncw_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "trunc.w.s"; break; case FOP(14, 16): - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_ceilw_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "ceil.w.s"; break; case FOP(15, 16): - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_floorw_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "floor.w.s"; break; case FOP(17, 16): gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "movcf.s"; break; case FOP(18, 16): gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); gen_op_float_movz_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "movz.s"; break; case FOP(19, 16): gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); gen_op_float_movn_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "movn.s"; break; case FOP(21, 16): check_cop1x(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_recip_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "recip.s"; break; case FOP(22, 16): check_cop1x(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_rsqrt_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "rsqrt.s"; break; case FOP(28, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); gen_op_float_recip2_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "recip2.s"; break; case FOP(29, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_recip1_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "recip1.s"; break; case FOP(30, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_rsqrt1_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "rsqrt1.s"; break; case FOP(31, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT2, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[2], ft); gen_op_float_rsqrt2_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "rsqrt2.s"; break; case FOP(33, 16): check_cp1_registers(ctx, fd); - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_cvtd_s(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.d.s"; break; case FOP(36, 16): - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_cvtw_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.w.s"; break; case FOP(37, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_cvtl_s(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.l.s"; break; case FOP(38, 16): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT1, fs); - GEN_LOAD_FREG_FTN(WT0, ft); + gen_load_fpr32(fpu32_T[1], fs); + gen_load_fpr32(fpu32_T[0], ft); gen_op_float_cvtps_s(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.ps.s"; break; case FOP(48, 16): @@ -5833,8 +5814,8 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(61, 16): case FOP(62, 16): case FOP(63, 16): - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); if (ctx->opcode & (1 << 6)) { check_cop1x(ctx); gen_cmpabs_s(func-48, cc); @@ -5846,190 +5827,190 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, break; case FOP(0, 17): check_cp1_registers(ctx, fs | ft | fd); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); gen_op_float_add_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "add.d"; optype = BINOP; break; case FOP(1, 17): check_cp1_registers(ctx, fs | ft | fd); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); gen_op_float_sub_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "sub.d"; optype = BINOP; break; case FOP(2, 17): check_cp1_registers(ctx, fs | ft | fd); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); gen_op_float_mul_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "mul.d"; optype = BINOP; break; case FOP(3, 17): check_cp1_registers(ctx, fs | ft | fd); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); gen_op_float_div_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "div.d"; optype = BINOP; break; case FOP(4, 17): check_cp1_registers(ctx, fs | fd); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_sqrt_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "sqrt.d"; break; case FOP(5, 17): check_cp1_registers(ctx, fs | fd); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_abs_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "abs.d"; break; case FOP(6, 17): check_cp1_registers(ctx, fs | fd); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_mov_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "mov.d"; break; case FOP(7, 17): check_cp1_registers(ctx, fs | fd); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_chs_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "neg.d"; break; case FOP(8, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_roundl_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "round.l.d"; break; case FOP(9, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_truncl_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "trunc.l.d"; break; case FOP(10, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_ceill_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "ceil.l.d"; break; case FOP(11, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_floorl_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "floor.l.d"; break; case FOP(12, 17): check_cp1_registers(ctx, fs); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_roundw_d(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "round.w.d"; break; case FOP(13, 17): check_cp1_registers(ctx, fs); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_truncw_d(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "trunc.w.d"; break; case FOP(14, 17): check_cp1_registers(ctx, fs); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_ceilw_d(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "ceil.w.d"; break; case FOP(15, 17): check_cp1_registers(ctx, fs); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_floorw_d(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "floor.w.d"; break; case FOP(17, 17): gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT2, fd); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[2], fd); gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "movcf.d"; break; case FOP(18, 17): gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT2, fd); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[2], fd); gen_op_float_movz_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "movz.d"; break; case FOP(19, 17): gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT2, fd); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[2], fd); gen_op_float_movn_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "movn.d"; break; case FOP(21, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_recip_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "recip.d"; break; case FOP(22, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_rsqrt_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "rsqrt.d"; break; case FOP(28, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT2, ft); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[2], ft); gen_op_float_recip2_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "recip2.d"; break; case FOP(29, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_recip1_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "recip1.d"; break; case FOP(30, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_rsqrt1_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "rsqrt1.d"; break; case FOP(31, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT2, ft); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[2], ft); gen_op_float_rsqrt2_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "rsqrt2.d"; break; case FOP(48, 17): @@ -6048,8 +6029,8 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(61, 17): case FOP(62, 17): case FOP(63, 17): - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); if (ctx->opcode & (1 << 6)) { check_cop1x(ctx); check_cp1_registers(ctx, fs | ft); @@ -6063,275 +6044,275 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, break; case FOP(32, 17): check_cp1_registers(ctx, fs); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_cvts_d(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.d"; break; case FOP(36, 17): check_cp1_registers(ctx, fs); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_cvtw_d(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.w.d"; break; case FOP(37, 17): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_cvtl_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.l.d"; break; case FOP(32, 20): - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_cvts_w(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.w"; break; case FOP(33, 20): check_cp1_registers(ctx, fd); - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_cvtd_w(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.d.w"; break; case FOP(32, 21): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_cvts_l(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.l"; break; case FOP(33, 21): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); gen_op_float_cvtd_l(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.d.l"; break; case FOP(38, 20): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); gen_op_float_cvtps_pw(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "cvt.ps.pw"; break; case FOP(0, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); gen_op_float_add_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "add.ps"; break; case FOP(1, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); gen_op_float_sub_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "sub.ps"; break; case FOP(2, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); gen_op_float_mul_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "mul.ps"; break; case FOP(5, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); gen_op_float_abs_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "abs.ps"; break; case FOP(6, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); gen_op_float_mov_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "mov.ps"; break; case FOP(7, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); gen_op_float_chs_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "neg.ps"; break; case FOP(17, 22): check_cp1_64bitmode(ctx); gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); - GEN_LOAD_FREG_FTN(WTH2, fd); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); + gen_load_fpr32h(fpu32h_T[2], fd); if (ft & 0x1) gen_op_float_movt_ps ((ft >> 2) & 0x7); else gen_op_float_movf_ps ((ft >> 2) & 0x7); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "movcf.ps"; break; case FOP(18, 22): check_cp1_64bitmode(ctx); gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); - GEN_LOAD_FREG_FTN(WTH2, fd); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); + gen_load_fpr32h(fpu32h_T[2], fd); gen_op_float_movz_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "movz.ps"; break; case FOP(19, 22): check_cp1_64bitmode(ctx); gen_load_gpr(cpu_T[0], ft); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); - GEN_LOAD_FREG_FTN(WTH2, fd); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); + gen_load_fpr32h(fpu32h_T[2], fd); gen_op_float_movn_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "movn.ps"; break; case FOP(24, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, ft); - GEN_LOAD_FREG_FTN(WTH0, ft); - GEN_LOAD_FREG_FTN(WT1, fs); - GEN_LOAD_FREG_FTN(WTH1, fs); + gen_load_fpr32(fpu32_T[0], ft); + gen_load_fpr32h(fpu32h_T[0], ft); + gen_load_fpr32(fpu32_T[1], fs); + gen_load_fpr32h(fpu32h_T[1], fs); gen_op_float_addr_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "addr.ps"; break; case FOP(26, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, ft); - GEN_LOAD_FREG_FTN(WTH0, ft); - GEN_LOAD_FREG_FTN(WT1, fs); - GEN_LOAD_FREG_FTN(WTH1, fs); + gen_load_fpr32(fpu32_T[0], ft); + gen_load_fpr32h(fpu32h_T[0], ft); + gen_load_fpr32(fpu32_T[1], fs); + gen_load_fpr32h(fpu32h_T[1], fs); gen_op_float_mulr_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "mulr.ps"; break; case FOP(28, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT2, fd); - GEN_LOAD_FREG_FTN(WTH2, fd); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[2], fd); + gen_load_fpr32h(fpu32h_T[2], fd); gen_op_float_recip2_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "recip2.ps"; break; case FOP(29, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); gen_op_float_recip1_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "recip1.ps"; break; case FOP(30, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); gen_op_float_rsqrt1_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "rsqrt1.ps"; break; case FOP(31, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT2, ft); - GEN_LOAD_FREG_FTN(WTH2, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[2], ft); + gen_load_fpr32h(fpu32h_T[2], ft); gen_op_float_rsqrt2_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "rsqrt2.ps"; break; case FOP(32, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WTH0, fs); + gen_load_fpr32h(fpu32h_T[0], fs); gen_op_float_cvts_pu(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.pu"; break; case FOP(36, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); gen_op_float_cvtpw_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "cvt.pw.ps"; break; case FOP(40, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); + gen_load_fpr32(fpu32_T[0], fs); gen_op_float_cvts_pl(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.pl"; break; case FOP(44, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); gen_op_float_pll_ps(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "pll.ps"; break; case FOP(45, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH1, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[1], ft); gen_op_float_plu_ps(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "plu.ps"; break; case FOP(46, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); gen_op_float_pul_ps(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "pul.ps"; break; case FOP(47, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WTH1, ft); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32h(fpu32h_T[1], ft); gen_op_float_puu_ps(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "puu.ps"; break; case FOP(48, 22): @@ -6351,10 +6332,10 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(62, 22): case FOP(63, 22): check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); if (ctx->opcode & (1 << 6)) { gen_cmpabs_ps(func-48, cc); opn = condnames_abs[func-48]; @@ -6402,41 +6383,41 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, switch (opc) { case OPC_LWXC1: check_cop1x(ctx); - op_ldst_lwc1(ctx); - GEN_STORE_FTN_FREG(fd, WT0); + tcg_gen_qemu_ld32s(fpu32_T[0], cpu_T[0], ctx->mem_idx); + gen_store_fpr32(fpu32_T[0], fd); opn = "lwxc1"; break; case OPC_LDXC1: check_cop1x(ctx); check_cp1_registers(ctx, fd); - op_ldst_ldc1(ctx); - GEN_STORE_FTN_FREG(fd, DT0); + tcg_gen_qemu_ld64(fpu64_T[0], cpu_T[0], ctx->mem_idx); + gen_store_fpr64(ctx, fpu64_T[0], fd); opn = "ldxc1"; break; case OPC_LUXC1: check_cp1_64bitmode(ctx); op_ldst(luxc1); - GEN_STORE_FTN_FREG(fd, DT0); + gen_store_fpr64(ctx, fpu64_T[0], fd); opn = "luxc1"; break; case OPC_SWXC1: check_cop1x(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - op_ldst_swc1(ctx); + gen_load_fpr32(fpu32_T[0], fs); + tcg_gen_qemu_st32(fpu32_T[0], cpu_T[0], ctx->mem_idx); opn = "swxc1"; store = 1; break; case OPC_SDXC1: check_cop1x(ctx); check_cp1_registers(ctx, fs); - GEN_LOAD_FREG_FTN(DT0, fs); - op_ldst_sdc1(ctx); + gen_load_fpr64(ctx, fpu64_T[0], fs); + tcg_gen_qemu_st64(fpu64_T[0], cpu_T[0], ctx->mem_idx); opn = "sdxc1"; store = 1; break; case OPC_SUXC1: check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(DT0, fs); + gen_load_fpr64(ctx, fpu64_T[0], fs); op_ldst(suxc1); opn = "suxc1"; store = 1; @@ -6459,138 +6440,138 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, case OPC_ALNV_PS: check_cp1_64bitmode(ctx); gen_load_gpr(cpu_T[0], fr); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); gen_op_float_alnv_ps(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "alnv.ps"; break; case OPC_MADD_S: check_cop1x(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); gen_op_float_muladd_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "madd.s"; break; case OPC_MADD_D: check_cop1x(ctx); check_cp1_registers(ctx, fd | fs | ft | fr); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); - GEN_LOAD_FREG_FTN(DT2, fr); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); + gen_load_fpr64(ctx, fpu64_T[2], fr); gen_op_float_muladd_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "madd.d"; break; case OPC_MADD_PS: check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); - GEN_LOAD_FREG_FTN(WTH2, fr); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); + gen_load_fpr32h(fpu32h_T[2], fr); gen_op_float_muladd_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "madd.ps"; break; case OPC_MSUB_S: check_cop1x(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); gen_op_float_mulsub_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "msub.s"; break; case OPC_MSUB_D: check_cop1x(ctx); check_cp1_registers(ctx, fd | fs | ft | fr); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); - GEN_LOAD_FREG_FTN(DT2, fr); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); + gen_load_fpr64(ctx, fpu64_T[2], fr); gen_op_float_mulsub_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "msub.d"; break; case OPC_MSUB_PS: check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); - GEN_LOAD_FREG_FTN(WTH2, fr); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); + gen_load_fpr32h(fpu32h_T[2], fr); gen_op_float_mulsub_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "msub.ps"; break; case OPC_NMADD_S: check_cop1x(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); gen_op_float_nmuladd_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "nmadd.s"; break; case OPC_NMADD_D: check_cop1x(ctx); check_cp1_registers(ctx, fd | fs | ft | fr); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); - GEN_LOAD_FREG_FTN(DT2, fr); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); + gen_load_fpr64(ctx, fpu64_T[2], fr); gen_op_float_nmuladd_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "nmadd.d"; break; case OPC_NMADD_PS: check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); - GEN_LOAD_FREG_FTN(WTH2, fr); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); + gen_load_fpr32h(fpu32h_T[2], fr); gen_op_float_nmuladd_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "nmadd.ps"; break; case OPC_NMSUB_S: check_cop1x(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); gen_op_float_nmulsub_s(); - GEN_STORE_FTN_FREG(fd, WT2); + gen_store_fpr32(fpu32_T[2], fd); opn = "nmsub.s"; break; case OPC_NMSUB_D: check_cop1x(ctx); check_cp1_registers(ctx, fd | fs | ft | fr); - GEN_LOAD_FREG_FTN(DT0, fs); - GEN_LOAD_FREG_FTN(DT1, ft); - GEN_LOAD_FREG_FTN(DT2, fr); + gen_load_fpr64(ctx, fpu64_T[0], fs); + gen_load_fpr64(ctx, fpu64_T[1], ft); + gen_load_fpr64(ctx, fpu64_T[2], fr); gen_op_float_nmulsub_d(); - GEN_STORE_FTN_FREG(fd, DT2); + gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "nmsub.d"; break; case OPC_NMSUB_PS: check_cp1_64bitmode(ctx); - GEN_LOAD_FREG_FTN(WT0, fs); - GEN_LOAD_FREG_FTN(WTH0, fs); - GEN_LOAD_FREG_FTN(WT1, ft); - GEN_LOAD_FREG_FTN(WTH1, ft); - GEN_LOAD_FREG_FTN(WT2, fr); - GEN_LOAD_FREG_FTN(WTH2, fr); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); + gen_load_fpr32(fpu32_T[2], fr); + gen_load_fpr32h(fpu32h_T[2], fr); gen_op_float_nmulsub_ps(); - GEN_STORE_FTN_FREG(fd, WT2); - GEN_STORE_FTN_FREG(fd, WTH2); + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "nmsub.ps"; break; default: @@ -7294,6 +7275,9 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, if (gen_opc_ptr >= gen_opc_end) break; + if (gen_opc_ptr >= gen_opc_end) + break; + #if defined (MIPS_SINGLE_STEP) break; #endif @@ -7487,6 +7471,10 @@ static void mips_tcg_init(void) TCG_AREG0, offsetof(CPUState, current_tc_hi), "current_tc_hi"); + current_fpu = tcg_global_mem_new(TCG_TYPE_PTR, + TCG_AREG0, + offsetof(CPUState, fpu), + "current_fpu"); #if TARGET_LONG_BITS > HOST_LONG_BITS cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0, offsetof(CPUState, t0), "T0"); @@ -7502,6 +7490,16 @@ static void mips_tcg_init(void) #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name); #include "helper.h" + fpu32_T[0] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft0.w[FP_ENDIAN_IDX]), "WT0"); + fpu32_T[1] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft1.w[FP_ENDIAN_IDX]), "WT1"); + fpu32_T[2] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft2.w[FP_ENDIAN_IDX]), "WT2"); + fpu64_T[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft0.d), "DT0"); + fpu64_T[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft1.d), "DT1"); + fpu64_T[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft2.d), "DT2"); + fpu32h_T[0] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft0.w[!FP_ENDIAN_IDX]), "WTH0"); + fpu32h_T[1] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft1.w[!FP_ENDIAN_IDX]), "WTH1"); + fpu32h_T[2] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft2.w[!FP_ENDIAN_IDX]), "WTH2"); + inited = 1; } -- cgit v1.2.3 From 0d1d0094d76a0423c55b345fc2f832a000b5b12f Mon Sep 17 00:00:00 2001 From: ths Date: Wed, 11 Jun 2008 13:24:47 +0000 Subject: Delete obsolete file. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4733 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/fop_template.c | 104 --------------------------------------------- 1 file changed, 104 deletions(-) delete mode 100644 target-mips/fop_template.c diff --git a/target-mips/fop_template.c b/target-mips/fop_template.c deleted file mode 100644 index 2a85a6b4a..000000000 --- a/target-mips/fop_template.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * MIPS emulation micro-operations templates for floating point reg - * load & store for qemu. - * - * Copyright (c) 2006 Marius Groeger - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if defined(FREG) - -#define OP_WLOAD_FREG(treg, tregname, FREG) \ - void glue(glue(op_load_fpr_,tregname), FREG) (void) \ - { \ - treg = env->fpu->fpr[FREG].w[FP_ENDIAN_IDX]; \ - FORCE_RET(); \ - } - -#define OP_WSTORE_FREG(treg, tregname, FREG) \ - void glue(glue(op_store_fpr_,tregname), FREG) (void) \ - { \ - env->fpu->fpr[FREG].w[FP_ENDIAN_IDX] = treg; \ - FORCE_RET(); \ - } - -/* WT0 = FREG.w: op_load_fpr_WT0_fprFREG */ -OP_WLOAD_FREG(WT0, WT0_fpr, FREG) -/* FREG.w = WT0: op_store_fpr_WT0_fprFREG */ -OP_WSTORE_FREG(WT0, WT0_fpr, FREG) - -OP_WLOAD_FREG(WT1, WT1_fpr, FREG) -OP_WSTORE_FREG(WT1, WT1_fpr, FREG) - -OP_WLOAD_FREG(WT2, WT2_fpr, FREG) -OP_WSTORE_FREG(WT2, WT2_fpr, FREG) - -#define OP_DLOAD_FREG(treg, tregname, FREG) \ - void glue(glue(op_load_fpr_,tregname), FREG) (void) \ - { \ - if (env->hflags & MIPS_HFLAG_F64) \ - treg = env->fpu->fpr[FREG].d; \ - else \ - treg = (uint64_t)(env->fpu->fpr[FREG | 1].w[FP_ENDIAN_IDX]) << 32 | \ - env->fpu->fpr[FREG & ~1].w[FP_ENDIAN_IDX]; \ - FORCE_RET(); \ - } - -#define OP_DSTORE_FREG(treg, tregname, FREG) \ - void glue(glue(op_store_fpr_,tregname), FREG) (void) \ - { \ - if (env->hflags & MIPS_HFLAG_F64) \ - env->fpu->fpr[FREG].d = treg; \ - else { \ - env->fpu->fpr[FREG | 1].w[FP_ENDIAN_IDX] = treg >> 32; \ - env->fpu->fpr[FREG & ~1].w[FP_ENDIAN_IDX] = treg; \ - } \ - FORCE_RET(); \ - } - -OP_DLOAD_FREG(DT0, DT0_fpr, FREG) -OP_DSTORE_FREG(DT0, DT0_fpr, FREG) - -OP_DLOAD_FREG(DT1, DT1_fpr, FREG) -OP_DSTORE_FREG(DT1, DT1_fpr, FREG) - -OP_DLOAD_FREG(DT2, DT2_fpr, FREG) -OP_DSTORE_FREG(DT2, DT2_fpr, FREG) - -#define OP_PSLOAD_FREG(treg, tregname, FREG) \ - void glue(glue(op_load_fpr_,tregname), FREG) (void) \ - { \ - treg = env->fpu->fpr[FREG].w[!FP_ENDIAN_IDX]; \ - FORCE_RET(); \ - } - -#define OP_PSSTORE_FREG(treg, tregname, FREG) \ - void glue(glue(op_store_fpr_,tregname), FREG) (void) \ - { \ - env->fpu->fpr[FREG].w[!FP_ENDIAN_IDX] = treg; \ - FORCE_RET(); \ - } - -OP_PSLOAD_FREG(WTH0, WTH0_fpr, FREG) -OP_PSSTORE_FREG(WTH0, WTH0_fpr, FREG) - -OP_PSLOAD_FREG(WTH1, WTH1_fpr, FREG) -OP_PSSTORE_FREG(WTH1, WTH1_fpr, FREG) - -OP_PSLOAD_FREG(WTH2, WTH2_fpr, FREG) -OP_PSSTORE_FREG(WTH2, WTH2_fpr, FREG) - -#endif -- cgit v1.2.3 From 5d0fc900d35e9f272c79d199e5854be8301dccf3 Mon Sep 17 00:00:00 2001 From: ths Date: Wed, 11 Jun 2008 15:27:54 +0000 Subject: Call most FP helpers without deroute through op.c git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4734 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/exec.h | 73 ----------------- target-mips/helper.h | 72 +++++++++++++++++ target-mips/op.c | 210 ------------------------------------------------ target-mips/translate.c | 163 ++++++++++++++++++------------------- 4 files changed, 154 insertions(+), 364 deletions(-) diff --git a/target-mips/exec.h b/target-mips/exec.h index 90f0a0269..42c2fc41f 100644 --- a/target-mips/exec.h +++ b/target-mips/exec.h @@ -103,79 +103,6 @@ void cpu_mips_update_irq (CPUState *env); void cpu_mips_clock_init (CPUState *env); void cpu_mips_tlb_flush (CPUState *env, int flush_global); -#define FOP_PROTO(op) \ -void do_float_ ## op ## _s(void); \ -void do_float_ ## op ## _d(void); -FOP_PROTO(roundl) -FOP_PROTO(roundw) -FOP_PROTO(truncl) -FOP_PROTO(truncw) -FOP_PROTO(ceill) -FOP_PROTO(ceilw) -FOP_PROTO(floorl) -FOP_PROTO(floorw) -FOP_PROTO(rsqrt) -FOP_PROTO(recip) -#undef FOP_PROTO - -#define FOP_PROTO(op) \ -void do_float_ ## op ## _s(void); \ -void do_float_ ## op ## _d(void); \ -void do_float_ ## op ## _ps(void); -FOP_PROTO(add) -FOP_PROTO(sub) -FOP_PROTO(mul) -FOP_PROTO(div) -FOP_PROTO(recip1) -FOP_PROTO(recip2) -FOP_PROTO(rsqrt1) -FOP_PROTO(rsqrt2) -#undef FOP_PROTO - -void do_float_cvtd_s(void); -void do_float_cvtd_w(void); -void do_float_cvtd_l(void); -void do_float_cvtl_d(void); -void do_float_cvtl_s(void); -void do_float_cvtps_pw(void); -void do_float_cvtpw_ps(void); -void do_float_cvts_d(void); -void do_float_cvts_w(void); -void do_float_cvts_l(void); -void do_float_cvts_pl(void); -void do_float_cvts_pu(void); -void do_float_cvtw_s(void); -void do_float_cvtw_d(void); - -void do_float_addr_ps(void); -void do_float_mulr_ps(void); - -#define FOP_PROTO(op) \ -void do_cmp_d_ ## op(long cc); \ -void do_cmpabs_d_ ## op(long cc); \ -void do_cmp_s_ ## op(long cc); \ -void do_cmpabs_s_ ## op(long cc); \ -void do_cmp_ps_ ## op(long cc); \ -void do_cmpabs_ps_ ## op(long cc); - -FOP_PROTO(f) -FOP_PROTO(un) -FOP_PROTO(eq) -FOP_PROTO(ueq) -FOP_PROTO(olt) -FOP_PROTO(ult) -FOP_PROTO(ole) -FOP_PROTO(ule) -FOP_PROTO(sf) -FOP_PROTO(ngle) -FOP_PROTO(seq) -FOP_PROTO(ngl) -FOP_PROTO(lt) -FOP_PROTO(nge) -FOP_PROTO(le) -FOP_PROTO(ngt) -#undef FOP_PROTO - static always_inline void env_to_regs(void) { } diff --git a/target-mips/helper.h b/target-mips/helper.h index ddc82f1df..9ac0eb9f6 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -130,3 +130,75 @@ DEF_HELPER(void, do_yield, (void)) /* CP1 functions */ DEF_HELPER(void, do_cfc1, (uint32_t reg)) DEF_HELPER(void, do_ctc1, (uint32_t reg)) + +DEF_HELPER(void, do_float_cvtd_s, (void)) +DEF_HELPER(void, do_float_cvtd_w, (void)) +DEF_HELPER(void, do_float_cvtd_l, (void)) +DEF_HELPER(void, do_float_cvtl_d, (void)) +DEF_HELPER(void, do_float_cvtl_s, (void)) +DEF_HELPER(void, do_float_cvtps_pw, (void)) +DEF_HELPER(void, do_float_cvtpw_ps, (void)) +DEF_HELPER(void, do_float_cvts_d, (void)) +DEF_HELPER(void, do_float_cvts_w, (void)) +DEF_HELPER(void, do_float_cvts_l, (void)) +DEF_HELPER(void, do_float_cvts_pl, (void)) +DEF_HELPER(void, do_float_cvts_pu, (void)) +DEF_HELPER(void, do_float_cvtw_s, (void)) +DEF_HELPER(void, do_float_cvtw_d, (void)) + +DEF_HELPER(void, do_float_addr_ps, (void)) +DEF_HELPER(void, do_float_mulr_ps, (void)) + +#define FOP_PROTO(op) \ +DEF_HELPER(void, do_float_ ## op ## _s, (void)) \ +DEF_HELPER(void, do_float_ ## op ## _d, (void)) +FOP_PROTO(roundl) +FOP_PROTO(roundw) +FOP_PROTO(truncl) +FOP_PROTO(truncw) +FOP_PROTO(ceill) +FOP_PROTO(ceilw) +FOP_PROTO(floorl) +FOP_PROTO(floorw) +FOP_PROTO(rsqrt) +FOP_PROTO(recip) +#undef FOP_PROTO + +#define FOP_PROTO(op) \ +DEF_HELPER(void, do_float_ ## op ## _s, (void)) \ +DEF_HELPER(void, do_float_ ## op ## _d, (void)) \ +DEF_HELPER(void, do_float_ ## op ## _ps, (void)) +FOP_PROTO(add) +FOP_PROTO(sub) +FOP_PROTO(mul) +FOP_PROTO(div) +FOP_PROTO(recip1) +FOP_PROTO(recip2) +FOP_PROTO(rsqrt1) +FOP_PROTO(rsqrt2) +#undef FOP_PROTO + +#define FOP_PROTO(op) \ +DEF_HELPER(void, do_cmp_d_ ## op, (long cc)) \ +DEF_HELPER(void, do_cmpabs_d_ ## op, (long cc)) \ +DEF_HELPER(void, do_cmp_s_ ## op, (long cc)) \ +DEF_HELPER(void, do_cmpabs_s_ ## op, (long cc)) \ +DEF_HELPER(void, do_cmp_ps_ ## op, (long cc)) \ +DEF_HELPER(void, do_cmpabs_ps_ ## op, (long cc)) +FOP_PROTO(f) +FOP_PROTO(un) +FOP_PROTO(eq) +FOP_PROTO(ueq) +FOP_PROTO(olt) +FOP_PROTO(ult) +FOP_PROTO(ole) +FOP_PROTO(ule) +FOP_PROTO(sf) +FOP_PROTO(ngle) +FOP_PROTO(seq) +FOP_PROTO(ngl) +FOP_PROTO(lt) +FOP_PROTO(nge) +FOP_PROTO(le) +FOP_PROTO(ngt) +#undef FOP_PROTO diff --git a/target-mips/op.c b/target-mips/op.c index 3d594aa98..c1ea67a66 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -377,36 +377,6 @@ void op_dmultu (void) #define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void) -FLOAT_OP(cvtd, s) -{ - CALL_FROM_TB0(do_float_cvtd_s); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(cvtd, w) -{ - CALL_FROM_TB0(do_float_cvtd_w); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(cvtd, l) -{ - CALL_FROM_TB0(do_float_cvtd_l); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(cvtl, d) -{ - CALL_FROM_TB0(do_float_cvtl_d); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(cvtl, s) -{ - CALL_FROM_TB0(do_float_cvtl_s); - DEBUG_FPU_STATE(); - FORCE_RET(); -} FLOAT_OP(cvtps, s) { WT2 = WT0; @@ -414,60 +384,6 @@ FLOAT_OP(cvtps, s) DEBUG_FPU_STATE(); FORCE_RET(); } -FLOAT_OP(cvtps, pw) -{ - CALL_FROM_TB0(do_float_cvtps_pw); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(cvtpw, ps) -{ - CALL_FROM_TB0(do_float_cvtpw_ps); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(cvts, d) -{ - CALL_FROM_TB0(do_float_cvts_d); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(cvts, w) -{ - CALL_FROM_TB0(do_float_cvts_w); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(cvts, l) -{ - CALL_FROM_TB0(do_float_cvts_l); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(cvts, pl) -{ - CALL_FROM_TB0(do_float_cvts_pl); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(cvts, pu) -{ - CALL_FROM_TB0(do_float_cvts_pu); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(cvtw, s) -{ - CALL_FROM_TB0(do_float_cvtw_s); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(cvtw, d) -{ - CALL_FROM_TB0(do_float_cvtw_d); - DEBUG_FPU_STATE(); - FORCE_RET(); -} FLOAT_OP(pll, ps) { @@ -494,35 +410,6 @@ FLOAT_OP(puu, ps) FORCE_RET(); } -#define FLOAT_ROUNDOP(op, ttype, stype) \ -FLOAT_OP(op ## ttype, stype) \ -{ \ - CALL_FROM_TB0(do_float_ ## op ## ttype ## _ ## stype); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} - -FLOAT_ROUNDOP(round, l, d) -FLOAT_ROUNDOP(round, l, s) -FLOAT_ROUNDOP(round, w, d) -FLOAT_ROUNDOP(round, w, s) - -FLOAT_ROUNDOP(trunc, l, d) -FLOAT_ROUNDOP(trunc, l, s) -FLOAT_ROUNDOP(trunc, w, d) -FLOAT_ROUNDOP(trunc, w, s) - -FLOAT_ROUNDOP(ceil, l, d) -FLOAT_ROUNDOP(ceil, l, s) -FLOAT_ROUNDOP(ceil, w, d) -FLOAT_ROUNDOP(ceil, w, s) - -FLOAT_ROUNDOP(floor, l, d) -FLOAT_ROUNDOP(floor, l, s) -FLOAT_ROUNDOP(floor, w, d) -FLOAT_ROUNDOP(floor, w, s) -#undef FLOAR_ROUNDOP - FLOAT_OP(movf, d) { if (!(env->fpu->fcr31 & PARAM1)) @@ -618,66 +505,6 @@ FLOAT_OP(movn, ps) FORCE_RET(); } -/* operations calling helpers, for s, d and ps */ -#define FLOAT_HOP(name) \ -FLOAT_OP(name, d) \ -{ \ - CALL_FROM_TB0(do_float_ ## name ## _d); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} \ -FLOAT_OP(name, s) \ -{ \ - CALL_FROM_TB0(do_float_ ## name ## _s); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} \ -FLOAT_OP(name, ps) \ -{ \ - CALL_FROM_TB0(do_float_ ## name ## _ps); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} -FLOAT_HOP(add) -FLOAT_HOP(sub) -FLOAT_HOP(mul) -FLOAT_HOP(div) -FLOAT_HOP(recip2) -FLOAT_HOP(rsqrt2) -FLOAT_HOP(rsqrt1) -FLOAT_HOP(recip1) -#undef FLOAT_HOP - -/* operations calling helpers, for s and d */ -#define FLOAT_HOP(name) \ -FLOAT_OP(name, d) \ -{ \ - CALL_FROM_TB0(do_float_ ## name ## _d); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} \ -FLOAT_OP(name, s) \ -{ \ - CALL_FROM_TB0(do_float_ ## name ## _s); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} -FLOAT_HOP(rsqrt) -FLOAT_HOP(recip) -#undef FLOAT_HOP - -/* operations calling helpers, for ps */ -#define FLOAT_HOP(name) \ -FLOAT_OP(name, ps) \ -{ \ - CALL_FROM_TB0(do_float_ ## name ## _ps); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} -FLOAT_HOP(addr) -FLOAT_HOP(mulr) -#undef FLOAT_HOP - /* ternary operations */ #define FLOAT_TERNOP(name1, name2) \ FLOAT_OP(name1 ## name2, d) \ @@ -836,43 +663,6 @@ FLOAT_OP(alnv, ps) extern void dump_fpu_s(CPUState *env); -#define CMP_OP(fmt, op) \ -void OPPROTO op_cmp ## _ ## fmt ## _ ## op(void) \ -{ \ - CALL_FROM_TB1(do_cmp ## _ ## fmt ## _ ## op, PARAM1); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} \ -void OPPROTO op_cmpabs ## _ ## fmt ## _ ## op(void) \ -{ \ - CALL_FROM_TB1(do_cmpabs ## _ ## fmt ## _ ## op, PARAM1); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} -#define CMP_OPS(op) \ -CMP_OP(d, op) \ -CMP_OP(s, op) \ -CMP_OP(ps, op) - -CMP_OPS(f) -CMP_OPS(un) -CMP_OPS(eq) -CMP_OPS(ueq) -CMP_OPS(olt) -CMP_OPS(ult) -CMP_OPS(ole) -CMP_OPS(ule) -CMP_OPS(sf) -CMP_OPS(ngle) -CMP_OPS(seq) -CMP_OPS(ngl) -CMP_OPS(lt) -CMP_OPS(nge) -CMP_OPS(le) -CMP_OPS(ngt) -#undef CMP_OPS -#undef CMP_OP - void op_bc1f (void) { T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1)); diff --git a/target-mips/translate.c b/target-mips/translate.c index 757e12bbd..b235eec8a 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -630,28 +630,28 @@ static inline void gen_store_fpr32h (TCGv t, int reg) tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX); } -#define FOP_CONDS(type, fmt) \ -static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = { \ - gen_op_cmp ## type ## _ ## fmt ## _f, \ - gen_op_cmp ## type ## _ ## fmt ## _un, \ - gen_op_cmp ## type ## _ ## fmt ## _eq, \ - gen_op_cmp ## type ## _ ## fmt ## _ueq, \ - gen_op_cmp ## type ## _ ## fmt ## _olt, \ - gen_op_cmp ## type ## _ ## fmt ## _ult, \ - gen_op_cmp ## type ## _ ## fmt ## _ole, \ - gen_op_cmp ## type ## _ ## fmt ## _ule, \ - gen_op_cmp ## type ## _ ## fmt ## _sf, \ - gen_op_cmp ## type ## _ ## fmt ## _ngle, \ - gen_op_cmp ## type ## _ ## fmt ## _seq, \ - gen_op_cmp ## type ## _ ## fmt ## _ngl, \ - gen_op_cmp ## type ## _ ## fmt ## _lt, \ - gen_op_cmp ## type ## _ ## fmt ## _nge, \ - gen_op_cmp ## type ## _ ## fmt ## _le, \ - gen_op_cmp ## type ## _ ## fmt ## _ngt, \ -}; \ -static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc) \ -{ \ - gen_op_cmp ## type ## _ ## fmt ## _table[n](cc); \ +#define FOP_CONDS(type, fmt) \ +static GenOpFunc1 * fcmp ## type ## _ ## fmt ## _table[16] = { \ + do_cmp ## type ## _ ## fmt ## _f, \ + do_cmp ## type ## _ ## fmt ## _un, \ + do_cmp ## type ## _ ## fmt ## _eq, \ + do_cmp ## type ## _ ## fmt ## _ueq, \ + do_cmp ## type ## _ ## fmt ## _olt, \ + do_cmp ## type ## _ ## fmt ## _ult, \ + do_cmp ## type ## _ ## fmt ## _ole, \ + do_cmp ## type ## _ ## fmt ## _ule, \ + do_cmp ## type ## _ ## fmt ## _sf, \ + do_cmp ## type ## _ ## fmt ## _ngle, \ + do_cmp ## type ## _ ## fmt ## _seq, \ + do_cmp ## type ## _ ## fmt ## _ngl, \ + do_cmp ## type ## _ ## fmt ## _lt, \ + do_cmp ## type ## _ ## fmt ## _nge, \ + do_cmp ## type ## _ ## fmt ## _le, \ + do_cmp ## type ## _ ## fmt ## _ngt, \ +}; \ +static inline void gen_cmp ## type ## _ ## fmt(int n, long cc) \ +{ \ + tcg_gen_helper_0_1i(fcmp ## type ## _ ## fmt ## _table[n], cc); \ } FOP_CONDS(, d) @@ -660,6 +660,7 @@ FOP_CONDS(, s) FOP_CONDS(abs, s) FOP_CONDS(, ps) FOP_CONDS(abs, ps) +#undef FOP_CONDS /* Tests */ #define OP_COND(name, cond) \ @@ -5597,7 +5598,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(0, 16): gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[1], ft); - gen_op_float_add_s(); + tcg_gen_helper_0_0(do_float_add_s); gen_store_fpr32(fpu32_T[2], fd); opn = "add.s"; optype = BINOP; @@ -5605,7 +5606,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(1, 16): gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[1], ft); - gen_op_float_sub_s(); + tcg_gen_helper_0_0(do_float_sub_s); gen_store_fpr32(fpu32_T[2], fd); opn = "sub.s"; optype = BINOP; @@ -5613,7 +5614,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(2, 16): gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[1], ft); - gen_op_float_mul_s(); + tcg_gen_helper_0_0(do_float_mul_s); gen_store_fpr32(fpu32_T[2], fd); opn = "mul.s"; optype = BINOP; @@ -5621,7 +5622,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(3, 16): gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[1], ft); - gen_op_float_div_s(); + tcg_gen_helper_0_0(do_float_div_s); gen_store_fpr32(fpu32_T[2], fd); opn = "div.s"; optype = BINOP; @@ -5653,52 +5654,52 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(8, 16): check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_roundl_s(); + tcg_gen_helper_0_0(do_float_roundl_s); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "round.l.s"; break; case FOP(9, 16): check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_truncl_s(); + tcg_gen_helper_0_0(do_float_truncl_s); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "trunc.l.s"; break; case FOP(10, 16): check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_ceill_s(); + tcg_gen_helper_0_0(do_float_ceill_s); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "ceil.l.s"; break; case FOP(11, 16): check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_floorl_s(); + tcg_gen_helper_0_0(do_float_floorl_s); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "floor.l.s"; break; case FOP(12, 16): gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_roundw_s(); + tcg_gen_helper_0_0(do_float_roundw_s); gen_store_fpr32(fpu32_T[2], fd); opn = "round.w.s"; break; case FOP(13, 16): gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_truncw_s(); + tcg_gen_helper_0_0(do_float_truncw_s); gen_store_fpr32(fpu32_T[2], fd); opn = "trunc.w.s"; break; case FOP(14, 16): gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_ceilw_s(); + tcg_gen_helper_0_0(do_float_ceilw_s); gen_store_fpr32(fpu32_T[2], fd); opn = "ceil.w.s"; break; case FOP(15, 16): gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_floorw_s(); + tcg_gen_helper_0_0(do_float_floorw_s); gen_store_fpr32(fpu32_T[2], fd); opn = "floor.w.s"; break; @@ -5729,14 +5730,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(21, 16): check_cop1x(ctx); gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_recip_s(); + tcg_gen_helper_0_0(do_float_recip_s); gen_store_fpr32(fpu32_T[2], fd); opn = "recip.s"; break; case FOP(22, 16): check_cop1x(ctx); gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_rsqrt_s(); + tcg_gen_helper_0_0(do_float_rsqrt_s); gen_store_fpr32(fpu32_T[2], fd); opn = "rsqrt.s"; break; @@ -5744,21 +5745,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[2], fd); - gen_op_float_recip2_s(); + tcg_gen_helper_0_0(do_float_recip2_s); gen_store_fpr32(fpu32_T[2], fd); opn = "recip2.s"; break; case FOP(29, 16): check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_recip1_s(); + tcg_gen_helper_0_0(do_float_recip1_s); gen_store_fpr32(fpu32_T[2], fd); opn = "recip1.s"; break; case FOP(30, 16): check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_rsqrt1_s(); + tcg_gen_helper_0_0(do_float_rsqrt1_s); gen_store_fpr32(fpu32_T[2], fd); opn = "rsqrt1.s"; break; @@ -5766,27 +5767,27 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[2], ft); - gen_op_float_rsqrt2_s(); + tcg_gen_helper_0_0(do_float_rsqrt2_s); gen_store_fpr32(fpu32_T[2], fd); opn = "rsqrt2.s"; break; case FOP(33, 16): check_cp1_registers(ctx, fd); gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_cvtd_s(); + tcg_gen_helper_0_0(do_float_cvtd_s); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.d.s"; break; case FOP(36, 16): gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_cvtw_s(); + tcg_gen_helper_0_0(do_float_cvtw_s); gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.w.s"; break; case FOP(37, 16): check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_cvtl_s(); + tcg_gen_helper_0_0(do_float_cvtl_s); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.l.s"; break; @@ -5829,7 +5830,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_registers(ctx, fs | ft | fd); gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[1], ft); - gen_op_float_add_d(); + tcg_gen_helper_0_0(do_float_add_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "add.d"; optype = BINOP; @@ -5838,7 +5839,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_registers(ctx, fs | ft | fd); gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[1], ft); - gen_op_float_sub_d(); + tcg_gen_helper_0_0(do_float_sub_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "sub.d"; optype = BINOP; @@ -5847,7 +5848,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_registers(ctx, fs | ft | fd); gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[1], ft); - gen_op_float_mul_d(); + tcg_gen_helper_0_0(do_float_mul_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "mul.d"; optype = BINOP; @@ -5856,7 +5857,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_registers(ctx, fs | ft | fd); gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[1], ft); - gen_op_float_div_d(); + tcg_gen_helper_0_0(do_float_div_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "div.d"; optype = BINOP; @@ -5892,56 +5893,56 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(8, 17): check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_roundl_d(); + tcg_gen_helper_0_0(do_float_roundl_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "round.l.d"; break; case FOP(9, 17): check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_truncl_d(); + tcg_gen_helper_0_0(do_float_truncl_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "trunc.l.d"; break; case FOP(10, 17): check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_ceill_d(); + tcg_gen_helper_0_0(do_float_ceill_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "ceil.l.d"; break; case FOP(11, 17): check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_floorl_d(); + tcg_gen_helper_0_0(do_float_floorl_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "floor.l.d"; break; case FOP(12, 17): check_cp1_registers(ctx, fs); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_roundw_d(); + tcg_gen_helper_0_0(do_float_roundw_d); gen_store_fpr32(fpu32_T[2], fd); opn = "round.w.d"; break; case FOP(13, 17): check_cp1_registers(ctx, fs); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_truncw_d(); + tcg_gen_helper_0_0(do_float_truncw_d); gen_store_fpr32(fpu32_T[2], fd); opn = "trunc.w.d"; break; case FOP(14, 17): check_cp1_registers(ctx, fs); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_ceilw_d(); + tcg_gen_helper_0_0(do_float_ceilw_d); gen_store_fpr32(fpu32_T[2], fd); opn = "ceil.w.d"; break; case FOP(15, 17): check_cp1_registers(ctx, fs); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_floorw_d(); + tcg_gen_helper_0_0(do_float_floorw_d); gen_store_fpr32(fpu32_T[2], fd); opn = "floor.w.d"; break; @@ -5972,14 +5973,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(21, 17): check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_recip_d(); + tcg_gen_helper_0_0(do_float_recip_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "recip.d"; break; case FOP(22, 17): check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_rsqrt_d(); + tcg_gen_helper_0_0(do_float_rsqrt_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "rsqrt.d"; break; @@ -5987,21 +5988,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[2], ft); - gen_op_float_recip2_d(); + tcg_gen_helper_0_0(do_float_recip2_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "recip2.d"; break; case FOP(29, 17): check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_recip1_d(); + tcg_gen_helper_0_0(do_float_recip1_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "recip1.d"; break; case FOP(30, 17): check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_rsqrt1_d(); + tcg_gen_helper_0_0(do_float_rsqrt1_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "rsqrt1.d"; break; @@ -6009,7 +6010,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[2], ft); - gen_op_float_rsqrt2_d(); + tcg_gen_helper_0_0(do_float_rsqrt2_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "rsqrt2.d"; break; @@ -6045,48 +6046,48 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(32, 17): check_cp1_registers(ctx, fs); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_cvts_d(); + tcg_gen_helper_0_0(do_float_cvts_d); gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.d"; break; case FOP(36, 17): check_cp1_registers(ctx, fs); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_cvtw_d(); + tcg_gen_helper_0_0(do_float_cvtw_d); gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.w.d"; break; case FOP(37, 17): check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_cvtl_d(); + tcg_gen_helper_0_0(do_float_cvtl_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.l.d"; break; case FOP(32, 20): gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_cvts_w(); + tcg_gen_helper_0_0(do_float_cvts_w); gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.w"; break; case FOP(33, 20): check_cp1_registers(ctx, fd); gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_cvtd_w(); + tcg_gen_helper_0_0(do_float_cvtd_w); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.d.w"; break; case FOP(32, 21): check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_cvts_l(); + tcg_gen_helper_0_0(do_float_cvts_l); gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.l"; break; case FOP(33, 21): check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_cvtd_l(); + tcg_gen_helper_0_0(do_float_cvtd_l); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.d.l"; break; @@ -6094,7 +6095,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32h(fpu32h_T[0], fs); - gen_op_float_cvtps_pw(); + tcg_gen_helper_0_0(do_float_cvtps_pw); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "cvt.ps.pw"; @@ -6105,7 +6106,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, gen_load_fpr32h(fpu32h_T[0], fs); gen_load_fpr32(fpu32_T[1], ft); gen_load_fpr32h(fpu32h_T[1], ft); - gen_op_float_add_ps(); + tcg_gen_helper_0_0(do_float_add_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "add.ps"; @@ -6116,7 +6117,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, gen_load_fpr32h(fpu32h_T[0], fs); gen_load_fpr32(fpu32_T[1], ft); gen_load_fpr32h(fpu32h_T[1], ft); - gen_op_float_sub_ps(); + tcg_gen_helper_0_0(do_float_sub_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "sub.ps"; @@ -6127,7 +6128,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, gen_load_fpr32h(fpu32h_T[0], fs); gen_load_fpr32(fpu32_T[1], ft); gen_load_fpr32h(fpu32h_T[1], ft); - gen_op_float_mul_ps(); + tcg_gen_helper_0_0(do_float_mul_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "mul.ps"; @@ -6204,7 +6205,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, gen_load_fpr32h(fpu32h_T[0], ft); gen_load_fpr32(fpu32_T[1], fs); gen_load_fpr32h(fpu32h_T[1], fs); - gen_op_float_addr_ps(); + tcg_gen_helper_0_0(do_float_addr_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "addr.ps"; @@ -6215,7 +6216,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, gen_load_fpr32h(fpu32h_T[0], ft); gen_load_fpr32(fpu32_T[1], fs); gen_load_fpr32h(fpu32h_T[1], fs); - gen_op_float_mulr_ps(); + tcg_gen_helper_0_0(do_float_mulr_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "mulr.ps"; @@ -6226,7 +6227,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, gen_load_fpr32h(fpu32h_T[0], fs); gen_load_fpr32(fpu32_T[2], fd); gen_load_fpr32h(fpu32h_T[2], fd); - gen_op_float_recip2_ps(); + tcg_gen_helper_0_0(do_float_recip2_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "recip2.ps"; @@ -6235,7 +6236,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32h(fpu32h_T[0], fs); - gen_op_float_recip1_ps(); + tcg_gen_helper_0_0(do_float_recip1_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "recip1.ps"; @@ -6244,7 +6245,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32h(fpu32h_T[0], fs); - gen_op_float_rsqrt1_ps(); + tcg_gen_helper_0_0(do_float_rsqrt1_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "rsqrt1.ps"; @@ -6255,7 +6256,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, gen_load_fpr32h(fpu32h_T[0], fs); gen_load_fpr32(fpu32_T[2], ft); gen_load_fpr32h(fpu32h_T[2], ft); - gen_op_float_rsqrt2_ps(); + tcg_gen_helper_0_0(do_float_rsqrt2_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "rsqrt2.ps"; @@ -6263,7 +6264,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(32, 22): check_cp1_64bitmode(ctx); gen_load_fpr32h(fpu32h_T[0], fs); - gen_op_float_cvts_pu(); + tcg_gen_helper_0_0(do_float_cvts_pu); gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.pu"; break; @@ -6271,7 +6272,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32h(fpu32h_T[0], fs); - gen_op_float_cvtpw_ps(); + tcg_gen_helper_0_0(do_float_cvtpw_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "cvt.pw.ps"; @@ -6279,7 +6280,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(40, 22): check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_cvts_pl(); + tcg_gen_helper_0_0(do_float_cvts_pl); gen_store_fpr32(fpu32_T[2], fd); opn = "cvt.s.pl"; break; -- cgit v1.2.3 From 2681b45add5f22694d645183a82824722b7191be Mon Sep 17 00:00:00 2001 From: ths Date: Wed, 11 Jun 2008 20:58:36 +0000 Subject: Update TODO list. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4735 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/TODO | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/target-mips/TODO b/target-mips/TODO index c58956cff..6722c20d7 100644 --- a/target-mips/TODO +++ b/target-mips/TODO @@ -30,6 +30,11 @@ General each ASID change. Using the MMU modes to implement ASIDs hinges on implementing the global bit efficiently. - save/restore of the CPU state is not implemented (see machine.c). +- Improve cpu state handling: + Step 1) Collect all the TC state in a single struct, so we need only + a single global pointer per TC. + Step 2) Use only a single TC context as working context, and copy the + contexts on TC switch. Likewise for FPU contexts. MIPS64 ------ -- cgit v1.2.3 From 08ba79632f106a14c981f888a3feaedf6c576fcf Mon Sep 17 00:00:00 2001 From: ths Date: Thu, 12 Jun 2008 03:15:13 +0000 Subject: TCGify a few more instructions. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4736 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/exec.h | 1 - target-mips/helper.h | 4 +++ target-mips/op.c | 76 ------------------------------------------------- target-mips/op_helper.c | 6 ++++ target-mips/translate.c | 40 ++++++++++++++++++-------- 5 files changed, 38 insertions(+), 89 deletions(-) diff --git a/target-mips/exec.h b/target-mips/exec.h index 42c2fc41f..1aa4851ce 100644 --- a/target-mips/exec.h +++ b/target-mips/exec.h @@ -78,7 +78,6 @@ void fpu_dump_state(CPUState *env, FILE *f, int (*fpu_fprintf)(FILE *f, const char *fmt, ...), int flags); void dump_sc (void); -void do_pmon (int function); int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, int mmu_idx, int is_softmmu); diff --git a/target-mips/helper.h b/target-mips/helper.h index 9ac0eb9f6..7918c9e99 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -202,3 +202,7 @@ FOP_PROTO(nge) FOP_PROTO(le) FOP_PROTO(ngt) #undef FOP_PROTO + +/* Special functions */ +DEF_HELPER(void, do_pmon, (int function)) +DEF_HELPER(void, do_wait, (void)) diff --git a/target-mips/op.c b/target-mips/op.c index c1ea67a66..43d819818 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -651,18 +651,6 @@ FLOAT_OP(alnv, ps) FORCE_RET(); } -#ifdef CONFIG_SOFTFLOAT -#define clear_invalid() do { \ - int flags = get_float_exception_flags(&env->fpu->fp_status); \ - flags &= ~float_flag_invalid; \ - set_float_exception_flags(flags, &env->fpu->fp_status); \ -} while(0) -#else -#define clear_invalid() do { } while(0) -#endif - -extern void dump_fpu_s(CPUState *env); - void op_bc1f (void) { T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1)); @@ -701,44 +689,7 @@ void op_bc1any4t (void) FORCE_RET(); } -void op_tlbwi (void) -{ - CALL_FROM_TB0(env->tlb->do_tlbwi); - FORCE_RET(); -} - -void op_tlbwr (void) -{ - CALL_FROM_TB0(env->tlb->do_tlbwr); - FORCE_RET(); -} - -void op_tlbp (void) -{ - CALL_FROM_TB0(env->tlb->do_tlbp); - FORCE_RET(); -} - -void op_tlbr (void) -{ - CALL_FROM_TB0(env->tlb->do_tlbr); - FORCE_RET(); -} - /* Specials */ -#if defined (CONFIG_USER_ONLY) -void op_tls_value (void) -{ - T0 = env->tls_value; -} -#endif - -void op_pmon (void) -{ - CALL_FROM_TB1(do_pmon, PARAM1); - FORCE_RET(); -} - void op_di (void) { T0 = env->CP0_Status; @@ -755,20 +706,6 @@ void op_ei (void) FORCE_RET(); } -void op_trap (void) -{ - if (T0) { - CALL_FROM_TB1(do_raise_exception, EXCP_TRAP); - } - FORCE_RET(); -} - -void op_debug (void) -{ - CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG); - FORCE_RET(); -} - void debug_pre_eret (void); void debug_post_eret (void); void op_eret (void) @@ -842,19 +779,6 @@ void op_rdhwr_ccres(void) FORCE_RET(); } -void op_save_state (void) -{ - env->hflags = PARAM1; - FORCE_RET(); -} - -void op_wait (void) -{ - env->halted = 1; - CALL_FROM_TB1(do_raise_exception, EXCP_HLT); - FORCE_RET(); -} - /* Bitfield operations. */ void op_ext(void) { diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index ae91acdb0..f573732e6 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -1401,6 +1401,12 @@ void do_pmon (int function) } } +void do_wait (void) +{ + env->halted = 1; + do_raise_exception(EXCP_HLT); +} + #if !defined(CONFIG_USER_ONLY) static void do_unaligned_access (target_ulong addr, int is_write, int is_user, void *retaddr); diff --git a/target-mips/translate.c b/target-mips/translate.c index b235eec8a..27d774f74 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -789,7 +789,11 @@ static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc) ctx->saved_pc = ctx->pc; } if (ctx->hflags != ctx->saved_hflags) { - gen_op_save_state(ctx->hflags); + TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); + + tcg_gen_movi_i32(r_tmp, ctx->hflags); + tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags)); + tcg_temp_free(r_tmp); ctx->saved_hflags = ctx->hflags; switch (ctx->hflags & MIPS_HFLAG_BMASK) { case MIPS_HFLAG_BR: @@ -2238,7 +2242,13 @@ static void gen_trap (DisasContext *ctx, uint32_t opc, } } save_cpu_state(ctx, 1); - gen_op_trap(); + { + int l1 = gen_new_label(); + + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); + tcg_gen_helper_0_1i(do_raise_exception, EXCP_TRAP); + gen_set_label(l1); + } ctx->bstate = BS_STOP; } @@ -5316,25 +5326,25 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int opn = "tlbwi"; if (!env->tlb->do_tlbwi) goto die; - gen_op_tlbwi(); + tcg_gen_helper_0_0(env->tlb->do_tlbwi); break; case OPC_TLBWR: opn = "tlbwr"; if (!env->tlb->do_tlbwr) goto die; - gen_op_tlbwr(); + tcg_gen_helper_0_0(env->tlb->do_tlbwr); break; case OPC_TLBP: opn = "tlbp"; if (!env->tlb->do_tlbp) goto die; - gen_op_tlbp(); + tcg_gen_helper_0_0(env->tlb->do_tlbp); break; case OPC_TLBR: opn = "tlbr"; if (!env->tlb->do_tlbr) goto die; - gen_op_tlbr(); + tcg_gen_helper_0_0(env->tlb->do_tlbr); break; case OPC_ERET: opn = "eret"; @@ -5362,7 +5372,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int ctx->pc += 4; save_cpu_state(ctx, 1); ctx->pc -= 4; - gen_op_wait(); + tcg_gen_helper_0_0(do_wait); ctx->bstate = BS_EXCP; break; default: @@ -6617,7 +6627,13 @@ static void decode_opc (CPUState *env, DisasContext *ctx) tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond)); tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1); tcg_temp_free(r_tmp); - gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK); + { + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); + + tcg_gen_movi_i32(r_tmp2, ctx->hflags & ~MIPS_HFLAG_BMASK); + tcg_gen_st_i32(r_tmp2, cpu_env, offsetof(CPUState, hflags)); + tcg_temp_free(r_tmp2); + } gen_goto_tb(ctx, 1, ctx->pc + 4); gen_set_label(l1); } @@ -6671,7 +6687,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) MIPS_INVAL("PMON / selsl"); generate_exception(ctx, EXCP_RI); #else - gen_op_pmon(sa); + tcg_gen_helper_0_1i(do_pmon, sa); #endif break; case OPC_SYSCALL: @@ -6827,7 +6843,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) break; case 29: #if defined (CONFIG_USER_ONLY) - gen_op_tls_value(); + tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, tls_value)); break; #endif default: /* Invalid */ @@ -7243,7 +7259,7 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, if (env->breakpoints[j] == ctx.pc) { save_cpu_state(&ctx, 1); ctx.bstate = BS_BRANCH; - gen_op_debug(); + tcg_gen_helper_0_1i(do_raise_exception, EXCP_DEBUG); /* Include the breakpoint location or the tb won't * be flushed when it must be. */ ctx.pc += 4; @@ -7285,7 +7301,7 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, } if (env->singlestep_enabled) { save_cpu_state(&ctx, ctx.bstate == BS_NONE); - gen_op_debug(); + tcg_gen_helper_0_1i(do_raise_exception, EXCP_DEBUG); } else { switch (ctx.bstate) { case BS_STOP: -- cgit v1.2.3 From 200ae688b21e84f13dcfb4349cf8aaa63dcbe692 Mon Sep 17 00:00:00 2001 From: ths Date: Thu, 12 Jun 2008 03:17:06 +0000 Subject: TCGify the simplest FP instructions. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4737 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/op.c | 27 --------------------------- target-mips/op_mem.c | 11 ----------- target-mips/translate.c | 28 ++++++++++++++-------------- 3 files changed, 14 insertions(+), 52 deletions(-) diff --git a/target-mips/op.c b/target-mips/op.c index 43d819818..7d7c4732d 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -377,14 +377,6 @@ void op_dmultu (void) #define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void) -FLOAT_OP(cvtps, s) -{ - WT2 = WT0; - WTH2 = WT1; - DEBUG_FPU_STATE(); - FORCE_RET(); -} - FLOAT_OP(pll, ps) { DT2 = ((uint64_t)WT0 << 32) | WT1; @@ -609,25 +601,6 @@ FLOAT_UNOP(abs) FLOAT_UNOP(chs) #undef FLOAT_UNOP -FLOAT_OP(mov, d) -{ - FDT2 = FDT0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(mov, s) -{ - FST2 = FST0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(mov, ps) -{ - FST2 = FST0; - FSTH2 = FSTH0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} FLOAT_OP(alnv, ps) { switch (T0 & 0x7) { diff --git a/target-mips/op_mem.c b/target-mips/op_mem.c index cb60d06be..31f58a814 100644 --- a/target-mips/op_mem.c +++ b/target-mips/op_mem.c @@ -267,14 +267,3 @@ void glue(op_sdr, MEMSUFFIX) (void) FORCE_RET(); } #endif /* TARGET_MIPS64 */ - -void glue(op_luxc1, MEMSUFFIX) (void) -{ - DT0 = glue(ldq, MEMSUFFIX)(T0 & ~0x7); - FORCE_RET(); -} -void glue(op_suxc1, MEMSUFFIX) (void) -{ - glue(stq, MEMSUFFIX)(T0 & ~0x7, DT0); - FORCE_RET(); -} diff --git a/target-mips/translate.c b/target-mips/translate.c index 27d774f74..aae802363 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -960,8 +960,6 @@ OP_LD_TABLE(wl); OP_LD_TABLE(wr); OP_ST_TABLE(wl); OP_ST_TABLE(wr); -OP_LD_TABLE(uxc1); -OP_ST_TABLE(uxc1); #define OP_LD(insn,fname) \ void inline op_ldst_##insn(DisasContext *ctx) \ @@ -5651,8 +5649,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, break; case FOP(6, 16): gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_mov_s(); - gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32(fpu32_T[0], fd); opn = "mov.s"; break; case FOP(7, 16): @@ -5803,9 +5800,12 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, break; case FOP(38, 16): check_cp1_64bitmode(ctx); - gen_load_fpr32(fpu32_T[1], fs); - gen_load_fpr32(fpu32_T[0], ft); - gen_op_float_cvtps_s(); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + tcg_gen_extu_i32_i64(fpu64_T[0], fpu32_T[0]); + tcg_gen_extu_i32_i64(fpu64_T[1], fpu32_T[1]); + tcg_gen_shli_i64(fpu64_T[1], fpu64_T[1], 32); + tcg_gen_or_i64(fpu64_T[2], fpu64_T[0], fpu64_T[1]); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "cvt.ps.s"; break; @@ -5889,8 +5889,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(6, 17): check_cp1_registers(ctx, fs | fd); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_mov_d(); - gen_store_fpr64(ctx, fpu64_T[2], fd); + gen_store_fpr64(ctx, fpu64_T[0], fd); opn = "mov.d"; break; case FOP(7, 17): @@ -6156,9 +6155,8 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32h(fpu32h_T[0], fs); - gen_op_float_mov_ps(); - gen_store_fpr32(fpu32_T[2], fd); - gen_store_fpr32h(fpu32h_T[2], fd); + gen_store_fpr32(fpu32_T[0], fd); + gen_store_fpr32h(fpu32h_T[0], fd); opn = "mov.ps"; break; case FOP(7, 22): @@ -6407,7 +6405,8 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, break; case OPC_LUXC1: check_cp1_64bitmode(ctx); - op_ldst(luxc1); + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~0x7); + tcg_gen_qemu_ld64(fpu64_T[0], cpu_T[0], ctx->mem_idx); gen_store_fpr64(ctx, fpu64_T[0], fd); opn = "luxc1"; break; @@ -6429,7 +6428,8 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, case OPC_SUXC1: check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); - op_ldst(suxc1); + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~0x7); + tcg_gen_qemu_st64(fpu64_T[0], cpu_T[0], ctx->mem_idx); opn = "suxc1"; store = 1; break; -- cgit v1.2.3 From c596defdb9507d9f98269e760616773e2acde371 Mon Sep 17 00:00:00 2001 From: malc Date: Thu, 12 Jun 2008 12:33:10 +0000 Subject: Reimplement brcond2 and refactor brcond git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4738 c046a42c-6fe2-441c-8c8c-71466251a162 --- tcg/ppc/tcg-target.c | 103 ++++++++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index f27f096ed..bc985519a 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -282,9 +282,12 @@ static int tcg_target_const_match(tcg_target_long val, #define RLWINM OPCD(21) -#define BCLR XO19(16) +#define BCLR XO19( 16) #define BCCTR XO19(528) #define CRAND XO19(257) +#define CRANDC XO19(129) +#define CRNAND XO19(225) +#define CROR XO19(449) #define EXTSB XO31(954) #define EXTSH XO31(922) @@ -870,11 +873,9 @@ static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val) ppc_addi (s, reg, reg, val); } -static void tcg_out_brcond(TCGContext *s, int cond, - TCGArg arg1, TCGArg arg2, int const_arg2, - int label_index) +static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2, + int const_arg2, int cr) { - TCGLabel *l = &s->labels[label_index]; int imm; uint32_t op; @@ -930,7 +931,7 @@ static void tcg_out_brcond(TCGContext *s, int cond, default: tcg_abort (); } - op |= BF (7); + op |= BF (cr); if (imm) tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff)); @@ -943,79 +944,79 @@ static void tcg_out_brcond(TCGContext *s, int cond, tcg_out32 (s, op | RA (arg1) | RB (arg2)); } +} + +static void tcg_out_bc (TCGContext *s, int bc, int label_index) +{ + TCGLabel *l = &s->labels[label_index]; + if (l->has_value) - tcg_out32 (s, tcg_to_bc[cond] | reloc_pc14_val (s->code_ptr, - l->u.value)); + tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value)); else { uint16_t val = *(uint16_t *) &s->code_ptr[2]; /* Thanks to Andrzej Zaborowski */ - tcg_out32 (s, tcg_to_bc[cond] | (val & 0xfffc)); + tcg_out32 (s, bc | (val & 0xfffc)); tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0); } } -/* brcond2 is taken verbatim from i386 tcg-target */ +static void tcg_out_brcond (TCGContext *s, int cond, + TCGArg arg1, TCGArg arg2, int const_arg2, + int label_index) +{ + tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7); + tcg_out_bc (s, tcg_to_bc[cond], label_index); +} + /* XXX: we implement it at the target level to avoid having to handle cross basic blocks temporaries */ -static void tcg_out_brcond2(TCGContext *s, - const TCGArg *args, const int *const_args) +static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args, + const int *const_args) { - int label_next; - label_next = gen_new_label(); - switch(args[4]) { + int cond = args[4], label_index = args[5], op; + struct { int bit1; int bit2; int cond2; } bits[] = { + [TCG_COND_LT ] = { CR_LT, CR_LT, TCG_COND_LT }, + [TCG_COND_LE ] = { CR_LT, CR_GT, TCG_COND_LT }, + [TCG_COND_GT ] = { CR_GT, CR_GT, TCG_COND_GT }, + [TCG_COND_GE ] = { CR_GT, CR_LT, TCG_COND_GT }, + [TCG_COND_LTU] = { CR_LT, CR_LT, TCG_COND_LTU }, + [TCG_COND_LEU] = { CR_LT, CR_GT, TCG_COND_LTU }, + [TCG_COND_GTU] = { CR_GT, CR_GT, TCG_COND_GTU }, + [TCG_COND_GEU] = { CR_GT, CR_LT, TCG_COND_GTU }, + }, *b = &bits[cond]; + + switch (cond) { case TCG_COND_EQ: - tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], label_next); - tcg_out_brcond(s, TCG_COND_EQ, args[1], args[3], const_args[3], args[5]); + tcg_out_cmp (s, TCG_COND_EQ, args[0], args[2], const_args[2], 6); + tcg_out_cmp (s, TCG_COND_EQ, args[1], args[3], const_args[3], 7); + tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ)); break; case TCG_COND_NE: - tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], args[5]); + tcg_out_cmp (s, TCG_COND_NE, args[0], args[2], const_args[2], 6); + tcg_out_cmp (s, TCG_COND_NE, args[1], args[3], const_args[3], 7); + tcg_out32 (s, CRNAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ)); break; case TCG_COND_LT: - tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_LT, args[0], args[2], const_args[2], args[5]); - break; case TCG_COND_LE: - tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_LE, args[0], args[2], const_args[2], args[5]); - break; case TCG_COND_GT: - tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_GT, args[0], args[2], const_args[2], args[5]); - break; case TCG_COND_GE: - tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_GE, args[0], args[2], const_args[2], args[5]); - break; case TCG_COND_LTU: - tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], args[5]); - break; case TCG_COND_LEU: - tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], args[5]); - break; case TCG_COND_GTU: - tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], args[5]); - break; case TCG_COND_GEU: - tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], args[5]); + op = (b->bit1 != b->bit2) ? CRANDC : CRAND; + tcg_out_cmp (s, b->cond2, args[1], args[3], const_args[3], 5); + tcg_out_cmp (s, TCG_COND_EQ, args[1], args[3], const_args[3], 6); + tcg_out_cmp (s, cond, args[0], args[2], const_args[2], 7); + tcg_out32 (s, op | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, b->bit2)); + tcg_out32 (s, CROR | BT (7, CR_EQ) | BA (5, b->bit1) | BB (7, CR_EQ)); break; default: tcg_abort(); } - tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr); + + tcg_out_bc (s, (BC | BI (7, CR_EQ) | BO_COND_TRUE), label_index); } static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args, -- cgit v1.2.3 From 2b0233abfb42d42c2ac1fb3d73953218f5e30b39 Mon Sep 17 00:00:00 2001 From: ths Date: Thu, 12 Jun 2008 12:42:35 +0000 Subject: Switch bitfield instructions and assorted special ops to TCG. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4739 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/helper.h | 19 ++++++ target-mips/op.c | 150 ------------------------------------------------ target-mips/op_helper.c | 123 +++++++++++++++++++++++++++++++++++++++ target-mips/translate.c | 92 ++++++++++++++--------------- 4 files changed, 189 insertions(+), 195 deletions(-) diff --git a/target-mips/helper.h b/target-mips/helper.h index 7918c9e99..246270a59 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -204,5 +204,24 @@ FOP_PROTO(ngt) #undef FOP_PROTO /* Special functions */ +DEF_HELPER(void, do_di, (void)) +DEF_HELPER(void, do_ei, (void)) +DEF_HELPER(void, do_eret, (void)) +DEF_HELPER(void, do_deret, (void)) +DEF_HELPER(void, do_rdhwr_cpunum, (void)) +DEF_HELPER(void, do_rdhwr_synci_step, (void)) +DEF_HELPER(void, do_rdhwr_cc, (void)) +DEF_HELPER(void, do_rdhwr_ccres, (void)) DEF_HELPER(void, do_pmon, (int function)) DEF_HELPER(void, do_wait, (void)) + +/* Bitfield operations. */ +DEF_HELPER(void, do_ext, (uint32_t pos, uint32_t size)) +DEF_HELPER(void, do_ins, (uint32_t pos, uint32_t size)) +DEF_HELPER(void, do_wsbh, (void)) +#ifdef TARGET_MIPS64 +DEF_HELPER(void, do_dext, (uint32_t pos, uint32_t size)) +DEF_HELPER(void, do_dins, (uint32_t pos, uint32_t size)) +DEF_HELPER(void, do_dsbh, (void)) +DEF_HELPER(void, do_dshd, (void)) +#endif diff --git a/target-mips/op.c b/target-mips/op.c index 7d7c4732d..254973f5a 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -661,153 +661,3 @@ void op_bc1any4t (void) DEBUG_FPU_STATE(); FORCE_RET(); } - -/* Specials */ -void op_di (void) -{ - T0 = env->CP0_Status; - env->CP0_Status = T0 & ~(1 << CP0St_IE); - CALL_FROM_TB1(cpu_mips_update_irq, env); - FORCE_RET(); -} - -void op_ei (void) -{ - T0 = env->CP0_Status; - env->CP0_Status = T0 | (1 << CP0St_IE); - CALL_FROM_TB1(cpu_mips_update_irq, env); - FORCE_RET(); -} - -void debug_pre_eret (void); -void debug_post_eret (void); -void op_eret (void) -{ - if (loglevel & CPU_LOG_EXEC) - CALL_FROM_TB0(debug_pre_eret); - if (env->CP0_Status & (1 << CP0St_ERL)) { - env->PC[env->current_tc] = env->CP0_ErrorEPC; - env->CP0_Status &= ~(1 << CP0St_ERL); - } else { - env->PC[env->current_tc] = env->CP0_EPC; - env->CP0_Status &= ~(1 << CP0St_EXL); - } - CALL_FROM_TB1(compute_hflags, env); - if (loglevel & CPU_LOG_EXEC) - CALL_FROM_TB0(debug_post_eret); - env->CP0_LLAddr = 1; - FORCE_RET(); -} - -void op_deret (void) -{ - if (loglevel & CPU_LOG_EXEC) - CALL_FROM_TB0(debug_pre_eret); - env->PC[env->current_tc] = env->CP0_DEPC; - env->hflags &= MIPS_HFLAG_DM; - CALL_FROM_TB1(compute_hflags, env); - if (loglevel & CPU_LOG_EXEC) - CALL_FROM_TB0(debug_post_eret); - env->CP0_LLAddr = 1; - FORCE_RET(); -} - -void op_rdhwr_cpunum(void) -{ - if ((env->hflags & MIPS_HFLAG_CP0) || - (env->CP0_HWREna & (1 << 0))) - T0 = env->CP0_EBase & 0x3ff; - else - CALL_FROM_TB1(do_raise_exception, EXCP_RI); - FORCE_RET(); -} - -void op_rdhwr_synci_step(void) -{ - if ((env->hflags & MIPS_HFLAG_CP0) || - (env->CP0_HWREna & (1 << 1))) - T0 = env->SYNCI_Step; - else - CALL_FROM_TB1(do_raise_exception, EXCP_RI); - FORCE_RET(); -} - -void op_rdhwr_cc(void) -{ - if ((env->hflags & MIPS_HFLAG_CP0) || - (env->CP0_HWREna & (1 << 2))) - T0 = env->CP0_Count; - else - CALL_FROM_TB1(do_raise_exception, EXCP_RI); - FORCE_RET(); -} - -void op_rdhwr_ccres(void) -{ - if ((env->hflags & MIPS_HFLAG_CP0) || - (env->CP0_HWREna & (1 << 3))) - T0 = env->CCRes; - else - CALL_FROM_TB1(do_raise_exception, EXCP_RI); - FORCE_RET(); -} - -/* Bitfield operations. */ -void op_ext(void) -{ - unsigned int pos = PARAM1; - unsigned int size = PARAM2; - - T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0)); - FORCE_RET(); -} - -void op_ins(void) -{ - unsigned int pos = PARAM1; - unsigned int size = PARAM2; - target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos; - - T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask)); - FORCE_RET(); -} - -void op_wsbh(void) -{ - T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF)); - FORCE_RET(); -} - -#if defined(TARGET_MIPS64) -void op_dext(void) -{ - unsigned int pos = PARAM1; - unsigned int size = PARAM2; - - T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL); - FORCE_RET(); -} - -void op_dins(void) -{ - unsigned int pos = PARAM1; - unsigned int size = PARAM2; - target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos; - - T0 = (T0 & ~mask) | ((T1 << pos) & mask); - FORCE_RET(); -} - -void op_dsbh(void) -{ - T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL); - FORCE_RET(); -} - -void op_dshd(void) -{ - T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL); - T0 = (T1 << 32) | (T1 >> 32); - FORCE_RET(); -} -#endif diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index f573732e6..93cd55e01 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -1348,6 +1348,21 @@ void dump_sc (void) } } +/* Specials */ +void do_di (void) +{ + T0 = env->CP0_Status; + env->CP0_Status = T0 & ~(1 << CP0St_IE); + cpu_mips_update_irq(env); +} + +void do_ei (void) +{ + T0 = env->CP0_Status; + env->CP0_Status = T0 | (1 << CP0St_IE); + cpu_mips_update_irq(env); +} + void debug_pre_eret (void) { fprintf(logfile, "ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx, @@ -1375,6 +1390,114 @@ void debug_post_eret (void) } } +void do_eret (void) +{ + if (loglevel & CPU_LOG_EXEC) + debug_pre_eret(); + if (env->CP0_Status & (1 << CP0St_ERL)) { + env->PC[env->current_tc] = env->CP0_ErrorEPC; + env->CP0_Status &= ~(1 << CP0St_ERL); + } else { + env->PC[env->current_tc] = env->CP0_EPC; + env->CP0_Status &= ~(1 << CP0St_EXL); + } + compute_hflags(env); + if (loglevel & CPU_LOG_EXEC) + debug_post_eret(); + env->CP0_LLAddr = 1; +} + +void do_deret (void) +{ + if (loglevel & CPU_LOG_EXEC) + debug_pre_eret(); + env->PC[env->current_tc] = env->CP0_DEPC; + env->hflags &= MIPS_HFLAG_DM; + compute_hflags(env); + if (loglevel & CPU_LOG_EXEC) + debug_post_eret(); + env->CP0_LLAddr = 1; +} + +void do_rdhwr_cpunum(void) +{ + if ((env->hflags & MIPS_HFLAG_CP0) || + (env->CP0_HWREna & (1 << 0))) + T0 = env->CP0_EBase & 0x3ff; + else + do_raise_exception(EXCP_RI); +} + +void do_rdhwr_synci_step(void) +{ + if ((env->hflags & MIPS_HFLAG_CP0) || + (env->CP0_HWREna & (1 << 1))) + T0 = env->SYNCI_Step; + else + do_raise_exception(EXCP_RI); +} + +void do_rdhwr_cc(void) +{ + if ((env->hflags & MIPS_HFLAG_CP0) || + (env->CP0_HWREna & (1 << 2))) + T0 = env->CP0_Count; + else + do_raise_exception(EXCP_RI); +} + +void do_rdhwr_ccres(void) +{ + if ((env->hflags & MIPS_HFLAG_CP0) || + (env->CP0_HWREna & (1 << 3))) + T0 = env->CCRes; + else + do_raise_exception(EXCP_RI); +} + +/* Bitfield operations. */ +void do_ext(uint32_t pos, uint32_t size) +{ + T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0)); +} + +void do_ins(uint32_t pos, uint32_t size) +{ + target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos; + + T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask)); +} + +void do_wsbh(void) +{ + T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF)); +} + +#if defined(TARGET_MIPS64) +void do_dext(uint32_t pos, uint32_t size) +{ + T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL); +} + +void do_dins(uint32_t pos, uint32_t size) +{ + target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos; + + T0 = (T0 & ~mask) | ((T1 << pos) & mask); +} + +void do_dsbh(void) +{ + T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL); +} + +void do_dshd(void) +{ + T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL); + T0 = (T1 << 32) | (T1 >> 32); +} +#endif + void do_pmon (int function) { function /= 2; diff --git a/target-mips/translate.c b/target-mips/translate.c index aae802363..82e629e82 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -2512,49 +2512,49 @@ static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt, case OPC_EXT: if (lsb + msb > 31) goto fail; - gen_op_ext(lsb, msb + 1); + tcg_gen_helper_0_2ii(do_ext, lsb, msb + 1); break; #if defined(TARGET_MIPS64) case OPC_DEXTM: if (lsb + msb > 63) goto fail; - gen_op_dext(lsb, msb + 1 + 32); + tcg_gen_helper_0_2ii(do_dext, lsb, msb + 1 + 32); break; case OPC_DEXTU: if (lsb + msb > 63) goto fail; - gen_op_dext(lsb + 32, msb + 1); + tcg_gen_helper_0_2ii(do_dext, lsb + 32, msb + 1); break; case OPC_DEXT: if (lsb + msb > 63) goto fail; - gen_op_dext(lsb, msb + 1); + tcg_gen_helper_0_2ii(do_dext, lsb, msb + 1); break; #endif case OPC_INS: if (lsb > msb) goto fail; gen_load_gpr(cpu_T[0], rt); - gen_op_ins(lsb, msb - lsb + 1); + tcg_gen_helper_0_2ii(do_ins, lsb, msb - lsb + 1); break; #if defined(TARGET_MIPS64) case OPC_DINSM: if (lsb > msb) goto fail; gen_load_gpr(cpu_T[0], rt); - gen_op_dins(lsb, msb - lsb + 1 + 32); + tcg_gen_helper_0_2ii(do_dins, lsb, msb - lsb + 1 + 32); break; case OPC_DINSU: if (lsb > msb) goto fail; gen_load_gpr(cpu_T[0], rt); - gen_op_dins(lsb + 32, msb - lsb + 1); + tcg_gen_helper_0_2ii(do_dins, lsb + 32, msb - lsb + 1); break; case OPC_DINS: if (lsb > msb) goto fail; gen_load_gpr(cpu_T[0], rt); - gen_op_dins(lsb, msb - lsb + 1); + tcg_gen_helper_0_2ii(do_dins, lsb, msb - lsb + 1); break; #endif default: @@ -5348,7 +5348,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int opn = "eret"; check_insn(env, ctx, ISA_MIPS2); save_cpu_state(ctx, 1); - gen_op_eret(); + tcg_gen_helper_0_0(do_eret); ctx->bstate = BS_EXCP; break; case OPC_DERET: @@ -5359,7 +5359,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int generate_exception(ctx, EXCP_RI); } else { save_cpu_state(ctx, 1); - gen_op_deret(); + tcg_gen_helper_0_0(do_deret); ctx->bstate = BS_EXCP; } break; @@ -6792,33 +6792,33 @@ static void decode_opc (CPUState *env, DisasContext *ctx) } break; case OPC_SPECIAL3: - op1 = MASK_SPECIAL3(ctx->opcode); - switch (op1) { - case OPC_EXT: - case OPC_INS: - check_insn(env, ctx, ISA_MIPS32R2); - gen_bitops(ctx, op1, rt, rs, sa, rd); - break; - case OPC_BSHFL: - check_insn(env, ctx, ISA_MIPS32R2); - op2 = MASK_BSHFL(ctx->opcode); - switch (op2) { - case OPC_WSBH: - gen_load_gpr(cpu_T[1], rt); - gen_op_wsbh(); - break; - case OPC_SEB: - gen_load_gpr(cpu_T[1], rt); - tcg_gen_ext8s_tl(cpu_T[0], cpu_T[1]); - break; - case OPC_SEH: - gen_load_gpr(cpu_T[1], rt); - tcg_gen_ext16s_tl(cpu_T[0], cpu_T[1]); - break; - default: /* Invalid */ - MIPS_INVAL("bshfl"); - generate_exception(ctx, EXCP_RI); - break; + op1 = MASK_SPECIAL3(ctx->opcode); + switch (op1) { + case OPC_EXT: + case OPC_INS: + check_insn(env, ctx, ISA_MIPS32R2); + gen_bitops(ctx, op1, rt, rs, sa, rd); + break; + case OPC_BSHFL: + check_insn(env, ctx, ISA_MIPS32R2); + op2 = MASK_BSHFL(ctx->opcode); + switch (op2) { + case OPC_WSBH: + gen_load_gpr(cpu_T[1], rt); + tcg_gen_helper_0_0(do_wsbh); + break; + case OPC_SEB: + gen_load_gpr(cpu_T[1], rt); + tcg_gen_ext8s_tl(cpu_T[0], cpu_T[1]); + break; + case OPC_SEH: + gen_load_gpr(cpu_T[1], rt); + tcg_gen_ext16s_tl(cpu_T[0], cpu_T[1]); + break; + default: /* Invalid */ + MIPS_INVAL("bshfl"); + generate_exception(ctx, EXCP_RI); + break; } gen_store_gpr(cpu_T[0], rd); break; @@ -6827,24 +6827,26 @@ static void decode_opc (CPUState *env, DisasContext *ctx) switch (rd) { case 0: save_cpu_state(ctx, 1); - gen_op_rdhwr_cpunum(); + tcg_gen_helper_0_0(do_rdhwr_cpunum); break; case 1: save_cpu_state(ctx, 1); - gen_op_rdhwr_synci_step(); + tcg_gen_helper_0_0(do_rdhwr_synci_step); break; case 2: save_cpu_state(ctx, 1); - gen_op_rdhwr_cc(); + tcg_gen_helper_0_0(do_rdhwr_cc); break; case 3: save_cpu_state(ctx, 1); - gen_op_rdhwr_ccres(); + tcg_gen_helper_0_0(do_rdhwr_ccres); break; case 29: #if defined (CONFIG_USER_ONLY) tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, tls_value)); break; +#else + /* XXX: Some CPUs implement this in hardware. Not supported yet. */ #endif default: /* Invalid */ MIPS_INVAL("rdhwr"); @@ -6879,11 +6881,11 @@ static void decode_opc (CPUState *env, DisasContext *ctx) switch (op2) { case OPC_DSBH: gen_load_gpr(cpu_T[1], rt); - gen_op_dsbh(); + tcg_gen_helper_0_0(do_dsbh); break; case OPC_DSHD: gen_load_gpr(cpu_T[1], rt); - gen_op_dshd(); + tcg_gen_helper_0_0(do_dshd); break; default: /* Invalid */ MIPS_INVAL("dbshfl"); @@ -6963,14 +6965,14 @@ static void decode_opc (CPUState *env, DisasContext *ctx) case OPC_DI: check_insn(env, ctx, ISA_MIPS32R2); save_cpu_state(ctx, 1); - gen_op_di(); + tcg_gen_helper_0_0(do_di); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; break; case OPC_EI: check_insn(env, ctx, ISA_MIPS32R2); save_cpu_state(ctx, 1); - gen_op_ei(); + tcg_gen_helper_0_0(do_ei); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; break; -- cgit v1.2.3 From 214c465f86138aadd7f59f050a188d4362bd3ab8 Mon Sep 17 00:00:00 2001 From: ths Date: Thu, 12 Jun 2008 12:43:29 +0000 Subject: Switch the standard multiplication instructions to TCG. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4740 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/exec.h | 2 - target-mips/helper.h | 2 + target-mips/op.c | 74 ---------------------- target-mips/op_helper.c | 22 ++++--- target-mips/translate.c | 160 +++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 166 insertions(+), 94 deletions(-) diff --git a/target-mips/exec.h b/target-mips/exec.h index 1aa4851ce..782d7f8cb 100644 --- a/target-mips/exec.h +++ b/target-mips/exec.h @@ -49,8 +49,6 @@ register target_ulong T1 asm(AREG2); #endif /* !defined(CONFIG_USER_ONLY) */ #if TARGET_LONG_BITS > HOST_LONG_BITS -void do_mult (void); -void do_multu (void); void do_madd (void); void do_maddu (void); void do_msub (void); diff --git a/target-mips/helper.h b/target-mips/helper.h index 246270a59..1092f8733 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -11,6 +11,8 @@ DEF_HELPER(void, do_clz, (void)) #ifdef TARGET_MIPS64 DEF_HELPER(void, do_dclo, (void)) DEF_HELPER(void, do_dclz, (void)) +DEF_HELPER(void, do_dmult, (void)) +DEF_HELPER(void, do_dmultu, (void)) #endif /* CP0 helpers */ diff --git a/target-mips/op.c b/target-mips/op.c index 254973f5a..2c99ad754 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -68,18 +68,6 @@ /* 64 bits arithmetic */ #if TARGET_LONG_BITS > HOST_LONG_BITS -void op_mult (void) -{ - CALL_FROM_TB0(do_mult); - FORCE_RET(); -} - -void op_multu (void) -{ - CALL_FROM_TB0(do_multu); - FORCE_RET(); -} - void op_madd (void) { CALL_FROM_TB0(do_madd); @@ -214,54 +202,6 @@ static always_inline void set_HI_LOT0 (uint64_t HILO) env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); } -void op_mult (void) -{ - set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); - FORCE_RET(); -} - -void op_multu (void) -{ - set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); - FORCE_RET(); -} - -void op_madd (void) -{ - int64_t tmp; - - tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); - set_HILO((int64_t)get_HILO() + tmp); - FORCE_RET(); -} - -void op_maddu (void) -{ - uint64_t tmp; - - tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); - set_HILO(get_HILO() + tmp); - FORCE_RET(); -} - -void op_msub (void) -{ - int64_t tmp; - - tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); - set_HILO((int64_t)get_HILO() - tmp); - FORCE_RET(); -} - -void op_msubu (void) -{ - uint64_t tmp; - - tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); - set_HILO(get_HILO() - tmp); - FORCE_RET(); -} - /* Multiplication variants of the vr54xx. */ void op_muls (void) { @@ -349,20 +289,6 @@ void op_mulshiu (void) #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ -#if defined(TARGET_MIPS64) -void op_dmult (void) -{ - CALL_FROM_TB4(muls64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1); - FORCE_RET(); -} - -void op_dmultu (void) -{ - CALL_FROM_TB4(mulu64, &(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1); - FORCE_RET(); -} -#endif - /* CP1 functions */ #if 0 # define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env) diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 93cd55e01..c5a4c9369 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -192,16 +192,6 @@ static always_inline void set_HI_LOT0 (uint64_t HILO) env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); } -void do_mult (void) -{ - set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); -} - -void do_multu (void) -{ - set_HILO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); -} - void do_madd (void) { int64_t tmp; @@ -306,6 +296,18 @@ void do_mulshiu (void) } #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ +#ifdef TARGET_MIPS64 +void do_dmult (void) +{ + muls64(&(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1); +} + +void do_dmultu (void) +{ + mulu64(&(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1); +} +#endif + #ifdef CONFIG_USER_ONLY void do_mfc0_random (void) { diff --git a/target-mips/translate.c b/target-mips/translate.c index 82e629e82..b7e3967ce 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -1941,11 +1941,47 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, opn = "divu"; break; case OPC_MULT: - gen_op_mult(); + { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); + tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]); + tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]); + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); + tcg_temp_free(r_tmp2); + tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); + tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); + gen_store_LO(cpu_T[0], 0); + gen_store_HI(cpu_T[1], 0); + } opn = "mult"; break; case OPC_MULTU: - gen_op_multu(); + { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); + tcg_gen_extu_tl_i64(r_tmp1, cpu_T[0]); + tcg_gen_extu_tl_i64(r_tmp2, cpu_T[1]); + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); + tcg_temp_free(r_tmp2); + tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); + tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); + gen_store_LO(cpu_T[0], 0); + gen_store_HI(cpu_T[1], 0); + } opn = "multu"; break; #if defined(TARGET_MIPS64) @@ -2003,28 +2039,136 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, opn = "ddivu"; break; case OPC_DMULT: - gen_op_dmult(); + tcg_gen_helper_0_0(do_dmult); opn = "dmult"; break; case OPC_DMULTU: - gen_op_dmultu(); + tcg_gen_helper_0_0(do_dmultu); opn = "dmultu"; break; #endif case OPC_MADD: - gen_op_madd(); + { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); + tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]); + tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]); + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); + gen_load_LO(cpu_T[0], 0); + gen_load_HI(cpu_T[1], 0); + tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]); + tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]); + tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); + tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); + tcg_temp_free(r_tmp3); + tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2); + tcg_temp_free(r_tmp2); + tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); + tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); + gen_store_LO(cpu_T[0], 0); + gen_store_HI(cpu_T[1], 0); + } opn = "madd"; break; case OPC_MADDU: - gen_op_maddu(); + { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); + tcg_gen_extu_tl_i64(r_tmp1, cpu_T[0]); + tcg_gen_extu_tl_i64(r_tmp2, cpu_T[1]); + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); + gen_load_LO(cpu_T[0], 0); + gen_load_HI(cpu_T[1], 0); + tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]); + tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]); + tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); + tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); + tcg_temp_free(r_tmp3); + tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2); + tcg_temp_free(r_tmp2); + tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); + tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); + gen_store_LO(cpu_T[0], 0); + gen_store_HI(cpu_T[1], 0); + } opn = "maddu"; break; case OPC_MSUB: - gen_op_msub(); + { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); + tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]); + tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]); + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); + gen_load_LO(cpu_T[0], 0); + gen_load_HI(cpu_T[1], 0); + tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]); + tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]); + tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); + tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); + tcg_temp_free(r_tmp3); + tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2); + tcg_temp_free(r_tmp2); + tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); + tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); + gen_store_LO(cpu_T[0], 0); + gen_store_HI(cpu_T[1], 0); + } opn = "msub"; break; case OPC_MSUBU: - gen_op_msubu(); + { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); + TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); + tcg_gen_extu_tl_i64(r_tmp1, cpu_T[0]); + tcg_gen_extu_tl_i64(r_tmp2, cpu_T[1]); + tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); + gen_load_LO(cpu_T[0], 0); + gen_load_HI(cpu_T[1], 0); + tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]); + tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]); + tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); + tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); + tcg_temp_free(r_tmp3); + tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2); + tcg_temp_free(r_tmp2); + tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); + tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); + tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); + gen_store_LO(cpu_T[0], 0); + gen_store_HI(cpu_T[1], 0); + } opn = "msubu"; break; default: -- cgit v1.2.3 From cc53d26d4dd464bcd22c23892b3f6c6f0b3780a9 Mon Sep 17 00:00:00 2001 From: malc Date: Fri, 13 Jun 2008 10:48:22 +0000 Subject: ISA version of CS4231A Hopefully someday will be merged with cs4231.c (SPARC version) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4741 c046a42c-6fe2-441c-8c8c-71466251a162 --- Makefile.target | 3 + configure | 9 + hw/audiodev.h | 3 + hw/cs4231a.c | 661 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ qemu-doc.texi | 9 +- vl.c | 10 + 6 files changed, 693 insertions(+), 2 deletions(-) create mode 100644 hw/cs4231a.c diff --git a/Makefile.target b/Makefile.target index 50f8c1b5c..fc8132adc 100644 --- a/Makefile.target +++ b/Makefile.target @@ -497,6 +497,9 @@ endif ifdef CONFIG_GUS SOUND_HW += gus.o gusemu_hal.o gusemu_mixer.o endif +ifdef CONFIG_CS4231A +SOUND_HW += cs4231a.o +endif ifdef CONFIG_VNC_TLS CPPFLAGS += $(CONFIG_VNC_TLS_CFLAGS) diff --git a/configure b/configure index f204d048c..64b7b4283 100755 --- a/configure +++ b/configure @@ -90,6 +90,7 @@ slirp="yes" adlib="no" ac97="no" gus="no" +cs4231a="no" oss="no" dsound="no" coreaudio="no" @@ -288,6 +289,8 @@ for opt do ;; --enable-gus) gus="yes" ;; + --enable-cs4231a) cs4231a="yes" + ;; --disable-kqemu) kqemu="no" ;; --disable-brlapi) brlapi="no" @@ -419,6 +422,7 @@ echo " --enable-mingw32 enable Win32 cross compilation with mingw32" echo " --enable-adlib enable Adlib emulation" echo " --enable-ac97 enable AC97 emulation" echo " --enable-gus enable Gravis Ultrasound emulation" +echo " --enable-cs4231a enable CS4231A emulation" echo " --enable-coreaudio enable Coreaudio audio driver" echo " --enable-alsa enable ALSA audio driver" echo " --enable-esd enable EsoundD audio driver" @@ -830,6 +834,7 @@ echo "mingw32 support $mingw32" echo "Adlib support $adlib" echo "AC97 support $ac97" echo "GUS support $gus" +echo "CS4231A support $cs4231a" echo "CoreAudio support $coreaudio" echo "ALSA support $alsa" echo "EsounD support $esd" @@ -1038,6 +1043,10 @@ if test "$gus" = "yes" ; then echo "CONFIG_GUS=yes" >> $config_mak echo "#define CONFIG_GUS 1" >> $config_h fi +if test "$cs4231a" = "yes" ; then + echo "CONFIG_CS4231A=yes" >> $config_mak + echo "#define CONFIG_CS4231A 1" >> $config_h +fi if test "$oss" = "yes" ; then echo "CONFIG_OSS=yes" >> $config_mak echo "#define CONFIG_OSS 1" >> $config_h diff --git a/hw/audiodev.h b/hw/audiodev.h index 3c02f19ff..5f4a21123 100644 --- a/hw/audiodev.h +++ b/hw/audiodev.h @@ -12,3 +12,6 @@ int GUS_init (AudioState *s, qemu_irq *pic); /* ac97.c */ int ac97_init (PCIBus *buf, AudioState *s); + +/* cs4231a.c */ +int cs4231a_init (AudioState *s, qemu_irq *pic); diff --git a/hw/cs4231a.c b/hw/cs4231a.c new file mode 100644 index 000000000..898c37e9e --- /dev/null +++ b/hw/cs4231a.c @@ -0,0 +1,661 @@ +/* + * QEMU Crystal CS4231 audio chip emulation + * + * Copyright (c) 2006 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "hw.h" +#include "audiodev.h" +#include "audio/audio.h" +#include "isa.h" +#include "qemu-timer.h" + +/* + Missing features: + ADC + Loopback + Timer + ADPCM + More... +*/ + +/* #define DEBUG */ +#define DEBUG_XLAW + +static struct { + int irq; + int dma; + int port; + int aci_counter; +} conf = {9, 3, 0x534, 1}; + +#ifdef DEBUG +#define dolog(...) AUD_log ("cs4231a", __VA_ARGS__) +#else +#define dolog(...) +#endif + +#define lwarn(...) AUD_log ("cs4231a", "warning: " __VA_ARGS__) +#define lerr(...) AUD_log ("cs4231a", "error: " __VA_ARGS__) + +#define CS_REGS 16 +#define CS_DREGS 32 + +typedef struct CSState { + QEMUSoundCard card; + qemu_irq *pic; + uint32_t regs[CS_REGS]; + uint8_t dregs[CS_DREGS]; + int irq; + int dma; + int port; + int shift; + int dma_running; + int audio_free; + int transferred; + int aci_counter; + SWVoiceOut *voice; + int16_t *tab; +} CSState; + +#define IO_READ_PROTO(name) \ + static uint32_t name (void *opaque, uint32_t addr) + +#define IO_WRITE_PROTO(name) \ + static void name (void *opaque, uint32_t addr, uint32_t val) + +#define GET_SADDR(addr) (addr & 3) + +#define MODE2 (1 << 6) +#define MCE (1 << 6) +#define PMCE (1 << 4) +#define CMCE (1 << 5) +#define TE (1 << 6) +#define PEN (1 << 0) +#define INT (1 << 0) +#define IEN (1 << 1) +#define PPIO (1 << 6) +#define PI (1 << 4) +#define CI (1 << 5) +#define TI (1 << 6) + +enum { + Index_Address, + Index_Data, + Status, + PIO_Data +}; + +enum { + Left_ADC_Input_Control, + Right_ADC_Input_Control, + Left_AUX1_Input_Control, + Right_AUX1_Input_Control, + Left_AUX2_Input_Control, + Right_AUX2_Input_Control, + Left_DAC_Output_Control, + Right_DAC_Output_Control, + FS_And_Playback_Data_Format, + Interface_Configuration, + Pin_Control, + Error_Status_And_Initialization, + MODE_And_ID, + Loopback_Control, + Playback_Upper_Base_Count, + Playback_Lower_Base_Count, + Alternate_Feature_Enable_I, + Alternate_Feature_Enable_II, + Left_Line_Input_Control, + Right_Line_Input_Control, + Timer_Low_Base, + Timer_High_Base, + RESERVED, + Alternate_Feature_Enable_III, + Alternate_Feature_Status, + Version_Chip_ID, + Mono_Input_And_Output_Control, + RESERVED_2, + Capture_Data_Format, + RESERVED_3, + Capture_Upper_Base_Count, + Capture_Lower_Base_Count +}; + +static int freqs[2][8] = { + { 8000, 16000, 27420, 32000, -1, -1, 48000, 9000 }, + { 5510, 11025, 18900, 22050, 37800, 44100, 33075, 6620 } +}; + +/* Tables courtesy http://hazelware.luggle.com/tutorials/mulawcompression.html */ +static int16_t MuLawDecompressTable[256] = +{ + -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956, + -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764, + -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412, + -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316, + -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, + -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, + -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, + -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, + -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, + -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, + -876, -844, -812, -780, -748, -716, -684, -652, + -620, -588, -556, -524, -492, -460, -428, -396, + -372, -356, -340, -324, -308, -292, -276, -260, + -244, -228, -212, -196, -180, -164, -148, -132, + -120, -112, -104, -96, -88, -80, -72, -64, + -56, -48, -40, -32, -24, -16, -8, 0, + 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, + 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, + 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, + 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, + 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, + 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, + 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, + 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, + 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, + 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, + 876, 844, 812, 780, 748, 716, 684, 652, + 620, 588, 556, 524, 492, 460, 428, 396, + 372, 356, 340, 324, 308, 292, 276, 260, + 244, 228, 212, 196, 180, 164, 148, 132, + 120, 112, 104, 96, 88, 80, 72, 64, + 56, 48, 40, 32, 24, 16, 8, 0 +}; + +static int16_t ALawDecompressTable[256] = +{ + -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, + -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, + -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, + -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, + -22016,-20992,-24064,-23040,-17920,-16896,-19968,-18944, + -30208,-29184,-32256,-31232,-26112,-25088,-28160,-27136, + -11008,-10496,-12032,-11520,-8960, -8448, -9984, -9472, + -15104,-14592,-16128,-15616,-13056,-12544,-14080,-13568, + -344, -328, -376, -360, -280, -264, -312, -296, + -472, -456, -504, -488, -408, -392, -440, -424, + -88, -72, -120, -104, -24, -8, -56, -40, + -216, -200, -248, -232, -152, -136, -184, -168, + -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, + -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, + -688, -656, -752, -720, -560, -528, -624, -592, + -944, -912, -1008, -976, -816, -784, -880, -848, + 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, + 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, + 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, + 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, + 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, + 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, + 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, + 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, + 344, 328, 376, 360, 280, 264, 312, 296, + 472, 456, 504, 488, 408, 392, 440, 424, + 88, 72, 120, 104, 24, 8, 56, 40, + 216, 200, 248, 232, 152, 136, 184, 168, + 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, + 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, + 688, 656, 752, 720, 560, 528, 624, 592, + 944, 912, 1008, 976, 816, 784, 880, 848 +}; + +static void cs_reset(void *opaque) +{ + CSState *s = opaque; + + s->regs[Index_Address] = 0x40; + s->regs[Index_Data] = 0x00; + s->regs[Status] = 0x00; + s->regs[PIO_Data] = 0x00; + + s->dregs[Left_ADC_Input_Control] = 0x00; + s->dregs[Right_ADC_Input_Control] = 0x00; + s->dregs[Left_AUX1_Input_Control] = 0x88; + s->dregs[Right_AUX1_Input_Control] = 0x88; + s->dregs[Left_AUX2_Input_Control] = 0x88; + s->dregs[Right_AUX2_Input_Control] = 0x88; + s->dregs[Left_DAC_Output_Control] = 0x80; + s->dregs[Right_DAC_Output_Control] = 0x80; + s->dregs[FS_And_Playback_Data_Format] = 0x00; + s->dregs[Interface_Configuration] = 0x08; + s->dregs[Pin_Control] = 0x00; + s->dregs[Error_Status_And_Initialization] = 0x00; + s->dregs[MODE_And_ID] = 0x8a; + s->dregs[Loopback_Control] = 0x00; + s->dregs[Playback_Upper_Base_Count] = 0x00; + s->dregs[Playback_Lower_Base_Count] = 0x00; + s->dregs[Alternate_Feature_Enable_I] = 0x00; + s->dregs[Alternate_Feature_Enable_II] = 0x00; + s->dregs[Left_Line_Input_Control] = 0x88; + s->dregs[Right_Line_Input_Control] = 0x88; + s->dregs[Timer_Low_Base] = 0x00; + s->dregs[Timer_High_Base] = 0x00; + s->dregs[RESERVED] = 0x00; + s->dregs[Alternate_Feature_Enable_III] = 0x00; + s->dregs[Alternate_Feature_Status] = 0x00; + s->dregs[Version_Chip_ID] = 0xa0; + s->dregs[Mono_Input_And_Output_Control] = 0xa0; + s->dregs[RESERVED_2] = 0x00; + s->dregs[Capture_Data_Format] = 0x00; + s->dregs[RESERVED_3] = 0x00; + s->dregs[Capture_Upper_Base_Count] = 0x00; + s->dregs[Capture_Lower_Base_Count] = 0x00; +} + +static void cs_audio_callback (void *opaque, int free) +{ + CSState *s = opaque; + s->audio_free = free; +} + +static void cs_reset_voices (CSState *s, uint32_t val) +{ + int xtal; + audsettings_t as; + +#ifdef DEBUG_XLAW + if (val == 0 || val == 32) + val = (1 << 4) | (1 << 5); +#endif + + xtal = val & 1; + as.freq = freqs[xtal][(val >> 1) & 7]; + + if (as.freq == -1) { + lerr ("unsupported frequency (val=%#x)\n", val); + goto error; + } + + as.nchannels = (val & (1 << 4)) ? 2 : 1; + as.endianness = 0; + s->tab = NULL; + + switch ((val >> 5) & ((s->dregs[MODE_And_ID] & MODE2) ? 7 : 3)) { + case 0: + as.fmt = AUD_FMT_U8; + s->shift = as.nchannels == 2; + break; + + case 1: + s->tab = MuLawDecompressTable; + goto x_law; + case 3: + s->tab = ALawDecompressTable; + x_law: + as.fmt = AUD_FMT_S16; + as.endianness = AUDIO_HOST_ENDIANNESS; + s->shift = as.nchannels == 2; + break; + + case 6: + as.endianness = 1; + case 2: + as.fmt = AUD_FMT_S16; + s->shift = as.nchannels; + break; + + case 7: + case 4: + lerr ("attempt to use reserved format value (%#x)\n", val); + goto error; + + case 5: + lerr ("ADPCM 4 bit IMA compatible format is not supported\n"); + goto error; + } + + s->voice = AUD_open_out ( + &s->card, + s->voice, + "cs4231a", + s, + cs_audio_callback, + &as + ); + + if (s->dregs[Interface_Configuration] & PEN) { + if (!s->dma_running) { + DMA_hold_DREQ (s->dma); + AUD_set_active_out (s->voice, 1); + s->transferred = 0; + } + s->dma_running = 1; + } + else { + if (s->dma_running) { + DMA_release_DREQ (s->dma); + AUD_set_active_out (s->voice, 0); + } + s->dma_running = 0; + } + return; + + error: + if (s->dma_running) { + DMA_release_DREQ (s->dma); + AUD_set_active_out (s->voice, 0); + } +} + +IO_READ_PROTO (cs_read) +{ + CSState *s = opaque; + uint32_t saddr, iaddr, ret; + + saddr = GET_SADDR (addr); + iaddr = ~0U; + + switch (saddr) { + case Index_Address: + ret = s->regs[saddr] & ~0x80; + break; + + case Index_Data: + if (!(s->dregs[MODE_And_ID] & MODE2)) + iaddr = s->regs[Index_Address] & 0x0f; + else + iaddr = s->regs[Index_Address] & 0x1f; + + ret = s->dregs[iaddr]; + if (iaddr == Error_Status_And_Initialization) { + /* keep SEAL happy */ + if (s->aci_counter) { + ret |= 1 << 5; + s->aci_counter -= 1; + } + } + break; + + default: + ret = s->regs[saddr]; + break; + } + dolog ("read %d:%d -> %d\n", saddr, iaddr, ret); + return ret; +} + +IO_WRITE_PROTO (cs_write) +{ + CSState *s = opaque; + uint32_t saddr, iaddr; + + saddr = GET_SADDR (addr); + + switch (saddr) { + case Index_Address: + if (!(s->regs[Index_Address] & MCE) && (val & MCE) + && (s->dregs[Interface_Configuration] & (3 << 3))) + s->aci_counter = conf.aci_counter; + + s->regs[Index_Address] = val & ~(1 << 7); + break; + + case Index_Data: + if (!(s->dregs[MODE_And_ID] & MODE2)) + iaddr = s->regs[Index_Address] & 0x0f; + else + iaddr = s->regs[Index_Address] & 0x1f; + + switch (iaddr) { + case RESERVED: + case RESERVED_2: + case RESERVED_3: + lwarn ("attempt to write %#x to reserved indirect register %d\n", + val, iaddr); + break; + + case FS_And_Playback_Data_Format: + if (s->regs[Index_Address] & MCE) { + cs_reset_voices (s, val); + } + else { + if (s->dregs[Alternate_Feature_Status] & PMCE) { + val = (val & ~0x0f) | (s->dregs[iaddr] & 0x0f); + cs_reset_voices (s, val); + } + else { + lwarn ("[P]MCE(%#x, %#x) is not set, val=%#x\n", + s->regs[Index_Address], + s->dregs[Alternate_Feature_Status], + val); + break; + } + } + s->dregs[iaddr] = val; + break; + + case Interface_Configuration: + val &= ~(1 << 5); /* D5 is reserved */ + s->dregs[iaddr] = val; + if (val & PPIO) { + lwarn ("PIO is not supported (%#x)\n", val); + break; + } + if (val & PEN) { + if (!s->dma_running) { + cs_reset_voices (s, s->dregs[FS_And_Playback_Data_Format]); + } + } + else { + if (s->dma_running) { + DMA_release_DREQ (s->dma); + AUD_set_active_out (s->voice, 0); + s->dma_running = 0; + } + } + break; + + case Error_Status_And_Initialization: + lwarn ("attempt to write to read only register %d\n", iaddr); + break; + + case MODE_And_ID: + dolog ("val=%#x\n", val); + if (val & MODE2) + s->dregs[iaddr] |= MODE2; + else + s->dregs[iaddr] &= ~MODE2; + break; + + case Alternate_Feature_Enable_I: + if (val & TE) + lerr ("timer is not yet supported\n"); + s->dregs[iaddr] = val; + break; + + case Alternate_Feature_Status: + if ((s->dregs[iaddr] & PI) && !(val & PI)) { + /* XXX: TI CI */ + qemu_irq_lower (s->pic[s->irq]); + s->regs[Status] &= ~INT; + } + s->dregs[iaddr] = val; + break; + + case Version_Chip_ID: + lwarn ("write to Version_Chip_ID register %#x\n", val); + s->dregs[iaddr] = val; + break; + + default: + s->dregs[iaddr] = val; + break; + } + dolog ("written value %#x to indirect register %d\n", val, iaddr); + break; + + case Status: + if (s->regs[Status] & INT) { + qemu_irq_lower (s->pic[s->irq]); + } + s->regs[Status] &= ~INT; + s->dregs[Alternate_Feature_Status] &= ~(PI | CI | TI); + break; + + case PIO_Data: + lwarn ("attempt to write value %#x to PIO register\n", val); + break; + } +} + +static int cs_write_audio (CSState *s, int nchan, int dma_pos, + int dma_len, int len) +{ + int temp, net; + uint8_t tmpbuf[4096]; + + temp = len; + net = 0; + + while (temp) { + int left = dma_len - dma_pos; + int copied; + size_t to_copy; + + to_copy = audio_MIN (temp, left); + if (to_copy > sizeof (tmpbuf)) { + to_copy = sizeof (tmpbuf); + } + + copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy); + if (s->tab) { + int i; + int16_t linbuf[4096]; + + for (i = 0; i < copied; ++i) + linbuf[i] = s->tab[tmpbuf[i]]; + copied = AUD_write (s->voice, linbuf, copied << 1); + copied >>= 1; + } + else { + copied = AUD_write (s->voice, tmpbuf, copied); + } + + temp -= copied; + dma_pos = (dma_pos + copied) % dma_len; + net += copied; + + if (!copied) { + break; + } + } + + return net; +} + +static int cs_dma_read (void *opaque, int nchan, int dma_pos, int dma_len) +{ + CSState *s = opaque; + int copy, written; + int till = -1; + + copy = s->voice ? (s->audio_free >> (s->tab != NULL)) : dma_len; + + if (s->dregs[Pin_Control] & IEN) { + till = (s->dregs[Playback_Lower_Base_Count] + | (s->dregs[Playback_Upper_Base_Count] << 8)) << s->shift; + till -= s->transferred; + copy = audio_MIN (till, copy); + } + + if ((copy <= 0) || (dma_len <= 0)) { + return dma_pos; + } + + written = cs_write_audio (s, nchan, dma_pos, dma_len, copy); + + dma_pos = (dma_pos + written) % dma_len; + s->audio_free -= (written << (s->tab != NULL)); + + if (written == till) { + s->regs[Status] |= INT; + s->dregs[Alternate_Feature_Status] |= PI; + s->transferred = 0; + qemu_irq_raise (s->pic[s->irq]); + } + else { + s->transferred += written; + } + + return dma_pos; +} + +static void cs_save(QEMUFile *f, void *opaque) +{ + CSState *s = opaque; + unsigned int i; + + for (i = 0; i < CS_REGS; i++) + qemu_put_be32s(f, &s->regs[i]); + + qemu_put_buffer(f, s->dregs, CS_DREGS); +} + +static int cs_load(QEMUFile *f, void *opaque, int version_id) +{ + CSState *s = opaque; + unsigned int i; + + if (version_id > 1) + return -EINVAL; + + for (i = 0; i < CS_REGS; i++) + qemu_get_be32s(f, &s->regs[i]); + + qemu_get_buffer(f, s->dregs, CS_DREGS); + return 0; +} + +int cs4231a_init (AudioState *audio, qemu_irq *pic) +{ + int i; + CSState *s; + + if (!audio) { + lerr ("No audio state\n"); + return -1; + } + + s = qemu_mallocz (sizeof (*s)); + if (!s) { + lerr ("Could not allocate memory for cs4231a (%zu bytes)\n", + sizeof (*s)); + return -1; + } + + s->pic = pic; + s->irq = conf.irq; + s->dma = conf.dma; + s->port = conf.port; + + for (i = 0; i < 4; i++) { + register_ioport_write (s->port + i, 1, 1, cs_write, s); + register_ioport_read (s->port + i, 1, 1, cs_read, s); + } + + DMA_register_channel (s->dma, cs_dma_read, s); + + register_savevm ("cs4231a", 0, 1, cs_save, cs_load, s); + qemu_register_reset (cs_reset, s); + cs_reset (s); + + AUD_register_card (audio,"cs4231a", &s->card); + return 0; +} diff --git a/qemu-doc.texi b/qemu-doc.texi index 7c60e79c9..d01a04b93 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -175,13 +175,16 @@ Adlib(OPL2) - Yamaha YM3812 compatible chip @item Gravis Ultrasound GF1 sound card @item +CS4231A compatible sound card +@item PCI UHCI USB controller and a virtual USB hub. @end itemize SMP is supported with up to 255 CPUs. -Note that adlib, ac97 and gus are only available when QEMU was configured -with --enable-adlib, --enable-ac97 or --enable-gus respectively. +Note that adlib, ac97, gus and cs4231a are only available when QEMU +was configured with --enable-adlib, --enable-ac97, --enable-gus or +--enable-cs4231a respectively. QEMU uses the PC BIOS from the Bochs project and the Plex86/Bochs LGPL VGA BIOS. @@ -191,6 +194,8 @@ QEMU uses YM3812 emulation by Tatsuyuki Satoh. QEMU uses GUS emulation(GUSEMU32 @url{http://www.deinmeister.de/gusemu/}) by Tibor "TS" Schütz. +CS4231A is the chip used in Windows Sound System and GUSMAX products + @c man end @node pcsys_quickstart diff --git a/vl.c b/vl.c index 671b7a41d..d759fde9a 100644 --- a/vl.c +++ b/vl.c @@ -7552,6 +7552,16 @@ struct soundhw soundhw[] = { { .init_isa = SB16_init } }, +#ifdef CONFIG_CS4231A + { + "cs4231a", + "CS4231A", + 0, + 1, + { .init_isa = cs4231a_init } + }, +#endif + #ifdef CONFIG_ADLIB { "adlib", -- cgit v1.2.3 From 4143f3e09cf780fdd2f1461f19a4e63987a09660 Mon Sep 17 00:00:00 2001 From: malc Date: Fri, 13 Jun 2008 18:16:59 +0000 Subject: Fix vm state save/load git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4742 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/cs4231a.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/hw/cs4231a.c b/hw/cs4231a.c index 898c37e9e..a18a1424e 100644 --- a/hw/cs4231a.c +++ b/hw/cs4231a.c @@ -601,17 +601,23 @@ static void cs_save(QEMUFile *f, void *opaque) { CSState *s = opaque; unsigned int i; + uint32_t val; for (i = 0; i < CS_REGS; i++) qemu_put_be32s(f, &s->regs[i]); qemu_put_buffer(f, s->dregs, CS_DREGS); + val = s->dma_running; qemu_put_be32s(f, &val); + val = s->audio_free; qemu_put_be32s(f, &val); + val = s->transferred; qemu_put_be32s(f, &val); + val = s->aci_counter; qemu_put_be32s(f, &val); } static int cs_load(QEMUFile *f, void *opaque, int version_id) { CSState *s = opaque; unsigned int i; + uint32_t val, dma_running; if (version_id > 1) return -EINVAL; @@ -620,6 +626,13 @@ static int cs_load(QEMUFile *f, void *opaque, int version_id) qemu_get_be32s(f, &s->regs[i]); qemu_get_buffer(f, s->dregs, CS_DREGS); + + qemu_get_be32s(f, &dma_running); + qemu_get_be32s(f, &val); s->audio_free = val; + qemu_get_be32s(f, &val); s->transferred = val; + qemu_get_be32s(f, &val); s->aci_counter = val; + if (dma_running && (s->dregs[Interface_Configuration] & PEN)) + cs_reset_voices (s, s->dregs[FS_And_Playback_Data_Format]); return 0; } -- cgit v1.2.3 From 2daf028464375416f1461710c95522890968f4f2 Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Sun, 15 Jun 2008 18:02:48 +0000 Subject: Fix Sparc32plus & Sparc64 debug output git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4743 c046a42c-6fe2-441c-8c8c-71466251a162 --- linux-user/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 6b4d8d72c..a4ffea3fd 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -779,8 +779,8 @@ static inline void save_window_offset(CPUSPARCState *env, int cwp1) sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)]; #if defined(DEBUG_WIN) - printf("win_overflow: sp_ptr=0x%x save_cwp=%d\n", - (int)sp_ptr, cwp1); + printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n", + sp_ptr, cwp1); #endif for(i = 0; i < 16; i++) { /* FIXME - what to do if put_user() fails? */ @@ -816,8 +816,8 @@ static void restore_window(CPUSPARCState *env) cwp1 = cpu_cwp_inc(env, env->cwp + 1); sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)]; #if defined(DEBUG_WIN) - printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n", - (int)sp_ptr, cwp1); + printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n", + sp_ptr, cwp1); #endif for(i = 0; i < 16; i++) { /* FIXME - what to do if get_user() fails? */ -- cgit v1.2.3 From 07bf2857b8517711b5af2c516208bf87c546419f Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Sun, 15 Jun 2008 18:06:39 +0000 Subject: Avoid temporary variable use across basic blocks for udivx git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4744 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-sparc/translate.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 999378a6d..a821ef3f3 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -3068,8 +3068,10 @@ static void disas_sparc_insn(DisasContext * dc) break; #ifdef TARGET_SPARC64 case 0xd: /* V9 udivx */ - gen_trap_ifdivzero_tl(cpu_src2); - tcg_gen_divu_i64(cpu_dst, cpu_src1, cpu_src2); + tcg_gen_mov_tl(cpu_cc_src, cpu_src1); + tcg_gen_mov_tl(cpu_cc_src2, cpu_src2); + gen_trap_ifdivzero_tl(cpu_cc_src2); + tcg_gen_divu_i64(cpu_dst, cpu_cc_src, cpu_cc_src2); break; #endif case 0xe: -- cgit v1.2.3 From 17ca26e7918353ae67fa9cfcbf61e3b90a1b3a6b Mon Sep 17 00:00:00 2001 From: malc Date: Wed, 18 Jun 2008 01:58:52 +0000 Subject: Save LR into proper place on callers stack frame git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4745 c046a42c-6fe2-441c-8c8c-71466251a162 --- tcg/ppc/tcg-target.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index bc985519a..c829b642c 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -823,7 +823,7 @@ void tcg_target_qemu_prologue (TCGContext *s) | (i * 4 + 8 + TCG_STATIC_CALL_ARGS_SIZE) ) ); - tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size - 4)); + tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size + 4)); tcg_out32 (s, MTSPR | RS (3) | CTR); tcg_out32 (s, BCCTR | BO_ALWAYS); @@ -836,7 +836,7 @@ void tcg_target_qemu_prologue (TCGContext *s) | (i * 4 + 8 + TCG_STATIC_CALL_ARGS_SIZE) ) ); - tcg_out32 (s, LWZ | RT (0) | RA (1) | (frame_size - 4)); + tcg_out32 (s, LWZ | RT (0) | RA (1) | (frame_size + 4)); tcg_out32 (s, MTSPR | RS (0) | LR); tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size); tcg_out32 (s, BCLR | BO_ALWAYS); -- cgit v1.2.3 From 94451178b6b7d6d08c0f16a5a1b0d03bf978f74b Mon Sep 17 00:00:00 2001 From: bellard Date: Wed, 18 Jun 2008 09:32:32 +0000 Subject: HLT, MWAIT and MONITOR insn fixes (initial patch by Alexander Graf) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4746 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-i386/helper.h | 4 ++-- target-i386/op_helper.c | 18 +++++++++++++----- target-i386/translate.c | 10 ++++++---- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/target-i386/helper.h b/target-i386/helper.h index 152029914..8df6acc8d 100644 --- a/target-i386/helper.h +++ b/target-i386/helper.h @@ -60,9 +60,9 @@ DEF_HELPER(void, helper_sysexit, (void)) DEF_HELPER(void, helper_syscall, (int next_eip_addend)) DEF_HELPER(void, helper_sysret, (int dflag)) #endif -DEF_HELPER(void, helper_hlt, (void)) +DEF_HELPER(void, helper_hlt, (int next_eip_addend)) DEF_HELPER(void, helper_monitor, (target_ulong ptr)) -DEF_HELPER(void, helper_mwait, (void)) +DEF_HELPER(void, helper_mwait, (int next_eip_addend)) DEF_HELPER(void, helper_debug, (void)) DEF_HELPER(void, helper_raise_interrupt, (int intno, int next_eip_addend)) DEF_HELPER(void, helper_raise_exception, (int exception_index)) diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c index 730ec8169..beb568741 100644 --- a/target-i386/op_helper.c +++ b/target-i386/op_helper.c @@ -4547,16 +4547,22 @@ void helper_idivq_EAX(target_ulong t0) } #endif -void helper_hlt(void) +static void do_hlt(void) { - helper_svm_check_intercept_param(SVM_EXIT_HLT, 0); - env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */ env->halted = 1; env->exception_index = EXCP_HLT; cpu_loop_exit(); } +void helper_hlt(int next_eip_addend) +{ + helper_svm_check_intercept_param(SVM_EXIT_HLT, 0); + EIP += next_eip_addend; + + do_hlt(); +} + void helper_monitor(target_ulong ptr) { if ((uint32_t)ECX != 0) @@ -4565,17 +4571,19 @@ void helper_monitor(target_ulong ptr) helper_svm_check_intercept_param(SVM_EXIT_MONITOR, 0); } -void helper_mwait(void) +void helper_mwait(int next_eip_addend) { if ((uint32_t)ECX != 0) raise_exception(EXCP0D_GPF); helper_svm_check_intercept_param(SVM_EXIT_MWAIT, 0); + EIP += next_eip_addend; + /* XXX: not complete but not completely erroneous */ if (env->cpu_index != 0 || env->next_cpu != NULL) { /* more than one CPU: do not sleep because another CPU may wake this one */ } else { - helper_hlt(); + do_hlt(); } } diff --git a/target-i386/translate.c b/target-i386/translate.c index 14903b4df..6f9c25672 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -6420,8 +6420,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) } else { if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); - gen_jmp_im(s->pc - s->cs_base); - tcg_gen_helper_0_0(helper_hlt); + gen_jmp_im(pc_start - s->cs_base); + tcg_gen_helper_0_1(helper_hlt, tcg_const_i32(s->pc - pc_start)); s->is_jmp = 3; } break; @@ -6519,6 +6519,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) goto illegal_op; + if (s->cc_op != CC_OP_DYNAMIC) + gen_op_set_cc_op(s->cc_op); gen_jmp_im(pc_start - s->cs_base); #ifdef TARGET_X86_64 if (s->aflag == 2) { @@ -6541,8 +6543,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) gen_op_set_cc_op(s->cc_op); s->cc_op = CC_OP_DYNAMIC; } - gen_jmp_im(s->pc - s->cs_base); - tcg_gen_helper_0_0(helper_mwait); + gen_jmp_im(pc_start - s->cs_base); + tcg_gen_helper_0_1(helper_mwait, tcg_const_i32(s->pc - pc_start)); gen_eob(s); break; default: -- cgit v1.2.3 From 2ecea9b8de5cd74df314541b87f712ae77f862ec Mon Sep 17 00:00:00 2001 From: aurel32 Date: Wed, 18 Jun 2008 22:10:01 +0000 Subject: Add image format option in monitor for removable media (Chris Wright) CVE-2008-1945 git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4747 c046a42c-6fe2-441c-8c8c-71466251a162 --- monitor.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/monitor.c b/monitor.c index 1eb8be1ed..9f1013ecf 100644 --- a/monitor.c +++ b/monitor.c @@ -396,18 +396,26 @@ static void do_eject(int force, const char *filename) eject_device(bs, force); } -static void do_change_block(const char *device, const char *filename) +static void do_change_block(const char *device, const char *filename, const char *fmt) { BlockDriverState *bs; + BlockDriver *drv = NULL; bs = bdrv_find(device); if (!bs) { term_printf("device not found\n"); return; } + if (fmt) { + drv = bdrv_find_format(fmt); + if (!drv) { + term_printf("invalid format %s\n", fmt); + return; + } + } if (eject_device(bs, 0) < 0) return; - bdrv_open(bs, filename, 0); + bdrv_open2(bs, filename, 0, drv); qemu_key_check(bs, filename); } @@ -426,12 +434,12 @@ static void do_change_vnc(const char *target) } } -static void do_change(const char *device, const char *target) +static void do_change(const char *device, const char *target, const char *fmt) { if (strcmp(device, "vnc") == 0) { do_change_vnc(target); } else { - do_change_block(device, target); + do_change_block(device, target, fmt); } } @@ -1339,8 +1347,8 @@ static term_cmd_t term_cmds[] = { "", "quit the emulator" }, { "eject", "-fB", do_eject, "[-f] device", "eject a removable medium (use -f to force it)" }, - { "change", "BF", do_change, - "device filename", "change a removable medium" }, + { "change", "BFs?", do_change, + "device filename [format]", "change a removable medium, optional format" }, { "screendump", "F", do_screen_dump, "filename", "save screen into PPM image 'filename'" }, { "logfile", "F", do_logfile, -- cgit v1.2.3 From e4bb997e06669b0a9990a5d7c9c14c77c945aeb9 Mon Sep 17 00:00:00 2001 From: aurel32 Date: Wed, 18 Jun 2008 22:10:12 +0000 Subject: PPC: fix mtfsfi (Tristan Gingold) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4748 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-ppc/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 19de8695a..28cb6abdd 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -362,7 +362,7 @@ EXTRACT_HELPER(TO, 21, 5); EXTRACT_HELPER(CRM, 12, 8); EXTRACT_HELPER(FM, 17, 8); EXTRACT_HELPER(SR, 16, 4); -EXTRACT_HELPER(FPIMM, 20, 4); +EXTRACT_HELPER(FPIMM, 12, 4); /*** Jump target decoding ***/ /* Displacement */ -- cgit v1.2.3 From d978c02c311e833059b9d64487e37a5d0253a30b Mon Sep 17 00:00:00 2001 From: aurel32 Date: Wed, 18 Jun 2008 22:10:21 +0000 Subject: Make save function optional (Ian Jackson) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4749 c046a42c-6fe2-441c-8c8c-71466251a162 --- vl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vl.c b/vl.c index d759fde9a..37301b02f 100644 --- a/vl.c +++ b/vl.c @@ -5987,6 +5987,10 @@ static int qemu_savevm_state(QEMUFile *f) qemu_put_be64(f, 0); /* total size */ for(se = first_se; se != NULL; se = se->next) { + if (se->save_state == NULL) + /* this one has a loader only, for backwards compatibility */ + continue; + /* ID string */ len = strlen(se->idstr); qemu_put_byte(f, len); -- cgit v1.2.3 From 33b6939fcb932a73965dc545c907f8e6bdd1b0cf Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Thu, 19 Jun 2008 15:56:22 +0000 Subject: Fix crash when returning from monitor or serial console to normal TCX view git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4750 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/tcx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/tcx.c b/hw/tcx.c index c72b99924..f0ae53ff3 100644 --- a/hw/tcx.c +++ b/hw/tcx.c @@ -186,6 +186,8 @@ static void tcx_update_display(void *opaque) if (ts->ds->depth == 0) return; + if (ts->ds->width != ts->width || ts->ds->height != ts->height) + dpy_resize(ts->ds, ts->width, ts->height); page = ts->vram_offset; y_start = -1; page_min = 0xffffffff; -- cgit v1.2.3 From 20483400d19273c11ee98821ce4592864e51bb81 Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Thu, 19 Jun 2008 16:07:48 +0000 Subject: Also fix 24 bit depth git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4751 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/tcx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/tcx.c b/hw/tcx.c index f0ae53ff3..a63b44188 100644 --- a/hw/tcx.c +++ b/hw/tcx.c @@ -266,6 +266,8 @@ static void tcx24_update_display(void *opaque) if (ts->ds->depth != 32) return; + if (ts->ds->width != ts->width || ts->ds->height != ts->height) + dpy_resize(ts->ds, ts->width, ts->height); page = ts->vram_offset; page24 = ts->vram24_offset; cpage = ts->cplane_offset; -- cgit v1.2.3 From 8f2ad0a3fc5e3569183d44bf1c7fcb95294be4c0 Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Thu, 19 Jun 2008 17:38:15 +0000 Subject: Fix buffer overruns (reported by Julian Seward) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4752 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/eccmemctl.c | 62 +++++++++++++++++++++++++++------------------------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/hw/eccmemctl.c b/hw/eccmemctl.c index fe7f27e06..5ee50aee0 100644 --- a/hw/eccmemctl.c +++ b/hw/eccmemctl.c @@ -40,16 +40,16 @@ * SMC (version 0, implementation 2) SS-10SX and SS-20 */ -/* Register offsets */ -#define ECC_MER 0 /* Memory Enable Register */ -#define ECC_MDR 4 /* Memory Delay Register */ -#define ECC_MFSR 8 /* Memory Fault Status Register */ -#define ECC_VCR 12 /* Video Configuration Register */ -#define ECC_MFAR0 16 /* Memory Fault Address Register 0 */ -#define ECC_MFAR1 20 /* Memory Fault Address Register 1 */ -#define ECC_DR 24 /* Diagnostic Register */ -#define ECC_ECR0 28 /* Event Count Register 0 */ -#define ECC_ECR1 32 /* Event Count Register 1 */ +/* Register indexes */ +#define ECC_MER 0 /* Memory Enable Register */ +#define ECC_MDR 1 /* Memory Delay Register */ +#define ECC_MFSR 2 /* Memory Fault Status Register */ +#define ECC_VCR 3 /* Video Configuration Register */ +#define ECC_MFAR0 4 /* Memory Fault Address Register 0 */ +#define ECC_MFAR1 5 /* Memory Fault Address Register 1 */ +#define ECC_DR 6 /* Diagnostic Register */ +#define ECC_ECR0 7 /* Event Count Register 0 */ +#define ECC_ECR1 8 /* Event Count Register 1 */ /* ECC fault control register */ #define ECC_MER_EE 0x00000001 /* Enable ECC checking */ @@ -129,34 +129,34 @@ static void ecc_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) { ECCState *s = opaque; - switch (addr & ECC_ADDR_MASK) { + switch ((addr & ECC_ADDR_MASK) >> 2) { case ECC_MER: - s->regs[0] = (s->regs[0] & (ECC_MER_VER | ECC_MER_IMPL)) | - (val & ~(ECC_MER_VER | ECC_MER_IMPL)); + s->regs[ECC_MER] = (s->regs[ECC_MER] & (ECC_MER_VER | ECC_MER_IMPL)) | + (val & ~(ECC_MER_VER | ECC_MER_IMPL)); DPRINTF("Write memory enable %08x\n", val); break; case ECC_MDR: - s->regs[1] = val & ECC_MDR_MASK; + s->regs[ECC_MDR] = val & ECC_MDR_MASK; DPRINTF("Write memory delay %08x\n", val); break; case ECC_MFSR: - s->regs[2] = val; + s->regs[ECC_MFSR] = val; DPRINTF("Write memory fault status %08x\n", val); break; case ECC_VCR: - s->regs[3] = val; + s->regs[ECC_VCR] = val; DPRINTF("Write slot configuration %08x\n", val); break; case ECC_DR: - s->regs[6] = val; + s->regs[ECC_DR] = val; DPRINTF("Write diagnosiic %08x\n", val); break; case ECC_ECR0: - s->regs[7] = val; + s->regs[ECC_ECR0] = val; DPRINTF("Write event count 1 %08x\n", val); break; case ECC_ECR1: - s->regs[7] = val; + s->regs[ECC_ECR0] = val; DPRINTF("Write event count 2 %08x\n", val); break; } @@ -167,41 +167,41 @@ static uint32_t ecc_mem_readl(void *opaque, target_phys_addr_t addr) ECCState *s = opaque; uint32_t ret = 0; - switch (addr & ECC_ADDR_MASK) { + switch ((addr & ECC_ADDR_MASK) >> 2) { case ECC_MER: - ret = s->regs[0]; + ret = s->regs[ECC_MER]; DPRINTF("Read memory enable %08x\n", ret); break; case ECC_MDR: - ret = s->regs[1]; + ret = s->regs[ECC_MDR]; DPRINTF("Read memory delay %08x\n", ret); break; case ECC_MFSR: - ret = s->regs[2]; + ret = s->regs[ECC_MFSR]; DPRINTF("Read memory fault status %08x\n", ret); break; case ECC_VCR: - ret = s->regs[3]; + ret = s->regs[ECC_VCR]; DPRINTF("Read slot configuration %08x\n", ret); break; case ECC_MFAR0: - ret = s->regs[4]; + ret = s->regs[ECC_MFAR0]; DPRINTF("Read memory fault address 0 %08x\n", ret); break; case ECC_MFAR1: - ret = s->regs[5]; + ret = s->regs[ECC_MFAR1]; DPRINTF("Read memory fault address 1 %08x\n", ret); break; case ECC_DR: - ret = s->regs[6]; + ret = s->regs[ECC_DR]; DPRINTF("Read diagnostic %08x\n", ret); break; case ECC_ECR0: - ret = s->regs[7]; + ret = s->regs[ECC_ECR0]; DPRINTF("Read event count 1 %08x\n", ret); break; case ECC_ECR1: - ret = s->regs[7]; + ret = s->regs[ECC_ECR0]; DPRINTF("Read event count 2 %08x\n", ret); break; } @@ -281,7 +281,6 @@ static void ecc_save(QEMUFile *f, void *opaque) static void ecc_reset(void *opaque) { ECCState *s = opaque; - int i; s->regs[ECC_MER] &= (ECC_MER_VER | ECC_MER_IMPL); s->regs[ECC_MER] |= ECC_MER_MRR; @@ -293,9 +292,6 @@ static void ecc_reset(void *opaque) s->regs[ECC_DR] = 0; s->regs[ECC_ECR0] = 0; s->regs[ECC_ECR1] = 0; - - for (i = 1; i < ECC_NREGS; i++) - s->regs[i] = 0; } void * ecc_init(target_phys_addr_t base, qemu_irq irq, uint32_t version) -- cgit v1.2.3 From a16336e4792c4f092bd2fdcd20c9d70c979b2b22 Mon Sep 17 00:00:00 2001 From: ths Date: Thu, 19 Jun 2008 18:35:02 +0000 Subject: Convert remaining MIPS FP instructions to TCG. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4753 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/helper.h | 7 + target-mips/op.c | 292 ----------------------------------- target-mips/op_helper.c | 87 +++++++++++ target-mips/translate.c | 403 +++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 426 insertions(+), 363 deletions(-) diff --git a/target-mips/helper.h b/target-mips/helper.h index 1092f8733..cba9cd7eb 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -154,6 +154,7 @@ DEF_HELPER(void, do_float_mulr_ps, (void)) #define FOP_PROTO(op) \ DEF_HELPER(void, do_float_ ## op ## _s, (void)) \ DEF_HELPER(void, do_float_ ## op ## _d, (void)) +FOP_PROTO(sqrt) FOP_PROTO(roundl) FOP_PROTO(roundw) FOP_PROTO(truncl) @@ -174,6 +175,12 @@ FOP_PROTO(add) FOP_PROTO(sub) FOP_PROTO(mul) FOP_PROTO(div) +FOP_PROTO(abs) +FOP_PROTO(chs) +FOP_PROTO(muladd) +FOP_PROTO(mulsub) +FOP_PROTO(nmuladd) +FOP_PROTO(nmulsub) FOP_PROTO(recip1) FOP_PROTO(recip2) FOP_PROTO(rsqrt1) diff --git a/target-mips/op.c b/target-mips/op.c index 2c99ad754..5e778f2b3 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -295,295 +295,3 @@ void op_mulshiu (void) #else # define DEBUG_FPU_STATE() do { } while(0) #endif - -/* Float support. - Single precition routines have a "s" suffix, double precision a - "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps", - paired single lowwer "pl", paired single upper "pu". */ - -#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void) - -FLOAT_OP(pll, ps) -{ - DT2 = ((uint64_t)WT0 << 32) | WT1; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(plu, ps) -{ - DT2 = ((uint64_t)WT0 << 32) | WTH1; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(pul, ps) -{ - DT2 = ((uint64_t)WTH0 << 32) | WT1; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(puu, ps) -{ - DT2 = ((uint64_t)WTH0 << 32) | WTH1; - DEBUG_FPU_STATE(); - FORCE_RET(); -} - -FLOAT_OP(movf, d) -{ - if (!(env->fpu->fcr31 & PARAM1)) - DT2 = DT0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(movf, s) -{ - if (!(env->fpu->fcr31 & PARAM1)) - WT2 = WT0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(movf, ps) -{ - unsigned int mask = GET_FP_COND (env->fpu) >> PARAM1; - if (!(mask & 1)) - WT2 = WT0; - if (!(mask & 2)) - WTH2 = WTH0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(movt, d) -{ - if (env->fpu->fcr31 & PARAM1) - DT2 = DT0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(movt, s) -{ - if (env->fpu->fcr31 & PARAM1) - WT2 = WT0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(movt, ps) -{ - unsigned int mask = GET_FP_COND (env->fpu) >> PARAM1; - if (mask & 1) - WT2 = WT0; - if (mask & 2) - WTH2 = WTH0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(movz, d) -{ - if (!T0) - DT2 = DT0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(movz, s) -{ - if (!T0) - WT2 = WT0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(movz, ps) -{ - if (!T0) { - WT2 = WT0; - WTH2 = WTH0; - } - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(movn, d) -{ - if (T0) - DT2 = DT0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(movn, s) -{ - if (T0) - WT2 = WT0; - DEBUG_FPU_STATE(); - FORCE_RET(); -} -FLOAT_OP(movn, ps) -{ - if (T0) { - WT2 = WT0; - WTH2 = WTH0; - } - DEBUG_FPU_STATE(); - FORCE_RET(); -} - -/* ternary operations */ -#define FLOAT_TERNOP(name1, name2) \ -FLOAT_OP(name1 ## name2, d) \ -{ \ - FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \ - FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} \ -FLOAT_OP(name1 ## name2, s) \ -{ \ - FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ - FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} \ -FLOAT_OP(name1 ## name2, ps) \ -{ \ - FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ - FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \ - FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ - FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} -FLOAT_TERNOP(mul, add) -FLOAT_TERNOP(mul, sub) -#undef FLOAT_TERNOP - -/* negated ternary operations */ -#define FLOAT_NTERNOP(name1, name2) \ -FLOAT_OP(n ## name1 ## name2, d) \ -{ \ - FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \ - FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \ - FDT2 = float64_chs(FDT2); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} \ -FLOAT_OP(n ## name1 ## name2, s) \ -{ \ - FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ - FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ - FST2 = float32_chs(FST2); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} \ -FLOAT_OP(n ## name1 ## name2, ps) \ -{ \ - FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ - FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \ - FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ - FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \ - FST2 = float32_chs(FST2); \ - FSTH2 = float32_chs(FSTH2); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} -FLOAT_NTERNOP(mul, add) -FLOAT_NTERNOP(mul, sub) -#undef FLOAT_NTERNOP - -/* unary operations, modifying fp status */ -#define FLOAT_UNOP(name) \ -FLOAT_OP(name, d) \ -{ \ - FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} \ -FLOAT_OP(name, s) \ -{ \ - FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} -FLOAT_UNOP(sqrt) -#undef FLOAT_UNOP - -/* unary operations, not modifying fp status */ -#define FLOAT_UNOP(name) \ -FLOAT_OP(name, d) \ -{ \ - FDT2 = float64_ ## name(FDT0); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} \ -FLOAT_OP(name, s) \ -{ \ - FST2 = float32_ ## name(FST0); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} \ -FLOAT_OP(name, ps) \ -{ \ - FST2 = float32_ ## name(FST0); \ - FSTH2 = float32_ ## name(FSTH0); \ - DEBUG_FPU_STATE(); \ - FORCE_RET(); \ -} -FLOAT_UNOP(abs) -FLOAT_UNOP(chs) -#undef FLOAT_UNOP - -FLOAT_OP(alnv, ps) -{ - switch (T0 & 0x7) { - case 0: - FST2 = FST0; - FSTH2 = FSTH0; - break; - case 4: -#ifdef TARGET_WORDS_BIGENDIAN - FSTH2 = FST0; - FST2 = FSTH1; -#else - FSTH2 = FST1; - FST2 = FSTH0; -#endif - break; - default: /* unpredictable */ - break; - } - DEBUG_FPU_STATE(); - FORCE_RET(); -} - -void op_bc1f (void) -{ - T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1)); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -void op_bc1any2f (void) -{ - T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1)); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -void op_bc1any4f (void) -{ - T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1)); - DEBUG_FPU_STATE(); - FORCE_RET(); -} - -void op_bc1t (void) -{ - T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1)); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -void op_bc1any2t (void) -{ - T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1)); - DEBUG_FPU_STATE(); - FORCE_RET(); -} -void op_bc1any4t (void) -{ - T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1)); - DEBUG_FPU_STATE(); - FORCE_RET(); -} diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index c5a4c9369..696295b90 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -1703,8 +1703,26 @@ static always_inline void update_fcr31(void) UPDATE_FP_FLAGS(env->fpu->fcr31, tmp); } +/* Float support. + Single precition routines have a "s" suffix, double precision a + "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps", + paired single lower "pl", paired single upper "pu". */ + #define FLOAT_OP(name, p) void do_float_##name##_##p(void) +/* unary operations, modifying fp status */ +#define FLOAT_UNOP(name) \ +FLOAT_OP(name, d) \ +{ \ + FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \ +} \ +FLOAT_OP(name, s) \ +{ \ + FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \ +} +FLOAT_UNOP(sqrt) +#undef FLOAT_UNOP + FLOAT_OP(cvtd, s) { set_float_exception_flags(0, &env->fpu->fp_status); @@ -1943,6 +1961,25 @@ FLOAT_OP(floorw, s) WT2 = FLOAT_SNAN32; } +/* unary operations, not modifying fp status */ +#define FLOAT_UNOP(name) \ +FLOAT_OP(name, d) \ +{ \ + FDT2 = float64_ ## name(FDT0); \ +} \ +FLOAT_OP(name, s) \ +{ \ + FST2 = float32_ ## name(FST0); \ +} \ +FLOAT_OP(name, ps) \ +{ \ + FST2 = float32_ ## name(FST0); \ + FSTH2 = float32_ ## name(FSTH0); \ +} +FLOAT_UNOP(abs) +FLOAT_UNOP(chs) +#undef FLOAT_UNOP + /* MIPS specific unary operations */ FLOAT_OP(recip, d) { @@ -2051,6 +2088,56 @@ FLOAT_BINOP(mul) FLOAT_BINOP(div) #undef FLOAT_BINOP +/* ternary operations */ +#define FLOAT_TERNOP(name1, name2) \ +FLOAT_OP(name1 ## name2, d) \ +{ \ + FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \ + FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \ +} \ +FLOAT_OP(name1 ## name2, s) \ +{ \ + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ +} \ +FLOAT_OP(name1 ## name2, ps) \ +{ \ + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ + FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \ + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ + FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \ +} +FLOAT_TERNOP(mul, add) +FLOAT_TERNOP(mul, sub) +#undef FLOAT_TERNOP + +/* negated ternary operations */ +#define FLOAT_NTERNOP(name1, name2) \ +FLOAT_OP(n ## name1 ## name2, d) \ +{ \ + FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \ + FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \ + FDT2 = float64_chs(FDT2); \ +} \ +FLOAT_OP(n ## name1 ## name2, s) \ +{ \ + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ + FST2 = float32_chs(FST2); \ +} \ +FLOAT_OP(n ## name1 ## name2, ps) \ +{ \ + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ + FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \ + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ + FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \ + FST2 = float32_chs(FST2); \ + FSTH2 = float32_chs(FSTH2); \ +} +FLOAT_NTERNOP(mul, add) +FLOAT_NTERNOP(mul, sub) +#undef FLOAT_NTERNOP + /* MIPS specific binary operations */ FLOAT_OP(recip2, d) { diff --git a/target-mips/translate.c b/target-mips/translate.c index b7e3967ce..56984147e 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -630,6 +630,21 @@ static inline void gen_store_fpr32h (TCGv t, int reg) tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX); } +static inline void get_fp_cond (TCGv t) +{ + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); + + tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31)); + tcg_gen_shri_i32(r_tmp2, r_tmp1, 24); + tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe); + tcg_gen_shri_i32(r_tmp1, r_tmp1, 23); + tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1); + tcg_gen_or_i32(t, r_tmp1, r_tmp2); + tcg_temp_free(r_tmp1); + tcg_temp_free(r_tmp2); +} + #define FOP_CONDS(type, fmt) \ static GenOpFunc1 * fcmp ## type ## _ ## fmt ## _table[16] = { \ do_cmp ## type ## _ ## fmt ## _f, \ @@ -5541,38 +5556,170 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, switch (op) { case OPC_BC1F: - gen_op_bc1f(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_not_tl(cpu_T[0], cpu_T[0]); + tcg_gen_movi_tl(cpu_T[1], 0x1 << cc); + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(cpu_T[0], 1); + gen_set_label(l2); + } opn = "bc1f"; goto not_likely; case OPC_BC1FL: - gen_op_bc1f(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_not_tl(cpu_T[0], cpu_T[0]); + tcg_gen_movi_tl(cpu_T[1], 0x1 << cc); + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(cpu_T[0], 1); + gen_set_label(l2); + } opn = "bc1fl"; goto likely; case OPC_BC1T: - gen_op_bc1t(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_movi_tl(cpu_T[1], 0x1 << cc); + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(cpu_T[0], 1); + gen_set_label(l2); + } opn = "bc1t"; goto not_likely; case OPC_BC1TL: - gen_op_bc1t(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_movi_tl(cpu_T[1], 0x1 << cc); + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(cpu_T[0], 1); + gen_set_label(l2); + } opn = "bc1tl"; likely: ctx->hflags |= MIPS_HFLAG_BL; tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond)); break; case OPC_BC1FANY2: - gen_op_bc1any2f(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_not_tl(cpu_T[0], cpu_T[0]); + tcg_gen_movi_tl(cpu_T[1], 0x3 << cc); + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(cpu_T[0], 1); + gen_set_label(l2); + } opn = "bc1any2f"; goto not_likely; case OPC_BC1TANY2: - gen_op_bc1any2t(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_movi_tl(cpu_T[1], 0x3 << cc); + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(cpu_T[0], 1); + gen_set_label(l2); + } opn = "bc1any2t"; goto not_likely; case OPC_BC1FANY4: - gen_op_bc1any4f(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_not_tl(cpu_T[0], cpu_T[0]); + tcg_gen_movi_tl(cpu_T[1], 0xf << cc); + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(cpu_T[0], 1); + gen_set_label(l2); + } opn = "bc1any4f"; goto not_likely; case OPC_BC1TANY4: - gen_op_bc1any4t(cc); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + + get_fp_cond(r_tmp1); + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_temp_free(r_tmp1); + tcg_gen_movi_tl(cpu_T[1], 0xf << cc); + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(cpu_T[0], 1); + gen_set_label(l2); + } opn = "bc1any4t"; not_likely: ctx->hflags |= MIPS_HFLAG_BC; @@ -5685,23 +5832,83 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) gen_store_gpr(cpu_T[0], rd); } -#define GEN_MOVCF(fmt) \ -static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \ -{ \ - uint32_t ccbit; \ - \ - if (cc) { \ - ccbit = 1 << (24 + cc); \ - } else \ - ccbit = 1 << 23; \ - if (!tf) \ - glue(gen_op_float_movf_, fmt)(ccbit); \ - else \ - glue(gen_op_float_movt_, fmt)(ccbit); \ +static inline void gen_movcf_s (int cc, int tf) +{ + uint32_t ccbit; + int cond; + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + int l1 = gen_new_label(); + + if (cc) + ccbit = 1 << (24 + cc); + else + ccbit = 1 << 23; + + if (tf) + cond = TCG_COND_EQ; + else + cond = TCG_COND_NE; + + tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31)); + tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit); + tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1); + tcg_gen_movi_i32(fpu32_T[2], fpu32_T[0]); + gen_set_label(l1); + tcg_temp_free(r_tmp1); } -GEN_MOVCF(d); -GEN_MOVCF(s); -#undef GEN_MOVCF + +static inline void gen_movcf_d (int cc, int tf) +{ + uint32_t ccbit; + int cond; + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); + int l1 = gen_new_label(); + + if (cc) + ccbit = 1 << (24 + cc); + else + ccbit = 1 << 23; + + if (tf) + cond = TCG_COND_EQ; + else + cond = TCG_COND_NE; + + tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31)); + tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit); + tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1); + tcg_gen_movi_i64(fpu64_T[2], fpu64_T[0]); + gen_set_label(l1); + tcg_temp_free(r_tmp1); +} + +static inline void gen_movcf_ps (int cc, int tf) +{ + int cond; + TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32); + TCGv r_tmp2 = tcg_temp_local_new(TCG_TYPE_I32); + int l1 = gen_new_label(); + int l2 = gen_new_label(); + + if (tf) + cond = TCG_COND_EQ; + else + cond = TCG_COND_NE; + + get_fp_cond(r_tmp1); + tcg_gen_shri_i32(r_tmp1, r_tmp1, cc); + tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x1); + tcg_gen_brcondi_i32(cond, r_tmp2, 0, l1); + tcg_gen_movi_i32(fpu32_T[2], fpu32_T[0]); + gen_set_label(l1); + tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x2); + tcg_gen_brcondi_i32(cond, r_tmp2, 0, l2); + tcg_gen_movi_i32(fpu32h_T[2], fpu32h_T[0]); + gen_set_label(l2); + tcg_temp_free(r_tmp1); + tcg_temp_free(r_tmp2); +} + static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd, int cc) @@ -5781,13 +5988,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, break; case FOP(4, 16): gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_sqrt_s(); + tcg_gen_helper_0_0(do_float_sqrt_s); gen_store_fpr32(fpu32_T[2], fd); opn = "sqrt.s"; break; case FOP(5, 16): gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_abs_s(); + tcg_gen_helper_0_0(do_float_abs_s); gen_store_fpr32(fpu32_T[2], fd); opn = "abs.s"; break; @@ -5798,7 +6005,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, break; case FOP(7, 16): gen_load_fpr32(fpu32_T[0], fs); - gen_op_float_chs_s(); + tcg_gen_helper_0_0(do_float_chs_s); gen_store_fpr32(fpu32_T[2], fd); opn = "neg.s"; break; @@ -5855,10 +6062,9 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, opn = "floor.w.s"; break; case FOP(17, 16): - gen_load_gpr(cpu_T[0], ft); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[2], fd); - gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1); + gen_movcf_s((ft >> 2) & 0x7, ft & 0x1); gen_store_fpr32(fpu32_T[2], fd); opn = "movcf.s"; break; @@ -5866,7 +6072,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, gen_load_gpr(cpu_T[0], ft); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[2], fd); - gen_op_float_movz_s(); + { + int l1 = gen_new_label(); + + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); + gen_set_label(l1); + } gen_store_fpr32(fpu32_T[2], fd); opn = "movz.s"; break; @@ -5874,7 +6086,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, gen_load_gpr(cpu_T[0], ft); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[2], fd); - gen_op_float_movn_s(); + { + int l1 = gen_new_label(); + + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); + gen_set_label(l1); + } gen_store_fpr32(fpu32_T[2], fd); opn = "movn.s"; break; @@ -6019,14 +6237,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(4, 17): check_cp1_registers(ctx, fs | fd); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_sqrt_d(); + tcg_gen_helper_0_0(do_float_sqrt_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "sqrt.d"; break; case FOP(5, 17): check_cp1_registers(ctx, fs | fd); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_abs_d(); + tcg_gen_helper_0_0(do_float_abs_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "abs.d"; break; @@ -6039,7 +6257,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, case FOP(7, 17): check_cp1_registers(ctx, fs | fd); gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_op_float_chs_d(); + tcg_gen_helper_0_0(do_float_chs_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "neg.d"; break; @@ -6100,10 +6318,9 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, opn = "floor.w.d"; break; case FOP(17, 17): - gen_load_gpr(cpu_T[0], ft); gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[2], fd); - gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1); + gen_movcf_d((ft >> 2) & 0x7, ft & 0x1); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "movcf.d"; break; @@ -6111,7 +6328,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, gen_load_gpr(cpu_T[0], ft); gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[2], fd); - gen_op_float_movz_d(); + { + int l1 = gen_new_label(); + + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + tcg_gen_mov_i64(fpu64_T[2], fpu64_T[0]); + gen_set_label(l1); + } gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "movz.d"; break; @@ -6119,7 +6342,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, gen_load_gpr(cpu_T[0], ft); gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[2], fd); - gen_op_float_movn_d(); + { + int l1 = gen_new_label(); + + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); + tcg_gen_mov_i64(fpu64_T[2], fpu64_T[0]); + gen_set_label(l1); + } gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "movn.d"; break; @@ -6290,7 +6519,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32h(fpu32h_T[0], fs); - gen_op_float_abs_ps(); + tcg_gen_helper_0_0(do_float_abs_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "abs.ps"; @@ -6307,22 +6536,18 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32h(fpu32h_T[0], fs); - gen_op_float_chs_ps(); + tcg_gen_helper_0_0(do_float_chs_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "neg.ps"; break; case FOP(17, 22): check_cp1_64bitmode(ctx); - gen_load_gpr(cpu_T[0], ft); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32h(fpu32h_T[0], fs); gen_load_fpr32(fpu32_T[2], fd); gen_load_fpr32h(fpu32h_T[2], fd); - if (ft & 0x1) - gen_op_float_movt_ps ((ft >> 2) & 0x7); - else - gen_op_float_movf_ps ((ft >> 2) & 0x7); + gen_movcf_ps((ft >> 2) & 0x7, ft & 0x1); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "movcf.ps"; @@ -6334,7 +6559,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, gen_load_fpr32h(fpu32h_T[0], fs); gen_load_fpr32(fpu32_T[2], fd); gen_load_fpr32h(fpu32h_T[2], fd); - gen_op_float_movz_ps(); + { + int l1 = gen_new_label(); + + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); + tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]); + gen_set_label(l1); + } gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "movz.ps"; @@ -6346,7 +6578,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, gen_load_fpr32h(fpu32h_T[0], fs); gen_load_fpr32(fpu32_T[2], fd); gen_load_fpr32h(fpu32h_T[2], fd); - gen_op_float_movn_ps(); + { + int l1 = gen_new_label(); + + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); + tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]); + gen_set_label(l1); + } gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "movn.ps"; @@ -6440,32 +6679,32 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[1], ft); - gen_op_float_pll_ps(); - gen_store_fpr64(ctx, fpu64_T[2], fd); + gen_store_fpr32h(fpu32_T[0], fd); + gen_store_fpr32(fpu32_T[1], fd); opn = "pll.ps"; break; case FOP(45, 22): check_cp1_64bitmode(ctx); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32h(fpu32h_T[1], ft); - gen_op_float_plu_ps(); - gen_store_fpr64(ctx, fpu64_T[2], fd); + gen_store_fpr32(fpu32h_T[1], fd); + gen_store_fpr32h(fpu32_T[0], fd); opn = "plu.ps"; break; case FOP(46, 22): check_cp1_64bitmode(ctx); gen_load_fpr32h(fpu32h_T[0], fs); gen_load_fpr32(fpu32_T[1], ft); - gen_op_float_pul_ps(); - gen_store_fpr64(ctx, fpu64_T[2], fd); + gen_store_fpr32(fpu32_T[1], fd); + gen_store_fpr32h(fpu32h_T[0], fd); opn = "pul.ps"; break; case FOP(47, 22): check_cp1_64bitmode(ctx); gen_load_fpr32h(fpu32h_T[0], fs); gen_load_fpr32h(fpu32h_T[1], ft); - gen_op_float_puu_ps(); - gen_store_fpr64(ctx, fpu64_T[2], fd); + gen_store_fpr32(fpu32h_T[1], fd); + gen_store_fpr32h(fpu32h_T[0], fd); opn = "puu.ps"; break; case FOP(48, 22): @@ -6595,10 +6834,32 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, case OPC_ALNV_PS: check_cp1_64bitmode(ctx); gen_load_gpr(cpu_T[0], fr); - gen_load_fpr64(ctx, fpu64_T[0], fs); - gen_load_fpr64(ctx, fpu64_T[1], ft); - gen_op_float_alnv_ps(); - gen_store_fpr64(ctx, fpu64_T[2], fd); + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x7); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); + { + int l1 = gen_new_label(); + int l2 = gen_new_label(); + + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); + tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 4, l2); +#ifdef TARGET_WORDS_BIGENDIAN + tcg_gen_mov_i32(fpu32h_T[2], fpu32_T[0]); + tcg_gen_mov_i32(fpu32_T[2], fpu32h_T[1]); +#else + tcg_gen_mov_i32(fpu32h_T[2], fpu32_T[1]); + tcg_gen_mov_i32(fpu32_T[2], fpu32h_T[0]); +#endif + gen_set_label(l2); + } + gen_store_fpr32(fpu32_T[2], fd); + gen_store_fpr32h(fpu32h_T[2], fd); opn = "alnv.ps"; break; case OPC_MADD_S: @@ -6606,7 +6867,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[1], ft); gen_load_fpr32(fpu32_T[2], fr); - gen_op_float_muladd_s(); + tcg_gen_helper_0_0(do_float_muladd_s); gen_store_fpr32(fpu32_T[2], fd); opn = "madd.s"; break; @@ -6616,7 +6877,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[1], ft); gen_load_fpr64(ctx, fpu64_T[2], fr); - gen_op_float_muladd_d(); + tcg_gen_helper_0_0(do_float_muladd_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "madd.d"; break; @@ -6628,7 +6889,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr32h(fpu32h_T[1], ft); gen_load_fpr32(fpu32_T[2], fr); gen_load_fpr32h(fpu32h_T[2], fr); - gen_op_float_muladd_ps(); + tcg_gen_helper_0_0(do_float_muladd_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "madd.ps"; @@ -6638,7 +6899,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[1], ft); gen_load_fpr32(fpu32_T[2], fr); - gen_op_float_mulsub_s(); + tcg_gen_helper_0_0(do_float_mulsub_s); gen_store_fpr32(fpu32_T[2], fd); opn = "msub.s"; break; @@ -6648,7 +6909,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[1], ft); gen_load_fpr64(ctx, fpu64_T[2], fr); - gen_op_float_mulsub_d(); + tcg_gen_helper_0_0(do_float_mulsub_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "msub.d"; break; @@ -6660,7 +6921,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr32h(fpu32h_T[1], ft); gen_load_fpr32(fpu32_T[2], fr); gen_load_fpr32h(fpu32h_T[2], fr); - gen_op_float_mulsub_ps(); + tcg_gen_helper_0_0(do_float_mulsub_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "msub.ps"; @@ -6670,7 +6931,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[1], ft); gen_load_fpr32(fpu32_T[2], fr); - gen_op_float_nmuladd_s(); + tcg_gen_helper_0_0(do_float_nmuladd_s); gen_store_fpr32(fpu32_T[2], fd); opn = "nmadd.s"; break; @@ -6680,7 +6941,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[1], ft); gen_load_fpr64(ctx, fpu64_T[2], fr); - gen_op_float_nmuladd_d(); + tcg_gen_helper_0_0(do_float_nmuladd_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "nmadd.d"; break; @@ -6692,7 +6953,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr32h(fpu32h_T[1], ft); gen_load_fpr32(fpu32_T[2], fr); gen_load_fpr32h(fpu32h_T[2], fr); - gen_op_float_nmuladd_ps(); + tcg_gen_helper_0_0(do_float_nmuladd_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "nmadd.ps"; @@ -6702,7 +6963,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[1], ft); gen_load_fpr32(fpu32_T[2], fr); - gen_op_float_nmulsub_s(); + tcg_gen_helper_0_0(do_float_nmulsub_s); gen_store_fpr32(fpu32_T[2], fd); opn = "nmsub.s"; break; @@ -6712,7 +6973,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[1], ft); gen_load_fpr64(ctx, fpu64_T[2], fr); - gen_op_float_nmulsub_d(); + tcg_gen_helper_0_0(do_float_nmulsub_d); gen_store_fpr64(ctx, fpu64_T[2], fd); opn = "nmsub.d"; break; @@ -6724,7 +6985,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, gen_load_fpr32h(fpu32h_T[1], ft); gen_load_fpr32(fpu32_T[2], fr); gen_load_fpr32h(fpu32h_T[2], fr); - gen_op_float_nmulsub_ps(); + tcg_gen_helper_0_0(do_float_nmulsub_ps); gen_store_fpr32(fpu32_T[2], fd); gen_store_fpr32h(fpu32h_T[2], fd); opn = "nmsub.ps"; -- cgit v1.2.3 From caa88be0f59c4b518a29b9e2706b537e675a5e5c Mon Sep 17 00:00:00 2001 From: ths Date: Thu, 19 Jun 2008 18:38:40 +0000 Subject: Remove now-dead code. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4754 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/op.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/target-mips/op.c b/target-mips/op.c index 5e778f2b3..89ee9ce45 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -27,26 +27,6 @@ #ifndef CALL_FROM_TB0 #define CALL_FROM_TB0(func) func() #endif -#ifndef CALL_FROM_TB1 -#define CALL_FROM_TB1(func, arg0) func(arg0) -#endif -#ifndef CALL_FROM_TB1_CONST16 -#define CALL_FROM_TB1_CONST16(func, arg0) CALL_FROM_TB1(func, arg0) -#endif -#ifndef CALL_FROM_TB2 -#define CALL_FROM_TB2(func, arg0, arg1) func(arg0, arg1) -#endif -#ifndef CALL_FROM_TB2_CONST16 -#define CALL_FROM_TB2_CONST16(func, arg0, arg1) \ - CALL_FROM_TB2(func, arg0, arg1) -#endif -#ifndef CALL_FROM_TB3 -#define CALL_FROM_TB3(func, arg0, arg1, arg2) func(arg0, arg1, arg2) -#endif -#ifndef CALL_FROM_TB4 -#define CALL_FROM_TB4(func, arg0, arg1, arg2, arg3) \ - func(arg0, arg1, arg2, arg3) -#endif /* Load and store */ #define MEMSUFFIX _raw @@ -288,10 +268,3 @@ void op_mulshiu (void) } #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ - -/* CP1 functions */ -#if 0 -# define DEBUG_FPU_STATE() CALL_FROM_TB1(dump_fpu, env) -#else -# define DEBUG_FPU_STATE() do { } while(0) -#endif -- cgit v1.2.3 From 278ed7c329b7e5a8dbef8da7efd42a5b73ca785d Mon Sep 17 00:00:00 2001 From: bellard Date: Fri, 20 Jun 2008 14:18:35 +0000 Subject: cmpxchg fixes git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4755 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-i386/op_helper.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c index beb568741..0b5fdc04c 100644 --- a/target-i386/op_helper.c +++ b/target-i386/op_helper.c @@ -1837,6 +1837,8 @@ void helper_cmpxchg8b(target_ulong a0) stq(a0, ((uint64_t)ECX << 32) | (uint32_t)EBX); eflags |= CC_Z; } else { + /* always do the store */ + stq(a0, d); EDX = (uint32_t)(d >> 32); EAX = (uint32_t)d; eflags &= ~CC_Z; @@ -1850,6 +1852,8 @@ void helper_cmpxchg16b(target_ulong a0) uint64_t d0, d1; int eflags; + if ((a0 & 0xf) != 0) + raise_exception(EXCP0D_GPF); eflags = cc_table[CC_OP].compute_all(); d0 = ldq(a0); d1 = ldq(a0 + 8); @@ -1858,6 +1862,9 @@ void helper_cmpxchg16b(target_ulong a0) stq(a0 + 8, ECX); eflags |= CC_Z; } else { + /* always do the store */ + stq(a0, d0); + stq(a0 + 8, d1); EDX = d1; EAX = d0; eflags &= ~CC_Z; -- cgit v1.2.3 From 92af06d216857de77bcadaf86cf9675cce9f1d3c Mon Sep 17 00:00:00 2001 From: ths Date: Fri, 20 Jun 2008 14:35:19 +0000 Subject: Convert vr54xx multiply instructions to TCG. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4756 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/helper.h | 15 ++++ target-mips/op.c | 223 ------------------------------------------------ target-mips/op_helper.c | 6 +- target-mips/translate.c | 28 +++--- 4 files changed, 32 insertions(+), 240 deletions(-) diff --git a/target-mips/helper.h b/target-mips/helper.h index cba9cd7eb..617e6d424 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -15,6 +15,21 @@ DEF_HELPER(void, do_dmult, (void)) DEF_HELPER(void, do_dmultu, (void)) #endif +DEF_HELPER(void, do_muls, (void)) +DEF_HELPER(void, do_mulsu, (void)) +DEF_HELPER(void, do_macc, (void)) +DEF_HELPER(void, do_maccu, (void)) +DEF_HELPER(void, do_msac, (void)) +DEF_HELPER(void, do_msacu, (void)) +DEF_HELPER(void, do_mulhi, (void)) +DEF_HELPER(void, do_mulhiu, (void)) +DEF_HELPER(void, do_mulshi, (void)) +DEF_HELPER(void, do_mulshiu, (void)) +DEF_HELPER(void, do_macchi, (void)) +DEF_HELPER(void, do_macchiu, (void)) +DEF_HELPER(void, do_msachi, (void)) +DEF_HELPER(void, do_msachiu, (void)) + /* CP0 helpers */ #ifndef CONFIG_USER_ONLY DEF_HELPER(void, do_mfc0_mvpcontrol, (void)) diff --git a/target-mips/op.c b/target-mips/op.c index 89ee9ce45..d617a076d 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -45,226 +45,3 @@ #include "op_mem.c" #undef MEMSUFFIX #endif - -/* 64 bits arithmetic */ -#if TARGET_LONG_BITS > HOST_LONG_BITS -void op_madd (void) -{ - CALL_FROM_TB0(do_madd); - FORCE_RET(); -} - -void op_maddu (void) -{ - CALL_FROM_TB0(do_maddu); - FORCE_RET(); -} - -void op_msub (void) -{ - CALL_FROM_TB0(do_msub); - FORCE_RET(); -} - -void op_msubu (void) -{ - CALL_FROM_TB0(do_msubu); - FORCE_RET(); -} - -/* Multiplication variants of the vr54xx. */ -void op_muls (void) -{ - CALL_FROM_TB0(do_muls); - FORCE_RET(); -} - -void op_mulsu (void) -{ - CALL_FROM_TB0(do_mulsu); - FORCE_RET(); -} - -void op_macc (void) -{ - CALL_FROM_TB0(do_macc); - FORCE_RET(); -} - -void op_macchi (void) -{ - CALL_FROM_TB0(do_macchi); - FORCE_RET(); -} - -void op_maccu (void) -{ - CALL_FROM_TB0(do_maccu); - FORCE_RET(); -} -void op_macchiu (void) -{ - CALL_FROM_TB0(do_macchiu); - FORCE_RET(); -} - -void op_msac (void) -{ - CALL_FROM_TB0(do_msac); - FORCE_RET(); -} - -void op_msachi (void) -{ - CALL_FROM_TB0(do_msachi); - FORCE_RET(); -} - -void op_msacu (void) -{ - CALL_FROM_TB0(do_msacu); - FORCE_RET(); -} - -void op_msachiu (void) -{ - CALL_FROM_TB0(do_msachiu); - FORCE_RET(); -} - -void op_mulhi (void) -{ - CALL_FROM_TB0(do_mulhi); - FORCE_RET(); -} - -void op_mulhiu (void) -{ - CALL_FROM_TB0(do_mulhiu); - FORCE_RET(); -} - -void op_mulshi (void) -{ - CALL_FROM_TB0(do_mulshi); - FORCE_RET(); -} - -void op_mulshiu (void) -{ - CALL_FROM_TB0(do_mulshiu); - FORCE_RET(); -} - -#else /* TARGET_LONG_BITS > HOST_LONG_BITS */ - -static always_inline uint64_t get_HILO (void) -{ - return ((uint64_t)env->HI[env->current_tc][0] << 32) | - ((uint64_t)(uint32_t)env->LO[env->current_tc][0]); -} - -static always_inline void set_HILO (uint64_t HILO) -{ - env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF); - env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); -} - -static always_inline void set_HIT0_LO (uint64_t HILO) -{ - env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF); - T0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); -} - -static always_inline void set_HI_LOT0 (uint64_t HILO) -{ - T0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF); - env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); -} - -/* Multiplication variants of the vr54xx. */ -void op_muls (void) -{ - set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); - FORCE_RET(); -} - -void op_mulsu (void) -{ - set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); - FORCE_RET(); -} - -void op_macc (void) -{ - set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); - FORCE_RET(); -} - -void op_macchi (void) -{ - set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); - FORCE_RET(); -} - -void op_maccu (void) -{ - set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); - FORCE_RET(); -} - -void op_macchiu (void) -{ - set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); - FORCE_RET(); -} - -void op_msac (void) -{ - set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); - FORCE_RET(); -} - -void op_msachi (void) -{ - set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); - FORCE_RET(); -} - -void op_msacu (void) -{ - set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); - FORCE_RET(); -} - -void op_msachiu (void) -{ - set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); - FORCE_RET(); -} - -void op_mulhi (void) -{ - set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); - FORCE_RET(); -} - -void op_mulhiu (void) -{ - set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); - FORCE_RET(); -} - -void op_mulshi (void) -{ - set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); - FORCE_RET(); -} - -void op_mulshiu (void) -{ - set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); - FORCE_RET(); -} - -#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 696295b90..16d3023a4 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -168,10 +168,9 @@ void do_dclz (void) #endif /* TARGET_MIPS64 */ /* 64 bits arithmetic for 32 bits hosts */ -#if TARGET_LONG_BITS > HOST_LONG_BITS static always_inline uint64_t get_HILO (void) { - return (env->HI[env->current_tc][0] << 32) | (uint32_t)env->LO[env->current_tc][0]; + return ((uint64_t)(env->HI[env->current_tc][0]) << 32) | (uint32_t)env->LO[env->current_tc][0]; } static always_inline void set_HILO (uint64_t HILO) @@ -192,6 +191,7 @@ static always_inline void set_HI_LOT0 (uint64_t HILO) env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); } +#if TARGET_LONG_BITS > HOST_LONG_BITS void do_madd (void) { int64_t tmp; @@ -223,6 +223,7 @@ void do_msubu (void) tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); set_HILO(get_HILO() - tmp); } +#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ /* Multiplication variants of the vr54xx. */ void do_muls (void) @@ -294,7 +295,6 @@ void do_mulshiu (void) { set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); } -#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ #ifdef TARGET_MIPS64 void do_dmult (void) diff --git a/target-mips/translate.c b/target-mips/translate.c index 56984147e..d441f2bdf 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -2204,59 +2204,59 @@ static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, switch (opc) { case OPC_VR54XX_MULS: - gen_op_muls(); + tcg_gen_helper_0_0(do_muls); opn = "muls"; break; case OPC_VR54XX_MULSU: - gen_op_mulsu(); + tcg_gen_helper_0_0(do_mulsu); opn = "mulsu"; break; case OPC_VR54XX_MACC: - gen_op_macc(); + tcg_gen_helper_0_0(do_macc); opn = "macc"; break; case OPC_VR54XX_MACCU: - gen_op_maccu(); + tcg_gen_helper_0_0(do_maccu); opn = "maccu"; break; case OPC_VR54XX_MSAC: - gen_op_msac(); + tcg_gen_helper_0_0(do_msac); opn = "msac"; break; case OPC_VR54XX_MSACU: - gen_op_msacu(); + tcg_gen_helper_0_0(do_msacu); opn = "msacu"; break; case OPC_VR54XX_MULHI: - gen_op_mulhi(); + tcg_gen_helper_0_0(do_mulhi); opn = "mulhi"; break; case OPC_VR54XX_MULHIU: - gen_op_mulhiu(); + tcg_gen_helper_0_0(do_mulhiu); opn = "mulhiu"; break; case OPC_VR54XX_MULSHI: - gen_op_mulshi(); + tcg_gen_helper_0_0(do_mulshi); opn = "mulshi"; break; case OPC_VR54XX_MULSHIU: - gen_op_mulshiu(); + tcg_gen_helper_0_0(do_mulshiu); opn = "mulshiu"; break; case OPC_VR54XX_MACCHI: - gen_op_macchi(); + tcg_gen_helper_0_0(do_macchi); opn = "macchi"; break; case OPC_VR54XX_MACCHIU: - gen_op_macchiu(); + tcg_gen_helper_0_0(do_macchiu); opn = "macchiu"; break; case OPC_VR54XX_MSACHI: - gen_op_msachi(); + tcg_gen_helper_0_0(do_msachi); opn = "msachi"; break; case OPC_VR54XX_MSACHIU: - gen_op_msachiu(); + tcg_gen_helper_0_0(do_msachiu); opn = "msachiu"; break; default: -- cgit v1.2.3 From 40f8e2fa4173c3338f53531c144e891ce03aabe5 Mon Sep 17 00:00:00 2001 From: bellard Date: Fri, 20 Jun 2008 14:50:55 +0000 Subject: added model_id and vendor cpu model options (initial patch by Dan Kenigsberg) - various cleanup git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4757 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-i386/helper.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/target-i386/helper.c b/target-i386/helper.c index 856d8965d..1625007e7 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -43,25 +43,25 @@ static void add_flagname_to_bitmaps(char *flagname, uint32_t *features, /* feature flags taken from "Intel Processor Identification and the CPUID * Instruction" and AMD's "CPUID Specification". In cases of disagreement * about feature names, the Linux name is used. */ - const char *feature_name[] = { + static const char *feature_name[] = { "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx", "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe", }; - const char *ext_feature_name[] = { + static const char *ext_feature_name[] = { "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est", "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL, NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; - const char *ext2_feature_name[] = { + static const char *ext2_feature_name[] = { "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mttr", "pge", "mca", "cmov", "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx", "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow", }; - const char *ext3_feature_name[] = { + static const char *ext3_feature_name[] = { "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse", "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -127,6 +127,7 @@ typedef struct x86_def_t { int stepping; uint32_t features, ext_features, ext2_features, ext3_features; uint32_t xlevel; + char model_id[48]; } x86_def_t; #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE) @@ -162,6 +163,7 @@ static x86_def_t x86_defs[] = { CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, .ext3_features = CPUID_EXT3_SVM, .xlevel = 0x8000000A, + .model_id = "QEMU Virtual CPU version " QEMU_VERSION, }, #endif { @@ -173,6 +175,7 @@ static x86_def_t x86_defs[] = { .features = PPRO_FEATURES, .ext_features = CPUID_EXT_SSE3, .xlevel = 0, + .model_id = "QEMU Virtual CPU version " QEMU_VERSION, }, { .name = "486", @@ -222,6 +225,8 @@ static x86_def_t x86_defs[] = { .features = PPRO_FEATURES | PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA, .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, .xlevel = 0x80000008, + /* XXX: put another string ? */ + .model_id = "QEMU Virtual CPU version " QEMU_VERSION, }, }; @@ -262,7 +267,6 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) family = strtol(val, &err, 10); if (!*val || *err || family < 0) { fprintf(stderr, "bad numerical value %s\n", val); - x86_cpu_def = 0; goto error; } x86_cpu_def->family = family; @@ -271,7 +275,6 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) model = strtol(val, &err, 10); if (!*val || *err || model < 0 || model > 0xf) { fprintf(stderr, "bad numerical value %s\n", val); - x86_cpu_def = 0; goto error; } x86_cpu_def->model = model; @@ -280,18 +283,31 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) stepping = strtol(val, &err, 10); if (!*val || *err || stepping < 0 || stepping > 0xf) { fprintf(stderr, "bad numerical value %s\n", val); - x86_cpu_def = 0; goto error; } x86_cpu_def->stepping = stepping; + } else if (!strcmp(featurestr, "vendor")) { + if (strlen(val) != 12) { + fprintf(stderr, "vendor string must be 12 chars long\n"); + goto error; + } + x86_cpu_def->vendor1 = 0; + x86_cpu_def->vendor2 = 0; + x86_cpu_def->vendor3 = 0; + for(i = 0; i < 4; i++) { + x86_cpu_def->vendor1 |= ((uint8_t)val[i ]) << (8 * i); + x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i); + x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i); + } + } else if (!strcmp(featurestr, "model_id")) { + pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id), + val); } else { fprintf(stderr, "unrecognized feature %s\n", featurestr); - x86_cpu_def = 0; goto error; } } else { fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr); - x86_cpu_def = 0; goto error; } featurestr = strtok(NULL, ","); @@ -344,14 +360,16 @@ static int cpu_x86_register (CPUX86State *env, const char *cpu_model) env->cpuid_xlevel = def->xlevel; env->cpuid_ext3_features = def->ext3_features; { - const char *model_id = "QEMU Virtual CPU version " QEMU_VERSION; + const char *model_id = def->model_id; int c, len, i; + if (!model_id) + model_id = ""; len = strlen(model_id); for(i = 0; i < 48; i++) { if (i >= len) c = '\0'; else - c = model_id[i]; + c = (uint8_t)model_id[i]; env->cpuid_model[i >> 2] |= c << (8 * (i & 3)); } } -- cgit v1.2.3 From 9fac3a3a7e7c7c6379179da8461894ad1249c87e Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Fri, 20 Jun 2008 15:06:42 +0000 Subject: Fix boot problem on i386 host introduced in r4690 git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4758 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-sparc/op_helper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index 7b28f72b8..f15cc224b 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -2622,12 +2622,12 @@ void helper_retry(void) void cpu_set_cwp(CPUState *env1, int new_cwp) { /* put the modified wrap registers at their proper location */ - if (env1->cwp == env->nwindows - 1) - memcpy32(env1->regbase, env1->regbase + env->nwindows * 16); + if (env1->cwp == env1->nwindows - 1) + memcpy32(env1->regbase, env1->regbase + env1->nwindows * 16); env1->cwp = new_cwp; /* put the wrap registers at their temporary location */ - if (new_cwp == env->nwindows - 1) - memcpy32(env1->regbase + env->nwindows * 16, env1->regbase); + if (new_cwp == env1->nwindows - 1) + memcpy32(env1->regbase + env1->nwindows * 16, env1->regbase); env1->regwptr = env1->regbase + (new_cwp * 16); } -- cgit v1.2.3 From c8c2227e913e5a41cc44746e22ad73e9880c06fb Mon Sep 17 00:00:00 2001 From: ths Date: Fri, 20 Jun 2008 15:12:14 +0000 Subject: Convert unaligned load/store to TCG. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4759 c046a42c-6fe2-441c-8c8c-71466251a162 --- configure | 6 - target-mips/helper.h | 11 ++ target-mips/op.c | 26 ---- target-mips/op_helper.c | 337 ++++++++++++++++++++++++++++++++++++++++++++++++ target-mips/translate.c | 55 +++----- 5 files changed, 364 insertions(+), 71 deletions(-) diff --git a/configure b/configure index 64b7b4283..fb704bae4 100755 --- a/configure +++ b/configure @@ -1280,28 +1280,22 @@ case "$target_cpu" in ;; mips|mipsel) echo "TARGET_ARCH=mips" >> $config_mak - echo "CONFIG_DYNGEN_OP=yes" >> $config_mak echo "#define TARGET_ARCH \"mips\"" >> $config_h echo "#define TARGET_MIPS 1" >> $config_h echo "#define TARGET_ABI_MIPSO32 1" >> $config_h - echo "#define CONFIG_DYNGEN_OP 1" >> $config_h ;; mipsn32|mipsn32el) echo "TARGET_ARCH=mipsn32" >> $config_mak - echo "CONFIG_DYNGEN_OP=yes" >> $config_mak echo "#define TARGET_ARCH \"mipsn32\"" >> $config_h echo "#define TARGET_MIPS 1" >> $config_h echo "#define TARGET_ABI_MIPSN32 1" >> $config_h - echo "#define CONFIG_DYNGEN_OP 1" >> $config_h ;; mips64|mips64el) echo "TARGET_ARCH=mips64" >> $config_mak - echo "CONFIG_DYNGEN_OP=yes" >> $config_mak echo "#define TARGET_ARCH \"mips64\"" >> $config_h echo "#define TARGET_MIPS 1" >> $config_h echo "#define TARGET_MIPS64 1" >> $config_h echo "#define TARGET_ABI_MIPSN64 1" >> $config_h - echo "#define CONFIG_DYNGEN_OP 1" >> $config_h ;; ppc) echo "TARGET_ARCH=ppc" >> $config_mak diff --git a/target-mips/helper.h b/target-mips/helper.h index 617e6d424..1638d29b3 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -6,6 +6,17 @@ DEF_HELPER(void, do_raise_exception_err, (int excp, int err)) DEF_HELPER(void, do_raise_exception, (int excp)) DEF_HELPER(void, do_interrupt_restart, (void)) +#ifdef TARGET_MIPS64 +DEF_HELPER(void, do_ldl, (int mem_idx)) +DEF_HELPER(void, do_ldr, (int mem_idx)) +DEF_HELPER(void, do_sdl, (int mem_idx)) +DEF_HELPER(void, do_sdr, (int mem_idx)) +#endif +DEF_HELPER(void, do_lwl, (int mem_idx)) +DEF_HELPER(void, do_lwr, (int mem_idx)) +DEF_HELPER(void, do_swl, (int mem_idx)) +DEF_HELPER(void, do_swr, (int mem_idx)) + DEF_HELPER(void, do_clo, (void)) DEF_HELPER(void, do_clz, (void)) #ifdef TARGET_MIPS64 diff --git a/target-mips/op.c b/target-mips/op.c index d617a076d..cbe4f413b 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -19,29 +19,3 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "config.h" -#include "exec.h" -#include "host-utils.h" - -#ifndef CALL_FROM_TB0 -#define CALL_FROM_TB0(func) func() -#endif - -/* Load and store */ -#define MEMSUFFIX _raw -#include "op_mem.c" -#undef MEMSUFFIX -#if !defined(CONFIG_USER_ONLY) -#define MEMSUFFIX _user -#include "op_mem.c" -#undef MEMSUFFIX - -#define MEMSUFFIX _super -#include "op_mem.c" -#undef MEMSUFFIX - -#define MEMSUFFIX _kernel -#include "op_mem.c" -#undef MEMSUFFIX -#endif diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 16d3023a4..602116a8b 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -308,6 +308,343 @@ void do_dmultu (void) } #endif +#ifdef TARGET_WORDS_BIGENDIAN +#define GET_LMASK(v) ((v) & 3) +#define GET_OFFSET(addr, offset) (addr + (offset)) +#else +#define GET_LMASK(v) (((v) & 3) ^ 3) +#define GET_OFFSET(addr, offset) (addr - (offset)) +#endif + +void do_lwl(int mem_idx) +{ + target_ulong tmp; + +#ifdef CONFIG_USER_ONLY +#define ldfun ldub_raw +#else + int (*ldfun)(target_ulong); + + switch (mem_idx) + { + case 0: ldfun = ldub_kernel; break; + case 1: ldfun = ldub_super; break; + default: + case 2: ldfun = ldub_user; break; + } +#endif + tmp = ldfun(T0); + T1 = (T1 & 0x00FFFFFF) | (tmp << 24); + + if (GET_LMASK(T0) <= 2) { + tmp = ldfun(GET_OFFSET(T0, 1)); + T1 = (T1 & 0xFF00FFFF) | (tmp << 16); + } + + if (GET_LMASK(T0) <= 1) { + tmp = ldfun(GET_OFFSET(T0, 2)); + T1 = (T1 & 0xFFFF00FF) | (tmp << 8); + } + + if (GET_LMASK(T0) == 0) { + tmp = ldfun(GET_OFFSET(T0, 3)); + T1 = (T1 & 0xFFFFFF00) | tmp; + } + T1 = (int32_t)T1; +} + +void do_lwr(int mem_idx) +{ + target_ulong tmp; + +#ifdef CONFIG_USER_ONLY +#define ldfun ldub_raw +#else + int (*ldfun)(target_ulong); + + switch (mem_idx) + { + case 0: ldfun = ldub_kernel; break; + case 1: ldfun = ldub_super; break; + default: + case 2: ldfun = ldub_user; break; + } +#endif + tmp = ldfun(T0); + T1 = (T1 & 0xFFFFFF00) | tmp; + + if (GET_LMASK(T0) >= 1) { + tmp = ldfun(GET_OFFSET(T0, -1)); + T1 = (T1 & 0xFFFF00FF) | (tmp << 8); + } + + if (GET_LMASK(T0) >= 2) { + tmp = ldfun(GET_OFFSET(T0, -2)); + T1 = (T1 & 0xFF00FFFF) | (tmp << 16); + } + + if (GET_LMASK(T0) == 3) { + tmp = ldfun(GET_OFFSET(T0, -3)); + T1 = (T1 & 0x00FFFFFF) | (tmp << 24); + } + T1 = (int32_t)T1; +} + +void do_swl(int mem_idx) +{ +#ifdef CONFIG_USER_ONLY +#define stfun stb_raw +#else + void (*stfun)(target_ulong, int); + + switch (mem_idx) + { + case 0: stfun = stb_kernel; break; + case 1: stfun = stb_super; break; + default: + case 2: stfun = stb_user; break; + } +#endif + stfun(T0, (uint8_t)(T1 >> 24)); + + if (GET_LMASK(T0) <= 2) + stfun(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 16)); + + if (GET_LMASK(T0) <= 1) + stfun(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 8)); + + if (GET_LMASK(T0) == 0) + stfun(GET_OFFSET(T0, 3), (uint8_t)T1); +} + +void do_swr(int mem_idx) +{ +#ifdef CONFIG_USER_ONLY +#define stfun stb_raw +#else + void (*stfun)(target_ulong, int); + + switch (mem_idx) + { + case 0: stfun = stb_kernel; break; + case 1: stfun = stb_super; break; + default: + case 2: stfun = stb_user; break; + } +#endif + stfun(T0, (uint8_t)T1); + + if (GET_LMASK(T0) >= 1) + stfun(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8)); + + if (GET_LMASK(T0) >= 2) + stfun(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16)); + + if (GET_LMASK(T0) == 3) + stfun(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24)); +} + +#if defined(TARGET_MIPS64) +/* "half" load and stores. We must do the memory access inline, + or fault handling won't work. */ + +#ifdef TARGET_WORDS_BIGENDIAN +#define GET_LMASK64(v) ((v) & 7) +#else +#define GET_LMASK64(v) (((v) & 7) ^ 7) +#endif + +void do_ldl(int mem_idx) +{ + uint64_t tmp; + +#ifdef CONFIG_USER_ONLY +#define ldfun ldub_raw +#else + target_ulong (*ldfun)(target_ulong); + + switch (mem_idx) + { + case 0: ldfun = ldub_kernel; break; + case 1: ldfun = ldub_super; break; + default: + case 2: ldfun = ldub_user; break; + } +#endif + tmp = ldfun(T0); + T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); + + if (GET_LMASK64(T0) <= 6) { + tmp = ldfun(GET_OFFSET(T0, 1)); + T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); + } + + if (GET_LMASK64(T0) <= 5) { + tmp = ldfun(GET_OFFSET(T0, 2)); + T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); + } + + if (GET_LMASK64(T0) <= 4) { + tmp = ldfun(GET_OFFSET(T0, 3)); + T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); + } + + if (GET_LMASK64(T0) <= 3) { + tmp = ldfun(GET_OFFSET(T0, 4)); + T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); + } + + if (GET_LMASK64(T0) <= 2) { + tmp = ldfun(GET_OFFSET(T0, 5)); + T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); + } + + if (GET_LMASK64(T0) <= 1) { + tmp = ldfun(GET_OFFSET(T0, 6)); + T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); + } + + if (GET_LMASK64(T0) == 0) { + tmp = ldfun(GET_OFFSET(T0, 7)); + T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; + } +} + +void do_ldr(int mem_idx) +{ + uint64_t tmp; + +#ifdef CONFIG_USER_ONLY +#define ldfun ldub_raw +#else + target_ulong (*ldfun)(target_ulong); + + switch (mem_idx) + { + case 0: ldfun = ldub_kernel; break; + case 1: ldfun = ldub_super; break; + default: + case 2: ldfun = ldub_user; break; + } +#endif + tmp = ldfun(T0); + T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; + + if (GET_LMASK64(T0) >= 1) { + tmp = ldfun(GET_OFFSET(T0, -1)); + T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); + } + + if (GET_LMASK64(T0) >= 2) { + tmp = ldfun(GET_OFFSET(T0, -2)); + T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); + } + + if (GET_LMASK64(T0) >= 3) { + tmp = ldfun(GET_OFFSET(T0, -3)); + T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); + } + + if (GET_LMASK64(T0) >= 4) { + tmp = ldfun(GET_OFFSET(T0, -4)); + T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); + } + + if (GET_LMASK64(T0) >= 5) { + tmp = ldfun(GET_OFFSET(T0, -5)); + T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); + } + + if (GET_LMASK64(T0) >= 6) { + tmp = ldfun(GET_OFFSET(T0, -6)); + T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); + } + + if (GET_LMASK64(T0) == 7) { + tmp = ldfun(GET_OFFSET(T0, -7)); + T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); + } +} + +void do_sdl(int mem_idx) +{ +#ifdef CONFIG_USER_ONLY +#define stfun stb_raw +#else + void (*stfun)(target_ulong, int); + + switch (mem_idx) + { + case 0: stfun = stb_kernel; break; + case 1: stfun = stb_super; break; + default: + case 2: stfun = stb_user; break; + } +#endif + stfun(T0, (uint8_t)(T1 >> 56)); + + if (GET_LMASK64(T0) <= 6) + stfun(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 48)); + + if (GET_LMASK64(T0) <= 5) + stfun(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 40)); + + if (GET_LMASK64(T0) <= 4) + stfun(GET_OFFSET(T0, 3), (uint8_t)(T1 >> 32)); + + if (GET_LMASK64(T0) <= 3) + stfun(GET_OFFSET(T0, 4), (uint8_t)(T1 >> 24)); + + if (GET_LMASK64(T0) <= 2) + stfun(GET_OFFSET(T0, 5), (uint8_t)(T1 >> 16)); + + if (GET_LMASK64(T0) <= 1) + stfun(GET_OFFSET(T0, 6), (uint8_t)(T1 >> 8)); + + if (GET_LMASK64(T0) <= 0) + stfun(GET_OFFSET(T0, 7), (uint8_t)T1); +} + +void do_sdr(int mem_idx) +{ +#ifdef CONFIG_USER_ONLY +#define stfun stb_raw +#else + void (*stfun)(target_ulong, int); + + switch (mem_idx) + { + case 0: stfun = stb_kernel; break; + case 1: stfun = stb_super; break; + default: + case 2: stfun = stb_user; break; + } +#endif + stfun(T0, (uint8_t)T1); + + if (GET_LMASK64(T0) >= 1) + stfun(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8)); + + if (GET_LMASK64(T0) >= 2) + stfun(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16)); + + if (GET_LMASK64(T0) >= 3) + stfun(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24)); + + if (GET_LMASK64(T0) >= 4) + stfun(GET_OFFSET(T0, -4), (uint8_t)(T1 >> 32)); + + if (GET_LMASK64(T0) >= 5) + stfun(GET_OFFSET(T0, -5), (uint8_t)(T1 >> 40)); + + if (GET_LMASK64(T0) >= 6) + stfun(GET_OFFSET(T0, -6), (uint8_t)(T1 >> 48)); + + if (GET_LMASK64(T0) == 7) + stfun(GET_OFFSET(T0, -7), (uint8_t)(T1 >> 56)); +} +#endif /* TARGET_MIPS64 */ + #ifdef CONFIG_USER_ONLY void do_mfc0_random (void) { diff --git a/target-mips/translate.c b/target-mips/translate.c index d441f2bdf..9fdf836a0 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -945,37 +945,6 @@ static always_inline void check_mips_64(DisasContext *ctx) } /* load/store instructions. */ -#if defined(CONFIG_USER_ONLY) -#define op_ldst(name) gen_op_##name##_raw() -#define OP_LD_TABLE(width) -#define OP_ST_TABLE(width) -#else -#define op_ldst(name) (*gen_op_##name[ctx->mem_idx])() -#define OP_LD_TABLE(width) \ -static GenOpFunc *gen_op_l##width[] = { \ - &gen_op_l##width##_kernel, \ - &gen_op_l##width##_super, \ - &gen_op_l##width##_user, \ -} -#define OP_ST_TABLE(width) \ -static GenOpFunc *gen_op_s##width[] = { \ - &gen_op_s##width##_kernel, \ - &gen_op_s##width##_super, \ - &gen_op_s##width##_user, \ -} -#endif - -#if defined(TARGET_MIPS64) -OP_LD_TABLE(dl); -OP_LD_TABLE(dr); -OP_ST_TABLE(dl); -OP_ST_TABLE(dr); -#endif -OP_LD_TABLE(wl); -OP_LD_TABLE(wr); -OP_ST_TABLE(wl); -OP_ST_TABLE(wr); - #define OP_LD(insn,fname) \ void inline op_ldst_##insn(DisasContext *ctx) \ { \ @@ -1094,25 +1063,29 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, opn = "scd"; break; case OPC_LDL: + save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - op_ldst(ldl); + tcg_gen_helper_0_1i(do_ldl, ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "ldl"; break; case OPC_SDL: + save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - op_ldst(sdl); + tcg_gen_helper_0_1i(do_sdl, ctx->mem_idx); opn = "sdl"; break; case OPC_LDR: + save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - op_ldst(ldr); + tcg_gen_helper_0_1i(do_ldr, ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "ldr"; break; case OPC_SDR: + save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - op_ldst(sdr); + tcg_gen_helper_0_1i(do_sdr, ctx->mem_idx); opn = "sdr"; break; #endif @@ -1157,25 +1130,29 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, opn = "lbu"; break; case OPC_LWL: + save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - op_ldst(lwl); + tcg_gen_helper_0_1i(do_lwl, ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "lwl"; break; case OPC_SWL: + save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - op_ldst(swl); + tcg_gen_helper_0_1i(do_swl, ctx->mem_idx); opn = "swr"; break; case OPC_LWR: + save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - op_ldst(lwr); + tcg_gen_helper_0_1i(do_lwr, ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "lwr"; break; case OPC_SWR: + save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - op_ldst(swr); + tcg_gen_helper_0_1i(do_swr, ctx->mem_idx); opn = "swr"; break; case OPC_LL: -- cgit v1.2.3 From 3fafcb48f9bfa2ff5cf48d42b63a954406e280ec Mon Sep 17 00:00:00 2001 From: ths Date: Fri, 20 Jun 2008 15:20:35 +0000 Subject: Delete obsolete prototypes. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4760 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/exec.h | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/target-mips/exec.h b/target-mips/exec.h index 782d7f8cb..ec1b0f4da 100644 --- a/target-mips/exec.h +++ b/target-mips/exec.h @@ -48,27 +48,6 @@ register target_ulong T1 asm(AREG2); #include "softmmu_exec.h" #endif /* !defined(CONFIG_USER_ONLY) */ -#if TARGET_LONG_BITS > HOST_LONG_BITS -void do_madd (void); -void do_maddu (void); -void do_msub (void); -void do_msubu (void); -void do_muls (void); -void do_mulsu (void); -void do_macc (void); -void do_macchi (void); -void do_maccu (void); -void do_macchiu (void); -void do_msac (void); -void do_msachi (void); -void do_msacu (void); -void do_msachiu (void); -void do_mulhi (void); -void do_mulhiu (void); -void do_mulshi (void); -void do_mulshiu (void); -#endif - void do_mtc0_status_debug(uint32_t old, uint32_t val); void do_mtc0_status_irqraise_debug(void); void dump_fpu(CPUState *env); -- cgit v1.2.3 From b6a8c26b60b864ca33136a740befd84532b8030f Mon Sep 17 00:00:00 2001 From: ths Date: Fri, 20 Jun 2008 15:21:28 +0000 Subject: Delete obsolete file. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4761 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/op_mem.c | 269 --------------------------------------------------- 1 file changed, 269 deletions(-) delete mode 100644 target-mips/op_mem.c diff --git a/target-mips/op_mem.c b/target-mips/op_mem.c deleted file mode 100644 index 31f58a814..000000000 --- a/target-mips/op_mem.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * MIPS emulation memory micro-operations for qemu. - * - * Copyright (c) 2004-2005 Jocelyn Mayer - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* "half" load and stores. We must do the memory access inline, - or fault handling won't work. */ - -#ifdef TARGET_WORDS_BIGENDIAN -#define GET_LMASK(v) ((v) & 3) -#define GET_OFFSET(addr, offset) (addr + (offset)) -#else -#define GET_LMASK(v) (((v) & 3) ^ 3) -#define GET_OFFSET(addr, offset) (addr - (offset)) -#endif - -void glue(op_lwl, MEMSUFFIX) (void) -{ - target_ulong tmp; - - tmp = glue(ldub, MEMSUFFIX)(T0); - T1 = (T1 & 0x00FFFFFF) | (tmp << 24); - - if (GET_LMASK(T0) <= 2) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 1)); - T1 = (T1 & 0xFF00FFFF) | (tmp << 16); - } - - if (GET_LMASK(T0) <= 1) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 2)); - T1 = (T1 & 0xFFFF00FF) | (tmp << 8); - } - - if (GET_LMASK(T0) == 0) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 3)); - T1 = (T1 & 0xFFFFFF00) | tmp; - } - T1 = (int32_t)T1; - FORCE_RET(); -} - -void glue(op_lwr, MEMSUFFIX) (void) -{ - target_ulong tmp; - - tmp = glue(ldub, MEMSUFFIX)(T0); - T1 = (T1 & 0xFFFFFF00) | tmp; - - if (GET_LMASK(T0) >= 1) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -1)); - T1 = (T1 & 0xFFFF00FF) | (tmp << 8); - } - - if (GET_LMASK(T0) >= 2) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -2)); - T1 = (T1 & 0xFF00FFFF) | (tmp << 16); - } - - if (GET_LMASK(T0) == 3) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -3)); - T1 = (T1 & 0x00FFFFFF) | (tmp << 24); - } - T1 = (int32_t)T1; - FORCE_RET(); -} - -void glue(op_swl, MEMSUFFIX) (void) -{ - glue(stb, MEMSUFFIX)(T0, (uint8_t)(T1 >> 24)); - - if (GET_LMASK(T0) <= 2) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 16)); - - if (GET_LMASK(T0) <= 1) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 8)); - - if (GET_LMASK(T0) == 0) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 3), (uint8_t)T1); - - FORCE_RET(); -} - -void glue(op_swr, MEMSUFFIX) (void) -{ - glue(stb, MEMSUFFIX)(T0, (uint8_t)T1); - - if (GET_LMASK(T0) >= 1) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8)); - - if (GET_LMASK(T0) >= 2) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16)); - - if (GET_LMASK(T0) == 3) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24)); - - FORCE_RET(); -} - -#if defined(TARGET_MIPS64) -/* "half" load and stores. We must do the memory access inline, - or fault handling won't work. */ - -#ifdef TARGET_WORDS_BIGENDIAN -#define GET_LMASK64(v) ((v) & 7) -#else -#define GET_LMASK64(v) (((v) & 7) ^ 7) -#endif - -void glue(op_ldl, MEMSUFFIX) (void) -{ - uint64_t tmp; - - tmp = glue(ldub, MEMSUFFIX)(T0); - T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); - - if (GET_LMASK64(T0) <= 6) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 1)); - T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); - } - - if (GET_LMASK64(T0) <= 5) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 2)); - T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); - } - - if (GET_LMASK64(T0) <= 4) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 3)); - T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); - } - - if (GET_LMASK64(T0) <= 3) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 4)); - T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); - } - - if (GET_LMASK64(T0) <= 2) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 5)); - T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); - } - - if (GET_LMASK64(T0) <= 1) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 6)); - T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); - } - - if (GET_LMASK64(T0) == 0) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 7)); - T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; - } - - FORCE_RET(); -} - -void glue(op_ldr, MEMSUFFIX) (void) -{ - uint64_t tmp; - - tmp = glue(ldub, MEMSUFFIX)(T0); - T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; - - if (GET_LMASK64(T0) >= 1) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -1)); - T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); - } - - if (GET_LMASK64(T0) >= 2) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -2)); - T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); - } - - if (GET_LMASK64(T0) >= 3) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -3)); - T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); - } - - if (GET_LMASK64(T0) >= 4) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -4)); - T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); - } - - if (GET_LMASK64(T0) >= 5) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -5)); - T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); - } - - if (GET_LMASK64(T0) >= 6) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -6)); - T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); - } - - if (GET_LMASK64(T0) == 7) { - tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -7)); - T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); - } - - FORCE_RET(); -} - -void glue(op_sdl, MEMSUFFIX) (void) -{ - glue(stb, MEMSUFFIX)(T0, (uint8_t)(T1 >> 56)); - - if (GET_LMASK64(T0) <= 6) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 48)); - - if (GET_LMASK64(T0) <= 5) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 40)); - - if (GET_LMASK64(T0) <= 4) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 3), (uint8_t)(T1 >> 32)); - - if (GET_LMASK64(T0) <= 3) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 4), (uint8_t)(T1 >> 24)); - - if (GET_LMASK64(T0) <= 2) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 5), (uint8_t)(T1 >> 16)); - - if (GET_LMASK64(T0) <= 1) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 6), (uint8_t)(T1 >> 8)); - - if (GET_LMASK64(T0) <= 0) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 7), (uint8_t)T1); - - FORCE_RET(); -} - -void glue(op_sdr, MEMSUFFIX) (void) -{ - glue(stb, MEMSUFFIX)(T0, (uint8_t)T1); - - if (GET_LMASK64(T0) >= 1) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8)); - - if (GET_LMASK64(T0) >= 2) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16)); - - if (GET_LMASK64(T0) >= 3) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24)); - - if (GET_LMASK64(T0) >= 4) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -4), (uint8_t)(T1 >> 32)); - - if (GET_LMASK64(T0) >= 5) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -5), (uint8_t)(T1 >> 40)); - - if (GET_LMASK64(T0) >= 6) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -6), (uint8_t)(T1 >> 48)); - - if (GET_LMASK64(T0) == 7) - glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -7), (uint8_t)(T1 >> 56)); - - FORCE_RET(); -} -#endif /* TARGET_MIPS64 */ -- cgit v1.2.3 From 3f05d3dc14a76fb62a1eda5c53dde0074ce1d1e1 Mon Sep 17 00:00:00 2001 From: ths Date: Fri, 20 Jun 2008 15:29:38 +0000 Subject: Delete obsolete file. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4762 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/op.c | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 target-mips/op.c diff --git a/target-mips/op.c b/target-mips/op.c deleted file mode 100644 index cbe4f413b..000000000 --- a/target-mips/op.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * MIPS emulation micro-operations for qemu. - * - * Copyright (c) 2004-2005 Jocelyn Mayer - * Copyright (c) 2006 Marius Groeger (FPU operations) - * Copyright (c) 2007 Thiemo Seufer (64-bit FPU support) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -- cgit v1.2.3 From 3b4366de399b384d715c631d32f024c2bde3a38a Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Fri, 20 Jun 2008 16:25:06 +0000 Subject: Add an opaque parameter to boot_set API, move function to monitor.c git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4763 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/hw.h | 5 ++--- hw/pc.c | 8 ++++---- monitor.c | 12 +++++++++++- vl.c | 8 -------- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index 2a461026e..b84ace07f 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -94,9 +94,8 @@ void qemu_register_reset(QEMUResetHandler *func, void *opaque); /* handler to set the boot_device for a specific type of QEMUMachine */ /* return 0 if success */ -typedef int QEMUBootSetHandler(const char *boot_device); -extern QEMUBootSetHandler *qemu_boot_set_handler; -void qemu_register_boot_set(QEMUBootSetHandler *func); +typedef int QEMUBootSetHandler(void *opaque, const char *boot_device); +void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque); /* These should really be in isa.h, but are here to make pc.h happy. */ typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data); diff --git a/hw/pc.c b/hw/pc.c index 3edeb502c..4c5e1c343 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -192,10 +192,10 @@ static int boot_device2nibble(char boot_device) /* copy/pasted from cmos_init, should be made a general function and used there as well */ -int pc_boot_set(const char *boot_device) +static int pc_boot_set(void *opaque, const char *boot_device) { #define PC_MAX_BOOT_DEVICES 3 - RTCState *s = rtc_state; + RTCState *s = (RTCState *)opaque; int nbds, bds[3] = { 0, }; int i; @@ -741,8 +741,6 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, below_4g_mem_size = ram_size; } - qemu_register_boot_set(pc_boot_set); - linux_boot = (kernel_filename != NULL); /* init CPUs */ @@ -917,6 +915,8 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size, rtc_state = rtc_init(0x70, i8259[8]); + qemu_register_boot_set(pc_boot_set, rtc_state); + register_ioport_read(0x92, 1, 1, ioport92_read, NULL); register_ioport_write(0x92, 1, 1, ioport92_write, NULL); diff --git a/monitor.c b/monitor.c index 9f1013ecf..815489867 100644 --- a/monitor.c +++ b/monitor.c @@ -1044,12 +1044,22 @@ static void do_ioport_read(int count, int format, int size, int addr, int has_in suffix, addr, size * 2, val); } +/* boot_set handler */ +static QEMUBootSetHandler *qemu_boot_set_handler = NULL; +static void *boot_opaque; + +void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque) +{ + qemu_boot_set_handler = func; + boot_opaque = opaque; +} + static void do_boot_set(const char *bootdevice) { int res; if (qemu_boot_set_handler) { - res = qemu_boot_set_handler(bootdevice); + res = qemu_boot_set_handler(boot_opaque, bootdevice); if (res == 0) term_printf("boot device list now set to %s\n", bootdevice); else diff --git a/vl.c b/vl.c index 37301b02f..908aa3922 100644 --- a/vl.c +++ b/vl.c @@ -6908,14 +6908,6 @@ void qemu_system_powerdown_request(void) cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); } -/* boot_set handler */ -QEMUBootSetHandler *qemu_boot_set_handler = NULL; - -void qemu_register_boot_set(QEMUBootSetHandler *func) -{ - qemu_boot_set_handler = func; -} - void main_loop_wait(int timeout) { IOHandlerRecord *ioh; -- cgit v1.2.3 From 81864572e67501d4385d23ba87163b17c3426eb8 Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Fri, 20 Jun 2008 16:25:56 +0000 Subject: Add support for boot_set command git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4764 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/sun4m.c | 22 ++++++++++++++++++++++ hw/sun4u.c | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/hw/sun4m.c b/hw/sun4m.c index 09c26270d..4bfc333a1 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -149,6 +149,26 @@ void DMA_register_channel (int nchan, { } +static int nvram_boot_set(void *opaque, const char *boot_device) +{ + unsigned int i; + uint8_t image[sizeof(ohwcfg_v3_t)]; + ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ + m48t59_t *nvram = (m48t59_t *)opaque; + + for (i = 0; i < sizeof(image); i++) + image[i] = m48t59_read(nvram, i) & 0xff; + + strcpy(header->boot_devices, boot_device); + header->nboot_devices = strlen(boot_device) & 0xff; + header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8)); + + for (i = 0; i < sizeof(image); i++) + m48t59_write(nvram, i, image[i]); + + return 0; +} + extern int nographic; static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, @@ -230,6 +250,8 @@ static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, for (i = 0; i < sizeof(image); i++) m48t59_write(nvram, i, image[i]); + + qemu_register_boot_set(nvram_boot_set, nvram); } static void *slavio_intctl; diff --git a/hw/sun4u.c b/hw/sun4u.c index 6e1dee956..49f049452 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -68,6 +68,26 @@ void DMA_register_channel (int nchan, { } +static int nvram_boot_set(void *opaque, const char *boot_device) +{ + unsigned int i; + uint8_t image[sizeof(ohwcfg_v3_t)]; + ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ + m48t59_t *nvram = (m48t59_t *)opaque; + + for (i = 0; i < sizeof(image); i++) + image[i] = m48t59_read(nvram, i) & 0xff; + + strcpy(header->boot_devices, boot_device); + header->nboot_devices = strlen(boot_device) & 0xff; + header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8)); + + for (i = 0; i < sizeof(image); i++) + m48t59_write(nvram, i, image[i]); + + return 0; +} + extern int nographic; static int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, @@ -155,6 +175,8 @@ static int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, for (i = 0; i < sizeof(image); i++) m48t59_write(nvram, i, image[i]); + qemu_register_boot_set(nvram_boot_set, nvram); + return 0; } -- cgit v1.2.3 From fd07bef4b49cc69ef1905b0713a6bf23026cc536 Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Fri, 20 Jun 2008 17:42:20 +0000 Subject: Update TODO git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4765 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-sparc/TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-sparc/TODO b/target-sparc/TODO index 0e998e276..30c17c44d 100644 --- a/target-sparc/TODO +++ b/target-sparc/TODO @@ -54,7 +54,7 @@ Sun4m: - Hardware devices do not match real boards - Floppy does not work - Missing keys, sendkey support for all keys - - CS4231 (DMA, make sound, make available for PC) + - CS4231: merge with cs4231a, add DMA - Add cg6, bwtwo - Arbitrary resolution support - PCI for MicroSparc-IIe -- cgit v1.2.3 From 279a65442eb53e74083b31fa629a10c0ed78e3f0 Mon Sep 17 00:00:00 2001 From: malc Date: Sat, 21 Jun 2008 17:14:50 +0000 Subject: Add calls to pci_device_save/load git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4766 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/ac97.c | 11 +++++++++-- hw/es1370.c | 10 ++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/hw/ac97.c b/hw/ac97.c index 83b438308..55c65df4f 100644 --- a/hw/ac97.c +++ b/hw/ac97.c @@ -1190,6 +1190,8 @@ static void ac97_save (QEMUFile *f, void *opaque) uint8_t active[LAST_INDEX]; AC97LinkState *s = opaque; + pci_device_save (s->pci_dev, f); + qemu_put_be32s (f, &s->glob_cnt); qemu_put_be32s (f, &s->glob_sta); qemu_put_be32s (f, &s->cas); @@ -1217,13 +1219,18 @@ static void ac97_save (QEMUFile *f, void *opaque) static int ac97_load (QEMUFile *f, void *opaque, int version_id) { + int ret; size_t i; uint8_t active[LAST_INDEX]; AC97LinkState *s = opaque; - if (version_id != 1) + if (version_id != 2) return -EINVAL; + ret = pci_device_load (s->pci_dev, f); + if (ret) + return ret; + qemu_get_be32s (f, &s->glob_cnt); qemu_get_be32s (f, &s->glob_sta); qemu_get_be32s (f, &s->cas); @@ -1370,7 +1377,7 @@ int ac97_init (PCIBus *bus, AudioState *audio) pci_register_io_region (&d->dev, 0, 256 * 4, PCI_ADDRESS_SPACE_IO, ac97_map); pci_register_io_region (&d->dev, 1, 64 * 4, PCI_ADDRESS_SPACE_IO, ac97_map); - register_savevm ("ac97", 0, 1, ac97_save, ac97_load, s); + register_savevm ("ac97", 0, 2, ac97_save, ac97_load, s); qemu_register_reset (ac97_on_reset, s); AUD_register_card (audio, "ac97", &s->card); ac97_on_reset (s); diff --git a/hw/es1370.c b/hw/es1370.c index 754f621a1..a2a017bd5 100644 --- a/hw/es1370.c +++ b/hw/es1370.c @@ -936,6 +936,7 @@ static void es1370_save (QEMUFile *f, void *opaque) ES1370State *s = opaque; size_t i; + pci_device_save (s->pci_dev, f); for (i = 0; i < NB_CHANNELS; ++i) { struct chan *d = &s->chan[i]; qemu_put_be32s (f, &d->shift); @@ -953,13 +954,18 @@ static void es1370_save (QEMUFile *f, void *opaque) static int es1370_load (QEMUFile *f, void *opaque, int version_id) { + int ret; uint32_t ctl, sctl; ES1370State *s = opaque; size_t i; - if (version_id != 1) + if (version_id != 2) return -EINVAL; + ret = pci_device_load (s->pci_dev, f); + if (ret) + return ret; + for (i = 0; i < NB_CHANNELS; ++i) { struct chan *d = &s->chan[i]; qemu_get_be32s (f, &d->shift); @@ -1056,7 +1062,7 @@ int es1370_init (PCIBus *bus, AudioState *audio) s->pci_dev = &d->dev; pci_register_io_region (&d->dev, 0, 256, PCI_ADDRESS_SPACE_IO, es1370_map); - register_savevm ("es1370", 0, 1, es1370_save, es1370_load, s); + register_savevm ("es1370", 0, 2, es1370_save, es1370_load, s); qemu_register_reset (es1370_on_reset, s); AUD_register_card (audio, "es1370", &s->card); -- cgit v1.2.3 From 5b5ef0db745c70d9ba967ea133542be3fc927180 Mon Sep 17 00:00:00 2001 From: malc Date: Sat, 21 Jun 2008 17:14:54 +0000 Subject: Add VM save/load support git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4767 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/gus.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/hw/gus.c b/hw/gus.c index c7a88463f..d39d91872 100644 --- a/hw/gus.c +++ b/hw/gus.c @@ -220,6 +220,40 @@ int GUS_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len) return dma_len; } +static void GUS_save (QEMUFile *f, void *opaque) +{ + int32_t val; + GUSState *s = opaque; + + val = s->freq; qemu_put_be32s (f, &val); + val = s->pos; qemu_put_be32s (f, &val); + val = s->left; qemu_put_be32s (f, &val); + val = s->shift; qemu_put_be32s (f, &val); + val = s->irqs; qemu_put_be32s (f, &val); + val = s->samples; qemu_put_be32s (f, &val); + qemu_put_be64s (f, &s->last_ticks); + qemu_put_buffer (f, s->himem, sizeof (s->himem)); +} + +static int GUS_load (QEMUFile *f, void *opaque, int version_id) +{ + int32_t val; + GUSState *s = opaque; + + if (version_id != 1) + return -EINVAL; + + qemu_get_be32s (f, &val); s->freq = val; + qemu_get_be32s (f, &val); s->pos = val; + qemu_get_be32s (f, &val); s->left = val; + qemu_get_be32s (f, &val); s->shift = val; + qemu_get_be32s (f, &val); s->irqs = val; + qemu_get_be32s (f, &val); s->samples = val; + qemu_get_be64s (f, &s->last_ticks); + qemu_get_buffer (f, s->himem, sizeof (s->himem)); + return 0; +} + int GUS_init (AudioState *audio, qemu_irq *pic) { GUSState *s; @@ -296,5 +330,7 @@ int GUS_init (AudioState *audio, qemu_irq *pic) s->pic = pic; AUD_set_active_out (s->voice, 1); + + register_savevm ("gus", 0, 1, GUS_save, GUS_load, s); return 0; } -- cgit v1.2.3 From 7a24c80011d50c1716e84ab70de097caa201746f Mon Sep 17 00:00:00 2001 From: malc Date: Sat, 21 Jun 2008 17:14:57 +0000 Subject: Rework period/buffer size setting git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4768 c046a42c-6fe2-441c-8c8c-71466251a162 --- audio/alsaaudio.c | 190 +++++++++++++++--------------------------------------- 1 file changed, 52 insertions(+), 138 deletions(-) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 43cfa258d..7d488859d 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -58,37 +58,15 @@ static struct { int period_size_out_overridden; int verbose; } conf = { -#define DEFAULT_BUFFER_SIZE 1024 -#define DEFAULT_PERIOD_SIZE 256 -#ifdef HIGH_LATENCY - .size_in_usec_in = 1, - .size_in_usec_out = 1, -#endif .pcm_name_out = "default", .pcm_name_in = "default", -#ifdef HIGH_LATENCY - .buffer_size_in = 400000, - .period_size_in = 400000 / 4, - .buffer_size_out = 400000, - .period_size_out = 400000 / 4, -#else - .buffer_size_in = DEFAULT_BUFFER_SIZE * 4, - .period_size_in = DEFAULT_PERIOD_SIZE * 4, - .buffer_size_out = DEFAULT_BUFFER_SIZE, - .period_size_out = DEFAULT_PERIOD_SIZE, - .buffer_size_in_overridden = 0, - .buffer_size_out_overridden = 0, - .period_size_in_overridden = 0, - .period_size_out_overridden = 0, -#endif - .threshold = 0, - .verbose = 0 }; struct alsa_params_req { int freq; snd_pcm_format_t fmt; int nchannels; + int size_in_usec; unsigned int buffer_size; unsigned int period_size; }; @@ -286,17 +264,16 @@ static int alsa_open (int in, struct alsa_params_req *req, snd_pcm_t *handle; snd_pcm_hw_params_t *hw_params; int err; + int size_in_usec; unsigned int freq, nchannels; const char *pcm_name = in ? conf.pcm_name_in : conf.pcm_name_out; - unsigned int period_size, buffer_size; snd_pcm_uframes_t obt_buffer_size; const char *typ = in ? "ADC" : "DAC"; snd_pcm_format_t obtfmt; freq = req->freq; - period_size = req->period_size; - buffer_size = req->buffer_size; nchannels = req->nchannels; + size_in_usec = req->size_in_usec; snd_pcm_hw_params_alloca (&hw_params); @@ -356,130 +333,61 @@ static int alsa_open (int in, struct alsa_params_req *req, goto err; } - if (!((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out))) { - if (!buffer_size) { - buffer_size = DEFAULT_BUFFER_SIZE; - period_size= DEFAULT_PERIOD_SIZE; - } - } - - if (buffer_size) { - if ((in && conf.size_in_usec_in) || (!in && conf.size_in_usec_out)) { - if (period_size) { - err = snd_pcm_hw_params_set_period_time_near ( - handle, - hw_params, - &period_size, - 0 - ); - if (err < 0) { - alsa_logerr2 (err, typ, - "Failed to set period time %d\n", - req->period_size); - goto err; - } - } + if (req->buffer_size) { + if (size_in_usec) { + int dir = 0; + unsigned int btime = req->buffer_size; err = snd_pcm_hw_params_set_buffer_time_near ( handle, hw_params, - &buffer_size, - 0 + &btime, + &dir ); - - if (err < 0) { - alsa_logerr2 (err, typ, - "Failed to set buffer time %d\n", - req->buffer_size); - goto err; - } } else { - int dir; - snd_pcm_uframes_t minval; - - if (period_size) { - minval = period_size; - dir = 0; - - err = snd_pcm_hw_params_get_period_size_min ( - hw_params, - &minval, - &dir - ); - if (err < 0) { - alsa_logerr ( - err, - "Could not get minmal period size for %s\n", - typ - ); - } - else { - if (period_size < minval) { - if ((in && conf.period_size_in_overridden) - || (!in && conf.period_size_out_overridden)) { - dolog ("%s period size(%d) is less " - "than minmal period size(%ld)\n", - typ, - period_size, - minval); - } - period_size = minval; - } - } + snd_pcm_uframes_t bsize = req->buffer_size; - err = snd_pcm_hw_params_set_period_size ( - handle, - hw_params, - period_size, - 0 - ); - if (err < 0) { - alsa_logerr2 (err, typ, "Failed to set period size %d\n", - req->period_size); - goto err; - } - } + err = snd_pcm_hw_params_set_buffer_size_near ( + handle, + hw_params, + &bsize + ); + } + if (err < 0) { + alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n", + size_in_usec ? "time" : "size", req->buffer_size); + goto err; + } + } + + if (req->period_size) { + if (size_in_usec) { + int dir = 0; + unsigned int ptime = req->period_size; - minval = buffer_size; - err = snd_pcm_hw_params_get_buffer_size_min ( + err = snd_pcm_hw_params_set_period_time_near ( + handle, hw_params, - &minval + &ptime, + &dir ); - if (err < 0) { - alsa_logerr (err, "Could not get minmal buffer size for %s\n", - typ); - } - else { - if (buffer_size < minval) { - if ((in && conf.buffer_size_in_overridden) - || (!in && conf.buffer_size_out_overridden)) { - dolog ( - "%s buffer size(%d) is less " - "than minimal buffer size(%ld)\n", - typ, - buffer_size, - minval - ); - } - buffer_size = minval; - } - } + } + else { + snd_pcm_uframes_t psize = req->period_size; - err = snd_pcm_hw_params_set_buffer_size ( + err = snd_pcm_hw_params_set_buffer_size_near ( handle, hw_params, - buffer_size + &psize ); - if (err < 0) { - alsa_logerr2 (err, typ, "Failed to set buffer size %d\n", - req->buffer_size); - goto err; - } } - } - else { - dolog ("warning: Buffer size is not set\n"); + + if (err < 0) { + alsa_logerr2 (err, typ, "Failed to set period %s to %d\n", + size_in_usec ? "time" : "size", req->period_size); + goto err; + } } err = snd_pcm_hw_params (handle, hw_params); @@ -697,6 +605,7 @@ static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as) req.nchannels = as->nchannels; req.period_size = conf.period_size_out; req.buffer_size = conf.buffer_size_out; + req.size_in_usec = conf.size_in_usec_in; if (alsa_open (0, &req, &obt, &handle)) { return -1; @@ -774,6 +683,7 @@ static int alsa_init_in (HWVoiceIn *hw, audsettings_t *as) req.nchannels = as->nchannels; req.period_size = conf.period_size_in; req.buffer_size = conf.buffer_size_in; + req.size_in_usec = conf.size_in_usec_in; if (alsa_open (1, &req, &obt, &handle)) { return -1; @@ -953,16 +863,20 @@ static struct audio_option alsa_options[] = { {"DAC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_out, "DAC period/buffer size in microseconds (otherwise in frames)", NULL, 0}, {"DAC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_out, - "DAC period size", &conf.period_size_out_overridden, 0}, + "DAC period size (0 to go with system default)", + &conf.period_size_out_overridden, 0}, {"DAC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_out, - "DAC buffer size", &conf.buffer_size_out_overridden, 0}, + "DAC buffer size (0 to go with system default)", + &conf.buffer_size_out_overridden, 0}, {"ADC_SIZE_IN_USEC", AUD_OPT_BOOL, &conf.size_in_usec_in, "ADC period/buffer size in microseconds (otherwise in frames)", NULL, 0}, {"ADC_PERIOD_SIZE", AUD_OPT_INT, &conf.period_size_in, - "ADC period size", &conf.period_size_in_overridden, 0}, + "ADC period size (0 to go with system default)", + &conf.period_size_in_overridden, 0}, {"ADC_BUFFER_SIZE", AUD_OPT_INT, &conf.buffer_size_in, - "ADC buffer size", &conf.buffer_size_in_overridden, 0}, + "ADC buffer size (0 to go with system default)", + &conf.buffer_size_in_overridden, 0}, {"THRESHOLD", AUD_OPT_INT, &conf.threshold, "(undocumented)", NULL, 0}, -- cgit v1.2.3 From 77599a1f7aa96370e8690652cc943f2208049f6c Mon Sep 17 00:00:00 2001 From: malc Date: Sat, 21 Jun 2008 17:15:00 +0000 Subject: Disable xLaw debugging git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4769 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/cs4231a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/cs4231a.c b/hw/cs4231a.c index a18a1424e..75529089f 100644 --- a/hw/cs4231a.c +++ b/hw/cs4231a.c @@ -37,7 +37,7 @@ */ /* #define DEBUG */ -#define DEBUG_XLAW +/* #define DEBUG_XLAW */ static struct { int irq; -- cgit v1.2.3 From 8210169a78ac3afa779abe763b7ab70517e4e161 Mon Sep 17 00:00:00 2001 From: malc Date: Sat, 21 Jun 2008 17:51:50 +0000 Subject: Do not save dynamic field git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4770 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/gus.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hw/gus.c b/hw/gus.c index d39d91872..9ff00d791 100644 --- a/hw/gus.c +++ b/hw/gus.c @@ -225,7 +225,6 @@ static void GUS_save (QEMUFile *f, void *opaque) int32_t val; GUSState *s = opaque; - val = s->freq; qemu_put_be32s (f, &val); val = s->pos; qemu_put_be32s (f, &val); val = s->left; qemu_put_be32s (f, &val); val = s->shift; qemu_put_be32s (f, &val); @@ -240,10 +239,9 @@ static int GUS_load (QEMUFile *f, void *opaque, int version_id) int32_t val; GUSState *s = opaque; - if (version_id != 1) + if (version_id != 2) return -EINVAL; - qemu_get_be32s (f, &val); s->freq = val; qemu_get_be32s (f, &val); s->pos = val; qemu_get_be32s (f, &val); s->left = val; qemu_get_be32s (f, &val); s->shift = val; @@ -331,6 +329,6 @@ int GUS_init (AudioState *audio, qemu_irq *pic) AUD_set_active_out (s->voice, 1); - register_savevm ("gus", 0, 1, GUS_save, GUS_load, s); + register_savevm ("gus", 0, 2, GUS_save, GUS_load, s); return 0; } -- cgit v1.2.3 From 5c6a0628b798b8409fd1212c9df7689057c06083 Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Sat, 21 Jun 2008 19:46:48 +0000 Subject: Avoid brcond problems, use temps for cpu_src1 & cpu_src2 git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4771 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-sparc/translate.c | 67 +++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/target-sparc/translate.c b/target-sparc/translate.c index a821ef3f3..2449eeb3e 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -450,8 +450,7 @@ static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2) { tcg_gen_mov_tl(cpu_cc_src, src1); tcg_gen_mov_tl(cpu_cc_src2, src2); - tcg_gen_add_tl(dst, src1, src2); - tcg_gen_mov_tl(cpu_cc_dst, dst); + tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); gen_cc_clear_icc(); gen_cc_NZ_icc(cpu_cc_dst); gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src); @@ -462,6 +461,7 @@ static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2) gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src); gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); #endif + tcg_gen_mov_tl(dst, cpu_cc_dst); } static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2) @@ -469,15 +469,14 @@ static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2) tcg_gen_mov_tl(cpu_cc_src, src1); tcg_gen_mov_tl(cpu_cc_src2, src2); gen_mov_reg_C(cpu_tmp0, cpu_psr); - tcg_gen_add_tl(dst, src1, cpu_tmp0); + tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0); gen_cc_clear_icc(); - gen_cc_C_add_icc(dst, cpu_cc_src); + gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src); #ifdef TARGET_SPARC64 gen_cc_clear_xcc(); - gen_cc_C_add_xcc(dst, cpu_cc_src); + gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src); #endif - tcg_gen_add_tl(dst, dst, cpu_cc_src2); - tcg_gen_mov_tl(cpu_cc_dst, dst); + tcg_gen_add_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2); gen_cc_NZ_icc(cpu_cc_dst); gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src); gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); @@ -486,14 +485,14 @@ static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2) gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src); gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); #endif + tcg_gen_mov_tl(dst, cpu_cc_dst); } static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2) { tcg_gen_mov_tl(cpu_cc_src, src1); tcg_gen_mov_tl(cpu_cc_src2, src2); - tcg_gen_add_tl(dst, src1, src2); - tcg_gen_mov_tl(cpu_cc_dst, dst); + tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); gen_cc_clear_icc(); gen_cc_NZ_icc(cpu_cc_dst); gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src); @@ -505,6 +504,7 @@ static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2) gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src); gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); #endif + tcg_gen_mov_tl(dst, cpu_cc_dst); } static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2) @@ -512,9 +512,8 @@ static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2) tcg_gen_mov_tl(cpu_cc_src, src1); tcg_gen_mov_tl(cpu_cc_src2, src2); gen_tag_tv(cpu_cc_src, cpu_cc_src2); - tcg_gen_add_tl(dst, src1, src2); - tcg_gen_mov_tl(cpu_cc_dst, dst); - gen_add_tv(dst, cpu_cc_src, cpu_cc_src2); + tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); + gen_add_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); gen_cc_clear_icc(); gen_cc_NZ_icc(cpu_cc_dst); gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src); @@ -524,6 +523,7 @@ static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2) gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src); gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); #endif + tcg_gen_mov_tl(dst, cpu_cc_dst); } /* old op: @@ -619,8 +619,7 @@ static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2) { tcg_gen_mov_tl(cpu_cc_src, src1); tcg_gen_mov_tl(cpu_cc_src2, src2); - tcg_gen_sub_tl(dst, src1, src2); - tcg_gen_mov_tl(cpu_cc_dst, dst); + tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); gen_cc_clear_icc(); gen_cc_NZ_icc(cpu_cc_dst); gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2); @@ -631,6 +630,7 @@ static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2) gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2); gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); #endif + tcg_gen_mov_tl(dst, cpu_cc_dst); } static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2) @@ -638,15 +638,14 @@ static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2) tcg_gen_mov_tl(cpu_cc_src, src1); tcg_gen_mov_tl(cpu_cc_src2, src2); gen_mov_reg_C(cpu_tmp0, cpu_psr); - tcg_gen_sub_tl(dst, src1, cpu_tmp0); + tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0); gen_cc_clear_icc(); - gen_cc_C_sub_icc(dst, cpu_cc_src); + gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src); #ifdef TARGET_SPARC64 gen_cc_clear_xcc(); - gen_cc_C_sub_xcc(dst, cpu_cc_src); + gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src); #endif - tcg_gen_sub_tl(dst, dst, cpu_cc_src2); - tcg_gen_mov_tl(cpu_cc_dst, dst); + tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2); gen_cc_NZ_icc(cpu_cc_dst); gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src); gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); @@ -655,14 +654,14 @@ static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2) gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src); gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); #endif + tcg_gen_mov_tl(dst, cpu_cc_dst); } static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2) { tcg_gen_mov_tl(cpu_cc_src, src1); tcg_gen_mov_tl(cpu_cc_src2, src2); - tcg_gen_sub_tl(dst, src1, src2); - tcg_gen_mov_tl(cpu_cc_dst, dst); + tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); gen_cc_clear_icc(); gen_cc_NZ_icc(cpu_cc_dst); gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2); @@ -674,6 +673,7 @@ static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2) gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2); gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); #endif + tcg_gen_mov_tl(dst, cpu_cc_dst); } static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2) @@ -681,9 +681,8 @@ static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2) tcg_gen_mov_tl(cpu_cc_src, src1); tcg_gen_mov_tl(cpu_cc_src2, src2); gen_tag_tv(cpu_cc_src, cpu_cc_src2); - tcg_gen_sub_tl(dst, src1, src2); - tcg_gen_mov_tl(cpu_cc_dst, dst); - gen_sub_tv(dst, cpu_cc_src, cpu_cc_src2); + tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); + gen_sub_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); gen_cc_clear_icc(); gen_cc_NZ_icc(cpu_cc_dst); gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2); @@ -693,6 +692,7 @@ static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2) gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2); gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); #endif + tcg_gen_mov_tl(dst, cpu_cc_dst); } static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2) @@ -741,13 +741,13 @@ static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2) tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0); /* do addition and update flags */ - tcg_gen_add_tl(dst, cpu_cc_src, cpu_cc_src2); - tcg_gen_mov_tl(cpu_cc_dst, dst); + tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); gen_cc_clear_icc(); gen_cc_NZ_icc(cpu_cc_dst); gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src); + tcg_gen_mov_tl(dst, cpu_cc_dst); } static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2) @@ -818,7 +818,7 @@ static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2) l2 = gen_new_label(); tcg_gen_mov_tl(cpu_cc_src, src1); tcg_gen_mov_tl(cpu_cc_src2, src2); - gen_trap_ifdivzero_tl(src2); + gen_trap_ifdivzero_tl(cpu_cc_src2); tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src, INT64_MIN, l1); tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src2, -1, l1); tcg_gen_movi_i64(dst, INT64_MIN); @@ -837,8 +837,7 @@ static inline void gen_op_div_cc(TCGv dst) gen_cc_clear_icc(); gen_cc_NZ_icc(cpu_cc_dst); l1 = gen_new_label(); - tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, cc_src2)); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1); + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_src2, 0, l1); tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF); gen_set_label(l1); } @@ -1866,11 +1865,9 @@ static inline TCGv get_src1(unsigned int insn, TCGv def) rs1 = GET_FIELD(insn, 13, 17); if (rs1 == 0) - //r_rs1 = tcg_const_tl(0); - tcg_gen_movi_tl(def, 0); + r_rs1 = tcg_const_tl(0); // XXX how to free? else if (rs1 < 8) - //r_rs1 = cpu_gregs[rs1]; - tcg_gen_mov_tl(def, cpu_gregs[rs1]); + r_rs1 = cpu_gregs[rs1]; else tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong)); return r_rs1; @@ -1916,8 +1913,8 @@ static void disas_sparc_insn(DisasContext * dc) rd = GET_FIELD(insn, 2, 6); cpu_dst = cpu_T[0]; - cpu_src1 = cpu_T[0]; // const - cpu_src2 = cpu_T[1]; // const + cpu_src1 = tcg_temp_new(TCG_TYPE_TL); // const + cpu_src2 = tcg_temp_new(TCG_TYPE_TL); // const // loads and stores cpu_addr = cpu_T[0]; -- cgit v1.2.3 From ece43b8d06f26c670b06c30c6bd1021580a005aa Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Sat, 21 Jun 2008 19:50:10 +0000 Subject: Convert some cpu_dst uses (with loads/stores) to cpu_tmp0 git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4772 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-sparc/translate.c | 134 +++++++++++++++++++++++------------------------ 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 2449eeb3e..548203b9a 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -2078,9 +2078,9 @@ static void disas_sparc_insn(DisasContext * dc) SPARCv8 manual, rdy on the microSPARC II */ #endif - tcg_gen_ld_tl(cpu_dst, cpu_env, + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y)); - gen_movl_TN_reg(rd, cpu_dst); + gen_movl_TN_reg(rd, cpu_tmp0); break; #ifdef TARGET_SPARC64 case 0x2: /* V9 rdccr */ @@ -2126,14 +2126,14 @@ static void disas_sparc_insn(DisasContext * dc) case 0x13: /* Graphics Status */ if (gen_trap_ifnofpu(dc, cpu_cond)) goto jmp_insn; - tcg_gen_ld_tl(cpu_dst, cpu_env, + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, gsr)); - gen_movl_TN_reg(rd, cpu_dst); + gen_movl_TN_reg(rd, cpu_tmp0); break; case 0x17: /* Tick compare */ - tcg_gen_ld_tl(cpu_dst, cpu_env, + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, tick_cmpr)); - gen_movl_TN_reg(rd, cpu_dst); + gen_movl_TN_reg(rd, cpu_tmp0); break; case 0x18: /* System tick */ { @@ -2149,9 +2149,9 @@ static void disas_sparc_insn(DisasContext * dc) } break; case 0x19: /* System tick compare */ - tcg_gen_ld_tl(cpu_dst, cpu_env, + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, stick_cmpr)); - gen_movl_TN_reg(rd, cpu_dst); + gen_movl_TN_reg(rd, cpu_tmp0); break; case 0x10: /* Performance Control */ case 0x11: /* Performance Instrumentation Counter */ @@ -2219,7 +2219,7 @@ static void disas_sparc_insn(DisasContext * dc) r_tsptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tsptr, cpu_env, offsetof(CPUState, tsptr)); - tcg_gen_ld_tl(cpu_dst, r_tsptr, + tcg_gen_ld_tl(cpu_tmp0, r_tsptr, offsetof(trap_state, tpc)); tcg_temp_free(r_tsptr); } @@ -2231,7 +2231,7 @@ static void disas_sparc_insn(DisasContext * dc) r_tsptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tsptr, cpu_env, offsetof(CPUState, tsptr)); - tcg_gen_ld_tl(cpu_dst, r_tsptr, + tcg_gen_ld_tl(cpu_tmp0, r_tsptr, offsetof(trap_state, tnpc)); tcg_temp_free(r_tsptr); } @@ -2243,7 +2243,7 @@ static void disas_sparc_insn(DisasContext * dc) r_tsptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tsptr, cpu_env, offsetof(CPUState, tsptr)); - tcg_gen_ld_tl(cpu_dst, r_tsptr, + tcg_gen_ld_tl(cpu_tmp0, r_tsptr, offsetof(trap_state, tstate)); tcg_temp_free(r_tsptr); } @@ -2255,7 +2255,7 @@ static void disas_sparc_insn(DisasContext * dc) r_tsptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tsptr, cpu_env, offsetof(CPUState, tsptr)); - tcg_gen_ld_i32(cpu_dst, r_tsptr, + tcg_gen_ld_i32(cpu_tmp0, r_tsptr, offsetof(trap_state, tt)); tcg_temp_free(r_tsptr); } @@ -2267,73 +2267,73 @@ static void disas_sparc_insn(DisasContext * dc) r_tickptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tickptr, cpu_env, offsetof(CPUState, tick)); - tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst, + tcg_gen_helper_1_1(helper_tick_get_count, cpu_tmp0, r_tickptr); - gen_movl_TN_reg(rd, cpu_dst); + gen_movl_TN_reg(rd, cpu_tmp0); tcg_temp_free(r_tickptr); } break; case 5: // tba - tcg_gen_ld_tl(cpu_dst, cpu_env, + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, tbr)); break; case 6: // pstate tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, pstate)); - tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); + tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); break; case 7: // tl tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, tl)); - tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); + tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); break; case 8: // pil tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, psrpil)); - tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); + tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); break; case 9: // cwp - tcg_gen_helper_1_0(helper_rdcwp, cpu_dst); + tcg_gen_helper_1_0(helper_rdcwp, cpu_tmp0); break; case 10: // cansave tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cansave)); - tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); + tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); break; case 11: // canrestore tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, canrestore)); - tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); + tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); break; case 12: // cleanwin tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cleanwin)); - tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); + tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); break; case 13: // otherwin tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, otherwin)); - tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); + tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); break; case 14: // wstate tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wstate)); - tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); + tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); break; case 16: // UA2005 gl tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, gl)); - tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); + tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); break; case 26: // UA2005 strand status if (!hypervisor(dc)) goto priv_insn; tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ssr)); - tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); + tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); break; case 31: // ver - tcg_gen_ld_tl(cpu_dst, cpu_env, + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, version)); break; case 15: // fq @@ -2343,9 +2343,9 @@ static void disas_sparc_insn(DisasContext * dc) #else tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wim)); - tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); + tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); #endif - gen_movl_TN_reg(rd, cpu_dst); + gen_movl_TN_reg(rd, cpu_tmp0); break; } else if (xop == 0x2b) { /* rdtbr / V9 flushw */ #ifdef TARGET_SPARC64 @@ -2353,8 +2353,8 @@ static void disas_sparc_insn(DisasContext * dc) #else if (!supervisor(dc)) goto priv_insn; - tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tbr)); - gen_movl_TN_reg(rd, cpu_dst); + tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, tbr)); + gen_movl_TN_reg(rd, cpu_tmp0); #endif break; #endif @@ -3149,8 +3149,8 @@ static void disas_sparc_insn(DisasContext * dc) { switch(rd) { case 0: /* wry */ - tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2); - tcg_gen_st_tl(cpu_dst, cpu_env, + tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); + tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y)); break; #ifndef TARGET_SPARC64 @@ -3193,8 +3193,8 @@ static void disas_sparc_insn(DisasContext * dc) case 0x13: /* Graphics Status */ if (gen_trap_ifnofpu(dc, cpu_cond)) goto jmp_insn; - tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2); - tcg_gen_st_tl(cpu_dst, cpu_env, + tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); + tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, gsr)); break; case 0x17: /* Tick compare */ @@ -3205,16 +3205,16 @@ static void disas_sparc_insn(DisasContext * dc) { TCGv r_tickptr; - tcg_gen_xor_tl(cpu_dst, cpu_src1, + tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); - tcg_gen_st_tl(cpu_dst, cpu_env, + tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, tick_cmpr)); r_tickptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tickptr, cpu_env, offsetof(CPUState, tick)); tcg_gen_helper_0_2(helper_tick_set_limit, - r_tickptr, cpu_dst); + r_tickptr, cpu_tmp0); tcg_temp_free(r_tickptr); } break; @@ -3244,16 +3244,16 @@ static void disas_sparc_insn(DisasContext * dc) { TCGv r_tickptr; - tcg_gen_xor_tl(cpu_dst, cpu_src1, + tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); - tcg_gen_st_tl(cpu_dst, cpu_env, + tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, stick_cmpr)); r_tickptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tickptr, cpu_env, offsetof(CPUState, stick)); tcg_gen_helper_0_2(helper_tick_set_limit, - r_tickptr, cpu_dst); + r_tickptr, cpu_tmp0); tcg_temp_free(r_tickptr); } break; @@ -3306,7 +3306,7 @@ static void disas_sparc_insn(DisasContext * dc) { if (!supervisor(dc)) goto priv_insn; - tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2); + tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); #ifdef TARGET_SPARC64 switch (rd) { case 0: // tpc @@ -3316,7 +3316,7 @@ static void disas_sparc_insn(DisasContext * dc) r_tsptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tsptr, cpu_env, offsetof(CPUState, tsptr)); - tcg_gen_st_tl(cpu_dst, r_tsptr, + tcg_gen_st_tl(cpu_tmp0, r_tsptr, offsetof(trap_state, tpc)); tcg_temp_free(r_tsptr); } @@ -3328,7 +3328,7 @@ static void disas_sparc_insn(DisasContext * dc) r_tsptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tsptr, cpu_env, offsetof(CPUState, tsptr)); - tcg_gen_st_tl(cpu_dst, r_tsptr, + tcg_gen_st_tl(cpu_tmp0, r_tsptr, offsetof(trap_state, tnpc)); tcg_temp_free(r_tsptr); } @@ -3340,7 +3340,7 @@ static void disas_sparc_insn(DisasContext * dc) r_tsptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tsptr, cpu_env, offsetof(CPUState, tsptr)); - tcg_gen_st_tl(cpu_dst, r_tsptr, + tcg_gen_st_tl(cpu_tmp0, r_tsptr, offsetof(trap_state, tstate)); tcg_temp_free(r_tsptr); @@ -3353,7 +3353,7 @@ static void disas_sparc_insn(DisasContext * dc) r_tsptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tsptr, cpu_env, offsetof(CPUState, tsptr)); - tcg_gen_st_i32(cpu_dst, r_tsptr, + tcg_gen_st_i32(cpu_tmp0, r_tsptr, offsetof(trap_state, tt)); tcg_temp_free(r_tsptr); } @@ -3366,74 +3366,74 @@ static void disas_sparc_insn(DisasContext * dc) tcg_gen_ld_ptr(r_tickptr, cpu_env, offsetof(CPUState, tick)); tcg_gen_helper_0_2(helper_tick_set_count, - r_tickptr, cpu_dst); + r_tickptr, cpu_tmp0); tcg_temp_free(r_tickptr); } break; case 5: // tba - tcg_gen_st_tl(cpu_dst, cpu_env, + tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, tbr)); break; case 6: // pstate save_state(dc, cpu_cond); - tcg_gen_helper_0_1(helper_wrpstate, cpu_dst); + tcg_gen_helper_0_1(helper_wrpstate, cpu_tmp0); gen_op_next_insn(); tcg_gen_exit_tb(0); dc->is_br = 1; break; case 7: // tl - tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); + tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, tl)); break; case 8: // pil - tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); + tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, psrpil)); break; case 9: // cwp - tcg_gen_helper_0_1(helper_wrcwp, cpu_dst); + tcg_gen_helper_0_1(helper_wrcwp, cpu_tmp0); break; case 10: // cansave - tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); + tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cansave)); break; case 11: // canrestore - tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); + tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, canrestore)); break; case 12: // cleanwin - tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); + tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cleanwin)); break; case 13: // otherwin - tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); + tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, otherwin)); break; case 14: // wstate - tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); + tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wstate)); break; case 16: // UA2005 gl - tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); + tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, gl)); break; case 26: // UA2005 strand status if (!hypervisor(dc)) goto priv_insn; - tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); + tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ssr)); break; @@ -3441,7 +3441,7 @@ static void disas_sparc_insn(DisasContext * dc) goto illegal_insn; } #else - tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); + tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wim)); #endif @@ -3452,13 +3452,13 @@ static void disas_sparc_insn(DisasContext * dc) #ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn; - tcg_gen_xor_tl(cpu_dst, cpu_dst, cpu_src2); - tcg_gen_st_tl(cpu_dst, cpu_env, + tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); + tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, tbr)); #else if (!hypervisor(dc)) goto priv_insn; - tcg_gen_xor_tl(cpu_dst, cpu_dst, cpu_src2); + tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); switch (rd) { case 0: // hpstate // XXX gen_op_wrhpstate(); @@ -3471,12 +3471,12 @@ static void disas_sparc_insn(DisasContext * dc) // XXX gen_op_wrhtstate(); break; case 3: // hintp - tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); + tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hintp)); break; case 5: // htba - tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); + tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, htba)); break; @@ -3484,14 +3484,14 @@ static void disas_sparc_insn(DisasContext * dc) { TCGv r_tickptr; - tcg_gen_st_tl(cpu_dst, cpu_env, + tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, hstick_cmpr)); r_tickptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tickptr, cpu_env, offsetof(CPUState, hstick)); tcg_gen_helper_0_2(helper_tick_set_limit, - r_tickptr, cpu_dst); + r_tickptr, cpu_tmp0); tcg_temp_free(r_tickptr); } break; -- cgit v1.2.3 From f3b5298316aa7885b83d49b6499388189b3e08f7 Mon Sep 17 00:00:00 2001 From: malc Date: Sat, 21 Jun 2008 20:09:32 +0000 Subject: Emit warning message if user supplied buffer/period size/time was rejected git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4773 c046a42c-6fe2-441c-8c8c-71466251a162 --- audio/alsaaudio.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 7d488859d..c926cae38 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -334,6 +334,8 @@ static int alsa_open (int in, struct alsa_params_req *req, } if (req->buffer_size) { + unsigned long obt; + if (size_in_usec) { int dir = 0; unsigned int btime = req->buffer_size; @@ -344,6 +346,7 @@ static int alsa_open (int in, struct alsa_params_req *req, &btime, &dir ); + obt = btime; } else { snd_pcm_uframes_t bsize = req->buffer_size; @@ -353,15 +356,22 @@ static int alsa_open (int in, struct alsa_params_req *req, hw_params, &bsize ); + obt = bsize; } if (err < 0) { alsa_logerr2 (err, typ, "Failed to set buffer %s to %d\n", size_in_usec ? "time" : "size", req->buffer_size); goto err; } + + if (obt - req->buffer_size) + dolog ("Requested buffer %s %u was rejected, using %lu\n", + size_in_usec ? "time" : "size", req->buffer_size, obt); } if (req->period_size) { + unsigned long obt; + if (size_in_usec) { int dir = 0; unsigned int ptime = req->period_size; @@ -372,6 +382,7 @@ static int alsa_open (int in, struct alsa_params_req *req, &ptime, &dir ); + obt = ptime; } else { snd_pcm_uframes_t psize = req->period_size; @@ -381,6 +392,7 @@ static int alsa_open (int in, struct alsa_params_req *req, hw_params, &psize ); + obt = psize; } if (err < 0) { @@ -388,6 +400,10 @@ static int alsa_open (int in, struct alsa_params_req *req, size_in_usec ? "time" : "size", req->period_size); goto err; } + + if (obt - req->period_size) + dolog ("Requested period %s %u was rejected, using %lu\n", + size_in_usec ? "time" : "size", req->period_size, obt); } err = snd_pcm_hw_params (handle, hw_params); -- cgit v1.2.3 From c0b5b109a8cb6cf51f23578d5feaa78f88ba5335 Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Sun, 22 Jun 2008 07:45:42 +0000 Subject: Add missing keys, sendkey support for all keys git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4774 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/slavio_serial.c | 2 +- monitor.c | 17 +++++++++++++++++ target-sparc/TODO | 1 - 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/hw/slavio_serial.c b/hw/slavio_serial.c index 37424c6cd..1ef3c119e 100644 --- a/hw/slavio_serial.c +++ b/hw/slavio_serial.c @@ -770,7 +770,7 @@ static const uint8_t e0_keycodes[128] = { 0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112, 113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0, }; static void sunkbd_event(void *opaque, int ch) diff --git a/monitor.c b/monitor.c index 815489867..914f4c6e3 100644 --- a/monitor.c +++ b/monitor.c @@ -904,6 +904,23 @@ static const KeyDef key_defs[] = { { 0xd2, "insert" }, { 0xd3, "delete" }, +#if defined(TARGET_SPARC) && !defined(TARGET_SPARC64) + { 0xf0, "stop" }, + { 0xf1, "again" }, + { 0xf2, "props" }, + { 0xf3, "undo" }, + { 0xf4, "front" }, + { 0xf5, "copy" }, + { 0xf6, "open" }, + { 0xf7, "paste" }, + { 0xf8, "find" }, + { 0xf9, "cut" }, + { 0xfa, "lf" }, + { 0xfb, "help" }, + { 0xfc, "meta_l" }, + { 0xfd, "meta_r" }, + { 0xfe, "compose" }, +#endif { 0, NULL }, }; diff --git a/target-sparc/TODO b/target-sparc/TODO index 30c17c44d..0d39994b2 100644 --- a/target-sparc/TODO +++ b/target-sparc/TODO @@ -53,7 +53,6 @@ Sun4m: - Unimplemented features/bugs: - Hardware devices do not match real boards - Floppy does not work - - Missing keys, sendkey support for all keys - CS4231: merge with cs4231a, add DMA - Add cg6, bwtwo - Arbitrary resolution support -- cgit v1.2.3 From 3f0436fe852f600b2685350f3f5f378b5d4ed0e1 Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Sun, 22 Jun 2008 08:52:58 +0000 Subject: Eliminate cpu_T[1] git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4775 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-sparc/translate.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 548203b9a..1ecf722fa 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -1918,7 +1918,6 @@ static void disas_sparc_insn(DisasContext * dc) // loads and stores cpu_addr = cpu_T[0]; - cpu_val = cpu_T[1]; switch (opc) { case 0: /* branches/sethi */ @@ -4745,6 +4744,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL); cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32); cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64); + cpu_val = tcg_temp_local_new(TCG_TYPE_TL); do { if (env->nb_breakpoints > 0) { @@ -4795,6 +4795,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32)); exit_gen_loop: + tcg_temp_free(cpu_val); tcg_temp_free(cpu_tmp64); tcg_temp_free(cpu_tmp32); tcg_temp_free(cpu_tmp0); @@ -4875,11 +4876,9 @@ void gen_intermediate_code_init(CPUSPARCState *env) TCG_AREG0, offsetof(CPUState, xcc), "xcc"); #endif - /* XXX: T0 and T1 should be temporaries */ + /* XXX: T0 should be a temporary */ cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0, offsetof(CPUState, t0), "T0"); - cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL, - TCG_AREG0, offsetof(CPUState, t1), "T1"); cpu_cond = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0, offsetof(CPUState, cond), "cond"); -- cgit v1.2.3 From d987963aa9769be66226456f08f99306d25cfd4f Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Sun, 22 Jun 2008 10:58:57 +0000 Subject: Eliminate cpu_T[0] git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4776 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-sparc/translate.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 1ecf722fa..98c629150 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -38,7 +38,7 @@ according to jump_pc[T2] */ /* global register indexes */ -static TCGv cpu_env, cpu_T[2], cpu_regwptr; +static TCGv cpu_env, cpu_regwptr; static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst; static TCGv cpu_psr, cpu_fsr, cpu_pc, cpu_npc, cpu_gregs[8]; static TCGv cpu_cond, cpu_src1, cpu_src2, cpu_dst, cpu_addr, cpu_val; @@ -1912,13 +1912,9 @@ static void disas_sparc_insn(DisasContext * dc) rd = GET_FIELD(insn, 2, 6); - cpu_dst = cpu_T[0]; cpu_src1 = tcg_temp_new(TCG_TYPE_TL); // const cpu_src2 = tcg_temp_new(TCG_TYPE_TL); // const - // loads and stores - cpu_addr = cpu_T[0]; - switch (opc) { case 0: /* branches/sethi */ { @@ -4220,7 +4216,7 @@ static void disas_sparc_insn(DisasContext * dc) save_state(dc, cpu_cond); r_const = tcg_const_i32(7); - tcg_gen_helper_0_2(helper_check_align, cpu_dst, + tcg_gen_helper_0_2(helper_check_align, cpu_addr, r_const); // XXX remove tcg_temp_free(r_const); ABI32_MASK(cpu_addr); @@ -4744,7 +4740,12 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL); cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32); cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64); + + cpu_dst = tcg_temp_local_new(TCG_TYPE_TL); + + // loads and stores cpu_val = tcg_temp_local_new(TCG_TYPE_TL); + cpu_addr = tcg_temp_local_new(TCG_TYPE_TL); do { if (env->nb_breakpoints > 0) { @@ -4795,7 +4796,9 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32)); exit_gen_loop: + tcg_temp_free(cpu_addr); tcg_temp_free(cpu_val); + tcg_temp_free(cpu_dst); tcg_temp_free(cpu_tmp64); tcg_temp_free(cpu_tmp32); tcg_temp_free(cpu_tmp0); @@ -4876,9 +4879,6 @@ void gen_intermediate_code_init(CPUSPARCState *env) TCG_AREG0, offsetof(CPUState, xcc), "xcc"); #endif - /* XXX: T0 should be a temporary */ - cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, - TCG_AREG0, offsetof(CPUState, t0), "T0"); cpu_cond = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0, offsetof(CPUState, cond), "cond"); -- cgit v1.2.3 From d50997f9144ec103db7f5f804337979211ddf5e6 Mon Sep 17 00:00:00 2001 From: malc Date: Sun, 22 Jun 2008 14:10:45 +0000 Subject: Add missing [SU]32 git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4777 c046a42c-6fe2-441c-8c8c-71466251a162 --- audio/audio.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/audio/audio.c b/audio/audio.c index c178584ca..46b39df76 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -549,6 +549,12 @@ static void audio_print_settings (audsettings_t *as) case AUD_FMT_U16: AUD_log (NULL, "U16"); break; + case AUD_FMT_S32: + AUD_log (NULL, "S32"); + break; + case AUD_FMT_U32: + AUD_log (NULL, "U32"); + break; default: AUD_log (NULL, "invalid(%d)", as->fmt); break; -- cgit v1.2.3 From a35e86c55fa2858c7828058f2e59956597aaa7af Mon Sep 17 00:00:00 2001 From: malc Date: Mon, 23 Jun 2008 05:47:03 +0000 Subject: Shuffle contents of tcg_target_reg_alloc_order Move reserved/volatile registers down. Currently qemu_ld/stXX are marked with TCG_OPF_CALL_CLOBBER and since memory accesses are frequent and R3 through R12 are volatile moving this down results in less spills and tighter generated code. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4778 c046a42c-6fe2-441c-8c8c-71466251a162 --- tcg/ppc/tcg-target.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index c829b642c..8d5f7dcfc 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -67,9 +67,20 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { }; static const int tcg_target_reg_alloc_order[] = { - TCG_REG_R0, - TCG_REG_R1, - TCG_REG_R2, + TCG_REG_R14, + TCG_REG_R15, + TCG_REG_R16, + TCG_REG_R17, + TCG_REG_R18, + TCG_REG_R19, + TCG_REG_R20, + TCG_REG_R21, + TCG_REG_R22, + TCG_REG_R23, + TCG_REG_R28, + TCG_REG_R29, + TCG_REG_R30, + TCG_REG_R31, TCG_REG_R3, TCG_REG_R4, TCG_REG_R5, @@ -81,24 +92,13 @@ static const int tcg_target_reg_alloc_order[] = { TCG_REG_R11, TCG_REG_R12, TCG_REG_R13, - TCG_REG_R14, - TCG_REG_R15, - TCG_REG_R16, - TCG_REG_R17, - TCG_REG_R18, - TCG_REG_R19, - TCG_REG_R20, - TCG_REG_R21, - TCG_REG_R22, - TCG_REG_R23, + TCG_REG_R0, + TCG_REG_R1, + TCG_REG_R2, TCG_REG_R24, TCG_REG_R25, TCG_REG_R26, - TCG_REG_R27, - TCG_REG_R28, - TCG_REG_R29, - TCG_REG_R30, - TCG_REG_R31 + TCG_REG_R27 }; static const int tcg_target_call_iarg_regs[] = { -- cgit v1.2.3 From ca88500f43053a61f8fda69e25b117525f2d9340 Mon Sep 17 00:00:00 2001 From: malc Date: Mon, 23 Jun 2008 05:47:06 +0000 Subject: According to gcc-4.3.0/gcc/config/rs6000/crtsavres.asm R13 is volatile git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4779 c046a42c-6fe2-441c-8c8c-71466251a162 --- tcg/ppc/tcg-target.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 8d5f7dcfc..39319903c 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -118,7 +118,6 @@ static const int tcg_target_call_oarg_regs[2] = { }; static const int tcg_target_callee_save_regs[] = { - TCG_REG_R13, /* should r13 be saved? */ TCG_REG_R14, TCG_REG_R15, TCG_REG_R16, -- cgit v1.2.3 From be24bb4f3007c3e07cbf1934f7e781493d876ab7 Mon Sep 17 00:00:00 2001 From: ths Date: Mon, 23 Jun 2008 12:57:09 +0000 Subject: Pass T0/T1 explicitly to helper functions, and clean up a few dyngen leftovers. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4780 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/exec.h | 1 - target-mips/helper.h | 300 ++++++------- target-mips/op_helper.c | 1063 +++++++++++++++++++++++------------------------ target-mips/translate.c | 871 ++++++++++++++++++++------------------ 4 files changed, 1130 insertions(+), 1105 deletions(-) diff --git a/target-mips/exec.h b/target-mips/exec.h index ec1b0f4da..2653d34c7 100644 --- a/target-mips/exec.h +++ b/target-mips/exec.h @@ -54,7 +54,6 @@ void dump_fpu(CPUState *env); void fpu_dump_state(CPUState *env, FILE *f, int (*fpu_fprintf)(FILE *f, const char *fmt, ...), int flags); -void dump_sc (void); int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, int mmu_idx, int is_softmmu); diff --git a/target-mips/helper.h b/target-mips/helper.h index 1638d29b3..15ef06493 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -7,157 +7,157 @@ DEF_HELPER(void, do_raise_exception, (int excp)) DEF_HELPER(void, do_interrupt_restart, (void)) #ifdef TARGET_MIPS64 -DEF_HELPER(void, do_ldl, (int mem_idx)) -DEF_HELPER(void, do_ldr, (int mem_idx)) -DEF_HELPER(void, do_sdl, (int mem_idx)) -DEF_HELPER(void, do_sdr, (int mem_idx)) +DEF_HELPER(target_ulong, do_ldl, (target_ulong t0, target_ulong t1, int mem_idx)) +DEF_HELPER(target_ulong, do_ldr, (target_ulong t0, target_ulong t1, int mem_idx)) +DEF_HELPER(void, do_sdl, (target_ulong t0, target_ulong t1, int mem_idx)) +DEF_HELPER(void, do_sdr, (target_ulong t0, target_ulong t1, int mem_idx)) #endif -DEF_HELPER(void, do_lwl, (int mem_idx)) -DEF_HELPER(void, do_lwr, (int mem_idx)) -DEF_HELPER(void, do_swl, (int mem_idx)) -DEF_HELPER(void, do_swr, (int mem_idx)) +DEF_HELPER(target_ulong, do_lwl, (target_ulong t0, target_ulong t1, int mem_idx)) +DEF_HELPER(target_ulong, do_lwr, (target_ulong t0, target_ulong t1, int mem_idx)) +DEF_HELPER(void, do_swl, (target_ulong t0, target_ulong t1, int mem_idx)) +DEF_HELPER(void, do_swr, (target_ulong t0, target_ulong t1, int mem_idx)) -DEF_HELPER(void, do_clo, (void)) -DEF_HELPER(void, do_clz, (void)) +DEF_HELPER(target_ulong, do_clo, (target_ulong t0)) +DEF_HELPER(target_ulong, do_clz, (target_ulong t0)) #ifdef TARGET_MIPS64 -DEF_HELPER(void, do_dclo, (void)) -DEF_HELPER(void, do_dclz, (void)) -DEF_HELPER(void, do_dmult, (void)) -DEF_HELPER(void, do_dmultu, (void)) +DEF_HELPER(target_ulong, do_dclo, (target_ulong t0)) +DEF_HELPER(target_ulong, do_dclz, (target_ulong t0)) +DEF_HELPER(void, do_dmult, (target_ulong t0, target_ulong t1)) +DEF_HELPER(void, do_dmultu, (target_ulong t0, target_ulong t1)) #endif -DEF_HELPER(void, do_muls, (void)) -DEF_HELPER(void, do_mulsu, (void)) -DEF_HELPER(void, do_macc, (void)) -DEF_HELPER(void, do_maccu, (void)) -DEF_HELPER(void, do_msac, (void)) -DEF_HELPER(void, do_msacu, (void)) -DEF_HELPER(void, do_mulhi, (void)) -DEF_HELPER(void, do_mulhiu, (void)) -DEF_HELPER(void, do_mulshi, (void)) -DEF_HELPER(void, do_mulshiu, (void)) -DEF_HELPER(void, do_macchi, (void)) -DEF_HELPER(void, do_macchiu, (void)) -DEF_HELPER(void, do_msachi, (void)) -DEF_HELPER(void, do_msachiu, (void)) +DEF_HELPER(target_ulong, do_muls, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_mulsu, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_macc, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_maccu, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_msac, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_msacu, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_mulhi, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_mulhiu, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_mulshi, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_mulshiu, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_macchi, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_macchiu, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_msachi, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_msachiu, (target_ulong t0, target_ulong t1)) /* CP0 helpers */ #ifndef CONFIG_USER_ONLY -DEF_HELPER(void, do_mfc0_mvpcontrol, (void)) -DEF_HELPER(void, do_mfc0_mvpconf0, (void)) -DEF_HELPER(void, do_mfc0_mvpconf1, (void)) -DEF_HELPER(void, do_mfc0_random, (void)) -DEF_HELPER(void, do_mfc0_tcstatus, (void)) -DEF_HELPER(void, do_mftc0_tcstatus, (void)) -DEF_HELPER(void, do_mfc0_tcbind, (void)) -DEF_HELPER(void, do_mftc0_tcbind, (void)) -DEF_HELPER(void, do_mfc0_tcrestart, (void)) -DEF_HELPER(void, do_mftc0_tcrestart, (void)) -DEF_HELPER(void, do_mfc0_tchalt, (void)) -DEF_HELPER(void, do_mftc0_tchalt, (void)) -DEF_HELPER(void, do_mfc0_tccontext, (void)) -DEF_HELPER(void, do_mftc0_tccontext, (void)) -DEF_HELPER(void, do_mfc0_tcschedule, (void)) -DEF_HELPER(void, do_mftc0_tcschedule, (void)) -DEF_HELPER(void, do_mfc0_tcschefback, (void)) -DEF_HELPER(void, do_mftc0_tcschefback, (void)) -DEF_HELPER(void, do_mfc0_count, (void)) -DEF_HELPER(void, do_mftc0_entryhi, (void)) -DEF_HELPER(void, do_mftc0_status, (void)) -DEF_HELPER(void, do_mfc0_lladdr, (void)) -DEF_HELPER(void, do_mfc0_watchlo, (uint32_t sel)) -DEF_HELPER(void, do_mfc0_watchhi, (uint32_t sel)) -DEF_HELPER(void, do_mfc0_debug, (void)) -DEF_HELPER(void, do_mftc0_debug, (void)) +DEF_HELPER(target_ulong, do_mfc0_mvpcontrol, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mfc0_mvpconf0, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mfc0_mvpconf1, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mfc0_random, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mfc0_tcstatus, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mftc0_tcstatus, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mfc0_tcbind, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mftc0_tcbind, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mfc0_tcrestart, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mftc0_tcrestart, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mfc0_tchalt, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mftc0_tchalt, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mfc0_tccontext, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mftc0_tccontext, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mfc0_tcschedule, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mftc0_tcschedule, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mfc0_tcschefback, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mftc0_tcschefback, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mfc0_count, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mftc0_entryhi, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mftc0_status, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mfc0_lladdr, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mfc0_watchlo, (target_ulong t0, uint32_t sel)) +DEF_HELPER(target_ulong, do_mfc0_watchhi, (target_ulong t0, uint32_t sel)) +DEF_HELPER(target_ulong, do_mfc0_debug, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mftc0_debug, (target_ulong t0)) #ifdef TARGET_MIPS64 -DEF_HELPER(void, do_dmfc0_tcrestart, (void)) -DEF_HELPER(void, do_dmfc0_tchalt, (void)) -DEF_HELPER(void, do_dmfc0_tccontext, (void)) -DEF_HELPER(void, do_dmfc0_tcschedule, (void)) -DEF_HELPER(void, do_dmfc0_tcschefback, (void)) -DEF_HELPER(void, do_dmfc0_lladdr, (void)) -DEF_HELPER(void, do_dmfc0_watchlo, (uint32_t sel)) +DEF_HELPER(target_ulong, do_dmfc0_tcrestart, (target_ulong t0)) +DEF_HELPER(target_ulong, do_dmfc0_tchalt, (target_ulong t0)) +DEF_HELPER(target_ulong, do_dmfc0_tccontext, (target_ulong t0)) +DEF_HELPER(target_ulong, do_dmfc0_tcschedule, (target_ulong t0)) +DEF_HELPER(target_ulong, do_dmfc0_tcschefback, (target_ulong t0)) +DEF_HELPER(target_ulong, do_dmfc0_lladdr, (target_ulong t0)) +DEF_HELPER(target_ulong, do_dmfc0_watchlo, (target_ulong t0, uint32_t sel)) #endif /* TARGET_MIPS64 */ -DEF_HELPER(void, do_mtc0_index, (void)) -DEF_HELPER(void, do_mtc0_mvpcontrol, (void)) -DEF_HELPER(void, do_mtc0_vpecontrol, (void)) -DEF_HELPER(void, do_mtc0_vpeconf0, (void)) -DEF_HELPER(void, do_mtc0_vpeconf1, (void)) -DEF_HELPER(void, do_mtc0_yqmask, (void)) -DEF_HELPER(void, do_mtc0_vpeopt, (void)) -DEF_HELPER(void, do_mtc0_entrylo0, (void)) -DEF_HELPER(void, do_mtc0_tcstatus, (void)) -DEF_HELPER(void, do_mttc0_tcstatus, (void)) -DEF_HELPER(void, do_mtc0_tcbind, (void)) -DEF_HELPER(void, do_mttc0_tcbind, (void)) -DEF_HELPER(void, do_mtc0_tcrestart, (void)) -DEF_HELPER(void, do_mttc0_tcrestart, (void)) -DEF_HELPER(void, do_mtc0_tchalt, (void)) -DEF_HELPER(void, do_mttc0_tchalt, (void)) -DEF_HELPER(void, do_mtc0_tccontext, (void)) -DEF_HELPER(void, do_mttc0_tccontext, (void)) -DEF_HELPER(void, do_mtc0_tcschedule, (void)) -DEF_HELPER(void, do_mttc0_tcschedule, (void)) -DEF_HELPER(void, do_mtc0_tcschefback, (void)) -DEF_HELPER(void, do_mttc0_tcschefback, (void)) -DEF_HELPER(void, do_mtc0_entrylo1, (void)) -DEF_HELPER(void, do_mtc0_context, (void)) -DEF_HELPER(void, do_mtc0_pagemask, (void)) -DEF_HELPER(void, do_mtc0_pagegrain, (void)) -DEF_HELPER(void, do_mtc0_wired, (void)) -DEF_HELPER(void, do_mtc0_srsconf0, (void)) -DEF_HELPER(void, do_mtc0_srsconf1, (void)) -DEF_HELPER(void, do_mtc0_srsconf2, (void)) -DEF_HELPER(void, do_mtc0_srsconf3, (void)) -DEF_HELPER(void, do_mtc0_srsconf4, (void)) -DEF_HELPER(void, do_mtc0_hwrena, (void)) -DEF_HELPER(void, do_mtc0_count, (void)) -DEF_HELPER(void, do_mtc0_entryhi, (void)) -DEF_HELPER(void, do_mttc0_entryhi, (void)) -DEF_HELPER(void, do_mtc0_compare, (void)) -DEF_HELPER(void, do_mtc0_status, (void)) -DEF_HELPER(void, do_mttc0_status, (void)) -DEF_HELPER(void, do_mtc0_intctl, (void)) -DEF_HELPER(void, do_mtc0_srsctl, (void)) -DEF_HELPER(void, do_mtc0_cause, (void)) -DEF_HELPER(void, do_mtc0_ebase, (void)) -DEF_HELPER(void, do_mtc0_config0, (void)) -DEF_HELPER(void, do_mtc0_config2, (void)) -DEF_HELPER(void, do_mtc0_watchlo, (uint32_t sel)) -DEF_HELPER(void, do_mtc0_watchhi, (uint32_t sel)) -DEF_HELPER(void, do_mtc0_xcontext, (void)) -DEF_HELPER(void, do_mtc0_framemask, (void)) -DEF_HELPER(void, do_mtc0_debug, (void)) -DEF_HELPER(void, do_mttc0_debug, (void)) -DEF_HELPER(void, do_mtc0_performance0, (void)) -DEF_HELPER(void, do_mtc0_taglo, (void)) -DEF_HELPER(void, do_mtc0_datalo, (void)) -DEF_HELPER(void, do_mtc0_taghi, (void)) -DEF_HELPER(void, do_mtc0_datahi, (void)) +DEF_HELPER(void, do_mtc0_index, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_mvpcontrol, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_vpecontrol, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_vpeconf0, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_vpeconf1, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_yqmask, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_vpeopt, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_entrylo0, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_tcstatus, (target_ulong t0)) +DEF_HELPER(void, do_mttc0_tcstatus, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_tcbind, (target_ulong t0)) +DEF_HELPER(void, do_mttc0_tcbind, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_tcrestart, (target_ulong t0)) +DEF_HELPER(void, do_mttc0_tcrestart, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_tchalt, (target_ulong t0)) +DEF_HELPER(void, do_mttc0_tchalt, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_tccontext, (target_ulong t0)) +DEF_HELPER(void, do_mttc0_tccontext, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_tcschedule, (target_ulong t0)) +DEF_HELPER(void, do_mttc0_tcschedule, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_tcschefback, (target_ulong t0)) +DEF_HELPER(void, do_mttc0_tcschefback, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_entrylo1, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_context, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_pagemask, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_pagegrain, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_wired, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_srsconf0, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_srsconf1, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_srsconf2, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_srsconf3, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_srsconf4, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_hwrena, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_count, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_entryhi, (target_ulong t0)) +DEF_HELPER(void, do_mttc0_entryhi, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_compare, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_status, (target_ulong t0)) +DEF_HELPER(void, do_mttc0_status, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_intctl, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_srsctl, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_cause, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_ebase, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_config0, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_config2, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_watchlo, (target_ulong t0, uint32_t sel)) +DEF_HELPER(void, do_mtc0_watchhi, (target_ulong t0, uint32_t sel)) +DEF_HELPER(void, do_mtc0_xcontext, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_framemask, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_debug, (target_ulong t0)) +DEF_HELPER(void, do_mttc0_debug, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_performance0, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_taglo, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_datalo, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_taghi, (target_ulong t0)) +DEF_HELPER(void, do_mtc0_datahi, (target_ulong t0)) #endif /* !CONFIG_USER_ONLY */ /* MIPS MT functions */ -DEF_HELPER(void, do_mftgpr, (uint32_t sel)) -DEF_HELPER(void, do_mftlo, (uint32_t sel)) -DEF_HELPER(void, do_mfthi, (uint32_t sel)) -DEF_HELPER(void, do_mftacx, (uint32_t sel)) -DEF_HELPER(void, do_mftdsp, (void)) -DEF_HELPER(void, do_mttgpr, (uint32_t sel)) -DEF_HELPER(void, do_mttlo, (uint32_t sel)) -DEF_HELPER(void, do_mtthi, (uint32_t sel)) -DEF_HELPER(void, do_mttacx, (uint32_t sel)) -DEF_HELPER(void, do_mttdsp, (void)) -DEF_HELPER(void, do_dmt, (void)) -DEF_HELPER(void, do_emt, (void)) -DEF_HELPER(void, do_dvpe, (void)) -DEF_HELPER(void, do_evpe, (void)) -DEF_HELPER(void, do_fork, (void)) -DEF_HELPER(void, do_yield, (void)) +DEF_HELPER(target_ulong, do_mftgpr, (target_ulong t0, uint32_t sel)) +DEF_HELPER(target_ulong, do_mftlo, (target_ulong t0, uint32_t sel)) +DEF_HELPER(target_ulong, do_mfthi, (target_ulong t0, uint32_t sel)) +DEF_HELPER(target_ulong, do_mftacx, (target_ulong t0, uint32_t sel)) +DEF_HELPER(target_ulong, do_mftdsp, (target_ulong t0)) +DEF_HELPER(void, do_mttgpr, (target_ulong t0, uint32_t sel)) +DEF_HELPER(void, do_mttlo, (target_ulong t0, uint32_t sel)) +DEF_HELPER(void, do_mtthi, (target_ulong t0, uint32_t sel)) +DEF_HELPER(void, do_mttacx, (target_ulong t0, uint32_t sel)) +DEF_HELPER(void, do_mttdsp, (target_ulong t0)) +DEF_HELPER(target_ulong, do_dmt, (target_ulong t0)) +DEF_HELPER(target_ulong, do_emt, (target_ulong t0)) +DEF_HELPER(target_ulong, do_dvpe, (target_ulong t0)) +DEF_HELPER(target_ulong, do_evpe, (target_ulong t0)) +DEF_HELPER(target_ulong, do_fork, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_yield, (target_ulong t0)) /* CP1 functions */ -DEF_HELPER(void, do_cfc1, (uint32_t reg)) -DEF_HELPER(void, do_ctc1, (uint32_t reg)) +DEF_HELPER(target_ulong, do_cfc1, (target_ulong t0, uint32_t reg)) +DEF_HELPER(void, do_ctc1, (target_ulong t0, uint32_t reg)) DEF_HELPER(void, do_float_cvtd_s, (void)) DEF_HELPER(void, do_float_cvtd_w, (void)) @@ -239,24 +239,24 @@ FOP_PROTO(ngt) #undef FOP_PROTO /* Special functions */ -DEF_HELPER(void, do_di, (void)) -DEF_HELPER(void, do_ei, (void)) -DEF_HELPER(void, do_eret, (void)) -DEF_HELPER(void, do_deret, (void)) -DEF_HELPER(void, do_rdhwr_cpunum, (void)) -DEF_HELPER(void, do_rdhwr_synci_step, (void)) -DEF_HELPER(void, do_rdhwr_cc, (void)) -DEF_HELPER(void, do_rdhwr_ccres, (void)) +DEF_HELPER(target_ulong, do_di, (target_ulong t0)) +DEF_HELPER(target_ulong, do_ei, (target_ulong t0)) +DEF_HELPER(void, do_eret, (target_ulong t0)) +DEF_HELPER(void, do_deret, (target_ulong t0)) +DEF_HELPER(target_ulong, do_rdhwr_cpunum, (target_ulong t0)) +DEF_HELPER(target_ulong, do_rdhwr_synci_step, (target_ulong t0)) +DEF_HELPER(target_ulong, do_rdhwr_cc, (target_ulong t0)) +DEF_HELPER(target_ulong, do_rdhwr_ccres, (target_ulong t0)) DEF_HELPER(void, do_pmon, (int function)) DEF_HELPER(void, do_wait, (void)) /* Bitfield operations. */ -DEF_HELPER(void, do_ext, (uint32_t pos, uint32_t size)) -DEF_HELPER(void, do_ins, (uint32_t pos, uint32_t size)) -DEF_HELPER(void, do_wsbh, (void)) +DEF_HELPER(target_ulong, do_ext, (target_ulong t0, target_ulong t1, uint32_t pos, uint32_t size)) +DEF_HELPER(target_ulong, do_ins, (target_ulong t0, target_ulong t1, uint32_t pos, uint32_t size)) +DEF_HELPER(target_ulong, do_wsbh, (target_ulong t0, target_ulong t1)) #ifdef TARGET_MIPS64 -DEF_HELPER(void, do_dext, (uint32_t pos, uint32_t size)) -DEF_HELPER(void, do_dins, (uint32_t pos, uint32_t size)) -DEF_HELPER(void, do_dsbh, (void)) -DEF_HELPER(void, do_dshd, (void)) +DEF_HELPER(target_ulong, do_dext, (target_ulong t0, target_ulong t1, uint32_t pos, uint32_t size)) +DEF_HELPER(target_ulong, do_dins, (target_ulong t0, target_ulong t1, uint32_t pos, uint32_t size)) +DEF_HELPER(target_ulong, do_dsbh, (target_ulong t0, target_ulong t1)) +DEF_HELPER(target_ulong, do_dshd, (target_ulong t0, target_ulong t1)) #endif diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 602116a8b..86a720d5a 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -33,7 +33,6 @@ void do_raise_exception_err (uint32_t exception, int error_code) #endif env->exception_index = exception; env->error_code = error_code; - T0 = 0; cpu_loop_exit(); } @@ -65,106 +64,26 @@ void do_restore_state (void *pc_ptr) } } -void do_clo (void) +target_ulong do_clo (target_ulong t0) { - T0 = clo32(T0); + return clo32(t0); } -void do_clz (void) +target_ulong do_clz (target_ulong t0) { - T0 = clz32(T0); + return clz32(t0); } #if defined(TARGET_MIPS64) -#if TARGET_LONG_BITS > HOST_LONG_BITS -/* Those might call libgcc functions. */ -void do_dsll (void) -{ - T0 = T0 << T1; -} - -void do_dsll32 (void) -{ - T0 = T0 << (T1 + 32); -} - -void do_dsra (void) -{ - T0 = (int64_t)T0 >> T1; -} - -void do_dsra32 (void) -{ - T0 = (int64_t)T0 >> (T1 + 32); -} - -void do_dsrl (void) -{ - T0 = T0 >> T1; -} - -void do_dsrl32 (void) -{ - T0 = T0 >> (T1 + 32); -} - -void do_drotr (void) -{ - target_ulong tmp; - - if (T1) { - tmp = T0 << (0x40 - T1); - T0 = (T0 >> T1) | tmp; - } -} - -void do_drotr32 (void) -{ - target_ulong tmp; - - tmp = T0 << (0x40 - (32 + T1)); - T0 = (T0 >> (32 + T1)) | tmp; -} - -void do_dsllv (void) -{ - T0 = T1 << (T0 & 0x3F); -} - -void do_dsrav (void) -{ - T0 = (int64_t)T1 >> (T0 & 0x3F); -} - -void do_dsrlv (void) -{ - T0 = T1 >> (T0 & 0x3F); -} - -void do_drotrv (void) -{ - target_ulong tmp; - - T0 &= 0x3F; - if (T0) { - tmp = T1 << (0x40 - T0); - T0 = (T1 >> T0) | tmp; - } else - T0 = T1; -} - -#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ - -void do_dclo (void) +target_ulong do_dclo (target_ulong t0) { - T0 = clo64(T0); + return clo64(t0); } -void do_dclz (void) +target_ulong do_dclz (target_ulong t0) { - T0 = clz64(T0); + return clz64(t0); } - #endif /* TARGET_MIPS64 */ /* 64 bits arithmetic for 32 bits hosts */ @@ -179,132 +98,160 @@ static always_inline void set_HILO (uint64_t HILO) env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); } -static always_inline void set_HIT0_LO (uint64_t HILO) +static always_inline void set_HIT0_LO (target_ulong t0, uint64_t HILO) { env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF); - T0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); + t0 = env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); } -static always_inline void set_HI_LOT0 (uint64_t HILO) +static always_inline void set_HI_LOT0 (target_ulong t0, uint64_t HILO) { - T0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF); + t0 = env->LO[env->current_tc][0] = (int32_t)(HILO & 0xFFFFFFFF); env->HI[env->current_tc][0] = (int32_t)(HILO >> 32); } #if TARGET_LONG_BITS > HOST_LONG_BITS -void do_madd (void) +void do_madd (target_ulong t0, target_ulong t1) { int64_t tmp; - tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); + tmp = ((int64_t)(int32_t)t0 * (int64_t)(int32_t)t1); set_HILO((int64_t)get_HILO() + tmp); } -void do_maddu (void) +void do_maddu (target_ulong t0, target_ulong t1) { uint64_t tmp; - tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); + tmp = ((uint64_t)(uint32_t)t0 * (uint64_t)(uint32_t)t1); set_HILO(get_HILO() + tmp); } -void do_msub (void) +void do_msub (target_ulong t0, target_ulong t1) { int64_t tmp; - tmp = ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); + tmp = ((int64_t)(int32_t)t0 * (int64_t)(int32_t)t1); set_HILO((int64_t)get_HILO() - tmp); } -void do_msubu (void) +void do_msubu (target_ulong t0, target_ulong t1) { uint64_t tmp; - tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); + tmp = ((uint64_t)(uint32_t)t0 * (uint64_t)(uint32_t)t1); set_HILO(get_HILO() - tmp); } #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ /* Multiplication variants of the vr54xx. */ -void do_muls (void) +target_ulong do_muls (target_ulong t0, target_ulong t1) { - set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); + set_HI_LOT0(t0, 0 - ((int64_t)(int32_t)t0 * (int64_t)(int32_t)t1)); + + return t0; } -void do_mulsu (void) +target_ulong do_mulsu (target_ulong t0, target_ulong t1) { - set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); + set_HI_LOT0(t0, 0 - ((uint64_t)(uint32_t)t0 * (uint64_t)(uint32_t)t1)); + + return t0; } -void do_macc (void) +target_ulong do_macc (target_ulong t0, target_ulong t1) { - set_HI_LOT0(((int64_t)get_HILO()) + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); + set_HI_LOT0(t0, ((int64_t)get_HILO()) + ((int64_t)(int32_t)t0 * (int64_t)(int32_t)t1)); + + return t0; } -void do_macchi (void) +target_ulong do_macchi (target_ulong t0, target_ulong t1) { - set_HIT0_LO(((int64_t)get_HILO()) + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); + set_HIT0_LO(t0, ((int64_t)get_HILO()) + ((int64_t)(int32_t)t0 * (int64_t)(int32_t)t1)); + + return t0; } -void do_maccu (void) +target_ulong do_maccu (target_ulong t0, target_ulong t1) { - set_HI_LOT0(((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); + set_HI_LOT0(t0, ((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)t0 * (uint64_t)(uint32_t)t1)); + + return t0; } -void do_macchiu (void) +target_ulong do_macchiu (target_ulong t0, target_ulong t1) { - set_HIT0_LO(((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); + set_HIT0_LO(t0, ((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)t0 * (uint64_t)(uint32_t)t1)); + + return t0; } -void do_msac (void) +target_ulong do_msac (target_ulong t0, target_ulong t1) { - set_HI_LOT0(((int64_t)get_HILO()) - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); + set_HI_LOT0(t0, ((int64_t)get_HILO()) - ((int64_t)(int32_t)t0 * (int64_t)(int32_t)t1)); + + return t0; } -void do_msachi (void) +target_ulong do_msachi (target_ulong t0, target_ulong t1) { - set_HIT0_LO(((int64_t)get_HILO()) - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); + set_HIT0_LO(t0, ((int64_t)get_HILO()) - ((int64_t)(int32_t)t0 * (int64_t)(int32_t)t1)); + + return t0; } -void do_msacu (void) +target_ulong do_msacu (target_ulong t0, target_ulong t1) { - set_HI_LOT0(((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); + set_HI_LOT0(t0, ((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)t0 * (uint64_t)(uint32_t)t1)); + + return t0; } -void do_msachiu (void) +target_ulong do_msachiu (target_ulong t0, target_ulong t1) { - set_HIT0_LO(((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); + set_HIT0_LO(t0, ((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)t0 * (uint64_t)(uint32_t)t1)); + + return t0; } -void do_mulhi (void) +target_ulong do_mulhi (target_ulong t0, target_ulong t1) { - set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1); + set_HIT0_LO(t0, (int64_t)(int32_t)t0 * (int64_t)(int32_t)t1); + + return t0; } -void do_mulhiu (void) +target_ulong do_mulhiu (target_ulong t0, target_ulong t1) { - set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1); + set_HIT0_LO(t0, (uint64_t)(uint32_t)t0 * (uint64_t)(uint32_t)t1); + + return t0; } -void do_mulshi (void) +target_ulong do_mulshi (target_ulong t0, target_ulong t1) { - set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1)); + set_HIT0_LO(t0, 0 - ((int64_t)(int32_t)t0 * (int64_t)(int32_t)t1)); + + return t0; } -void do_mulshiu (void) +target_ulong do_mulshiu (target_ulong t0, target_ulong t1) { - set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1)); + set_HIT0_LO(t0, 0 - ((uint64_t)(uint32_t)t0 * (uint64_t)(uint32_t)t1)); + + return t0; } #ifdef TARGET_MIPS64 -void do_dmult (void) +void do_dmult (target_ulong t0, target_ulong t1) { - muls64(&(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1); + muls64(&(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), t0, t1); } -void do_dmultu (void) +void do_dmultu (target_ulong t0, target_ulong t1) { - mulu64(&(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), T0, T1); + mulu64(&(env->LO[env->current_tc][0]), &(env->HI[env->current_tc][0]), t0, t1); } #endif @@ -316,7 +263,7 @@ void do_dmultu (void) #define GET_OFFSET(addr, offset) (addr - (offset)) #endif -void do_lwl(int mem_idx) +target_ulong do_lwl(target_ulong t0, target_ulong t1, int mem_idx) { target_ulong tmp; @@ -333,27 +280,27 @@ void do_lwl(int mem_idx) case 2: ldfun = ldub_user; break; } #endif - tmp = ldfun(T0); - T1 = (T1 & 0x00FFFFFF) | (tmp << 24); + tmp = ldfun(t0); + t1 = (t1 & 0x00FFFFFF) | (tmp << 24); - if (GET_LMASK(T0) <= 2) { - tmp = ldfun(GET_OFFSET(T0, 1)); - T1 = (T1 & 0xFF00FFFF) | (tmp << 16); + if (GET_LMASK(t0) <= 2) { + tmp = ldfun(GET_OFFSET(t0, 1)); + t1 = (t1 & 0xFF00FFFF) | (tmp << 16); } - if (GET_LMASK(T0) <= 1) { - tmp = ldfun(GET_OFFSET(T0, 2)); - T1 = (T1 & 0xFFFF00FF) | (tmp << 8); + if (GET_LMASK(t0) <= 1) { + tmp = ldfun(GET_OFFSET(t0, 2)); + t1 = (t1 & 0xFFFF00FF) | (tmp << 8); } - if (GET_LMASK(T0) == 0) { - tmp = ldfun(GET_OFFSET(T0, 3)); - T1 = (T1 & 0xFFFFFF00) | tmp; + if (GET_LMASK(t0) == 0) { + tmp = ldfun(GET_OFFSET(t0, 3)); + t1 = (t1 & 0xFFFFFF00) | tmp; } - T1 = (int32_t)T1; + return (int32_t)t1; } -void do_lwr(int mem_idx) +target_ulong do_lwr(target_ulong t0, target_ulong t1, int mem_idx) { target_ulong tmp; @@ -370,27 +317,27 @@ void do_lwr(int mem_idx) case 2: ldfun = ldub_user; break; } #endif - tmp = ldfun(T0); - T1 = (T1 & 0xFFFFFF00) | tmp; + tmp = ldfun(t0); + t1 = (t1 & 0xFFFFFF00) | tmp; - if (GET_LMASK(T0) >= 1) { - tmp = ldfun(GET_OFFSET(T0, -1)); - T1 = (T1 & 0xFFFF00FF) | (tmp << 8); + if (GET_LMASK(t0) >= 1) { + tmp = ldfun(GET_OFFSET(t0, -1)); + t1 = (t1 & 0xFFFF00FF) | (tmp << 8); } - if (GET_LMASK(T0) >= 2) { - tmp = ldfun(GET_OFFSET(T0, -2)); - T1 = (T1 & 0xFF00FFFF) | (tmp << 16); + if (GET_LMASK(t0) >= 2) { + tmp = ldfun(GET_OFFSET(t0, -2)); + t1 = (t1 & 0xFF00FFFF) | (tmp << 16); } - if (GET_LMASK(T0) == 3) { - tmp = ldfun(GET_OFFSET(T0, -3)); - T1 = (T1 & 0x00FFFFFF) | (tmp << 24); + if (GET_LMASK(t0) == 3) { + tmp = ldfun(GET_OFFSET(t0, -3)); + t1 = (t1 & 0x00FFFFFF) | (tmp << 24); } - T1 = (int32_t)T1; + return (int32_t)t1; } -void do_swl(int mem_idx) +void do_swl(target_ulong t0, target_ulong t1, int mem_idx) { #ifdef CONFIG_USER_ONLY #define stfun stb_raw @@ -405,19 +352,19 @@ void do_swl(int mem_idx) case 2: stfun = stb_user; break; } #endif - stfun(T0, (uint8_t)(T1 >> 24)); + stfun(t0, (uint8_t)(t1 >> 24)); - if (GET_LMASK(T0) <= 2) - stfun(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 16)); + if (GET_LMASK(t0) <= 2) + stfun(GET_OFFSET(t0, 1), (uint8_t)(t1 >> 16)); - if (GET_LMASK(T0) <= 1) - stfun(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 8)); + if (GET_LMASK(t0) <= 1) + stfun(GET_OFFSET(t0, 2), (uint8_t)(t1 >> 8)); - if (GET_LMASK(T0) == 0) - stfun(GET_OFFSET(T0, 3), (uint8_t)T1); + if (GET_LMASK(t0) == 0) + stfun(GET_OFFSET(t0, 3), (uint8_t)t1); } -void do_swr(int mem_idx) +void do_swr(target_ulong t0, target_ulong t1, int mem_idx) { #ifdef CONFIG_USER_ONLY #define stfun stb_raw @@ -432,16 +379,16 @@ void do_swr(int mem_idx) case 2: stfun = stb_user; break; } #endif - stfun(T0, (uint8_t)T1); + stfun(t0, (uint8_t)t1); - if (GET_LMASK(T0) >= 1) - stfun(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8)); + if (GET_LMASK(t0) >= 1) + stfun(GET_OFFSET(t0, -1), (uint8_t)(t1 >> 8)); - if (GET_LMASK(T0) >= 2) - stfun(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16)); + if (GET_LMASK(t0) >= 2) + stfun(GET_OFFSET(t0, -2), (uint8_t)(t1 >> 16)); - if (GET_LMASK(T0) == 3) - stfun(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24)); + if (GET_LMASK(t0) == 3) + stfun(GET_OFFSET(t0, -3), (uint8_t)(t1 >> 24)); } #if defined(TARGET_MIPS64) @@ -454,14 +401,14 @@ void do_swr(int mem_idx) #define GET_LMASK64(v) (((v) & 7) ^ 7) #endif -void do_ldl(int mem_idx) +target_ulong do_ldl(target_ulong t0, target_ulong t1, int mem_idx) { uint64_t tmp; #ifdef CONFIG_USER_ONLY #define ldfun ldub_raw #else - target_ulong (*ldfun)(target_ulong); + int (*ldfun)(target_ulong); switch (mem_idx) { @@ -471,53 +418,55 @@ void do_ldl(int mem_idx) case 2: ldfun = ldub_user; break; } #endif - tmp = ldfun(T0); - T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); + tmp = ldfun(t0); + t1 = (t1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); - if (GET_LMASK64(T0) <= 6) { - tmp = ldfun(GET_OFFSET(T0, 1)); - T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); + if (GET_LMASK64(t0) <= 6) { + tmp = ldfun(GET_OFFSET(t0, 1)); + t1 = (t1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); } - if (GET_LMASK64(T0) <= 5) { - tmp = ldfun(GET_OFFSET(T0, 2)); - T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); + if (GET_LMASK64(t0) <= 5) { + tmp = ldfun(GET_OFFSET(t0, 2)); + t1 = (t1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); } - if (GET_LMASK64(T0) <= 4) { - tmp = ldfun(GET_OFFSET(T0, 3)); - T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); + if (GET_LMASK64(t0) <= 4) { + tmp = ldfun(GET_OFFSET(t0, 3)); + t1 = (t1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); } - if (GET_LMASK64(T0) <= 3) { - tmp = ldfun(GET_OFFSET(T0, 4)); - T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); + if (GET_LMASK64(t0) <= 3) { + tmp = ldfun(GET_OFFSET(t0, 4)); + t1 = (t1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); } - if (GET_LMASK64(T0) <= 2) { - tmp = ldfun(GET_OFFSET(T0, 5)); - T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); + if (GET_LMASK64(t0) <= 2) { + tmp = ldfun(GET_OFFSET(t0, 5)); + t1 = (t1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); } - if (GET_LMASK64(T0) <= 1) { - tmp = ldfun(GET_OFFSET(T0, 6)); - T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); + if (GET_LMASK64(t0) <= 1) { + tmp = ldfun(GET_OFFSET(t0, 6)); + t1 = (t1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); } - if (GET_LMASK64(T0) == 0) { - tmp = ldfun(GET_OFFSET(T0, 7)); - T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; + if (GET_LMASK64(t0) == 0) { + tmp = ldfun(GET_OFFSET(t0, 7)); + t1 = (t1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; } + + return t1; } -void do_ldr(int mem_idx) +target_ulong do_ldr(target_ulong t0, target_ulong t1, int mem_idx) { uint64_t tmp; #ifdef CONFIG_USER_ONLY #define ldfun ldub_raw #else - target_ulong (*ldfun)(target_ulong); + int (*ldfun)(target_ulong); switch (mem_idx) { @@ -527,46 +476,48 @@ void do_ldr(int mem_idx) case 2: ldfun = ldub_user; break; } #endif - tmp = ldfun(T0); - T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; + tmp = ldfun(t0); + t1 = (t1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; - if (GET_LMASK64(T0) >= 1) { - tmp = ldfun(GET_OFFSET(T0, -1)); - T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); + if (GET_LMASK64(t0) >= 1) { + tmp = ldfun(GET_OFFSET(t0, -1)); + t1 = (t1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); } - if (GET_LMASK64(T0) >= 2) { - tmp = ldfun(GET_OFFSET(T0, -2)); - T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); + if (GET_LMASK64(t0) >= 2) { + tmp = ldfun(GET_OFFSET(t0, -2)); + t1 = (t1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); } - if (GET_LMASK64(T0) >= 3) { - tmp = ldfun(GET_OFFSET(T0, -3)); - T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); + if (GET_LMASK64(t0) >= 3) { + tmp = ldfun(GET_OFFSET(t0, -3)); + t1 = (t1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); } - if (GET_LMASK64(T0) >= 4) { - tmp = ldfun(GET_OFFSET(T0, -4)); - T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); + if (GET_LMASK64(t0) >= 4) { + tmp = ldfun(GET_OFFSET(t0, -4)); + t1 = (t1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); } - if (GET_LMASK64(T0) >= 5) { - tmp = ldfun(GET_OFFSET(T0, -5)); - T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); + if (GET_LMASK64(t0) >= 5) { + tmp = ldfun(GET_OFFSET(t0, -5)); + t1 = (t1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); } - if (GET_LMASK64(T0) >= 6) { - tmp = ldfun(GET_OFFSET(T0, -6)); - T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); + if (GET_LMASK64(t0) >= 6) { + tmp = ldfun(GET_OFFSET(t0, -6)); + t1 = (t1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); } - if (GET_LMASK64(T0) == 7) { - tmp = ldfun(GET_OFFSET(T0, -7)); - T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); + if (GET_LMASK64(t0) == 7) { + tmp = ldfun(GET_OFFSET(t0, -7)); + t1 = (t1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); } + + return t1; } -void do_sdl(int mem_idx) +void do_sdl(target_ulong t0, target_ulong t1, int mem_idx) { #ifdef CONFIG_USER_ONLY #define stfun stb_raw @@ -581,31 +532,31 @@ void do_sdl(int mem_idx) case 2: stfun = stb_user; break; } #endif - stfun(T0, (uint8_t)(T1 >> 56)); + stfun(t0, (uint8_t)(t1 >> 56)); - if (GET_LMASK64(T0) <= 6) - stfun(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 48)); + if (GET_LMASK64(t0) <= 6) + stfun(GET_OFFSET(t0, 1), (uint8_t)(t1 >> 48)); - if (GET_LMASK64(T0) <= 5) - stfun(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 40)); + if (GET_LMASK64(t0) <= 5) + stfun(GET_OFFSET(t0, 2), (uint8_t)(t1 >> 40)); - if (GET_LMASK64(T0) <= 4) - stfun(GET_OFFSET(T0, 3), (uint8_t)(T1 >> 32)); + if (GET_LMASK64(t0) <= 4) + stfun(GET_OFFSET(t0, 3), (uint8_t)(t1 >> 32)); - if (GET_LMASK64(T0) <= 3) - stfun(GET_OFFSET(T0, 4), (uint8_t)(T1 >> 24)); + if (GET_LMASK64(t0) <= 3) + stfun(GET_OFFSET(t0, 4), (uint8_t)(t1 >> 24)); - if (GET_LMASK64(T0) <= 2) - stfun(GET_OFFSET(T0, 5), (uint8_t)(T1 >> 16)); + if (GET_LMASK64(t0) <= 2) + stfun(GET_OFFSET(t0, 5), (uint8_t)(t1 >> 16)); - if (GET_LMASK64(T0) <= 1) - stfun(GET_OFFSET(T0, 6), (uint8_t)(T1 >> 8)); + if (GET_LMASK64(t0) <= 1) + stfun(GET_OFFSET(t0, 6), (uint8_t)(t1 >> 8)); - if (GET_LMASK64(T0) <= 0) - stfun(GET_OFFSET(T0, 7), (uint8_t)T1); + if (GET_LMASK64(t0) <= 0) + stfun(GET_OFFSET(t0, 7), (uint8_t)t1); } -void do_sdr(int mem_idx) +void do_sdr(target_ulong t0, target_ulong t1, int mem_idx) { #ifdef CONFIG_USER_ONLY #define stfun stb_raw @@ -620,28 +571,28 @@ void do_sdr(int mem_idx) case 2: stfun = stb_user; break; } #endif - stfun(T0, (uint8_t)T1); + stfun(t0, (uint8_t)t1); - if (GET_LMASK64(T0) >= 1) - stfun(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8)); + if (GET_LMASK64(t0) >= 1) + stfun(GET_OFFSET(t0, -1), (uint8_t)(t1 >> 8)); - if (GET_LMASK64(T0) >= 2) - stfun(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16)); + if (GET_LMASK64(t0) >= 2) + stfun(GET_OFFSET(t0, -2), (uint8_t)(t1 >> 16)); - if (GET_LMASK64(T0) >= 3) - stfun(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24)); + if (GET_LMASK64(t0) >= 3) + stfun(GET_OFFSET(t0, -3), (uint8_t)(t1 >> 24)); - if (GET_LMASK64(T0) >= 4) - stfun(GET_OFFSET(T0, -4), (uint8_t)(T1 >> 32)); + if (GET_LMASK64(t0) >= 4) + stfun(GET_OFFSET(t0, -4), (uint8_t)(t1 >> 32)); - if (GET_LMASK64(T0) >= 5) - stfun(GET_OFFSET(T0, -5), (uint8_t)(T1 >> 40)); + if (GET_LMASK64(t0) >= 5) + stfun(GET_OFFSET(t0, -5), (uint8_t)(t1 >> 40)); - if (GET_LMASK64(T0) >= 6) - stfun(GET_OFFSET(T0, -6), (uint8_t)(T1 >> 48)); + if (GET_LMASK64(t0) >= 6) + stfun(GET_OFFSET(t0, -6), (uint8_t)(t1 >> 48)); - if (GET_LMASK64(T0) == 7) - stfun(GET_OFFSET(T0, -7), (uint8_t)(T1 >> 56)); + if (GET_LMASK64(t0) == 7) + stfun(GET_OFFSET(t0, -7), (uint8_t)(t1 >> 56)); } #endif /* TARGET_MIPS64 */ @@ -699,203 +650,207 @@ void cpu_mips_tlb_flush (CPUState *env, int flush_global) #else /* CP0 helpers */ -void do_mfc0_mvpcontrol (void) +target_ulong do_mfc0_mvpcontrol (target_ulong t0) { - T0 = env->mvp->CP0_MVPControl; + return env->mvp->CP0_MVPControl; } -void do_mfc0_mvpconf0 (void) +target_ulong do_mfc0_mvpconf0 (target_ulong t0) { - T0 = env->mvp->CP0_MVPConf0; + return env->mvp->CP0_MVPConf0; } -void do_mfc0_mvpconf1 (void) +target_ulong do_mfc0_mvpconf1 (target_ulong t0) { - T0 = env->mvp->CP0_MVPConf1; + return env->mvp->CP0_MVPConf1; } -void do_mfc0_random (void) +target_ulong do_mfc0_random (target_ulong t0) { - T0 = (int32_t)cpu_mips_get_random(env); + return (int32_t)cpu_mips_get_random(env); } -void do_mfc0_tcstatus (void) +target_ulong do_mfc0_tcstatus (target_ulong t0) { - T0 = env->CP0_TCStatus[env->current_tc]; + return env->CP0_TCStatus[env->current_tc]; } -void do_mftc0_tcstatus(void) +target_ulong do_mftc0_tcstatus(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->CP0_TCStatus[other_tc]; + return env->CP0_TCStatus[other_tc]; } -void do_mfc0_tcbind (void) +target_ulong do_mfc0_tcbind (target_ulong t0) { - T0 = env->CP0_TCBind[env->current_tc]; + return env->CP0_TCBind[env->current_tc]; } -void do_mftc0_tcbind(void) +target_ulong do_mftc0_tcbind(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->CP0_TCBind[other_tc]; + return env->CP0_TCBind[other_tc]; } -void do_mfc0_tcrestart (void) +target_ulong do_mfc0_tcrestart (target_ulong t0) { - T0 = env->PC[env->current_tc]; + return env->PC[env->current_tc]; } -void do_mftc0_tcrestart(void) +target_ulong do_mftc0_tcrestart(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->PC[other_tc]; + return env->PC[other_tc]; } -void do_mfc0_tchalt (void) +target_ulong do_mfc0_tchalt (target_ulong t0) { - T0 = env->CP0_TCHalt[env->current_tc]; + return env->CP0_TCHalt[env->current_tc]; } -void do_mftc0_tchalt(void) +target_ulong do_mftc0_tchalt(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->CP0_TCHalt[other_tc]; + return env->CP0_TCHalt[other_tc]; } -void do_mfc0_tccontext (void) +target_ulong do_mfc0_tccontext (target_ulong t0) { - T0 = env->CP0_TCContext[env->current_tc]; + return env->CP0_TCContext[env->current_tc]; } -void do_mftc0_tccontext(void) +target_ulong do_mftc0_tccontext(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->CP0_TCContext[other_tc]; + return env->CP0_TCContext[other_tc]; } -void do_mfc0_tcschedule (void) +target_ulong do_mfc0_tcschedule (target_ulong t0) { - T0 = env->CP0_TCSchedule[env->current_tc]; + return env->CP0_TCSchedule[env->current_tc]; } -void do_mftc0_tcschedule(void) +target_ulong do_mftc0_tcschedule(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->CP0_TCSchedule[other_tc]; + return env->CP0_TCSchedule[other_tc]; } -void do_mfc0_tcschefback (void) +target_ulong do_mfc0_tcschefback (target_ulong t0) { - T0 = env->CP0_TCScheFBack[env->current_tc]; + return env->CP0_TCScheFBack[env->current_tc]; } -void do_mftc0_tcschefback(void) +target_ulong do_mftc0_tcschefback(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->CP0_TCScheFBack[other_tc]; + return env->CP0_TCScheFBack[other_tc]; } -void do_mfc0_count (void) +target_ulong do_mfc0_count (target_ulong t0) { - T0 = (int32_t)cpu_mips_get_count(env); + return (int32_t)cpu_mips_get_count(env); } -void do_mftc0_entryhi(void) +target_ulong do_mftc0_entryhi(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff); + return (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff); } -void do_mftc0_status(void) +target_ulong do_mftc0_status(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); uint32_t tcstatus = env->CP0_TCStatus[other_tc]; - T0 = env->CP0_Status & ~0xf1000018; - T0 |= tcstatus & (0xf << CP0TCSt_TCU0); - T0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX); - T0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU); + t0 = env->CP0_Status & ~0xf1000018; + t0 |= tcstatus & (0xf << CP0TCSt_TCU0); + t0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX); + t0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU); + + return t0; } -void do_mfc0_lladdr (void) +target_ulong do_mfc0_lladdr (target_ulong t0) { - T0 = (int32_t)env->CP0_LLAddr >> 4; + return (int32_t)env->CP0_LLAddr >> 4; } -void do_mfc0_watchlo (uint32_t sel) +target_ulong do_mfc0_watchlo (target_ulong t0, uint32_t sel) { - T0 = (int32_t)env->CP0_WatchLo[sel]; + return (int32_t)env->CP0_WatchLo[sel]; } -void do_mfc0_watchhi (uint32_t sel) +target_ulong do_mfc0_watchhi (target_ulong t0, uint32_t sel) { - T0 = env->CP0_WatchHi[sel]; + return env->CP0_WatchHi[sel]; } -void do_mfc0_debug (void) +target_ulong do_mfc0_debug (target_ulong t0) { - T0 = env->CP0_Debug; + t0 = env->CP0_Debug; if (env->hflags & MIPS_HFLAG_DM) - T0 |= 1 << CP0DB_DM; + t0 |= 1 << CP0DB_DM; + + return t0; } -void do_mftc0_debug(void) +target_ulong do_mftc0_debug(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); /* XXX: Might be wrong, check with EJTAG spec. */ - T0 = (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | - (env->CP0_Debug_tcstatus[other_tc] & - ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); + return (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | + (env->CP0_Debug_tcstatus[other_tc] & + ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); } #if defined(TARGET_MIPS64) -void do_dmfc0_tcrestart (void) +target_ulong do_dmfc0_tcrestart (target_ulong t0) { - T0 = env->PC[env->current_tc]; + return env->PC[env->current_tc]; } -void do_dmfc0_tchalt (void) +target_ulong do_dmfc0_tchalt (target_ulong t0) { - T0 = env->CP0_TCHalt[env->current_tc]; + return env->CP0_TCHalt[env->current_tc]; } -void do_dmfc0_tccontext (void) +target_ulong do_dmfc0_tccontext (target_ulong t0) { - T0 = env->CP0_TCContext[env->current_tc]; + return env->CP0_TCContext[env->current_tc]; } -void do_dmfc0_tcschedule (void) +target_ulong do_dmfc0_tcschedule (target_ulong t0) { - T0 = env->CP0_TCSchedule[env->current_tc]; + return env->CP0_TCSchedule[env->current_tc]; } -void do_dmfc0_tcschefback (void) +target_ulong do_dmfc0_tcschefback (target_ulong t0) { - T0 = env->CP0_TCScheFBack[env->current_tc]; + return env->CP0_TCScheFBack[env->current_tc]; } -void do_dmfc0_lladdr (void) +target_ulong do_dmfc0_lladdr (target_ulong t0) { - T0 = env->CP0_LLAddr >> 4; + return env->CP0_LLAddr >> 4; } -void do_dmfc0_watchlo (uint32_t sel) +target_ulong do_dmfc0_watchlo (target_ulong t0, uint32_t sel) { - T0 = env->CP0_WatchLo[sel]; + return env->CP0_WatchLo[sel]; } #endif /* TARGET_MIPS64 */ -void do_mtc0_index (void) +void do_mtc0_index (target_ulong t0) { int num = 1; unsigned int tmp = env->tlb->nb_tlb; @@ -904,10 +859,10 @@ void do_mtc0_index (void) tmp >>= 1; num <<= 1; } while (tmp); - env->CP0_Index = (env->CP0_Index & 0x80000000) | (T0 & (num - 1)); + env->CP0_Index = (env->CP0_Index & 0x80000000) | (t0 & (num - 1)); } -void do_mtc0_mvpcontrol (void) +void do_mtc0_mvpcontrol (target_ulong t0) { uint32_t mask = 0; uint32_t newval; @@ -917,21 +872,21 @@ void do_mtc0_mvpcontrol (void) (1 << CP0MVPCo_EVP); if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) mask |= (1 << CP0MVPCo_STLB); - newval = (env->mvp->CP0_MVPControl & ~mask) | (T0 & mask); + newval = (env->mvp->CP0_MVPControl & ~mask) | (t0 & mask); // TODO: Enable/disable shared TLB, enable/disable VPEs. env->mvp->CP0_MVPControl = newval; } -void do_mtc0_vpecontrol (void) +void do_mtc0_vpecontrol (target_ulong t0) { uint32_t mask; uint32_t newval; mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) | (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC); - newval = (env->CP0_VPEControl & ~mask) | (T0 & mask); + newval = (env->CP0_VPEControl & ~mask) | (t0 & mask); /* Yield scheduler intercept not implemented. */ /* Gating storage scheduler intercept not implemented. */ @@ -941,7 +896,7 @@ void do_mtc0_vpecontrol (void) env->CP0_VPEControl = newval; } -void do_mtc0_vpeconf0 (void) +void do_mtc0_vpeconf0 (target_ulong t0) { uint32_t mask = 0; uint32_t newval; @@ -951,14 +906,14 @@ void do_mtc0_vpeconf0 (void) mask |= (0xff << CP0VPEC0_XTC); mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA); } - newval = (env->CP0_VPEConf0 & ~mask) | (T0 & mask); + newval = (env->CP0_VPEConf0 & ~mask) | (t0 & mask); // TODO: TC exclusive handling due to ERL/EXL. env->CP0_VPEConf0 = newval; } -void do_mtc0_vpeconf1 (void) +void do_mtc0_vpeconf1 (target_ulong t0) { uint32_t mask = 0; uint32_t newval; @@ -966,7 +921,7 @@ void do_mtc0_vpeconf1 (void) if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) mask |= (0xff << CP0VPEC1_NCX) | (0xff << CP0VPEC1_NCP2) | (0xff << CP0VPEC1_NCP1); - newval = (env->CP0_VPEConf1 & ~mask) | (T0 & mask); + newval = (env->CP0_VPEConf1 & ~mask) | (t0 & mask); /* UDI not implemented. */ /* CP2 not implemented. */ @@ -976,57 +931,57 @@ void do_mtc0_vpeconf1 (void) env->CP0_VPEConf1 = newval; } -void do_mtc0_yqmask (void) +void do_mtc0_yqmask (target_ulong t0) { /* Yield qualifier inputs not implemented. */ env->CP0_YQMask = 0x00000000; } -void do_mtc0_vpeopt (void) +void do_mtc0_vpeopt (target_ulong t0) { - env->CP0_VPEOpt = T0 & 0x0000ffff; + env->CP0_VPEOpt = t0 & 0x0000ffff; } -void do_mtc0_entrylo0 (void) +void do_mtc0_entrylo0 (target_ulong t0) { /* Large physaddr (PABITS) not implemented */ /* 1k pages not implemented */ - env->CP0_EntryLo0 = T0 & 0x3FFFFFFF; + env->CP0_EntryLo0 = t0 & 0x3FFFFFFF; } -void do_mtc0_tcstatus (void) +void do_mtc0_tcstatus (target_ulong t0) { uint32_t mask = env->CP0_TCStatus_rw_bitmask; uint32_t newval; - newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (T0 & mask); + newval = (env->CP0_TCStatus[env->current_tc] & ~mask) | (t0 & mask); // TODO: Sync with CP0_Status. env->CP0_TCStatus[env->current_tc] = newval; } -void do_mttc0_tcstatus (void) +void do_mttc0_tcstatus (target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); // TODO: Sync with CP0_Status. - env->CP0_TCStatus[other_tc] = T0; + env->CP0_TCStatus[other_tc] = t0; } -void do_mtc0_tcbind (void) +void do_mtc0_tcbind (target_ulong t0) { uint32_t mask = (1 << CP0TCBd_TBE); uint32_t newval; if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) mask |= (1 << CP0TCBd_CurVPE); - newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (T0 & mask); + newval = (env->CP0_TCBind[env->current_tc] & ~mask) | (t0 & mask); env->CP0_TCBind[env->current_tc] = newval; } -void do_mttc0_tcbind (void) +void do_mttc0_tcbind (target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); uint32_t mask = (1 << CP0TCBd_TBE); @@ -1034,99 +989,99 @@ void do_mttc0_tcbind (void) if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC)) mask |= (1 << CP0TCBd_CurVPE); - newval = (env->CP0_TCBind[other_tc] & ~mask) | (T0 & mask); + newval = (env->CP0_TCBind[other_tc] & ~mask) | (t0 & mask); env->CP0_TCBind[other_tc] = newval; } -void do_mtc0_tcrestart (void) +void do_mtc0_tcrestart (target_ulong t0) { - env->PC[env->current_tc] = T0; + env->PC[env->current_tc] = t0; env->CP0_TCStatus[env->current_tc] &= ~(1 << CP0TCSt_TDS); env->CP0_LLAddr = 0ULL; /* MIPS16 not implemented. */ } -void do_mttc0_tcrestart (void) +void do_mttc0_tcrestart (target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - env->PC[other_tc] = T0; + env->PC[other_tc] = t0; env->CP0_TCStatus[other_tc] &= ~(1 << CP0TCSt_TDS); env->CP0_LLAddr = 0ULL; /* MIPS16 not implemented. */ } -void do_mtc0_tchalt (void) +void do_mtc0_tchalt (target_ulong t0) { - env->CP0_TCHalt[env->current_tc] = T0 & 0x1; + env->CP0_TCHalt[env->current_tc] = t0 & 0x1; // TODO: Halt TC / Restart (if allocated+active) TC. } -void do_mttc0_tchalt (void) +void do_mttc0_tchalt (target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); // TODO: Halt TC / Restart (if allocated+active) TC. - env->CP0_TCHalt[other_tc] = T0; + env->CP0_TCHalt[other_tc] = t0; } -void do_mtc0_tccontext (void) +void do_mtc0_tccontext (target_ulong t0) { - env->CP0_TCContext[env->current_tc] = T0; + env->CP0_TCContext[env->current_tc] = t0; } -void do_mttc0_tccontext (void) +void do_mttc0_tccontext (target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - env->CP0_TCContext[other_tc] = T0; + env->CP0_TCContext[other_tc] = t0; } -void do_mtc0_tcschedule (void) +void do_mtc0_tcschedule (target_ulong t0) { - env->CP0_TCSchedule[env->current_tc] = T0; + env->CP0_TCSchedule[env->current_tc] = t0; } -void do_mttc0_tcschedule (void) +void do_mttc0_tcschedule (target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - env->CP0_TCSchedule[other_tc] = T0; + env->CP0_TCSchedule[other_tc] = t0; } -void do_mtc0_tcschefback (void) +void do_mtc0_tcschefback (target_ulong t0) { - env->CP0_TCScheFBack[env->current_tc] = T0; + env->CP0_TCScheFBack[env->current_tc] = t0; } -void do_mttc0_tcschefback (void) +void do_mttc0_tcschefback (target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - env->CP0_TCScheFBack[other_tc] = T0; + env->CP0_TCScheFBack[other_tc] = t0; } -void do_mtc0_entrylo1 (void) +void do_mtc0_entrylo1 (target_ulong t0) { /* Large physaddr (PABITS) not implemented */ /* 1k pages not implemented */ - env->CP0_EntryLo1 = T0 & 0x3FFFFFFF; + env->CP0_EntryLo1 = t0 & 0x3FFFFFFF; } -void do_mtc0_context (void) +void do_mtc0_context (target_ulong t0) { - env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (T0 & ~0x007FFFFF); + env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (t0 & ~0x007FFFFF); } -void do_mtc0_pagemask (void) +void do_mtc0_pagemask (target_ulong t0) { /* 1k pages not implemented */ - env->CP0_PageMask = T0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1)); + env->CP0_PageMask = t0 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1)); } -void do_mtc0_pagegrain (void) +void do_mtc0_pagegrain (target_ulong t0) { /* SmartMIPS not implemented */ /* Large physaddr (PABITS) not implemented */ @@ -1134,52 +1089,52 @@ void do_mtc0_pagegrain (void) env->CP0_PageGrain = 0; } -void do_mtc0_wired (void) +void do_mtc0_wired (target_ulong t0) { - env->CP0_Wired = T0 % env->tlb->nb_tlb; + env->CP0_Wired = t0 % env->tlb->nb_tlb; } -void do_mtc0_srsconf0 (void) +void do_mtc0_srsconf0 (target_ulong t0) { - env->CP0_SRSConf0 |= T0 & env->CP0_SRSConf0_rw_bitmask; + env->CP0_SRSConf0 |= t0 & env->CP0_SRSConf0_rw_bitmask; } -void do_mtc0_srsconf1 (void) +void do_mtc0_srsconf1 (target_ulong t0) { - env->CP0_SRSConf1 |= T0 & env->CP0_SRSConf1_rw_bitmask; + env->CP0_SRSConf1 |= t0 & env->CP0_SRSConf1_rw_bitmask; } -void do_mtc0_srsconf2 (void) +void do_mtc0_srsconf2 (target_ulong t0) { - env->CP0_SRSConf2 |= T0 & env->CP0_SRSConf2_rw_bitmask; + env->CP0_SRSConf2 |= t0 & env->CP0_SRSConf2_rw_bitmask; } -void do_mtc0_srsconf3 (void) +void do_mtc0_srsconf3 (target_ulong t0) { - env->CP0_SRSConf3 |= T0 & env->CP0_SRSConf3_rw_bitmask; + env->CP0_SRSConf3 |= t0 & env->CP0_SRSConf3_rw_bitmask; } -void do_mtc0_srsconf4 (void) +void do_mtc0_srsconf4 (target_ulong t0) { - env->CP0_SRSConf4 |= T0 & env->CP0_SRSConf4_rw_bitmask; + env->CP0_SRSConf4 |= t0 & env->CP0_SRSConf4_rw_bitmask; } -void do_mtc0_hwrena (void) +void do_mtc0_hwrena (target_ulong t0) { - env->CP0_HWREna = T0 & 0x0000000F; + env->CP0_HWREna = t0 & 0x0000000F; } -void do_mtc0_count (void) +void do_mtc0_count (target_ulong t0) { - cpu_mips_store_count(env, T0); + cpu_mips_store_count(env, t0); } -void do_mtc0_entryhi (void) +void do_mtc0_entryhi (target_ulong t0) { target_ulong old, val; /* 1k pages not implemented */ - val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF); + val = t0 & ((TARGET_PAGE_MASK << 1) | 0xFF); #if defined(TARGET_MIPS64) val &= env->SEGMask; #endif @@ -1194,25 +1149,25 @@ void do_mtc0_entryhi (void) cpu_mips_tlb_flush(env, 1); } -void do_mttc0_entryhi(void) +void do_mttc0_entryhi(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (T0 & ~0xff); - env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (T0 & 0xff); + env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (t0 & ~0xff); + env->CP0_TCStatus[other_tc] = (env->CP0_TCStatus[other_tc] & ~0xff) | (t0 & 0xff); } -void do_mtc0_compare (void) +void do_mtc0_compare (target_ulong t0) { - cpu_mips_store_compare(env, T0); + cpu_mips_store_compare(env, t0); } -void do_mtc0_status (void) +void do_mtc0_status (target_ulong t0) { uint32_t val, old; uint32_t mask = env->CP0_Status_rw_bitmask; - val = T0 & mask; + val = t0 & mask; old = env->CP0_Status; env->CP0_Status = (env->CP0_Status & ~mask) | val; compute_hflags(env); @@ -1221,31 +1176,31 @@ void do_mtc0_status (void) cpu_mips_update_irq(env); } -void do_mttc0_status(void) +void do_mttc0_status(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); uint32_t tcstatus = env->CP0_TCStatus[other_tc]; - env->CP0_Status = T0 & ~0xf1000018; - tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (T0 & (0xf << CP0St_CU0)); - tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((T0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX)); - tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((T0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU)); + env->CP0_Status = t0 & ~0xf1000018; + tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (t0 & (0xf << CP0St_CU0)); + tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((t0 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX)); + tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((t0 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU)); env->CP0_TCStatus[other_tc] = tcstatus; } -void do_mtc0_intctl (void) +void do_mtc0_intctl (target_ulong t0) { /* vectored interrupts not implemented, no performance counters. */ - env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (T0 & 0x000002e0); + env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (t0 & 0x000002e0); } -void do_mtc0_srsctl (void) +void do_mtc0_srsctl (target_ulong t0) { uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS); - env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (T0 & mask); + env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (t0 & mask); } -void do_mtc0_cause (void) +void do_mtc0_cause (target_ulong t0) { uint32_t mask = 0x00C00300; uint32_t old = env->CP0_Cause; @@ -1253,7 +1208,7 @@ void do_mtc0_cause (void) if (env->insn_flags & ISA_MIPS32R2) mask |= 1 << CP0Ca_DC; - env->CP0_Cause = (env->CP0_Cause & ~mask) | (T0 & mask); + env->CP0_Cause = (env->CP0_Cause & ~mask) | (t0 & mask); if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) { if (env->CP0_Cause & (1 << CP0Ca_DC)) @@ -1264,95 +1219,95 @@ void do_mtc0_cause (void) /* Handle the software interrupt as an hardware one, as they are very similar */ - if (T0 & CP0Ca_IP_mask) { + if (t0 & CP0Ca_IP_mask) { cpu_mips_update_irq(env); } } -void do_mtc0_ebase (void) +void do_mtc0_ebase (target_ulong t0) { /* vectored interrupts not implemented */ /* Multi-CPU not implemented */ - env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000); + env->CP0_EBase = 0x80000000 | (t0 & 0x3FFFF000); } -void do_mtc0_config0 (void) +void do_mtc0_config0 (target_ulong t0) { - env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (T0 & 0x00000007); + env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (t0 & 0x00000007); } -void do_mtc0_config2 (void) +void do_mtc0_config2 (target_ulong t0) { /* tertiary/secondary caches not implemented */ env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF); } -void do_mtc0_watchlo (uint32_t sel) +void do_mtc0_watchlo (target_ulong t0, uint32_t sel) { /* Watch exceptions for instructions, data loads, data stores not implemented. */ - env->CP0_WatchLo[sel] = (T0 & ~0x7); + env->CP0_WatchLo[sel] = (t0 & ~0x7); } -void do_mtc0_watchhi (uint32_t sel) +void do_mtc0_watchhi (target_ulong t0, uint32_t sel) { - env->CP0_WatchHi[sel] = (T0 & 0x40FF0FF8); - env->CP0_WatchHi[sel] &= ~(env->CP0_WatchHi[sel] & T0 & 0x7); + env->CP0_WatchHi[sel] = (t0 & 0x40FF0FF8); + env->CP0_WatchHi[sel] &= ~(env->CP0_WatchHi[sel] & t0 & 0x7); } -void do_mtc0_xcontext (void) +void do_mtc0_xcontext (target_ulong t0) { target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1; - env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask); + env->CP0_XContext = (env->CP0_XContext & mask) | (t0 & ~mask); } -void do_mtc0_framemask (void) +void do_mtc0_framemask (target_ulong t0) { - env->CP0_Framemask = T0; /* XXX */ + env->CP0_Framemask = t0; /* XXX */ } -void do_mtc0_debug (void) +void do_mtc0_debug (target_ulong t0) { - env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120); - if (T0 & (1 << CP0DB_DM)) + env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (t0 & 0x13300120); + if (t0 & (1 << CP0DB_DM)) env->hflags |= MIPS_HFLAG_DM; else env->hflags &= ~MIPS_HFLAG_DM; } -void do_mttc0_debug(void) +void do_mttc0_debug(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); /* XXX: Might be wrong, check with EJTAG spec. */ - env->CP0_Debug_tcstatus[other_tc] = T0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)); + env->CP0_Debug_tcstatus[other_tc] = t0 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)); env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) | - (T0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); + (t0 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))); } -void do_mtc0_performance0 (void) +void do_mtc0_performance0 (target_ulong t0) { - env->CP0_Performance0 = T0 & 0x000007ff; + env->CP0_Performance0 = t0 & 0x000007ff; } -void do_mtc0_taglo (void) +void do_mtc0_taglo (target_ulong t0) { - env->CP0_TagLo = T0 & 0xFFFFFCF6; + env->CP0_TagLo = t0 & 0xFFFFFCF6; } -void do_mtc0_datalo (void) +void do_mtc0_datalo (target_ulong t0) { - env->CP0_DataLo = T0; /* XXX */ + env->CP0_DataLo = t0; /* XXX */ } -void do_mtc0_taghi (void) +void do_mtc0_taghi (target_ulong t0) { - env->CP0_TagHi = T0; /* XXX */ + env->CP0_TagHi = t0; /* XXX */ } -void do_mtc0_datahi (void) +void do_mtc0_datahi (target_ulong t0) { - env->CP0_DataHi = T0; /* XXX */ + env->CP0_DataHi = t0; /* XXX */ } void do_mtc0_status_debug(uint32_t old, uint32_t val) @@ -1376,117 +1331,127 @@ void do_mtc0_status_irqraise_debug(void) #endif /* !CONFIG_USER_ONLY */ /* MIPS MT functions */ -void do_mftgpr(uint32_t sel) +target_ulong do_mftgpr(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->gpr[other_tc][sel]; + return env->gpr[other_tc][sel]; } -void do_mftlo(uint32_t sel) +target_ulong do_mftlo(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->LO[other_tc][sel]; + return env->LO[other_tc][sel]; } -void do_mfthi(uint32_t sel) +target_ulong do_mfthi(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->HI[other_tc][sel]; + return env->HI[other_tc][sel]; } -void do_mftacx(uint32_t sel) +target_ulong do_mftacx(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->ACX[other_tc][sel]; + return env->ACX[other_tc][sel]; } -void do_mftdsp(void) +target_ulong do_mftdsp(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->DSPControl[other_tc]; + return env->DSPControl[other_tc]; } -void do_mttgpr(uint32_t sel) +void do_mttgpr(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->gpr[other_tc][sel]; + env->gpr[other_tc][sel] = t0; } -void do_mttlo(uint32_t sel) +void do_mttlo(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->LO[other_tc][sel]; + env->LO[other_tc][sel] = t0; } -void do_mtthi(uint32_t sel) +void do_mtthi(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->HI[other_tc][sel]; + env->HI[other_tc][sel] = t0; } -void do_mttacx(uint32_t sel) +void do_mttacx(target_ulong t0, uint32_t sel) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->ACX[other_tc][sel]; + env->ACX[other_tc][sel] = t0; } -void do_mttdsp(void) +void do_mttdsp(target_ulong t0) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); - T0 = env->DSPControl[other_tc]; + env->DSPControl[other_tc] = t0; } /* MIPS MT functions */ -void do_dmt(void) +target_ulong do_dmt(target_ulong t0) { // TODO - T0 = 0; - // rt = T0 + t0 = 0; + // rt = t0 + + return t0; } -void do_emt(void) +target_ulong do_emt(target_ulong t0) { // TODO - T0 = 0; - // rt = T0 + t0 = 0; + // rt = t0 + + return t0; } -void do_dvpe(void) +target_ulong do_dvpe(target_ulong t0) { // TODO - T0 = 0; - // rt = T0 + t0 = 0; + // rt = t0 + + return t0; } -void do_evpe(void) +target_ulong do_evpe(target_ulong t0) { // TODO - T0 = 0; - // rt = T0 + t0 = 0; + // rt = t0 + + return t0; } -void do_fork(void) +target_ulong do_fork(target_ulong t0, target_ulong t1) { - // T0 = rt, T1 = rs - T0 = 0; + // t0 = rt, t1 = rs + t0 = 0; // TODO: store to TC register + + return t0; } -void do_yield(void) +target_ulong do_yield(target_ulong t0) { - if (T0 < 0) { + if (t0 < 0) { /* No scheduling policy implemented. */ - if (T0 != -2) { + if (t0 != -2) { if (env->CP0_VPEControl & (1 << CP0VPECo_YSI) && env->CP0_TCStatus[env->current_tc] & (1 << CP0TCSt_DT)) { env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT); @@ -1494,20 +1459,20 @@ void do_yield(void) do_raise_exception(EXCP_THREAD); } } - } else if (T0 == 0) { + } else if (t0 == 0) { if (0 /* TODO: TC underflow */) { env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT); do_raise_exception(EXCP_THREAD); } else { // TODO: Deallocate TC } - } else if (T0 > 0) { + } else if (t0 > 0) { /* Yield qualifier inputs not implemented. */ env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT); env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT; do_raise_exception(EXCP_THREAD); } - T0 = env->CP0_YQMask; + return env->CP0_YQMask; } /* CP1 functions */ @@ -1673,33 +1638,23 @@ void r4k_do_tlbr (void) #endif /* !CONFIG_USER_ONLY */ -void dump_ldst (const unsigned char *func) -{ - if (loglevel) - fprintf(logfile, "%s => " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__, T0, T1); -} - -void dump_sc (void) -{ - if (loglevel) { - fprintf(logfile, "%s " TARGET_FMT_lx " at " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", __func__, - T1, T0, env->CP0_LLAddr); - } -} - /* Specials */ -void do_di (void) +target_ulong do_di (target_ulong t0) { - T0 = env->CP0_Status; - env->CP0_Status = T0 & ~(1 << CP0St_IE); + t0 = env->CP0_Status; + env->CP0_Status = t0 & ~(1 << CP0St_IE); cpu_mips_update_irq(env); + + return t0; } -void do_ei (void) +target_ulong do_ei (target_ulong t0) { - T0 = env->CP0_Status; - env->CP0_Status = T0 | (1 << CP0St_IE); + t0 = env->CP0_Status; + env->CP0_Status = t0 | (1 << CP0St_IE); cpu_mips_update_irq(env); + + return t0; } void debug_pre_eret (void) @@ -1729,7 +1684,7 @@ void debug_post_eret (void) } } -void do_eret (void) +void do_eret (target_ulong t0) { if (loglevel & CPU_LOG_EXEC) debug_pre_eret(); @@ -1746,7 +1701,7 @@ void do_eret (void) env->CP0_LLAddr = 1; } -void do_deret (void) +void do_deret (target_ulong t0) { if (loglevel & CPU_LOG_EXEC) debug_pre_eret(); @@ -1758,82 +1713,90 @@ void do_deret (void) env->CP0_LLAddr = 1; } -void do_rdhwr_cpunum(void) +target_ulong do_rdhwr_cpunum(target_ulong t0) { if ((env->hflags & MIPS_HFLAG_CP0) || (env->CP0_HWREna & (1 << 0))) - T0 = env->CP0_EBase & 0x3ff; + t0 = env->CP0_EBase & 0x3ff; else do_raise_exception(EXCP_RI); + + return t0; } -void do_rdhwr_synci_step(void) +target_ulong do_rdhwr_synci_step(target_ulong t0) { if ((env->hflags & MIPS_HFLAG_CP0) || (env->CP0_HWREna & (1 << 1))) - T0 = env->SYNCI_Step; + t0 = env->SYNCI_Step; else do_raise_exception(EXCP_RI); + + return t0; } -void do_rdhwr_cc(void) +target_ulong do_rdhwr_cc(target_ulong t0) { if ((env->hflags & MIPS_HFLAG_CP0) || (env->CP0_HWREna & (1 << 2))) - T0 = env->CP0_Count; + t0 = env->CP0_Count; else do_raise_exception(EXCP_RI); + + return t0; } -void do_rdhwr_ccres(void) +target_ulong do_rdhwr_ccres(target_ulong t0) { if ((env->hflags & MIPS_HFLAG_CP0) || (env->CP0_HWREna & (1 << 3))) - T0 = env->CCRes; + t0 = env->CCRes; else do_raise_exception(EXCP_RI); + + return t0; } /* Bitfield operations. */ -void do_ext(uint32_t pos, uint32_t size) +target_ulong do_ext(target_ulong t0, target_ulong t1, uint32_t pos, uint32_t size) { - T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0)); + return (int32_t)((t1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0)); } -void do_ins(uint32_t pos, uint32_t size) +target_ulong do_ins(target_ulong t0, target_ulong t1, uint32_t pos, uint32_t size) { target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos; - T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask)); + return (int32_t)((t0 & ~mask) | ((t1 << pos) & mask)); } -void do_wsbh(void) +target_ulong do_wsbh(target_ulong t0, target_ulong t1) { - T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF)); + return (int32_t)(((t1 << 8) & ~0x00FF00FF) | ((t1 >> 8) & 0x00FF00FF)); } #if defined(TARGET_MIPS64) -void do_dext(uint32_t pos, uint32_t size) +target_ulong do_dext(target_ulong t0, target_ulong t1, uint32_t pos, uint32_t size) { - T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL); + return (t1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL); } -void do_dins(uint32_t pos, uint32_t size) +target_ulong do_dins(target_ulong t0, target_ulong t1, uint32_t pos, uint32_t size) { target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos; - T0 = (T0 & ~mask) | ((T1 << pos) & mask); + return (t0 & ~mask) | ((t1 << pos) & mask); } -void do_dsbh(void) +target_ulong do_dsbh(target_ulong t0, target_ulong t1) { - T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL); + return ((t1 << 8) & ~0x00FF00FF00FF00FFULL) | ((t1 >> 8) & 0x00FF00FF00FF00FFULL); } -void do_dshd(void) +target_ulong do_dshd(target_ulong t0, target_ulong t1) { - T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL); - T0 = (T1 << 32) | (T1 >> 32); + t1 = ((t1 << 16) & ~0x0000FFFF0000FFFFULL) | ((t1 >> 16) & 0x0000FFFF0000FFFFULL); + return (t1 << 32) | (t1 >> 32); } #endif @@ -1955,51 +1918,53 @@ unsigned int ieee_rm[] = { #define RESTORE_ROUNDING_MODE \ set_float_rounding_mode(ieee_rm[env->fpu->fcr31 & 3], &env->fpu->fp_status) -void do_cfc1 (uint32_t reg) +target_ulong do_cfc1 (target_ulong t0, uint32_t reg) { switch (reg) { case 0: - T0 = (int32_t)env->fpu->fcr0; + t0 = (int32_t)env->fpu->fcr0; break; case 25: - T0 = ((env->fpu->fcr31 >> 24) & 0xfe) | ((env->fpu->fcr31 >> 23) & 0x1); + t0 = ((env->fpu->fcr31 >> 24) & 0xfe) | ((env->fpu->fcr31 >> 23) & 0x1); break; case 26: - T0 = env->fpu->fcr31 & 0x0003f07c; + t0 = env->fpu->fcr31 & 0x0003f07c; break; case 28: - T0 = (env->fpu->fcr31 & 0x00000f83) | ((env->fpu->fcr31 >> 22) & 0x4); + t0 = (env->fpu->fcr31 & 0x00000f83) | ((env->fpu->fcr31 >> 22) & 0x4); break; default: - T0 = (int32_t)env->fpu->fcr31; + t0 = (int32_t)env->fpu->fcr31; break; } + + return t0; } -void do_ctc1 (uint32_t reg) +void do_ctc1 (target_ulong t0, uint32_t reg) { switch(reg) { case 25: - if (T0 & 0xffffff00) + if (t0 & 0xffffff00) return; - env->fpu->fcr31 = (env->fpu->fcr31 & 0x017fffff) | ((T0 & 0xfe) << 24) | - ((T0 & 0x1) << 23); + env->fpu->fcr31 = (env->fpu->fcr31 & 0x017fffff) | ((t0 & 0xfe) << 24) | + ((t0 & 0x1) << 23); break; case 26: - if (T0 & 0x007c0000) + if (t0 & 0x007c0000) return; - env->fpu->fcr31 = (env->fpu->fcr31 & 0xfffc0f83) | (T0 & 0x0003f07c); + env->fpu->fcr31 = (env->fpu->fcr31 & 0xfffc0f83) | (t0 & 0x0003f07c); break; case 28: - if (T0 & 0x007c0000) + if (t0 & 0x007c0000) return; - env->fpu->fcr31 = (env->fpu->fcr31 & 0xfefff07c) | (T0 & 0x00000f83) | - ((T0 & 0x4) << 22); + env->fpu->fcr31 = (env->fpu->fcr31 & 0xfefff07c) | (t0 & 0x00000f83) | + ((t0 & 0x4) << 22); break; case 31: - if (T0 & 0x007c0000) + if (t0 & 0x007c0000) return; - env->fpu->fcr31 = T0; + env->fpu->fcr31 = t0; break; default: return; diff --git a/target-mips/translate.c b/target-mips/translate.c index 9fdf836a0..3d135cc60 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -428,22 +428,74 @@ static TCGv cpu_env, current_tc_gprs, current_tc_hi, current_fpu, cpu_T[2]; /* FPU TNs, global for now. */ static TCGv fpu32_T[3], fpu64_T[3], fpu32h_T[3]; -static inline void tcg_gen_helper_0_1i(void *func, TCGv arg) +static inline void tcg_gen_helper_0_i(void *func, TCGv arg) { - TCGv t = tcg_const_i32(arg); + TCGv tmp = tcg_const_i32(arg); - tcg_gen_helper_0_1(func, t); - tcg_temp_free(t); + tcg_gen_helper_0_1(func, tmp); + tcg_temp_free(tmp); } -static inline void tcg_gen_helper_0_2ii(void *func, TCGv arg1, TCGv arg2) +static inline void tcg_gen_helper_0_ii(void *func, TCGv arg1, TCGv arg2) { - TCGv t1 = tcg_const_i32(arg1); - TCGv t2 = tcg_const_i32(arg2); + TCGv tmp1 = tcg_const_i32(arg1); + TCGv tmp2 = tcg_const_i32(arg2); - tcg_gen_helper_0_2(func, t1, t2); - tcg_temp_free(t1); - tcg_temp_free(t2); + tcg_gen_helper_0_2(func, tmp1, tmp2); + tcg_temp_free(tmp1); + tcg_temp_free(tmp2); +} + +static inline void tcg_gen_helper_0_1i(void *func, TCGv arg1, TCGv arg2) +{ + TCGv tmp = tcg_const_i32(arg2); + + tcg_gen_helper_0_2(func, arg1, tmp); + tcg_temp_free(tmp); +} + +static inline void tcg_gen_helper_0_2i(void *func, TCGv arg1, TCGv arg2, TCGv arg3) +{ + TCGv tmp = tcg_const_i32(arg3); + + tcg_gen_helper_0_3(func, arg1, arg2, tmp); + tcg_temp_free(tmp); +} + +static inline void tcg_gen_helper_0_2ii(void *func, TCGv arg1, TCGv arg2, TCGv arg3, TCGv arg4) +{ + TCGv tmp1 = tcg_const_i32(arg3); + TCGv tmp2 = tcg_const_i32(arg3); + + tcg_gen_helper_0_4(func, arg1, arg2, tmp1, tmp2); + tcg_temp_free(tmp1); + tcg_temp_free(tmp2); +} + +static inline void tcg_gen_helper_1_1i(void *func, TCGv ret, TCGv arg1, TCGv arg2) +{ + TCGv tmp = tcg_const_i32(arg2); + + tcg_gen_helper_1_2(func, ret, arg1, tmp); + tcg_temp_free(tmp); +} + +static inline void tcg_gen_helper_1_2i(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3) +{ + TCGv tmp = tcg_const_i32(arg3); + + tcg_gen_helper_1_3(func, ret, arg1, arg2, tmp); + tcg_temp_free(tmp); +} + +static inline void tcg_gen_helper_1_2ii(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, TCGv arg4) +{ + TCGv tmp1 = tcg_const_i32(arg3); + TCGv tmp2 = tcg_const_i32(arg3); + + tcg_gen_helper_1_4(func, ret, arg1, arg2, tmp1, tmp2); + tcg_temp_free(tmp1); + tcg_temp_free(tmp2); } typedef struct DisasContext { @@ -540,37 +592,44 @@ static inline void gen_store_HI (TCGv t, int reg) } /* Moves to/from shadow registers. */ -static inline void gen_load_srsgpr (TCGv t, int reg) +static inline void gen_load_srsgpr (int from, int to) { - if (reg == 0) - tcg_gen_movi_tl(t, 0); + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL); + + if (from == 0) + tcg_gen_movi_tl(r_tmp1, 0); else { - TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); - tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl)); - tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS); - tcg_gen_andi_i32(r_tmp, r_tmp, 0xf); - tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32); - tcg_gen_add_i32(r_tmp, cpu_env, r_tmp); + tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl)); + tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS); + tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf); + tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32); + tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2); - tcg_gen_ld_tl(t, r_tmp, sizeof(target_ulong) * reg); - tcg_temp_free(r_tmp); + tcg_gen_ld_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * from); + tcg_temp_free(r_tmp2); } + gen_store_gpr(r_tmp1, to); + tcg_temp_free(r_tmp1); } -static inline void gen_store_srsgpr (TCGv t, int reg) +static inline void gen_store_srsgpr (int from, int to) { - if (reg != 0) { - TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32); - - tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl)); - tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS); - tcg_gen_andi_i32(r_tmp, r_tmp, 0xf); - tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32); - tcg_gen_add_i32(r_tmp, cpu_env, r_tmp); - - tcg_gen_st_tl(t, r_tmp, sizeof(target_ulong) * reg); - tcg_temp_free(r_tmp); + if (to != 0) { + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL); + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); + + gen_load_gpr(r_tmp1, from); + tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl)); + tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS); + tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf); + tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32); + tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2); + + tcg_gen_st_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * to); + tcg_temp_free(r_tmp1); + tcg_temp_free(r_tmp2); } } @@ -666,7 +725,7 @@ static GenOpFunc1 * fcmp ## type ## _ ## fmt ## _table[16] = { \ }; \ static inline void gen_cmp ## type ## _ ## fmt(int n, long cc) \ { \ - tcg_gen_helper_0_1i(fcmp ## type ## _ ## fmt ## _table[n], cc); \ + tcg_gen_helper_0_i(fcmp ## type ## _ ## fmt ## _table[n], cc); \ } FOP_CONDS(, d) @@ -679,16 +738,16 @@ FOP_CONDS(abs, ps) /* Tests */ #define OP_COND(name, cond) \ -void glue(gen_op_, name) (void) \ +void glue(gen_op_, name) (TCGv t0, TCGv t1) \ { \ int l1 = gen_new_label(); \ int l2 = gen_new_label(); \ \ - tcg_gen_brcond_tl(cond, cpu_T[0], cpu_T[1], l1); \ - tcg_gen_movi_tl(cpu_T[0], 0); \ + tcg_gen_brcond_tl(cond, t0, t1, l1); \ + tcg_gen_movi_tl(t0, 0); \ tcg_gen_br(l2); \ gen_set_label(l1); \ - tcg_gen_movi_tl(cpu_T[0], 1); \ + tcg_gen_movi_tl(t0, 1); \ gen_set_label(l2); \ } OP_COND(eq, TCG_COND_EQ); @@ -700,16 +759,16 @@ OP_COND(ltu, TCG_COND_LTU); #undef OP_COND #define OP_CONDI(name, cond) \ -void glue(gen_op_, name) (target_ulong val) \ +void glue(gen_op_, name) (TCGv t, target_ulong val) \ { \ int l1 = gen_new_label(); \ int l2 = gen_new_label(); \ \ - tcg_gen_brcondi_tl(cond, cpu_T[0], val, l1); \ - tcg_gen_movi_tl(cpu_T[0], 0); \ + tcg_gen_brcondi_tl(cond, t, val, l1); \ + tcg_gen_movi_tl(t, 0); \ tcg_gen_br(l2); \ gen_set_label(l1); \ - tcg_gen_movi_tl(cpu_T[0], 1); \ + tcg_gen_movi_tl(t, 1); \ gen_set_label(l2); \ } OP_CONDI(lti, TCG_COND_LT); @@ -717,16 +776,16 @@ OP_CONDI(ltiu, TCG_COND_LTU); #undef OP_CONDI #define OP_CONDZ(name, cond) \ -void glue(gen_op_, name) (void) \ +void glue(gen_op_, name) (TCGv t) \ { \ int l1 = gen_new_label(); \ int l2 = gen_new_label(); \ \ - tcg_gen_brcondi_tl(cond, cpu_T[0], 0, l1); \ - tcg_gen_movi_tl(cpu_T[0], 0); \ + tcg_gen_brcondi_tl(cond, t, 0, l1); \ + tcg_gen_movi_tl(t, 0); \ tcg_gen_br(l2); \ gen_set_label(l1); \ - tcg_gen_movi_tl(cpu_T[0], 1); \ + tcg_gen_movi_tl(t, 1); \ gen_set_label(l2); \ } OP_CONDZ(gez, TCG_COND_GE); @@ -840,7 +899,7 @@ static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err) { save_cpu_state(ctx, 1); - tcg_gen_helper_0_2ii(do_raise_exception_err, excp, err); + tcg_gen_helper_0_ii(do_raise_exception_err, excp, err); tcg_gen_helper_0_0(do_interrupt_restart); tcg_gen_exit_tb(0); } @@ -849,15 +908,15 @@ static always_inline void generate_exception (DisasContext *ctx, int excp) { save_cpu_state(ctx, 1); - tcg_gen_helper_0_1i(do_raise_exception, excp); + tcg_gen_helper_0_i(do_raise_exception, excp); tcg_gen_helper_0_0(do_interrupt_restart); tcg_gen_exit_tb(0); } /* Addresses computation */ -static inline void gen_op_addr_add (void) +static inline void gen_op_addr_add (TCGv t0, TCGv t1) { - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_add_tl(t0, t0, t1); #if defined(TARGET_MIPS64) /* For compatibility with 32-bit code, data reference in user mode @@ -874,7 +933,7 @@ static inline void gen_op_addr_add (void) tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX)); tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1); tcg_temp_free(r_tmp); - tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_i64(t0, t0); gen_set_label(l1); } #endif @@ -946,9 +1005,9 @@ static always_inline void check_mips_64(DisasContext *ctx) /* load/store instructions. */ #define OP_LD(insn,fname) \ -void inline op_ldst_##insn(DisasContext *ctx) \ +void inline op_ldst_##insn(TCGv t0, DisasContext *ctx) \ { \ - tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx); \ + tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx); \ } OP_LD(lb,ld8s); OP_LD(lbu,ld8u); @@ -962,9 +1021,9 @@ OP_LD(ld,ld64); #undef OP_LD #define OP_ST(insn,fname) \ -void inline op_ldst_##insn(DisasContext *ctx) \ +void inline op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \ { \ - tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx); \ + tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx); \ } OP_ST(sb,st8); OP_ST(sh,st16); @@ -975,11 +1034,11 @@ OP_ST(sd,st64); #undef OP_ST #define OP_LD_ATOMIC(insn,fname) \ -void inline op_ldst_##insn(DisasContext *ctx) \ +void inline op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \ { \ - tcg_gen_mov_tl(cpu_T[1], cpu_T[0]); \ - tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx); \ - tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr)); \ + tcg_gen_mov_tl(t1, t0); \ + tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx); \ + tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, CP0_LLAddr)); \ } OP_LD_ATOMIC(ll,ld32s); #if defined(TARGET_MIPS64) @@ -988,26 +1047,26 @@ OP_LD_ATOMIC(lld,ld64); #undef OP_LD_ATOMIC #define OP_ST_ATOMIC(insn,fname,almask) \ -void inline op_ldst_##insn(DisasContext *ctx) \ +void inline op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \ { \ TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL); \ int l1 = gen_new_label(); \ int l2 = gen_new_label(); \ int l3 = gen_new_label(); \ \ - tcg_gen_andi_tl(r_tmp, cpu_T[0], almask); \ + tcg_gen_andi_tl(r_tmp, t0, almask); \ tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1); \ - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \ + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr)); \ generate_exception(ctx, EXCP_AdES); \ gen_set_label(l1); \ tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr)); \ - tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2); \ + tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2); \ tcg_temp_free(r_tmp); \ - tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx); \ - tcg_gen_movi_tl(cpu_T[0], 1); \ + tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx); \ + tcg_gen_movi_tl(t0, 1); \ tcg_gen_br(l3); \ gen_set_label(l2); \ - tcg_gen_movi_tl(cpu_T[0], 0); \ + tcg_gen_movi_tl(t0, 0); \ gen_set_label(l3); \ } OP_ST_ATOMIC(sc,st32,0x3); @@ -1029,141 +1088,141 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, } else { gen_load_gpr(cpu_T[0], base); tcg_gen_movi_tl(cpu_T[1], offset); - gen_op_addr_add(); + gen_op_addr_add(cpu_T[0], cpu_T[1]); } /* Don't do NOP if destination is zero: we must perform the actual memory access. */ switch (opc) { #if defined(TARGET_MIPS64) case OPC_LWU: - op_ldst_lwu(ctx); + op_ldst_lwu(cpu_T[0], ctx); gen_store_gpr(cpu_T[0], rt); opn = "lwu"; break; case OPC_LD: - op_ldst_ld(ctx); + op_ldst_ld(cpu_T[0], ctx); gen_store_gpr(cpu_T[0], rt); opn = "ld"; break; case OPC_LLD: - op_ldst_lld(ctx); + op_ldst_lld(cpu_T[0], cpu_T[1], ctx); gen_store_gpr(cpu_T[0], rt); opn = "lld"; break; case OPC_SD: gen_load_gpr(cpu_T[1], rt); - op_ldst_sd(ctx); + op_ldst_sd(cpu_T[0], cpu_T[1], ctx); opn = "sd"; break; case OPC_SCD: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - op_ldst_scd(ctx); + op_ldst_scd(cpu_T[0], cpu_T[1], ctx); gen_store_gpr(cpu_T[0], rt); opn = "scd"; break; case OPC_LDL: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_1i(do_ldl, ctx->mem_idx); + tcg_gen_helper_1_2i(do_ldl, cpu_T[1], cpu_T[0], cpu_T[1], ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "ldl"; break; case OPC_SDL: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_1i(do_sdl, ctx->mem_idx); + tcg_gen_helper_0_2i(do_sdl, cpu_T[0], cpu_T[1], ctx->mem_idx); opn = "sdl"; break; case OPC_LDR: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_1i(do_ldr, ctx->mem_idx); + tcg_gen_helper_1_2i(do_ldr, cpu_T[1], cpu_T[0], cpu_T[1], ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "ldr"; break; case OPC_SDR: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_1i(do_sdr, ctx->mem_idx); + tcg_gen_helper_0_2i(do_sdr, cpu_T[0], cpu_T[1], ctx->mem_idx); opn = "sdr"; break; #endif case OPC_LW: - op_ldst_lw(ctx); + op_ldst_lw(cpu_T[0], ctx); gen_store_gpr(cpu_T[0], rt); opn = "lw"; break; case OPC_SW: gen_load_gpr(cpu_T[1], rt); - op_ldst_sw(ctx); + op_ldst_sw(cpu_T[0], cpu_T[1], ctx); opn = "sw"; break; case OPC_LH: - op_ldst_lh(ctx); + op_ldst_lh(cpu_T[0], ctx); gen_store_gpr(cpu_T[0], rt); opn = "lh"; break; case OPC_SH: gen_load_gpr(cpu_T[1], rt); - op_ldst_sh(ctx); + op_ldst_sh(cpu_T[0], cpu_T[1], ctx); opn = "sh"; break; case OPC_LHU: - op_ldst_lhu(ctx); + op_ldst_lhu(cpu_T[0], ctx); gen_store_gpr(cpu_T[0], rt); opn = "lhu"; break; case OPC_LB: - op_ldst_lb(ctx); + op_ldst_lb(cpu_T[0], ctx); gen_store_gpr(cpu_T[0], rt); opn = "lb"; break; case OPC_SB: gen_load_gpr(cpu_T[1], rt); - op_ldst_sb(ctx); + op_ldst_sb(cpu_T[0], cpu_T[1], ctx); opn = "sb"; break; case OPC_LBU: - op_ldst_lbu(ctx); + op_ldst_lbu(cpu_T[0], ctx); gen_store_gpr(cpu_T[0], rt); opn = "lbu"; break; case OPC_LWL: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_1i(do_lwl, ctx->mem_idx); + tcg_gen_helper_1_2i(do_lwl, cpu_T[1], cpu_T[0], cpu_T[1], ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "lwl"; break; case OPC_SWL: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_1i(do_swl, ctx->mem_idx); + tcg_gen_helper_0_2i(do_swl, cpu_T[0], cpu_T[1], ctx->mem_idx); opn = "swr"; break; case OPC_LWR: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_1i(do_lwr, ctx->mem_idx); + tcg_gen_helper_1_2i(do_lwr, cpu_T[1], cpu_T[0], cpu_T[1], ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "lwr"; break; case OPC_SWR: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_1i(do_swr, ctx->mem_idx); + tcg_gen_helper_0_2i(do_swr, cpu_T[0], cpu_T[1], ctx->mem_idx); opn = "swr"; break; case OPC_LL: - op_ldst_ll(ctx); + op_ldst_ll(cpu_T[0], cpu_T[1], ctx); gen_store_gpr(cpu_T[0], rt); opn = "ll"; break; case OPC_SC: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); - op_ldst_sc(ctx); + op_ldst_sc(cpu_T[0], cpu_T[1], ctx); gen_store_gpr(cpu_T[0], rt); opn = "sc"; break; @@ -1188,7 +1247,7 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, } else { gen_load_gpr(cpu_T[0], base); tcg_gen_movi_tl(cpu_T[1], offset); - gen_op_addr_add(); + gen_op_addr_add(cpu_T[0], cpu_T[1]); } /* Don't do NOP if destination is zero: we must perform the actual memory access. */ @@ -1245,7 +1304,6 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, case OPC_SLTI: case OPC_SLTIU: uimm = (target_long)imm; /* Sign extend to 32/64 bits */ - tcg_gen_movi_tl(cpu_T[1], uimm); /* Fall through. */ case OPC_ANDI: case OPC_ORI: @@ -1334,11 +1392,11 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, break; #endif case OPC_SLTI: - gen_op_lti(uimm); + gen_op_lti(cpu_T[0], uimm); opn = "slti"; break; case OPC_SLTIU: - gen_op_ltiu(uimm); + gen_op_ltiu(cpu_T[0], uimm); opn = "sltiu"; break; case OPC_ANDI: @@ -1645,11 +1703,11 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, break; #endif case OPC_SLT: - gen_op_lt(); + gen_op_lt(cpu_T[0], cpu_T[1]); opn = "slt"; break; case OPC_SLTU: - gen_op_ltu(); + gen_op_ltu(cpu_T[0], cpu_T[1]); opn = "sltu"; break; case OPC_AND: @@ -2031,11 +2089,11 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, opn = "ddivu"; break; case OPC_DMULT: - tcg_gen_helper_0_0(do_dmult); + tcg_gen_helper_0_2(do_dmult, cpu_T[0], cpu_T[1]); opn = "dmult"; break; case OPC_DMULTU: - tcg_gen_helper_0_0(do_dmultu); + tcg_gen_helper_0_2(do_dmultu, cpu_T[0], cpu_T[1]); opn = "dmultu"; break; #endif @@ -2181,59 +2239,59 @@ static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, switch (opc) { case OPC_VR54XX_MULS: - tcg_gen_helper_0_0(do_muls); + tcg_gen_helper_1_2(do_muls, cpu_T[0], cpu_T[0], cpu_T[1]); opn = "muls"; break; case OPC_VR54XX_MULSU: - tcg_gen_helper_0_0(do_mulsu); + tcg_gen_helper_1_2(do_mulsu, cpu_T[0], cpu_T[0], cpu_T[1]); opn = "mulsu"; break; case OPC_VR54XX_MACC: - tcg_gen_helper_0_0(do_macc); + tcg_gen_helper_1_2(do_macc, cpu_T[0], cpu_T[0], cpu_T[1]); opn = "macc"; break; case OPC_VR54XX_MACCU: - tcg_gen_helper_0_0(do_maccu); + tcg_gen_helper_1_2(do_maccu, cpu_T[0], cpu_T[0], cpu_T[1]); opn = "maccu"; break; case OPC_VR54XX_MSAC: - tcg_gen_helper_0_0(do_msac); + tcg_gen_helper_1_2(do_msac, cpu_T[0], cpu_T[0], cpu_T[1]); opn = "msac"; break; case OPC_VR54XX_MSACU: - tcg_gen_helper_0_0(do_msacu); + tcg_gen_helper_1_2(do_msacu, cpu_T[0], cpu_T[0], cpu_T[1]); opn = "msacu"; break; case OPC_VR54XX_MULHI: - tcg_gen_helper_0_0(do_mulhi); + tcg_gen_helper_1_2(do_mulhi, cpu_T[0], cpu_T[0], cpu_T[1]); opn = "mulhi"; break; case OPC_VR54XX_MULHIU: - tcg_gen_helper_0_0(do_mulhiu); + tcg_gen_helper_1_2(do_mulhiu, cpu_T[0], cpu_T[0], cpu_T[1]); opn = "mulhiu"; break; case OPC_VR54XX_MULSHI: - tcg_gen_helper_0_0(do_mulshi); + tcg_gen_helper_1_2(do_mulshi, cpu_T[0], cpu_T[0], cpu_T[1]); opn = "mulshi"; break; case OPC_VR54XX_MULSHIU: - tcg_gen_helper_0_0(do_mulshiu); + tcg_gen_helper_1_2(do_mulshiu, cpu_T[0], cpu_T[0], cpu_T[1]); opn = "mulshiu"; break; case OPC_VR54XX_MACCHI: - tcg_gen_helper_0_0(do_macchi); + tcg_gen_helper_1_2(do_macchi, cpu_T[0], cpu_T[0], cpu_T[1]); opn = "macchi"; break; case OPC_VR54XX_MACCHIU: - tcg_gen_helper_0_0(do_macchiu); + tcg_gen_helper_1_2(do_macchiu, cpu_T[0], cpu_T[0], cpu_T[1]); opn = "macchiu"; break; case OPC_VR54XX_MSACHI: - tcg_gen_helper_0_0(do_msachi); + tcg_gen_helper_1_2(do_msachi, cpu_T[0], cpu_T[0], cpu_T[1]); opn = "msachi"; break; case OPC_VR54XX_MSACHIU: - tcg_gen_helper_0_0(do_msachiu); + tcg_gen_helper_1_2(do_msachiu, cpu_T[0], cpu_T[0], cpu_T[1]); opn = "msachiu"; break; default: @@ -2257,20 +2315,20 @@ static void gen_cl (DisasContext *ctx, uint32_t opc, gen_load_gpr(cpu_T[0], rs); switch (opc) { case OPC_CLO: - tcg_gen_helper_0_0(do_clo); + tcg_gen_helper_1_1(do_clo, cpu_T[0], cpu_T[0]); opn = "clo"; break; case OPC_CLZ: - tcg_gen_helper_0_0(do_clz); + tcg_gen_helper_1_1(do_clz, cpu_T[0], cpu_T[0]); opn = "clz"; break; #if defined(TARGET_MIPS64) case OPC_DCLO: - tcg_gen_helper_0_0(do_dclo); + tcg_gen_helper_1_1(do_dclo, cpu_T[0], cpu_T[0]); opn = "dclo"; break; case OPC_DCLZ: - tcg_gen_helper_0_0(do_dclz); + tcg_gen_helper_1_1(do_dclz, cpu_T[0], cpu_T[0]); opn = "dclz"; break; #endif @@ -2288,6 +2346,8 @@ static void gen_trap (DisasContext *ctx, uint32_t opc, int rs, int rt, int16_t imm) { int cond; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); cond = 0; /* Load needed operands */ @@ -2300,8 +2360,8 @@ static void gen_trap (DisasContext *ctx, uint32_t opc, case OPC_TNE: /* Compare two registers */ if (rs != rt) { - gen_load_gpr(cpu_T[0], rs); - gen_load_gpr(cpu_T[1], rt); + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); cond = 1; } break; @@ -2313,8 +2373,8 @@ static void gen_trap (DisasContext *ctx, uint32_t opc, case OPC_TNEI: /* Compare register to immediate */ if (rs != 0 || imm != 0) { - gen_load_gpr(cpu_T[0], rs); - tcg_gen_movi_tl(cpu_T[1], (int32_t)imm); + gen_load_gpr(t0, rs); + tcg_gen_movi_tl(t1, (int32_t)imm); cond = 1; } break; @@ -2328,7 +2388,7 @@ static void gen_trap (DisasContext *ctx, uint32_t opc, case OPC_TGEU: /* rs >= rs unsigned */ case OPC_TGEIU: /* r0 >= 0 unsigned */ /* Always trap */ - tcg_gen_movi_tl(cpu_T[0], 1); + tcg_gen_movi_tl(t0, 1); break; case OPC_TLT: /* rs < rs */ case OPC_TLTI: /* r0 < 0 */ @@ -2337,53 +2397,56 @@ static void gen_trap (DisasContext *ctx, uint32_t opc, case OPC_TNE: /* rs != rs */ case OPC_TNEI: /* r0 != 0 */ /* Never trap: treat as NOP. */ - return; + goto out; default: MIPS_INVAL("trap"); generate_exception(ctx, EXCP_RI); - return; + goto out; } } else { switch (opc) { case OPC_TEQ: case OPC_TEQI: - gen_op_eq(); + gen_op_eq(t0, t1); break; case OPC_TGE: case OPC_TGEI: - gen_op_ge(); + gen_op_ge(t0, t1); break; case OPC_TGEU: case OPC_TGEIU: - gen_op_geu(); + gen_op_geu(t0, t1); break; case OPC_TLT: case OPC_TLTI: - gen_op_lt(); + gen_op_lt(t0, t1); break; case OPC_TLTU: case OPC_TLTIU: - gen_op_ltu(); + gen_op_ltu(t0, t1); break; case OPC_TNE: case OPC_TNEI: - gen_op_ne(); + gen_op_ne(t0, t1); break; default: MIPS_INVAL("trap"); generate_exception(ctx, EXCP_RI); - return; + goto out; } } save_cpu_state(ctx, 1); { int l1 = gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); - tcg_gen_helper_0_1i(do_raise_exception, EXCP_TRAP); + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); + tcg_gen_helper_0_i(do_raise_exception, EXCP_TRAP); gen_set_label(l1); } ctx->bstate = BS_STOP; + out: + tcg_temp_free(t0); + tcg_temp_free(t1); } static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) @@ -2546,69 +2609,69 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, } else { switch (opc) { case OPC_BEQ: - gen_op_eq(); + gen_op_eq(cpu_T[0], cpu_T[1]); MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto not_likely; case OPC_BEQL: - gen_op_eq(); + gen_op_eq(cpu_T[0], cpu_T[1]); MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto likely; case OPC_BNE: - gen_op_ne(); + gen_op_ne(cpu_T[0], cpu_T[1]); MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto not_likely; case OPC_BNEL: - gen_op_ne(); + gen_op_ne(cpu_T[0], cpu_T[1]); MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto likely; case OPC_BGEZ: - gen_op_gez(); + gen_op_gez(cpu_T[0]); MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BGEZL: - gen_op_gez(); + gen_op_gez(cpu_T[0]); MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BGEZAL: - gen_op_gez(); + gen_op_gez(cpu_T[0]); MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget); blink = 31; goto not_likely; case OPC_BGEZALL: - gen_op_gez(); + gen_op_gez(cpu_T[0]); blink = 31; MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BGTZ: - gen_op_gtz(); + gen_op_gtz(cpu_T[0]); MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BGTZL: - gen_op_gtz(); + gen_op_gtz(cpu_T[0]); MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLEZ: - gen_op_lez(); + gen_op_lez(cpu_T[0]); MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BLEZL: - gen_op_lez(); + gen_op_lez(cpu_T[0]); MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLTZ: - gen_op_ltz(); + gen_op_ltz(cpu_T[0]); MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BLTZL: - gen_op_ltz(); + gen_op_ltz(cpu_T[0]); MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLTZAL: - gen_op_ltz(); + gen_op_ltz(cpu_T[0]); blink = 31; MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget); not_likely: @@ -2616,7 +2679,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond)); break; case OPC_BLTZALL: - gen_op_ltz(); + gen_op_ltz(cpu_T[0]); blink = 31; MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget); likely: @@ -2648,49 +2711,49 @@ static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt, case OPC_EXT: if (lsb + msb > 31) goto fail; - tcg_gen_helper_0_2ii(do_ext, lsb, msb + 1); + tcg_gen_helper_1_2ii(do_ext, cpu_T[0], cpu_T[0], cpu_T[1], lsb, msb + 1); break; #if defined(TARGET_MIPS64) case OPC_DEXTM: if (lsb + msb > 63) goto fail; - tcg_gen_helper_0_2ii(do_dext, lsb, msb + 1 + 32); + tcg_gen_helper_1_2ii(do_dext, cpu_T[0], cpu_T[0], cpu_T[1], lsb, msb + 1 + 32); break; case OPC_DEXTU: if (lsb + msb > 63) goto fail; - tcg_gen_helper_0_2ii(do_dext, lsb + 32, msb + 1); + tcg_gen_helper_1_2ii(do_dext, cpu_T[0], cpu_T[0], cpu_T[1], lsb + 32, msb + 1); break; case OPC_DEXT: if (lsb + msb > 63) goto fail; - tcg_gen_helper_0_2ii(do_dext, lsb, msb + 1); + tcg_gen_helper_1_2ii(do_dext, cpu_T[0], cpu_T[0], cpu_T[1], lsb, msb + 1); break; #endif case OPC_INS: if (lsb > msb) goto fail; gen_load_gpr(cpu_T[0], rt); - tcg_gen_helper_0_2ii(do_ins, lsb, msb - lsb + 1); + tcg_gen_helper_1_2ii(do_ins, cpu_T[0], cpu_T[0], cpu_T[1], lsb, msb - lsb + 1); break; #if defined(TARGET_MIPS64) case OPC_DINSM: if (lsb > msb) goto fail; gen_load_gpr(cpu_T[0], rt); - tcg_gen_helper_0_2ii(do_dins, lsb, msb - lsb + 1 + 32); + tcg_gen_helper_1_2ii(do_dins, cpu_T[0], cpu_T[0], cpu_T[1], lsb, msb - lsb + 1 + 32); break; case OPC_DINSU: if (lsb > msb) goto fail; gen_load_gpr(cpu_T[0], rt); - tcg_gen_helper_0_2ii(do_dins, lsb + 32, msb - lsb + 1); + tcg_gen_helper_1_2ii(do_dins, cpu_T[0], cpu_T[0], cpu_T[1], lsb + 32, msb - lsb + 1); break; case OPC_DINS: if (lsb > msb) goto fail; gen_load_gpr(cpu_T[0], rt); - tcg_gen_helper_0_2ii(do_dins, lsb, msb - lsb + 1); + tcg_gen_helper_1_2ii(do_dins, cpu_T[0], cpu_T[0], cpu_T[1], lsb, msb - lsb + 1); break; #endif default: @@ -2750,17 +2813,17 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_mvpcontrol); + tcg_gen_helper_1_1(do_mfc0_mvpcontrol, cpu_T[0], cpu_T[0]); rn = "MVPControl"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_mvpconf0); + tcg_gen_helper_1_1(do_mfc0_mvpconf0, cpu_T[0], cpu_T[0]); rn = "MVPConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_mvpconf1); + tcg_gen_helper_1_1(do_mfc0_mvpconf1, cpu_T[0], cpu_T[0]); rn = "MVPConf1"; break; default: @@ -2770,7 +2833,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 1: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mfc0_random); + tcg_gen_helper_1_1(do_mfc0_random, cpu_T[0], cpu_T[0]); rn = "Random"; break; case 1: @@ -2821,37 +2884,37 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_tcstatus); + tcg_gen_helper_1_1(do_mfc0_tcstatus, cpu_T[0], cpu_T[0]); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_tcbind); + tcg_gen_helper_1_1(do_mfc0_tcbind, cpu_T[0], cpu_T[0]); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_tcrestart); + tcg_gen_helper_1_1(do_mfc0_tcrestart, cpu_T[0], cpu_T[0]); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_tchalt); + tcg_gen_helper_1_1(do_mfc0_tchalt, cpu_T[0], cpu_T[0]); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_tccontext); + tcg_gen_helper_1_1(do_mfc0_tccontext, cpu_T[0], cpu_T[0]); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_tcschedule); + tcg_gen_helper_1_1(do_mfc0_tcschedule, cpu_T[0], cpu_T[0]); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_tcschefback); + tcg_gen_helper_1_1(do_mfc0_tcschefback, cpu_T[0], cpu_T[0]); rn = "TCScheFBack"; break; default: @@ -2877,7 +2940,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Context"; break; case 1: -// tcg_gen_helper_0_0(do_mfc0_contextconfig); /* SmartMIPS ASE */ +// tcg_gen_helper_1_1(do_mfc0_contextconfig, cpu_T[0], cpu_T[0]); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -2959,7 +3022,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mfc0_count); + tcg_gen_helper_1_1(do_mfc0_count, cpu_T[0], cpu_T[0]); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -3085,7 +3148,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 17: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mfc0_lladdr); + tcg_gen_helper_1_1(do_mfc0_lladdr, cpu_T[0], cpu_T[0]); rn = "LLAddr"; break; default: @@ -3095,7 +3158,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - tcg_gen_helper_0_1i(do_mfc0_watchlo, sel); + tcg_gen_helper_1_1i(do_mfc0_watchlo, cpu_T[0], cpu_T[0], sel); rn = "WatchLo"; break; default: @@ -3105,7 +3168,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ...7: - tcg_gen_helper_0_1i(do_mfc0_watchhi, sel); + tcg_gen_helper_1_1i(do_mfc0_watchhi, cpu_T[0], cpu_T[0], sel); rn = "WatchHi"; break; default: @@ -3144,23 +3207,23 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mfc0_debug); /* EJTAG support */ + tcg_gen_helper_1_1(do_mfc0_debug, cpu_T[0], cpu_T[0]); /* EJTAG support */ rn = "Debug"; break; case 1: -// tcg_gen_helper_0_0(do_mfc0_tracecontrol); /* PDtrace support */ +// tcg_gen_helper_1_1(do_mfc0_tracecontrol, cpu_T[0], cpu_T[0]); /* PDtrace support */ rn = "TraceControl"; // break; case 2: -// tcg_gen_helper_0_0(do_mfc0_tracecontrol2); /* PDtrace support */ +// tcg_gen_helper_1_1(do_mfc0_tracecontrol2, cpu_T[0], cpu_T[0]); /* PDtrace support */ rn = "TraceControl2"; // break; case 3: -// tcg_gen_helper_0_0(do_mfc0_usertracedata); /* PDtrace support */ +// tcg_gen_helper_1_1(do_mfc0_usertracedata, cpu_T[0], cpu_T[0]); /* PDtrace support */ rn = "UserTraceData"; // break; case 4: -// tcg_gen_helper_0_0(do_mfc0_debug); /* PDtrace support */ +// tcg_gen_helper_1_1(do_mfc0_tracebpc, cpu_T[0], cpu_T[0]); /* PDtrace support */ rn = "TraceBPC"; // break; default: @@ -3186,31 +3249,31 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Performance0"; break; case 1: -// tcg_gen_helper_0_0(do_mfc0_performance1); +// tcg_gen_helper_1_1(do_mfc0_performance1, cpu_T[0], cpu_T[0]); rn = "Performance1"; // break; case 2: -// tcg_gen_helper_0_0(do_mfc0_performance2); +// tcg_gen_helper_1_1(do_mfc0_performance2, cpu_T[0], cpu_T[0]); rn = "Performance2"; // break; case 3: -// tcg_gen_helper_0_0(do_mfc0_performance3); +// tcg_gen_helper_1_1(do_mfc0_performance3, cpu_T[0], cpu_T[0]); rn = "Performance3"; // break; case 4: -// tcg_gen_helper_0_0(do_mfc0_performance4); +// tcg_gen_helper_1_1(do_mfc0_performance4, cpu_T[0], cpu_T[0]); rn = "Performance4"; // break; case 5: -// tcg_gen_helper_0_0(do_mfc0_performance5); +// tcg_gen_helper_1_1(do_mfc0_performance5, cpu_T[0], cpu_T[0]); rn = "Performance5"; // break; case 6: -// tcg_gen_helper_0_0(do_mfc0_performance6); +// tcg_gen_helper_1_1(do_mfc0_performance6, cpu_T[0], cpu_T[0]); rn = "Performance6"; // break; case 7: -// tcg_gen_helper_0_0(do_mfc0_performance7); +// tcg_gen_helper_1_1(do_mfc0_performance7, cpu_T[0], cpu_T[0]); rn = "Performance7"; // break; default: @@ -3324,12 +3387,12 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_index); + tcg_gen_helper_0_1(do_mtc0_index, cpu_T[0]); rn = "Index"; break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_mvpcontrol); + tcg_gen_helper_0_1(do_mtc0_mvpcontrol, cpu_T[0]); rn = "MVPControl"; break; case 2: @@ -3354,22 +3417,22 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_vpecontrol); + tcg_gen_helper_0_1(do_mtc0_vpecontrol, cpu_T[0]); rn = "VPEControl"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_vpeconf0); + tcg_gen_helper_0_1(do_mtc0_vpeconf0, cpu_T[0]); rn = "VPEConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_vpeconf1); + tcg_gen_helper_0_1(do_mtc0_vpeconf1, cpu_T[0]); rn = "VPEConf1"; break; case 4: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_yqmask); + tcg_gen_helper_0_1(do_mtc0_yqmask, cpu_T[0]); rn = "YQMask"; break; case 5: @@ -3384,7 +3447,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 7: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_vpeopt); + tcg_gen_helper_0_1(do_mtc0_vpeopt, cpu_T[0]); rn = "VPEOpt"; break; default: @@ -3394,42 +3457,42 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_entrylo0); + tcg_gen_helper_0_1(do_mtc0_entrylo0, cpu_T[0]); rn = "EntryLo0"; break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_tcstatus); + tcg_gen_helper_0_1(do_mtc0_tcstatus, cpu_T[0]); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_tcbind); + tcg_gen_helper_0_1(do_mtc0_tcbind, cpu_T[0]); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_tcrestart); + tcg_gen_helper_0_1(do_mtc0_tcrestart, cpu_T[0]); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_tchalt); + tcg_gen_helper_0_1(do_mtc0_tchalt, cpu_T[0]); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_tccontext); + tcg_gen_helper_0_1(do_mtc0_tccontext, cpu_T[0]); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_tcschedule); + tcg_gen_helper_0_1(do_mtc0_tcschedule, cpu_T[0]); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_tcschefback); + tcg_gen_helper_0_1(do_mtc0_tcschefback, cpu_T[0]); rn = "TCScheFBack"; break; default: @@ -3439,7 +3502,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_entrylo1); + tcg_gen_helper_0_1(do_mtc0_entrylo1, cpu_T[0]); rn = "EntryLo1"; break; default: @@ -3449,11 +3512,11 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 4: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_context); + tcg_gen_helper_0_1(do_mtc0_context, cpu_T[0]); rn = "Context"; break; case 1: -// tcg_gen_helper_0_0(do_mtc0_contextconfig); /* SmartMIPS ASE */ +// tcg_gen_helper_0_1(do_mtc0_contextconfig, cpu_T[0]); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -3463,12 +3526,12 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 5: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_pagemask); + tcg_gen_helper_0_1(do_mtc0_pagemask, cpu_T[0]); rn = "PageMask"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_pagegrain); + tcg_gen_helper_0_1(do_mtc0_pagegrain, cpu_T[0]); rn = "PageGrain"; break; default: @@ -3478,32 +3541,32 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 6: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_wired); + tcg_gen_helper_0_1(do_mtc0_wired, cpu_T[0]); rn = "Wired"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_srsconf0); + tcg_gen_helper_0_1(do_mtc0_srsconf0, cpu_T[0]); rn = "SRSConf0"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_srsconf1); + tcg_gen_helper_0_1(do_mtc0_srsconf1, cpu_T[0]); rn = "SRSConf1"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_srsconf2); + tcg_gen_helper_0_1(do_mtc0_srsconf2, cpu_T[0]); rn = "SRSConf2"; break; case 4: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_srsconf3); + tcg_gen_helper_0_1(do_mtc0_srsconf3, cpu_T[0]); rn = "SRSConf3"; break; case 5: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_srsconf4); + tcg_gen_helper_0_1(do_mtc0_srsconf4, cpu_T[0]); rn = "SRSConf4"; break; default: @@ -3514,7 +3577,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_hwrena); + tcg_gen_helper_0_1(do_mtc0_hwrena, cpu_T[0]); rn = "HWREna"; break; default: @@ -3528,7 +3591,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_count); + tcg_gen_helper_0_1(do_mtc0_count, cpu_T[0]); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -3541,7 +3604,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 10: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_entryhi); + tcg_gen_helper_0_1(do_mtc0_entryhi, cpu_T[0]); rn = "EntryHi"; break; default: @@ -3551,7 +3614,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 11: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_compare); + tcg_gen_helper_0_1(do_mtc0_compare, cpu_T[0]); rn = "Compare"; break; /* 6,7 are implementation dependent */ @@ -3564,7 +3627,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 12: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_status); + tcg_gen_helper_0_1(do_mtc0_status, cpu_T[0]); /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; @@ -3572,14 +3635,14 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_intctl); + tcg_gen_helper_0_1(do_mtc0_intctl, cpu_T[0]); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "IntCtl"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_srsctl); + tcg_gen_helper_0_1(do_mtc0_srsctl, cpu_T[0]); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSCtl"; @@ -3598,7 +3661,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 13: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_cause); + tcg_gen_helper_0_1(do_mtc0_cause, cpu_T[0]); rn = "Cause"; break; default: @@ -3625,7 +3688,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_ebase); + tcg_gen_helper_0_1(do_mtc0_ebase, cpu_T[0]); rn = "EBase"; break; default: @@ -3635,7 +3698,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 16: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_config0); + tcg_gen_helper_0_1(do_mtc0_config0, cpu_T[0]); rn = "Config"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -3645,7 +3708,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Config1"; break; case 2: - tcg_gen_helper_0_0(do_mtc0_config2); + tcg_gen_helper_0_1(do_mtc0_config2, cpu_T[0]); rn = "Config2"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -3682,7 +3745,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - tcg_gen_helper_0_1i(do_mtc0_watchlo, sel); + tcg_gen_helper_0_1i(do_mtc0_watchlo, cpu_T[0], sel); rn = "WatchLo"; break; default: @@ -3692,7 +3755,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ... 7: - tcg_gen_helper_0_1i(do_mtc0_watchhi, sel); + tcg_gen_helper_0_1i(do_mtc0_watchhi, cpu_T[0], sel); rn = "WatchHi"; break; default: @@ -3704,7 +3767,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: #if defined(TARGET_MIPS64) check_insn(env, ctx, ISA_MIPS3); - tcg_gen_helper_0_0(do_mtc0_xcontext); + tcg_gen_helper_0_1(do_mtc0_xcontext, cpu_T[0]); rn = "XContext"; break; #endif @@ -3716,7 +3779,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) /* Officially reserved, but sel 0 is used for R1x000 framemask */ switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_framemask); + tcg_gen_helper_0_1(do_mtc0_framemask, cpu_T[0]); rn = "Framemask"; break; default: @@ -3730,20 +3793,20 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_debug); /* EJTAG support */ + tcg_gen_helper_0_1(do_mtc0_debug, cpu_T[0]); /* EJTAG support */ /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; rn = "Debug"; break; case 1: -// tcg_gen_helper_0_0(do_mtc0_tracecontrol); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracecontrol, cpu_T[0]); /* PDtrace support */ rn = "TraceControl"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; // break; case 2: -// tcg_gen_helper_0_0(do_mtc0_tracecontrol2); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracecontrol2, cpu_T[0]); /* PDtrace support */ rn = "TraceControl2"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -3751,13 +3814,13 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; -// tcg_gen_helper_0_0(do_mtc0_usertracedata); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_usertracedata, cpu_T[0]); /* PDtrace support */ rn = "UserTraceData"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; // break; case 4: -// tcg_gen_helper_0_0(do_mtc0_debug); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracebpc, cpu_T[0]); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceBPC"; @@ -3780,35 +3843,35 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 25: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_performance0); + tcg_gen_helper_0_1(do_mtc0_performance0, cpu_T[0]); rn = "Performance0"; break; case 1: -// tcg_gen_helper_0_0(do_mtc0_performance1); +// tcg_gen_helper_0_1(do_mtc0_performance1, cpu_T[0]); rn = "Performance1"; // break; case 2: -// tcg_gen_helper_0_0(do_mtc0_performance2); +// tcg_gen_helper_0_1(do_mtc0_performance2, cpu_T[0]); rn = "Performance2"; // break; case 3: -// tcg_gen_helper_0_0(do_mtc0_performance3); +// tcg_gen_helper_0_1(do_mtc0_performance3, cpu_T[0]); rn = "Performance3"; // break; case 4: -// tcg_gen_helper_0_0(do_mtc0_performance4); +// tcg_gen_helper_0_1(do_mtc0_performance4, cpu_T[0]); rn = "Performance4"; // break; case 5: -// tcg_gen_helper_0_0(do_mtc0_performance5); +// tcg_gen_helper_0_1(do_mtc0_performance5, cpu_T[0]); rn = "Performance5"; // break; case 6: -// tcg_gen_helper_0_0(do_mtc0_performance6); +// tcg_gen_helper_0_1(do_mtc0_performance6, cpu_T[0]); rn = "Performance6"; // break; case 7: -// tcg_gen_helper_0_0(do_mtc0_performance7); +// tcg_gen_helper_0_1(do_mtc0_performance7, cpu_T[0]); rn = "Performance7"; // break; default: @@ -3835,14 +3898,14 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - tcg_gen_helper_0_0(do_mtc0_taglo); + tcg_gen_helper_0_1(do_mtc0_taglo, cpu_T[0]); rn = "TagLo"; break; case 1: case 3: case 5: case 7: - tcg_gen_helper_0_0(do_mtc0_datalo); + tcg_gen_helper_0_1(do_mtc0_datalo, cpu_T[0]); rn = "DataLo"; break; default: @@ -3855,14 +3918,14 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - tcg_gen_helper_0_0(do_mtc0_taghi); + tcg_gen_helper_0_1(do_mtc0_taghi, cpu_T[0]); rn = "TagHi"; break; case 1: case 3: case 5: case 7: - tcg_gen_helper_0_0(do_mtc0_datahi); + tcg_gen_helper_0_1(do_mtc0_datahi, cpu_T[0]); rn = "DataHi"; break; default: @@ -3931,17 +3994,17 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_mvpcontrol); + tcg_gen_helper_1_1(do_mfc0_mvpcontrol, cpu_T[0], cpu_T[0]); rn = "MVPControl"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_mvpconf0); + tcg_gen_helper_1_1(do_mfc0_mvpconf0, cpu_T[0], cpu_T[0]); rn = "MVPConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_mvpconf1); + tcg_gen_helper_1_1(do_mfc0_mvpconf1, cpu_T[0], cpu_T[0]); rn = "MVPConf1"; break; default: @@ -3951,7 +4014,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 1: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mfc0_random); + tcg_gen_helper_1_1(do_mfc0_random, cpu_T[0], cpu_T[0]); rn = "Random"; break; case 1: @@ -4001,37 +4064,37 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_tcstatus); + tcg_gen_helper_1_1(do_mfc0_tcstatus, cpu_T[0], cpu_T[0]); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mfc0_tcbind); + tcg_gen_helper_1_1(do_mfc0_tcbind, cpu_T[0], cpu_T[0]); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_dmfc0_tcrestart); + tcg_gen_helper_1_1(do_dmfc0_tcrestart, cpu_T[0], cpu_T[0]); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_dmfc0_tchalt); + tcg_gen_helper_1_1(do_dmfc0_tchalt, cpu_T[0], cpu_T[0]); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_dmfc0_tccontext); + tcg_gen_helper_1_1(do_dmfc0_tccontext, cpu_T[0], cpu_T[0]); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_dmfc0_tcschedule); + tcg_gen_helper_1_1(do_dmfc0_tcschedule, cpu_T[0], cpu_T[0]); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_dmfc0_tcschefback); + tcg_gen_helper_1_1(do_dmfc0_tcschefback, cpu_T[0], cpu_T[0]); rn = "TCScheFBack"; break; default: @@ -4055,7 +4118,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Context"; break; case 1: -// tcg_gen_helper_0_0(do_dmfc0_contextconfig); /* SmartMIPS ASE */ +// tcg_gen_helper_1_1(do_dmfc0_contextconfig, cpu_T[0], cpu_T[0]); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -4136,7 +4199,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mfc0_count); + tcg_gen_helper_1_1(do_mfc0_count, cpu_T[0], cpu_T[0]); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -4259,7 +4322,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 17: switch (sel) { case 0: - tcg_gen_helper_0_0(do_dmfc0_lladdr); + tcg_gen_helper_1_1(do_dmfc0_lladdr, cpu_T[0], cpu_T[0]); rn = "LLAddr"; break; default: @@ -4269,7 +4332,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - tcg_gen_helper_0_1i(do_dmfc0_watchlo, sel); + tcg_gen_helper_1_1i(do_dmfc0_watchlo, cpu_T[0], cpu_T[0], sel); rn = "WatchLo"; break; default: @@ -4279,7 +4342,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ... 7: - tcg_gen_helper_0_1i(do_mfc0_watchhi, sel); + tcg_gen_helper_1_1i(do_mfc0_watchhi, cpu_T[0], cpu_T[0], sel); rn = "WatchHi"; break; default: @@ -4315,23 +4378,23 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mfc0_debug); /* EJTAG support */ + tcg_gen_helper_1_1(do_mfc0_debug, cpu_T[0], cpu_T[0]); /* EJTAG support */ rn = "Debug"; break; case 1: -// tcg_gen_helper_0_0(do_dmfc0_tracecontrol); /* PDtrace support */ +// tcg_gen_helper_1_1(do_dmfc0_tracecontrol, cpu_T[0], cpu_T[0]); /* PDtrace support */ rn = "TraceControl"; // break; case 2: -// tcg_gen_helper_0_0(do_dmfc0_tracecontrol2); /* PDtrace support */ +// tcg_gen_helper_1_1(do_dmfc0_tracecontrol2, cpu_T[0], cpu_T[0]); /* PDtrace support */ rn = "TraceControl2"; // break; case 3: -// tcg_gen_helper_0_0(do_dmfc0_usertracedata); /* PDtrace support */ +// tcg_gen_helper_1_1(do_dmfc0_usertracedata, cpu_T[0], cpu_T[0]); /* PDtrace support */ rn = "UserTraceData"; // break; case 4: -// tcg_gen_helper_0_0(do_dmfc0_debug); /* PDtrace support */ +// tcg_gen_helper_1_1(do_dmfc0_tracebpc, cpu_T[0], cpu_T[0]); /* PDtrace support */ rn = "TraceBPC"; // break; default: @@ -4356,31 +4419,31 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Performance0"; break; case 1: -// tcg_gen_helper_0_0(do_dmfc0_performance1); +// tcg_gen_helper_1_1(do_dmfc0_performance1, cpu_T[0], cpu_T[0]); rn = "Performance1"; // break; case 2: -// tcg_gen_helper_0_0(do_dmfc0_performance2); +// tcg_gen_helper_1_1(do_dmfc0_performance2, cpu_T[0], cpu_T[0]); rn = "Performance2"; // break; case 3: -// tcg_gen_helper_0_0(do_dmfc0_performance3); +// tcg_gen_helper_1_1(do_dmfc0_performance3, cpu_T[0], cpu_T[0]); rn = "Performance3"; // break; case 4: -// tcg_gen_helper_0_0(do_dmfc0_performance4); +// tcg_gen_helper_1_1(do_dmfc0_performance4, cpu_T[0], cpu_T[0]); rn = "Performance4"; // break; case 5: -// tcg_gen_helper_0_0(do_dmfc0_performance5); +// tcg_gen_helper_1_1(do_dmfc0_performance5, cpu_T[0], cpu_T[0]); rn = "Performance5"; // break; case 6: -// tcg_gen_helper_0_0(do_dmfc0_performance6); +// tcg_gen_helper_1_1(do_dmfc0_performance6, cpu_T[0], cpu_T[0]); rn = "Performance6"; // break; case 7: -// tcg_gen_helper_0_0(do_dmfc0_performance7); +// tcg_gen_helper_1_1(do_dmfc0_performance7, cpu_T[0], cpu_T[0]); rn = "Performance7"; // break; default: @@ -4493,12 +4556,12 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_index); + tcg_gen_helper_0_1(do_mtc0_index, cpu_T[0]); rn = "Index"; break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_mvpcontrol); + tcg_gen_helper_0_1(do_mtc0_mvpcontrol, cpu_T[0]); rn = "MVPControl"; break; case 2: @@ -4523,22 +4586,22 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_vpecontrol); + tcg_gen_helper_0_1(do_mtc0_vpecontrol, cpu_T[0]); rn = "VPEControl"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_vpeconf0); + tcg_gen_helper_0_1(do_mtc0_vpeconf0, cpu_T[0]); rn = "VPEConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_vpeconf1); + tcg_gen_helper_0_1(do_mtc0_vpeconf1, cpu_T[0]); rn = "VPEConf1"; break; case 4: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_yqmask); + tcg_gen_helper_0_1(do_mtc0_yqmask, cpu_T[0]); rn = "YQMask"; break; case 5: @@ -4553,7 +4616,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 7: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_vpeopt); + tcg_gen_helper_0_1(do_mtc0_vpeopt, cpu_T[0]); rn = "VPEOpt"; break; default: @@ -4563,42 +4626,42 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_entrylo0); + tcg_gen_helper_0_1(do_mtc0_entrylo0, cpu_T[0]); rn = "EntryLo0"; break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_tcstatus); + tcg_gen_helper_0_1(do_mtc0_tcstatus, cpu_T[0]); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_tcbind); + tcg_gen_helper_0_1(do_mtc0_tcbind, cpu_T[0]); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_tcrestart); + tcg_gen_helper_0_1(do_mtc0_tcrestart, cpu_T[0]); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_tchalt); + tcg_gen_helper_0_1(do_mtc0_tchalt, cpu_T[0]); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_tccontext); + tcg_gen_helper_0_1(do_mtc0_tccontext, cpu_T[0]); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_tcschedule); + tcg_gen_helper_0_1(do_mtc0_tcschedule, cpu_T[0]); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_mtc0_tcschefback); + tcg_gen_helper_0_1(do_mtc0_tcschefback, cpu_T[0]); rn = "TCScheFBack"; break; default: @@ -4608,7 +4671,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_entrylo1); + tcg_gen_helper_0_1(do_mtc0_entrylo1, cpu_T[0]); rn = "EntryLo1"; break; default: @@ -4618,11 +4681,11 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 4: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_context); + tcg_gen_helper_0_1(do_mtc0_context, cpu_T[0]); rn = "Context"; break; case 1: -// tcg_gen_helper_0_0(do_mtc0_contextconfig); /* SmartMIPS ASE */ +// tcg_gen_helper_0_1(do_mtc0_contextconfig, cpu_T[0]); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -4632,12 +4695,12 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 5: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_pagemask); + tcg_gen_helper_0_1(do_mtc0_pagemask, cpu_T[0]); rn = "PageMask"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_pagegrain); + tcg_gen_helper_0_1(do_mtc0_pagegrain, cpu_T[0]); rn = "PageGrain"; break; default: @@ -4647,32 +4710,32 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 6: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_wired); + tcg_gen_helper_0_1(do_mtc0_wired, cpu_T[0]); rn = "Wired"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_srsconf0); + tcg_gen_helper_0_1(do_mtc0_srsconf0, cpu_T[0]); rn = "SRSConf0"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_srsconf1); + tcg_gen_helper_0_1(do_mtc0_srsconf1, cpu_T[0]); rn = "SRSConf1"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_srsconf2); + tcg_gen_helper_0_1(do_mtc0_srsconf2, cpu_T[0]); rn = "SRSConf2"; break; case 4: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_srsconf3); + tcg_gen_helper_0_1(do_mtc0_srsconf3, cpu_T[0]); rn = "SRSConf3"; break; case 5: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_srsconf4); + tcg_gen_helper_0_1(do_mtc0_srsconf4, cpu_T[0]); rn = "SRSConf4"; break; default: @@ -4683,7 +4746,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_hwrena); + tcg_gen_helper_0_1(do_mtc0_hwrena, cpu_T[0]); rn = "HWREna"; break; default: @@ -4697,7 +4760,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_count); + tcg_gen_helper_0_1(do_mtc0_count, cpu_T[0]); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -4710,7 +4773,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 10: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_entryhi); + tcg_gen_helper_0_1(do_mtc0_entryhi, cpu_T[0]); rn = "EntryHi"; break; default: @@ -4720,7 +4783,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 11: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_compare); + tcg_gen_helper_0_1(do_mtc0_compare, cpu_T[0]); rn = "Compare"; break; /* 6,7 are implementation dependent */ @@ -4733,7 +4796,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 12: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_status); + tcg_gen_helper_0_1(do_mtc0_status, cpu_T[0]); /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; @@ -4741,14 +4804,14 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_intctl); + tcg_gen_helper_0_1(do_mtc0_intctl, cpu_T[0]); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "IntCtl"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_srsctl); + tcg_gen_helper_0_1(do_mtc0_srsctl, cpu_T[0]); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSCtl"; @@ -4767,7 +4830,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 13: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_cause); + tcg_gen_helper_0_1(do_mtc0_cause, cpu_T[0]); rn = "Cause"; break; default: @@ -4794,7 +4857,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_0(do_mtc0_ebase); + tcg_gen_helper_0_1(do_mtc0_ebase, cpu_T[0]); rn = "EBase"; break; default: @@ -4804,7 +4867,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 16: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_config0); + tcg_gen_helper_0_1(do_mtc0_config0, cpu_T[0]); rn = "Config"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -4814,7 +4877,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Config1"; break; case 2: - tcg_gen_helper_0_0(do_mtc0_config2); + tcg_gen_helper_0_1(do_mtc0_config2, cpu_T[0]); rn = "Config2"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -4842,7 +4905,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - tcg_gen_helper_0_1i(do_mtc0_watchlo, sel); + tcg_gen_helper_0_1i(do_mtc0_watchlo, cpu_T[0], sel); rn = "WatchLo"; break; default: @@ -4852,7 +4915,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ... 7: - tcg_gen_helper_0_1i(do_mtc0_watchhi, sel); + tcg_gen_helper_0_1i(do_mtc0_watchhi, cpu_T[0], sel); rn = "WatchHi"; break; default: @@ -4863,7 +4926,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS3); - tcg_gen_helper_0_0(do_mtc0_xcontext); + tcg_gen_helper_0_1(do_mtc0_xcontext, cpu_T[0]); rn = "XContext"; break; default: @@ -4874,7 +4937,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) /* Officially reserved, but sel 0 is used for R1x000 framemask */ switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_framemask); + tcg_gen_helper_0_1(do_mtc0_framemask, cpu_T[0]); rn = "Framemask"; break; default: @@ -4888,32 +4951,32 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_debug); /* EJTAG support */ + tcg_gen_helper_0_1(do_mtc0_debug, cpu_T[0]); /* EJTAG support */ /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; rn = "Debug"; break; case 1: -// tcg_gen_helper_0_0(do_mtc0_tracecontrol); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracecontrol, cpu_T[0]); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceControl"; // break; case 2: -// tcg_gen_helper_0_0(do_mtc0_tracecontrol2); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracecontrol2, cpu_T[0]); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceControl2"; // break; case 3: -// tcg_gen_helper_0_0(do_mtc0_usertracedata); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_usertracedata, cpu_T[0]); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "UserTraceData"; // break; case 4: -// tcg_gen_helper_0_0(do_mtc0_debug); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracebpc, cpu_T[0]); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceBPC"; @@ -4936,35 +4999,35 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 25: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mtc0_performance0); + tcg_gen_helper_0_1(do_mtc0_performance0, cpu_T[0]); rn = "Performance0"; break; case 1: -// tcg_gen_helper_0_0(do_mtc0_performance1); +// tcg_gen_helper_0_1(do_mtc0_performance1, cpu_T[0]); rn = "Performance1"; // break; case 2: -// tcg_gen_helper_0_0(do_mtc0_performance2); +// tcg_gen_helper_0_1(do_mtc0_performance2, cpu_T[0]); rn = "Performance2"; // break; case 3: -// tcg_gen_helper_0_0(do_mtc0_performance3); +// tcg_gen_helper_0_1(do_mtc0_performance3, cpu_T[0]); rn = "Performance3"; // break; case 4: -// tcg_gen_helper_0_0(do_mtc0_performance4); +// tcg_gen_helper_0_1(do_mtc0_performance4, cpu_T[0]); rn = "Performance4"; // break; case 5: -// tcg_gen_helper_0_0(do_mtc0_performance5); +// tcg_gen_helper_0_1(do_mtc0_performance5, cpu_T[0]); rn = "Performance5"; // break; case 6: -// tcg_gen_helper_0_0(do_mtc0_performance6); +// tcg_gen_helper_0_1(do_mtc0_performance6, cpu_T[0]); rn = "Performance6"; // break; case 7: -// tcg_gen_helper_0_0(do_mtc0_performance7); +// tcg_gen_helper_0_1(do_mtc0_performance7, cpu_T[0]); rn = "Performance7"; // break; default: @@ -4991,14 +5054,14 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - tcg_gen_helper_0_0(do_mtc0_taglo); + tcg_gen_helper_0_1(do_mtc0_taglo, cpu_T[0]); rn = "TagLo"; break; case 1: case 3: case 5: case 7: - tcg_gen_helper_0_0(do_mtc0_datalo); + tcg_gen_helper_0_1(do_mtc0_datalo, cpu_T[0]); rn = "DataLo"; break; default: @@ -5011,14 +5074,14 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - tcg_gen_helper_0_0(do_mtc0_taghi); + tcg_gen_helper_0_1(do_mtc0_taghi, cpu_T[0]); rn = "TagHi"; break; case 1: case 3: case 5: case 7: - tcg_gen_helper_0_0(do_mtc0_datahi); + tcg_gen_helper_0_1(do_mtc0_datahi, cpu_T[0]); rn = "DataHi"; break; default: @@ -5088,25 +5151,25 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, case 2: switch (sel) { case 1: - tcg_gen_helper_0_0(do_mftc0_tcstatus); + tcg_gen_helper_1_1(do_mftc0_tcstatus, cpu_T[0], cpu_T[0]); break; case 2: - tcg_gen_helper_0_0(do_mftc0_tcbind); + tcg_gen_helper_1_1(do_mftc0_tcbind, cpu_T[0], cpu_T[0]); break; case 3: - tcg_gen_helper_0_0(do_mftc0_tcrestart); + tcg_gen_helper_1_1(do_mftc0_tcrestart, cpu_T[0], cpu_T[0]); break; case 4: - tcg_gen_helper_0_0(do_mftc0_tchalt); + tcg_gen_helper_1_1(do_mftc0_tchalt, cpu_T[0], cpu_T[0]); break; case 5: - tcg_gen_helper_0_0(do_mftc0_tccontext); + tcg_gen_helper_1_1(do_mftc0_tccontext, cpu_T[0], cpu_T[0]); break; case 6: - tcg_gen_helper_0_0(do_mftc0_tcschedule); + tcg_gen_helper_1_1(do_mftc0_tcschedule, cpu_T[0], cpu_T[0]); break; case 7: - tcg_gen_helper_0_0(do_mftc0_tcschefback); + tcg_gen_helper_1_1(do_mftc0_tcschefback, cpu_T[0], cpu_T[0]); break; default: gen_mfc0(env, ctx, rt, sel); @@ -5116,7 +5179,7 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, case 10: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mftc0_entryhi); + tcg_gen_helper_1_1(do_mftc0_entryhi, cpu_T[0], cpu_T[0]); break; default: gen_mfc0(env, ctx, rt, sel); @@ -5125,7 +5188,7 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, case 12: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mftc0_status); + tcg_gen_helper_1_1(do_mftc0_status, cpu_T[0], cpu_T[0]); break; default: gen_mfc0(env, ctx, rt, sel); @@ -5134,7 +5197,7 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, case 23: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mftc0_debug); + tcg_gen_helper_1_1(do_mftc0_debug, cpu_T[0], cpu_T[0]); break; default: gen_mfc0(env, ctx, rt, sel); @@ -5147,49 +5210,49 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, } else switch (sel) { /* GPR registers. */ case 0: - tcg_gen_helper_0_1i(do_mftgpr, rt); + tcg_gen_helper_1_1i(do_mftgpr, cpu_T[0], cpu_T[0], rt); break; /* Auxiliary CPU registers */ case 1: switch (rt) { case 0: - tcg_gen_helper_0_1i(do_mftlo, 0); + tcg_gen_helper_1_1i(do_mftlo, cpu_T[0], cpu_T[0], 0); break; case 1: - tcg_gen_helper_0_1i(do_mfthi, 0); + tcg_gen_helper_1_1i(do_mfthi, cpu_T[0], cpu_T[0], 0); break; case 2: - tcg_gen_helper_0_1i(do_mftacx, 0); + tcg_gen_helper_1_1i(do_mftacx, cpu_T[0], cpu_T[0], 0); break; case 4: - tcg_gen_helper_0_1i(do_mftlo, 1); + tcg_gen_helper_1_1i(do_mftlo, cpu_T[0], cpu_T[0], 1); break; case 5: - tcg_gen_helper_0_1i(do_mfthi, 1); + tcg_gen_helper_1_1i(do_mfthi, cpu_T[0], cpu_T[0], 1); break; case 6: - tcg_gen_helper_0_1i(do_mftacx, 1); + tcg_gen_helper_1_1i(do_mftacx, cpu_T[0], cpu_T[0], 1); break; case 8: - tcg_gen_helper_0_1i(do_mftlo, 2); + tcg_gen_helper_1_1i(do_mftlo, cpu_T[0], cpu_T[0], 2); break; case 9: - tcg_gen_helper_0_1i(do_mfthi, 2); + tcg_gen_helper_1_1i(do_mfthi, cpu_T[0], cpu_T[0], 2); break; case 10: - tcg_gen_helper_0_1i(do_mftacx, 2); + tcg_gen_helper_1_1i(do_mftacx, cpu_T[0], cpu_T[0], 2); break; case 12: - tcg_gen_helper_0_1i(do_mftlo, 3); + tcg_gen_helper_1_1i(do_mftlo, cpu_T[0], cpu_T[0], 3); break; case 13: - tcg_gen_helper_0_1i(do_mfthi, 3); + tcg_gen_helper_1_1i(do_mfthi, cpu_T[0], cpu_T[0], 3); break; case 14: - tcg_gen_helper_0_1i(do_mftacx, 3); + tcg_gen_helper_1_1i(do_mftacx, cpu_T[0], cpu_T[0], 3); break; case 16: - tcg_gen_helper_0_0(do_mftdsp); + tcg_gen_helper_1_1(do_mftdsp, cpu_T[0], cpu_T[0]); break; default: goto die; @@ -5208,7 +5271,7 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, break; case 3: /* XXX: For now we support only a single FPU context. */ - tcg_gen_helper_0_1i(do_cfc1, rt); + tcg_gen_helper_1_1i(do_cfc1, cpu_T[0], cpu_T[0], rt); break; /* COP2: Not implemented. */ case 4: @@ -5252,25 +5315,25 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, case 2: switch (sel) { case 1: - tcg_gen_helper_0_0(do_mttc0_tcstatus); + tcg_gen_helper_0_1(do_mttc0_tcstatus, cpu_T[0]); break; case 2: - tcg_gen_helper_0_0(do_mttc0_tcbind); + tcg_gen_helper_0_1(do_mttc0_tcbind, cpu_T[0]); break; case 3: - tcg_gen_helper_0_0(do_mttc0_tcrestart); + tcg_gen_helper_0_1(do_mttc0_tcrestart, cpu_T[0]); break; case 4: - tcg_gen_helper_0_0(do_mttc0_tchalt); + tcg_gen_helper_0_1(do_mttc0_tchalt, cpu_T[0]); break; case 5: - tcg_gen_helper_0_0(do_mttc0_tccontext); + tcg_gen_helper_0_1(do_mttc0_tccontext, cpu_T[0]); break; case 6: - tcg_gen_helper_0_0(do_mttc0_tcschedule); + tcg_gen_helper_0_1(do_mttc0_tcschedule, cpu_T[0]); break; case 7: - tcg_gen_helper_0_0(do_mttc0_tcschefback); + tcg_gen_helper_0_1(do_mttc0_tcschefback, cpu_T[0]); break; default: gen_mtc0(env, ctx, rd, sel); @@ -5280,7 +5343,7 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, case 10: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mttc0_entryhi); + tcg_gen_helper_0_1(do_mttc0_entryhi, cpu_T[0]); break; default: gen_mtc0(env, ctx, rd, sel); @@ -5289,7 +5352,7 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, case 12: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mttc0_status); + tcg_gen_helper_0_1(do_mttc0_status, cpu_T[0]); break; default: gen_mtc0(env, ctx, rd, sel); @@ -5298,7 +5361,7 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, case 23: switch (sel) { case 0: - tcg_gen_helper_0_0(do_mttc0_debug); + tcg_gen_helper_0_1(do_mttc0_debug, cpu_T[0]); break; default: gen_mtc0(env, ctx, rd, sel); @@ -5311,49 +5374,49 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, } else switch (sel) { /* GPR registers. */ case 0: - tcg_gen_helper_0_1i(do_mttgpr, rd); + tcg_gen_helper_0_1i(do_mttgpr, cpu_T[0], rd); break; /* Auxiliary CPU registers */ case 1: switch (rd) { case 0: - tcg_gen_helper_0_1i(do_mttlo, 0); + tcg_gen_helper_0_1i(do_mttlo, cpu_T[0], 0); break; case 1: - tcg_gen_helper_0_1i(do_mtthi, 0); + tcg_gen_helper_0_1i(do_mtthi, cpu_T[0], 0); break; case 2: - tcg_gen_helper_0_1i(do_mttacx, 0); + tcg_gen_helper_0_1i(do_mttacx, cpu_T[0], 0); break; case 4: - tcg_gen_helper_0_1i(do_mttlo, 1); + tcg_gen_helper_0_1i(do_mttlo, cpu_T[0], 1); break; case 5: - tcg_gen_helper_0_1i(do_mtthi, 1); + tcg_gen_helper_0_1i(do_mtthi, cpu_T[0], 1); break; case 6: - tcg_gen_helper_0_1i(do_mttacx, 1); + tcg_gen_helper_0_1i(do_mttacx, cpu_T[0], 1); break; case 8: - tcg_gen_helper_0_1i(do_mttlo, 2); + tcg_gen_helper_0_1i(do_mttlo, cpu_T[0], 2); break; case 9: - tcg_gen_helper_0_1i(do_mtthi, 2); + tcg_gen_helper_0_1i(do_mtthi, cpu_T[0], 2); break; case 10: - tcg_gen_helper_0_1i(do_mttacx, 2); + tcg_gen_helper_0_1i(do_mttacx, cpu_T[0], 2); break; case 12: - tcg_gen_helper_0_1i(do_mttlo, 3); + tcg_gen_helper_0_1i(do_mttlo, cpu_T[0], 3); break; case 13: - tcg_gen_helper_0_1i(do_mtthi, 3); + tcg_gen_helper_0_1i(do_mtthi, cpu_T[0], 3); break; case 14: - tcg_gen_helper_0_1i(do_mttacx, 3); + tcg_gen_helper_0_1i(do_mttacx, cpu_T[0], 3); break; case 16: - tcg_gen_helper_0_0(do_mttdsp); + tcg_gen_helper_0_1(do_mttdsp, cpu_T[0]); break; default: goto die; @@ -5372,7 +5435,7 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, break; case 3: /* XXX: For now we support only a single FPU context. */ - tcg_gen_helper_0_1i(do_ctc1, rd); + tcg_gen_helper_0_1i(do_ctc1, cpu_T[0], rd); break; /* COP2: Not implemented. */ case 4: @@ -5484,7 +5547,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int opn = "eret"; check_insn(env, ctx, ISA_MIPS2); save_cpu_state(ctx, 1); - tcg_gen_helper_0_0(do_eret); + tcg_gen_helper_0_1(do_eret, cpu_T[0]); ctx->bstate = BS_EXCP; break; case OPC_DERET: @@ -5495,7 +5558,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int generate_exception(ctx, EXCP_RI); } else { save_cpu_state(ctx, 1); - tcg_gen_helper_0_0(do_deret); + tcg_gen_helper_0_1(do_deret, cpu_T[0]); ctx->bstate = BS_EXCP; } break; @@ -5734,13 +5797,13 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) opn = "mtc1"; break; case OPC_CFC1: - tcg_gen_helper_0_1i(do_cfc1, fs); + tcg_gen_helper_1_1i(do_cfc1, cpu_T[0], cpu_T[0], fs); gen_store_gpr(cpu_T[0], rt); opn = "cfc1"; break; case OPC_CTC1: gen_load_gpr(cpu_T[0], rt); - tcg_gen_helper_0_1i(do_ctc1, fs); + tcg_gen_helper_0_1i(do_ctc1, cpu_T[0], fs); opn = "ctc1"; break; case OPC_DMFC1: @@ -6745,7 +6808,7 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, } else { gen_load_gpr(cpu_T[0], base); gen_load_gpr(cpu_T[1], index); - gen_op_addr_add(); + gen_op_addr_add(cpu_T[0], cpu_T[1]); } /* Don't do NOP if destination is zero: we must perform the actual memory access. */ @@ -7069,7 +7132,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) MIPS_INVAL("PMON / selsl"); generate_exception(ctx, EXCP_RI); #else - tcg_gen_helper_0_1i(do_pmon, sa); + tcg_gen_helper_0_i(do_pmon, sa); #endif break; case OPC_SYSCALL: @@ -7187,7 +7250,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx) switch (op2) { case OPC_WSBH: gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_0(do_wsbh); + tcg_gen_helper_1_2(do_wsbh, cpu_T[0], cpu_T[0], cpu_T[1]); break; case OPC_SEB: gen_load_gpr(cpu_T[1], rt); @@ -7209,19 +7272,19 @@ static void decode_opc (CPUState *env, DisasContext *ctx) switch (rd) { case 0: save_cpu_state(ctx, 1); - tcg_gen_helper_0_0(do_rdhwr_cpunum); + tcg_gen_helper_1_1(do_rdhwr_cpunum, cpu_T[0], cpu_T[0]); break; case 1: save_cpu_state(ctx, 1); - tcg_gen_helper_0_0(do_rdhwr_synci_step); + tcg_gen_helper_1_1(do_rdhwr_synci_step, cpu_T[0], cpu_T[0]); break; case 2: save_cpu_state(ctx, 1); - tcg_gen_helper_0_0(do_rdhwr_cc); + tcg_gen_helper_1_1(do_rdhwr_cc, cpu_T[0], cpu_T[0]); break; case 3: save_cpu_state(ctx, 1); - tcg_gen_helper_0_0(do_rdhwr_ccres); + tcg_gen_helper_1_1(do_rdhwr_ccres, cpu_T[0], cpu_T[0]); break; case 29: #if defined (CONFIG_USER_ONLY) @@ -7241,12 +7304,12 @@ static void decode_opc (CPUState *env, DisasContext *ctx) check_insn(env, ctx, ASE_MT); gen_load_gpr(cpu_T[0], rt); gen_load_gpr(cpu_T[1], rs); - tcg_gen_helper_0_0(do_fork); + tcg_gen_helper_1_2(do_fork, cpu_T[0], cpu_T[0], cpu_T[1]); break; case OPC_YIELD: check_insn(env, ctx, ASE_MT); gen_load_gpr(cpu_T[0], rs); - tcg_gen_helper_0_0(do_yield); + tcg_gen_helper_1_1(do_yield, cpu_T[0], cpu_T[0]); gen_store_gpr(cpu_T[0], rd); break; #if defined(TARGET_MIPS64) @@ -7263,11 +7326,11 @@ static void decode_opc (CPUState *env, DisasContext *ctx) switch (op2) { case OPC_DSBH: gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_0(do_dsbh); + tcg_gen_helper_1_2(do_dsbh, cpu_T[0], cpu_T[0], cpu_T[1]); break; case OPC_DSHD: gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_0(do_dshd); + tcg_gen_helper_1_2(do_dshd, cpu_T[0], cpu_T[0], cpu_T[1]); break; default: /* Invalid */ MIPS_INVAL("dbshfl"); @@ -7330,31 +7393,31 @@ static void decode_opc (CPUState *env, DisasContext *ctx) switch (op2) { case OPC_DMT: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_dmt); + tcg_gen_helper_1_1(do_dmt, cpu_T[0], cpu_T[0]); break; case OPC_EMT: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_emt); + tcg_gen_helper_1_1(do_emt, cpu_T[0], cpu_T[0]); break; case OPC_DVPE: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_dvpe); + tcg_gen_helper_1_1(do_dvpe, cpu_T[0], cpu_T[0]); break; case OPC_EVPE: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_0(do_evpe); + tcg_gen_helper_1_1(do_evpe, cpu_T[0], cpu_T[0]); break; case OPC_DI: check_insn(env, ctx, ISA_MIPS32R2); save_cpu_state(ctx, 1); - tcg_gen_helper_0_0(do_di); + tcg_gen_helper_1_1(do_di, cpu_T[0], cpu_T[0]); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; break; case OPC_EI: check_insn(env, ctx, ISA_MIPS32R2); save_cpu_state(ctx, 1); - tcg_gen_helper_0_0(do_ei); + tcg_gen_helper_1_1(do_ei, cpu_T[0], cpu_T[0]); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; break; @@ -7367,13 +7430,11 @@ static void decode_opc (CPUState *env, DisasContext *ctx) break; case OPC_RDPGPR: check_insn(env, ctx, ISA_MIPS32R2); - gen_load_srsgpr(cpu_T[0], rt); - gen_store_gpr(cpu_T[0], rd); + gen_load_srsgpr(rt, rd); break; case OPC_WRPGPR: check_insn(env, ctx, ISA_MIPS32R2); - gen_load_gpr(cpu_T[0], rt); - gen_store_srsgpr(cpu_T[0], rd); + gen_store_srsgpr(rt, rd); break; default: MIPS_INVAL("cp0"); @@ -7643,7 +7704,7 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, if (env->breakpoints[j] == ctx.pc) { save_cpu_state(&ctx, 1); ctx.bstate = BS_BRANCH; - tcg_gen_helper_0_1i(do_raise_exception, EXCP_DEBUG); + tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG); /* Include the breakpoint location or the tb won't * be flushed when it must be. */ ctx.pc += 4; @@ -7685,7 +7746,7 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, } if (env->singlestep_enabled) { save_cpu_state(&ctx, ctx.bstate == BS_NONE); - tcg_gen_helper_0_1i(do_raise_exception, EXCP_DEBUG); + tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG); } else { switch (ctx.bstate) { case BS_STOP: -- cgit v1.2.3 From 0bbd4a0ddb9f867dfcd1b59e9a84187706f400c3 Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Mon, 23 Jun 2008 16:58:04 +0000 Subject: Fix compiler warning (Jan Kiszka) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4781 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-sparc/cpu.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index f30a606c9..b56dc91ff 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -366,13 +366,14 @@ static inline int cpu_cwp_dec(CPUSPARCState *env1, int cwp) } while (0) #define GET_CWP64(env) (env->nwindows - 1 - (env)->cwp) +#ifndef NO_CPU_IO_DEFS static inline void PUT_CWP64(CPUSPARCState *env1, int cwp) { if (unlikely(cwp >= env1->nwindows || cwp < 0)) cwp = 0; cpu_set_cwp(env1, env1->nwindows - 1 - cwp); } - +#endif #endif int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc); -- cgit v1.2.3 From e7fb1406b06165daf7c06c6b08d2a10be51f7d1d Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Mon, 23 Jun 2008 17:52:43 +0000 Subject: Fix some compiler signed/unsigned char warnings git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4782 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/firmware_abi.h | 2 +- hw/sun4m.c | 8 ++++---- hw/sun4u.c | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/hw/firmware_abi.h b/hw/firmware_abi.h index 499949363..713484d41 100644 --- a/hw/firmware_abi.h +++ b/hw/firmware_abi.h @@ -139,7 +139,7 @@ OpenBIOS_finish_partition(struct OpenBIOS_nvpart_v1 *header, uint32_t size) } static inline uint32_t -OpenBIOS_set_var(uint8_t *nvram, uint32_t addr, const unsigned char *str) +OpenBIOS_set_var(uint8_t *nvram, uint32_t addr, const char *str) { uint32_t len; diff --git a/hw/sun4m.c b/hw/sun4m.c index 4bfc333a1..e1ff225e3 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -159,7 +159,7 @@ static int nvram_boot_set(void *opaque, const char *boot_device) for (i = 0; i < sizeof(image); i++) image[i] = m48t59_read(nvram, i) & 0xff; - strcpy(header->boot_devices, boot_device); + strcpy((char *)header->boot_devices, boot_device); header->nboot_devices = strlen(boot_device) & 0xff; header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8)); @@ -187,17 +187,17 @@ static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, memset(image, '\0', sizeof(image)); // Try to match PPC NVRAM - strcpy(header->struct_ident, "QEMU_BIOS"); + strcpy((char *)header->struct_ident, "QEMU_BIOS"); header->struct_version = cpu_to_be32(3); /* structure v3 */ header->nvram_size = cpu_to_be16(0x2000); header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t)); header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg)); - strcpy(header->arch, arch); + strcpy((char *)header->arch, arch); header->nb_cpus = smp_cpus & 0xff; header->RAM0_base = 0; header->RAM0_size = cpu_to_be64((uint64_t)RAM_size); - strcpy(header->boot_devices, boot_devices); + strcpy((char *)header->boot_devices, boot_devices); header->nboot_devices = strlen(boot_devices) & 0xff; header->kernel_image = cpu_to_be64((uint64_t)KERNEL_LOAD_ADDR); header->kernel_size = cpu_to_be64((uint64_t)kernel_size); diff --git a/hw/sun4u.c b/hw/sun4u.c index 49f049452..f97c7a05b 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -78,7 +78,7 @@ static int nvram_boot_set(void *opaque, const char *boot_device) for (i = 0; i < sizeof(image); i++) image[i] = m48t59_read(nvram, i) & 0xff; - strcpy(header->boot_devices, boot_device); + strcpy((char *)header->boot_devices, boot_device); header->nboot_devices = strlen(boot_device) & 0xff; header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8)); @@ -91,7 +91,7 @@ static int nvram_boot_set(void *opaque, const char *boot_device) extern int nographic; static int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, - const unsigned char *arch, + const char *arch, ram_addr_t RAM_size, const char *boot_devices, uint32_t kernel_image, uint32_t kernel_size, @@ -110,17 +110,17 @@ static int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, memset(image, '\0', sizeof(image)); // Try to match PPC NVRAM - strcpy(header->struct_ident, "QEMU_BIOS"); + strcpy((char *)header->struct_ident, "QEMU_BIOS"); header->struct_version = cpu_to_be32(3); /* structure v3 */ header->nvram_size = cpu_to_be16(NVRAM_size); header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t)); header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg)); - strcpy(header->arch, arch); + strcpy((char *)header->arch, arch); header->nb_cpus = smp_cpus & 0xff; header->RAM0_base = 0; header->RAM0_size = cpu_to_be64((uint64_t)RAM_size); - strcpy(header->boot_devices, boot_devices); + strcpy((char *)header->boot_devices, boot_devices); header->nboot_devices = strlen(boot_devices) & 0xff; header->kernel_image = cpu_to_be64((uint64_t)kernel_image); header->kernel_size = cpu_to_be64((uint64_t)kernel_size); -- cgit v1.2.3 From 8ff9cbf776ccb6306a8a0699bc4c8f5a8af7f922 Mon Sep 17 00:00:00 2001 From: malc Date: Mon, 23 Jun 2008 18:33:30 +0000 Subject: Make mixer emulation a configure option (Jan Kiszka) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4783 c046a42c-6fe2-441c-8c8c-71466251a162 --- audio/mixeng.c | 2 -- audio/mixeng_template.h | 10 +++++----- configure | 9 +++++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/audio/mixeng.c b/audio/mixeng.c index b668c524e..5e0426cb6 100644 --- a/audio/mixeng.c +++ b/audio/mixeng.c @@ -28,8 +28,6 @@ #define AUDIO_CAP "mixeng" #include "audio_int.h" -#define NOVOL - /* 8 bit */ #define ENDIAN_CONVERSION natural #define ENDIAN_CONVERT(v) (v) diff --git a/audio/mixeng_template.h b/audio/mixeng_template.h index d726441e2..21eef58bf 100644 --- a/audio/mixeng_template.h +++ b/audio/mixeng_template.h @@ -31,14 +31,14 @@ #define HALF (IN_MAX >> 1) #endif -#ifdef NOVOL -#define VOL(a, b) a -#else +#ifdef CONFIG_MIXEMU #ifdef FLOAT_MIXENG #define VOL(a, b) ((a) * (b)) #else #define VOL(a, b) ((a) * (b)) >> 32 #endif +#else +#define VOL(a, b) a #endif #define ET glue (ENDIAN_CONVERSION, glue (_, IN_T)) @@ -113,7 +113,7 @@ static void glue (glue (conv_, ET), _to_stereo) { st_sample_t *out = dst; IN_T *in = (IN_T *) src; -#ifndef NOVOL +#ifdef CONFIG_MIXEMU if (vol->mute) { mixeng_clear (dst, samples); return; @@ -133,7 +133,7 @@ static void glue (glue (conv_, ET), _to_mono) { st_sample_t *out = dst; IN_T *in = (IN_T *) src; -#ifndef NOVOL +#ifdef CONFIG_MIXEMU if (vol->mute) { mixeng_clear (dst, samples); return; diff --git a/configure b/configure index fb704bae4..efecd20c4 100755 --- a/configure +++ b/configure @@ -114,6 +114,7 @@ build_docs="no" uname_release="" curses="yes" nptl="yes" +mixemu="no" # OS specific targetos=`uname -s` @@ -337,6 +338,8 @@ for opt do ;; --disable-nptl) nptl="no" ;; + --enable-mixemu) mixemu="yes" + ;; *) echo "ERROR: unknown option $opt"; show_help="yes" ;; esac @@ -428,6 +431,7 @@ echo " --enable-alsa enable ALSA audio driver" echo " --enable-esd enable EsoundD audio driver" echo " --enable-fmod enable FMOD audio driver" echo " --enable-dsound enable DirectSound audio driver" +echo " --enable-mixemu enable mixer emulation" echo " --disable-brlapi disable BrlAPI" echo " --disable-vnc-tls disable TLS encryption for VNC server" echo " --disable-curses disable curses output" @@ -839,6 +843,7 @@ echo "CoreAudio support $coreaudio" echo "ALSA support $alsa" echo "EsounD support $esd" echo "DSound support $dsound" +echo "Mixer emulation $mixemu" if test "$fmod" = "yes"; then if test -z $fmod_lib || test -z $fmod_inc; then echo @@ -1067,6 +1072,10 @@ if test "$dsound" = "yes" ; then echo "CONFIG_DSOUND=yes" >> $config_mak echo "#define CONFIG_DSOUND 1" >> $config_h fi +if test "$mixemu" = "yes" ; then + echo "CONFIG_MIXEMU=yes" >> $config_mak + echo "#define CONFIG_MIXEMU 1" >> $config_h +fi if test "$fmod" = "yes" ; then echo "CONFIG_FMOD=yes" >> $config_mak echo "CONFIG_FMOD_LIB=$fmod_lib" >> $config_mak -- cgit v1.2.3 From 6c5c1e2057e558fa26c1dcde042ef1f7e35193ea Mon Sep 17 00:00:00 2001 From: ths Date: Tue, 24 Jun 2008 15:12:27 +0000 Subject: Use temporaries instead of fixed registers for some instructions. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4784 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/helper.h | 8 +- target-mips/op_helper.c | 12 +- target-mips/translate.c | 691 ++++++++++++++++++++++++++++-------------------- 3 files changed, 408 insertions(+), 303 deletions(-) diff --git a/target-mips/helper.h b/target-mips/helper.h index 15ef06493..710290883 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -152,11 +152,11 @@ DEF_HELPER(target_ulong, do_dmt, (target_ulong t0)) DEF_HELPER(target_ulong, do_emt, (target_ulong t0)) DEF_HELPER(target_ulong, do_dvpe, (target_ulong t0)) DEF_HELPER(target_ulong, do_evpe, (target_ulong t0)) -DEF_HELPER(target_ulong, do_fork, (target_ulong t0, target_ulong t1)) +DEF_HELPER(void, do_fork, (target_ulong t0, target_ulong t1)) DEF_HELPER(target_ulong, do_yield, (target_ulong t0)) /* CP1 functions */ -DEF_HELPER(target_ulong, do_cfc1, (target_ulong t0, uint32_t reg)) +DEF_HELPER(target_ulong, do_cfc1, (uint32_t reg)) DEF_HELPER(void, do_ctc1, (target_ulong t0, uint32_t reg)) DEF_HELPER(void, do_float_cvtd_s, (void)) @@ -241,8 +241,8 @@ FOP_PROTO(ngt) /* Special functions */ DEF_HELPER(target_ulong, do_di, (target_ulong t0)) DEF_HELPER(target_ulong, do_ei, (target_ulong t0)) -DEF_HELPER(void, do_eret, (target_ulong t0)) -DEF_HELPER(void, do_deret, (target_ulong t0)) +DEF_HELPER(void, do_eret, (void)) +DEF_HELPER(void, do_deret, (void)) DEF_HELPER(target_ulong, do_rdhwr_cpunum, (target_ulong t0)) DEF_HELPER(target_ulong, do_rdhwr_synci_step, (target_ulong t0)) DEF_HELPER(target_ulong, do_rdhwr_cc, (target_ulong t0)) diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 86a720d5a..bb3660751 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -1438,13 +1438,11 @@ target_ulong do_evpe(target_ulong t0) return t0; } -target_ulong do_fork(target_ulong t0, target_ulong t1) +void do_fork(target_ulong t0, target_ulong t1) { // t0 = rt, t1 = rs t0 = 0; // TODO: store to TC register - - return t0; } target_ulong do_yield(target_ulong t0) @@ -1684,7 +1682,7 @@ void debug_post_eret (void) } } -void do_eret (target_ulong t0) +void do_eret (void) { if (loglevel & CPU_LOG_EXEC) debug_pre_eret(); @@ -1701,7 +1699,7 @@ void do_eret (target_ulong t0) env->CP0_LLAddr = 1; } -void do_deret (target_ulong t0) +void do_deret (void) { if (loglevel & CPU_LOG_EXEC) debug_pre_eret(); @@ -1918,8 +1916,10 @@ unsigned int ieee_rm[] = { #define RESTORE_ROUNDING_MODE \ set_float_rounding_mode(ieee_rm[env->fpu->fcr31 & 3], &env->fpu->fp_status) -target_ulong do_cfc1 (target_ulong t0, uint32_t reg) +target_ulong do_cfc1 (uint32_t reg) { + target_ulong t0; + switch (reg) { case 0: t0 = (int32_t)env->fpu->fcr0; diff --git a/target-mips/translate.c b/target-mips/translate.c index 3d135cc60..75fa404d8 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -472,6 +472,14 @@ static inline void tcg_gen_helper_0_2ii(void *func, TCGv arg1, TCGv arg2, TCGv a tcg_temp_free(tmp2); } +static inline void tcg_gen_helper_1_i(void *func, TCGv ret, TCGv arg) +{ + TCGv tmp = tcg_const_i32(arg); + + tcg_gen_helper_1_1(func, ret, tmp); + tcg_temp_free(tmp); +} + static inline void tcg_gen_helper_1_1i(void *func, TCGv ret, TCGv arg1, TCGv arg2) { TCGv tmp = tcg_const_i32(arg2); @@ -2233,112 +2241,123 @@ static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) { const char *opn = "mul vr54xx"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); - gen_load_gpr(cpu_T[0], rs); - gen_load_gpr(cpu_T[1], rt); + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); switch (opc) { case OPC_VR54XX_MULS: - tcg_gen_helper_1_2(do_muls, cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_helper_1_2(do_muls, t0, t0, t1); opn = "muls"; break; case OPC_VR54XX_MULSU: - tcg_gen_helper_1_2(do_mulsu, cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_helper_1_2(do_mulsu, t0, t0, t1); opn = "mulsu"; break; case OPC_VR54XX_MACC: - tcg_gen_helper_1_2(do_macc, cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_helper_1_2(do_macc, t0, t0, t1); opn = "macc"; break; case OPC_VR54XX_MACCU: - tcg_gen_helper_1_2(do_maccu, cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_helper_1_2(do_maccu, t0, t0, t1); opn = "maccu"; break; case OPC_VR54XX_MSAC: - tcg_gen_helper_1_2(do_msac, cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_helper_1_2(do_msac, t0, t0, t1); opn = "msac"; break; case OPC_VR54XX_MSACU: - tcg_gen_helper_1_2(do_msacu, cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_helper_1_2(do_msacu, t0, t0, t1); opn = "msacu"; break; case OPC_VR54XX_MULHI: - tcg_gen_helper_1_2(do_mulhi, cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_helper_1_2(do_mulhi, t0, t0, t1); opn = "mulhi"; break; case OPC_VR54XX_MULHIU: - tcg_gen_helper_1_2(do_mulhiu, cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_helper_1_2(do_mulhiu, t0, t0, t1); opn = "mulhiu"; break; case OPC_VR54XX_MULSHI: - tcg_gen_helper_1_2(do_mulshi, cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_helper_1_2(do_mulshi, t0, t0, t1); opn = "mulshi"; break; case OPC_VR54XX_MULSHIU: - tcg_gen_helper_1_2(do_mulshiu, cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_helper_1_2(do_mulshiu, t0, t0, t1); opn = "mulshiu"; break; case OPC_VR54XX_MACCHI: - tcg_gen_helper_1_2(do_macchi, cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_helper_1_2(do_macchi, t0, t0, t1); opn = "macchi"; break; case OPC_VR54XX_MACCHIU: - tcg_gen_helper_1_2(do_macchiu, cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_helper_1_2(do_macchiu, t0, t0, t1); opn = "macchiu"; break; case OPC_VR54XX_MSACHI: - tcg_gen_helper_1_2(do_msachi, cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_helper_1_2(do_msachi, t0, t0, t1); opn = "msachi"; break; case OPC_VR54XX_MSACHIU: - tcg_gen_helper_1_2(do_msachiu, cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_helper_1_2(do_msachiu, t0, t0, t1); opn = "msachiu"; break; default: MIPS_INVAL("mul vr54xx"); generate_exception(ctx, EXCP_RI); - return; + goto out; } - gen_store_gpr(cpu_T[0], rd); + gen_store_gpr(t0, rd); MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); + + out: + tcg_temp_free(t0); + tcg_temp_free(t1); } static void gen_cl (DisasContext *ctx, uint32_t opc, int rd, int rs) { const char *opn = "CLx"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + if (rd == 0) { /* Treat as NOP. */ MIPS_DEBUG("NOP"); - return; + goto out; } - gen_load_gpr(cpu_T[0], rs); + gen_load_gpr(t0, rs); switch (opc) { case OPC_CLO: - tcg_gen_helper_1_1(do_clo, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_clo, t0, t0); opn = "clo"; break; case OPC_CLZ: - tcg_gen_helper_1_1(do_clz, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_clz, t0, t0); opn = "clz"; break; #if defined(TARGET_MIPS64) case OPC_DCLO: - tcg_gen_helper_1_1(do_dclo, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_dclo, t0, t0); opn = "dclo"; break; case OPC_DCLZ: - tcg_gen_helper_1_1(do_dclz, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_dclz, t0, t0); opn = "dclz"; break; #endif default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); - return; + goto out; } - gen_store_gpr(cpu_T[0], rd); + gen_store_gpr(t0, rd); MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]); + + out: + tcg_temp_free(t0); } /* Traps */ @@ -2470,6 +2489,8 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, target_ulong btarget = -1; int blink = 0; int bcond = 0; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); if (ctx->hflags & MIPS_HFLAG_BMASK) { #ifdef MIPS_DEBUG_DISAS @@ -2480,7 +2501,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, } #endif generate_exception(ctx, EXCP_RI); - return; + goto out; } /* Load needed operands */ @@ -2491,8 +2512,8 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, case OPC_BNEL: /* Compare two registers */ if (rs != rt) { - gen_load_gpr(cpu_T[0], rs); - gen_load_gpr(cpu_T[1], rt); + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); bcond = 1; } btarget = ctx->pc + 4 + offset; @@ -2511,7 +2532,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, case OPC_BLTZL: /* Compare to zero */ if (rs != 0) { - gen_load_gpr(cpu_T[0], rs); + gen_load_gpr(t0, rs); bcond = 1; } btarget = ctx->pc + 4 + offset; @@ -2529,14 +2550,14 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, others are reserved. */ MIPS_INVAL("jump hint"); generate_exception(ctx, EXCP_RI); - return; + goto out; } gen_save_breg_target(rs); break; default: MIPS_INVAL("branch/jump"); generate_exception(ctx, EXCP_RI); - return; + goto out; } if (bcond == 0) { /* No condition to be computed */ @@ -2563,26 +2584,26 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, case OPC_BLTZ: /* 0 < 0 */ /* Treat as NOP. */ MIPS_DEBUG("bnever (NOP)"); - return; + goto out; case OPC_BLTZAL: /* 0 < 0 */ - tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8); - gen_store_gpr(cpu_T[0], 31); + tcg_gen_movi_tl(t0, ctx->pc + 8); + gen_store_gpr(t0, 31); MIPS_DEBUG("bnever and link"); - return; + goto out; case OPC_BLTZALL: /* 0 < 0 likely */ - tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8); - gen_store_gpr(cpu_T[0], 31); + tcg_gen_movi_tl(t0, ctx->pc + 8); + gen_store_gpr(t0, 31); /* Skip the instruction in the delay slot */ MIPS_DEBUG("bnever, link and skip"); ctx->pc += 4; - return; + goto out; case OPC_BNEL: /* rx != rx likely */ case OPC_BGTZL: /* 0 > 0 likely */ case OPC_BLTZL: /* 0 < 0 likely */ /* Skip the instruction in the delay slot */ MIPS_DEBUG("bnever and skip"); ctx->pc += 4; - return; + goto out; case OPC_J: ctx->hflags |= MIPS_HFLAG_B; MIPS_DEBUG("j " TARGET_FMT_lx, btarget); @@ -2604,92 +2625,92 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, default: MIPS_INVAL("branch/jump"); generate_exception(ctx, EXCP_RI); - return; + goto out; } } else { switch (opc) { case OPC_BEQ: - gen_op_eq(cpu_T[0], cpu_T[1]); + gen_op_eq(t0, t1); MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto not_likely; case OPC_BEQL: - gen_op_eq(cpu_T[0], cpu_T[1]); + gen_op_eq(t0, t1); MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto likely; case OPC_BNE: - gen_op_ne(cpu_T[0], cpu_T[1]); + gen_op_ne(t0, t1); MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto not_likely; case OPC_BNEL: - gen_op_ne(cpu_T[0], cpu_T[1]); + gen_op_ne(t0, t1); MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx, regnames[rs], regnames[rt], btarget); goto likely; case OPC_BGEZ: - gen_op_gez(cpu_T[0]); + gen_op_gez(t0); MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BGEZL: - gen_op_gez(cpu_T[0]); + gen_op_gez(t0); MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BGEZAL: - gen_op_gez(cpu_T[0]); + gen_op_gez(t0); MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget); blink = 31; goto not_likely; case OPC_BGEZALL: - gen_op_gez(cpu_T[0]); + gen_op_gez(t0); blink = 31; MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BGTZ: - gen_op_gtz(cpu_T[0]); + gen_op_gtz(t0); MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BGTZL: - gen_op_gtz(cpu_T[0]); + gen_op_gtz(t0); MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLEZ: - gen_op_lez(cpu_T[0]); + gen_op_lez(t0); MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BLEZL: - gen_op_lez(cpu_T[0]); + gen_op_lez(t0); MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLTZ: - gen_op_ltz(cpu_T[0]); + gen_op_ltz(t0); MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget); goto not_likely; case OPC_BLTZL: - gen_op_ltz(cpu_T[0]); + gen_op_ltz(t0); MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget); goto likely; case OPC_BLTZAL: - gen_op_ltz(cpu_T[0]); + gen_op_ltz(t0); blink = 31; MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget); not_likely: ctx->hflags |= MIPS_HFLAG_BC; - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, bcond)); break; case OPC_BLTZALL: - gen_op_ltz(cpu_T[0]); + gen_op_ltz(t0); blink = 31; MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget); likely: ctx->hflags |= MIPS_HFLAG_BL; - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, bcond)); break; default: MIPS_INVAL("conditional branch/jump"); generate_exception(ctx, EXCP_RI); - return; + goto out; } } MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx, @@ -2697,72 +2718,83 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, ctx->btarget = btarget; if (blink > 0) { - tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8); - gen_store_gpr(cpu_T[0], blink); + tcg_gen_movi_tl(t0, ctx->pc + 8); + gen_store_gpr(t0, blink); } + + out: + tcg_temp_free(t0); + tcg_temp_free(t1); } /* special3 bitfield operations */ static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt, int rs, int lsb, int msb) { - gen_load_gpr(cpu_T[1], rs); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t1, rs); switch (opc) { case OPC_EXT: if (lsb + msb > 31) goto fail; - tcg_gen_helper_1_2ii(do_ext, cpu_T[0], cpu_T[0], cpu_T[1], lsb, msb + 1); + tcg_gen_helper_1_2ii(do_ext, t0, t0, t1, lsb, msb + 1); break; #if defined(TARGET_MIPS64) case OPC_DEXTM: if (lsb + msb > 63) goto fail; - tcg_gen_helper_1_2ii(do_dext, cpu_T[0], cpu_T[0], cpu_T[1], lsb, msb + 1 + 32); + tcg_gen_helper_1_2ii(do_dext, t0, t0, t1, lsb, msb + 1 + 32); break; case OPC_DEXTU: if (lsb + msb > 63) goto fail; - tcg_gen_helper_1_2ii(do_dext, cpu_T[0], cpu_T[0], cpu_T[1], lsb + 32, msb + 1); + tcg_gen_helper_1_2ii(do_dext, t0, t0, t1, lsb + 32, msb + 1); break; case OPC_DEXT: if (lsb + msb > 63) goto fail; - tcg_gen_helper_1_2ii(do_dext, cpu_T[0], cpu_T[0], cpu_T[1], lsb, msb + 1); + tcg_gen_helper_1_2ii(do_dext, t0, t0, t1, lsb, msb + 1); break; #endif case OPC_INS: if (lsb > msb) goto fail; - gen_load_gpr(cpu_T[0], rt); - tcg_gen_helper_1_2ii(do_ins, cpu_T[0], cpu_T[0], cpu_T[1], lsb, msb - lsb + 1); + gen_load_gpr(t0, rt); + tcg_gen_helper_1_2ii(do_ins, t0, t0, t1, lsb, msb - lsb + 1); break; #if defined(TARGET_MIPS64) case OPC_DINSM: if (lsb > msb) goto fail; - gen_load_gpr(cpu_T[0], rt); - tcg_gen_helper_1_2ii(do_dins, cpu_T[0], cpu_T[0], cpu_T[1], lsb, msb - lsb + 1 + 32); + gen_load_gpr(t0, rt); + tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1 + 32); break; case OPC_DINSU: if (lsb > msb) goto fail; - gen_load_gpr(cpu_T[0], rt); - tcg_gen_helper_1_2ii(do_dins, cpu_T[0], cpu_T[0], cpu_T[1], lsb + 32, msb - lsb + 1); + gen_load_gpr(t0, rt); + tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb + 32, msb - lsb + 1); break; case OPC_DINS: if (lsb > msb) goto fail; - gen_load_gpr(cpu_T[0], rt); - tcg_gen_helper_1_2ii(do_dins, cpu_T[0], cpu_T[0], cpu_T[1], lsb, msb - lsb + 1); + gen_load_gpr(t0, rt); + tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1); break; #endif default: fail: MIPS_INVAL("bitops"); generate_exception(ctx, EXCP_RI); + tcg_temp_free(t0); + tcg_temp_free(t1); return; } - gen_store_gpr(cpu_T[0], rt); + gen_store_gpr(t0, rt); + tcg_temp_free(t0); + tcg_temp_free(t1); } /* CP0 (MMU and control) */ @@ -5134,7 +5166,7 @@ die: } #endif /* TARGET_MIPS64 */ -static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, +static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd, int u, int sel, int h) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); @@ -5286,6 +5318,7 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, rt, u, sel, h); } #endif + gen_store_gpr(cpu_T[0], rd); return; die: @@ -5298,11 +5331,12 @@ die: generate_exception(ctx, EXCP_RI); } -static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, +static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt, int u, int sel, int h) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + gen_load_gpr(cpu_T[0], rt); if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) != (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE)))) @@ -5507,15 +5541,13 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int /* Treat as NOP. */ return; } - gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1, + gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1, ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); - gen_store_gpr(cpu_T[0], rd); opn = "mftr"; break; case OPC_MTTR: check_insn(env, ctx, ASE_MT); - gen_load_gpr(cpu_T[0], rt); - gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1, + gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1, ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); opn = "mttr"; break; @@ -5547,7 +5579,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int opn = "eret"; check_insn(env, ctx, ISA_MIPS2); save_cpu_state(ctx, 1); - tcg_gen_helper_0_1(do_eret, cpu_T[0]); + tcg_gen_helper_0_0(do_eret); ctx->bstate = BS_EXCP; break; case OPC_DERET: @@ -5558,7 +5590,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int generate_exception(ctx, EXCP_RI); } else { save_cpu_state(ctx, 1); - tcg_gen_helper_0_1(do_deret, cpu_T[0]); + tcg_gen_helper_0_0(do_deret); ctx->bstate = BS_EXCP; } break; @@ -5588,6 +5620,8 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, { target_ulong btarget; const char *opn = "cp1 cond branch"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); if (cc != 0) check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32); @@ -5602,16 +5636,16 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); get_fp_cond(r_tmp1); - tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); tcg_temp_free(r_tmp1); - tcg_gen_not_tl(cpu_T[0], cpu_T[0]); - tcg_gen_movi_tl(cpu_T[1], 0x1 << cc); - tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); - tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_not_tl(t0, t0); + tcg_gen_movi_tl(t1, 0x1 << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); tcg_gen_br(l2); gen_set_label(l1); - tcg_gen_movi_tl(cpu_T[0], 1); + tcg_gen_movi_tl(t0, 1); gen_set_label(l2); } opn = "bc1f"; @@ -5623,16 +5657,16 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); get_fp_cond(r_tmp1); - tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); tcg_temp_free(r_tmp1); - tcg_gen_not_tl(cpu_T[0], cpu_T[0]); - tcg_gen_movi_tl(cpu_T[1], 0x1 << cc); - tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); - tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_not_tl(t0, t0); + tcg_gen_movi_tl(t1, 0x1 << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); tcg_gen_br(l2); gen_set_label(l1); - tcg_gen_movi_tl(cpu_T[0], 1); + tcg_gen_movi_tl(t0, 1); gen_set_label(l2); } opn = "bc1fl"; @@ -5644,15 +5678,15 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); get_fp_cond(r_tmp1); - tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); tcg_temp_free(r_tmp1); - tcg_gen_movi_tl(cpu_T[1], 0x1 << cc); - tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); - tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_movi_tl(t1, 0x1 << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); tcg_gen_br(l2); gen_set_label(l1); - tcg_gen_movi_tl(cpu_T[0], 1); + tcg_gen_movi_tl(t0, 1); gen_set_label(l2); } opn = "bc1t"; @@ -5664,21 +5698,21 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); get_fp_cond(r_tmp1); - tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); tcg_temp_free(r_tmp1); - tcg_gen_movi_tl(cpu_T[1], 0x1 << cc); - tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); - tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_movi_tl(t1, 0x1 << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); tcg_gen_br(l2); gen_set_label(l1); - tcg_gen_movi_tl(cpu_T[0], 1); + tcg_gen_movi_tl(t0, 1); gen_set_label(l2); } opn = "bc1tl"; likely: ctx->hflags |= MIPS_HFLAG_BL; - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, bcond)); break; case OPC_BC1FANY2: { @@ -5687,16 +5721,16 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); get_fp_cond(r_tmp1); - tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); tcg_temp_free(r_tmp1); - tcg_gen_not_tl(cpu_T[0], cpu_T[0]); - tcg_gen_movi_tl(cpu_T[1], 0x3 << cc); - tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); - tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_not_tl(t0, t0); + tcg_gen_movi_tl(t1, 0x3 << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); tcg_gen_br(l2); gen_set_label(l1); - tcg_gen_movi_tl(cpu_T[0], 1); + tcg_gen_movi_tl(t0, 1); gen_set_label(l2); } opn = "bc1any2f"; @@ -5708,15 +5742,15 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); get_fp_cond(r_tmp1); - tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); tcg_temp_free(r_tmp1); - tcg_gen_movi_tl(cpu_T[1], 0x3 << cc); - tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); - tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_movi_tl(t1, 0x3 << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); tcg_gen_br(l2); gen_set_label(l1); - tcg_gen_movi_tl(cpu_T[0], 1); + tcg_gen_movi_tl(t0, 1); gen_set_label(l2); } opn = "bc1any2t"; @@ -5728,16 +5762,16 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); get_fp_cond(r_tmp1); - tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); tcg_temp_free(r_tmp1); - tcg_gen_not_tl(cpu_T[0], cpu_T[0]); - tcg_gen_movi_tl(cpu_T[1], 0xf << cc); - tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); - tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_not_tl(t0, t0); + tcg_gen_movi_tl(t1, 0xf << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); tcg_gen_br(l2); gen_set_label(l1); - tcg_gen_movi_tl(cpu_T[0], 1); + tcg_gen_movi_tl(t0, 1); gen_set_label(l2); } opn = "bc1any4f"; @@ -5749,30 +5783,34 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); get_fp_cond(r_tmp1); - tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); tcg_temp_free(r_tmp1); - tcg_gen_movi_tl(cpu_T[1], 0xf << cc); - tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); - tcg_gen_movi_tl(cpu_T[0], 0); + tcg_gen_movi_tl(t1, 0xf << cc); + tcg_gen_and_tl(t0, t0, t1); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_gen_movi_tl(t0, 0); tcg_gen_br(l2); gen_set_label(l1); - tcg_gen_movi_tl(cpu_T[0], 1); + tcg_gen_movi_tl(t0, 1); gen_set_label(l2); } opn = "bc1any4t"; not_likely: ctx->hflags |= MIPS_HFLAG_BC; - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, bcond)); break; default: MIPS_INVAL(opn); generate_exception (ctx, EXCP_RI); - return; + goto out; } MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn, ctx->hflags, btarget); ctx->btarget = btarget; + + out: + tcg_temp_free(t0); + tcg_temp_free(t1); } /* Coprocessor 1 (FPU) */ @@ -5782,60 +5820,64 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) { const char *opn = "cp1 move"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); switch (opc) { case OPC_MFC1: gen_load_fpr32(fpu32_T[0], fs); - tcg_gen_ext_i32_tl(cpu_T[0], fpu32_T[0]); - gen_store_gpr(cpu_T[0], rt); + tcg_gen_ext_i32_tl(t0, fpu32_T[0]); + gen_store_gpr(t0, rt); opn = "mfc1"; break; case OPC_MTC1: - gen_load_gpr(cpu_T[0], rt); - tcg_gen_trunc_tl_i32(fpu32_T[0], cpu_T[0]); + gen_load_gpr(t0, rt); + tcg_gen_trunc_tl_i32(fpu32_T[0], t0); gen_store_fpr32(fpu32_T[0], fs); opn = "mtc1"; break; case OPC_CFC1: - tcg_gen_helper_1_1i(do_cfc1, cpu_T[0], cpu_T[0], fs); - gen_store_gpr(cpu_T[0], rt); + tcg_gen_helper_1_i(do_cfc1, t0, fs); + gen_store_gpr(t0, rt); opn = "cfc1"; break; case OPC_CTC1: - gen_load_gpr(cpu_T[0], rt); - tcg_gen_helper_0_1i(do_ctc1, cpu_T[0], fs); + gen_load_gpr(t0, rt); + tcg_gen_helper_0_1i(do_ctc1, t0, fs); opn = "ctc1"; break; case OPC_DMFC1: gen_load_fpr64(ctx, fpu64_T[0], fs); - tcg_gen_mov_tl(cpu_T[0], fpu64_T[0]); - gen_store_gpr(cpu_T[0], rt); + tcg_gen_mov_tl(t0, fpu64_T[0]); + gen_store_gpr(t0, rt); opn = "dmfc1"; break; case OPC_DMTC1: - gen_load_gpr(cpu_T[0], rt); - tcg_gen_mov_tl(fpu64_T[0], cpu_T[0]); + gen_load_gpr(t0, rt); + tcg_gen_mov_tl(fpu64_T[0], t0); gen_store_fpr64(ctx, fpu64_T[0], fs); opn = "dmtc1"; break; case OPC_MFHC1: gen_load_fpr32h(fpu32h_T[0], fs); - tcg_gen_ext_i32_tl(cpu_T[0], fpu32h_T[0]); - gen_store_gpr(cpu_T[0], rt); + tcg_gen_ext_i32_tl(t0, fpu32h_T[0]); + gen_store_gpr(t0, rt); opn = "mfhc1"; break; case OPC_MTHC1: - gen_load_gpr(cpu_T[0], rt); - tcg_gen_trunc_tl_i32(fpu32h_T[0], cpu_T[0]); + gen_load_gpr(t0, rt); + tcg_gen_trunc_tl_i32(fpu32h_T[0], t0); gen_store_fpr32h(fpu32h_T[0], fs); opn = "mthc1"; break; default: MIPS_INVAL(opn); generate_exception (ctx, EXCP_RI); - return; + goto out; } MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]); + + out: + tcg_temp_free(t0); } static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) @@ -5843,6 +5885,8 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) int l1 = gen_new_label(); uint32_t ccbit; TCGCond cond; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); if (cc) ccbit = 1 << (24 + cc); @@ -5853,8 +5897,8 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) else cond = TCG_COND_NE; - gen_load_gpr(cpu_T[0], rd); - gen_load_gpr(cpu_T[1], rs); + gen_load_gpr(t0, rd); + gen_load_gpr(t1, rs); { TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR); TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32); @@ -5866,10 +5910,12 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) tcg_gen_brcondi_i32(cond, r_tmp, 0, l1); tcg_temp_free(r_tmp); } - tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(t0, t1); + tcg_temp_free(t1); gen_set_label(l1); - gen_store_gpr(cpu_T[0], rd); + gen_store_gpr(t0, rd); + tcg_temp_free(t0); } static inline void gen_movcf_s (int cc, int tf) @@ -6109,13 +6155,15 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, opn = "movcf.s"; break; case FOP(18, 16): - gen_load_gpr(cpu_T[0], ft); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[2], fd); { int l1 = gen_new_label(); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + gen_load_gpr(t0, ft); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_temp_free(t0); tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); gen_set_label(l1); } @@ -6123,13 +6171,15 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, opn = "movz.s"; break; case FOP(19, 16): - gen_load_gpr(cpu_T[0], ft); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32(fpu32_T[2], fd); { int l1 = gen_new_label(); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); + gen_load_gpr(t0, ft); + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); + tcg_temp_free(t0); tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); gen_set_label(l1); } @@ -6365,13 +6415,15 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, opn = "movcf.d"; break; case FOP(18, 17): - gen_load_gpr(cpu_T[0], ft); gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[2], fd); { int l1 = gen_new_label(); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + gen_load_gpr(t0, ft); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_temp_free(t0); tcg_gen_mov_i64(fpu64_T[2], fpu64_T[0]); gen_set_label(l1); } @@ -6379,13 +6431,15 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, opn = "movz.d"; break; case FOP(19, 17): - gen_load_gpr(cpu_T[0], ft); gen_load_fpr64(ctx, fpu64_T[0], fs); gen_load_fpr64(ctx, fpu64_T[2], fd); { int l1 = gen_new_label(); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); + gen_load_gpr(t0, ft); + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); + tcg_temp_free(t0); tcg_gen_mov_i64(fpu64_T[2], fpu64_T[0]); gen_set_label(l1); } @@ -6594,15 +6648,17 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, break; case FOP(18, 22): check_cp1_64bitmode(ctx); - gen_load_gpr(cpu_T[0], ft); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32h(fpu32h_T[0], fs); gen_load_fpr32(fpu32_T[2], fd); gen_load_fpr32h(fpu32h_T[2], fd); { int l1 = gen_new_label(); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + gen_load_gpr(t0, ft); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); + tcg_temp_free(t0); tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]); gen_set_label(l1); @@ -6613,15 +6669,17 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, break; case FOP(19, 22): check_cp1_64bitmode(ctx); - gen_load_gpr(cpu_T[0], ft); gen_load_fpr32(fpu32_T[0], fs); gen_load_fpr32h(fpu32h_T[0], fs); gen_load_fpr32(fpu32_T[2], fd); gen_load_fpr32h(fpu32h_T[2], fd); { int l1 = gen_new_label(); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); + gen_load_gpr(t0, ft); + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); + tcg_temp_free(t0); tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]); gen_set_label(l1); @@ -6800,43 +6858,45 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, { const char *opn = "extended float load/store"; int store = 0; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); if (base == 0) { - gen_load_gpr(cpu_T[0], index); + gen_load_gpr(t0, index); } else if (index == 0) { - gen_load_gpr(cpu_T[0], base); + gen_load_gpr(t0, base); } else { - gen_load_gpr(cpu_T[0], base); - gen_load_gpr(cpu_T[1], index); - gen_op_addr_add(cpu_T[0], cpu_T[1]); + gen_load_gpr(t0, base); + gen_load_gpr(t1, index); + gen_op_addr_add(t0, t1); } /* Don't do NOP if destination is zero: we must perform the actual memory access. */ switch (opc) { case OPC_LWXC1: check_cop1x(ctx); - tcg_gen_qemu_ld32s(fpu32_T[0], cpu_T[0], ctx->mem_idx); + tcg_gen_qemu_ld32s(fpu32_T[0], t0, ctx->mem_idx); gen_store_fpr32(fpu32_T[0], fd); opn = "lwxc1"; break; case OPC_LDXC1: check_cop1x(ctx); check_cp1_registers(ctx, fd); - tcg_gen_qemu_ld64(fpu64_T[0], cpu_T[0], ctx->mem_idx); + tcg_gen_qemu_ld64(fpu64_T[0], t0, ctx->mem_idx); gen_store_fpr64(ctx, fpu64_T[0], fd); opn = "ldxc1"; break; case OPC_LUXC1: check_cp1_64bitmode(ctx); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~0x7); - tcg_gen_qemu_ld64(fpu64_T[0], cpu_T[0], ctx->mem_idx); + tcg_gen_andi_tl(t0, t0, ~0x7); + tcg_gen_qemu_ld64(fpu64_T[0], t0, ctx->mem_idx); gen_store_fpr64(ctx, fpu64_T[0], fd); opn = "luxc1"; break; case OPC_SWXC1: check_cop1x(ctx); gen_load_fpr32(fpu32_T[0], fs); - tcg_gen_qemu_st32(fpu32_T[0], cpu_T[0], ctx->mem_idx); + tcg_gen_qemu_st32(fpu32_T[0], t0, ctx->mem_idx); opn = "swxc1"; store = 1; break; @@ -6844,23 +6904,27 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc, check_cop1x(ctx); check_cp1_registers(ctx, fs); gen_load_fpr64(ctx, fpu64_T[0], fs); - tcg_gen_qemu_st64(fpu64_T[0], cpu_T[0], ctx->mem_idx); + tcg_gen_qemu_st64(fpu64_T[0], t0, ctx->mem_idx); opn = "sdxc1"; store = 1; break; case OPC_SUXC1: check_cp1_64bitmode(ctx); gen_load_fpr64(ctx, fpu64_T[0], fs); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ~0x7); - tcg_gen_qemu_st64(fpu64_T[0], cpu_T[0], ctx->mem_idx); + tcg_gen_andi_tl(t0, t0, ~0x7); + tcg_gen_qemu_st64(fpu64_T[0], t0, ctx->mem_idx); opn = "suxc1"; store = 1; break; default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); + tcg_temp_free(t0); + tcg_temp_free(t1); return; } + tcg_temp_free(t0); + tcg_temp_free(t1); MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd], regnames[index], regnames[base]); } @@ -6873,22 +6937,25 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, switch (opc) { case OPC_ALNV_PS: check_cp1_64bitmode(ctx); - gen_load_gpr(cpu_T[0], fr); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x7); - gen_load_fpr32(fpu32_T[0], fs); - gen_load_fpr32h(fpu32h_T[0], fs); - gen_load_fpr32(fpu32_T[1], ft); - gen_load_fpr32h(fpu32h_T[1], ft); { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); int l1 = gen_new_label(); int l2 = gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); + gen_load_gpr(t0, fr); + tcg_gen_andi_tl(t0, t0, 0x7); + gen_load_fpr32(fpu32_T[0], fs); + gen_load_fpr32h(fpu32h_T[0], fs); + gen_load_fpr32(fpu32_T[1], ft); + gen_load_fpr32h(fpu32h_T[1], ft); + + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1); tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]); tcg_gen_br(l2); gen_set_label(l1); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 4, l2); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2); + tcg_temp_free(t0); #ifdef TARGET_WORDS_BIGENDIAN tcg_gen_mov_i32(fpu32h_T[2], fpu32_T[0]); tcg_gen_mov_i32(fpu32_T[2], fpu32h_T[1]); @@ -7247,70 +7314,96 @@ static void decode_opc (CPUState *env, DisasContext *ctx) case OPC_BSHFL: check_insn(env, ctx, ISA_MIPS32R2); op2 = MASK_BSHFL(ctx->opcode); - switch (op2) { - case OPC_WSBH: - gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_1_2(do_wsbh, cpu_T[0], cpu_T[0], cpu_T[1]); - break; - case OPC_SEB: - gen_load_gpr(cpu_T[1], rt); - tcg_gen_ext8s_tl(cpu_T[0], cpu_T[1]); - break; - case OPC_SEH: - gen_load_gpr(cpu_T[1], rt); - tcg_gen_ext16s_tl(cpu_T[0], cpu_T[1]); - break; - default: /* Invalid */ - MIPS_INVAL("bshfl"); - generate_exception(ctx, EXCP_RI); - break; + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); + + switch (op2) { + case OPC_WSBH: + gen_load_gpr(t1, rt); + tcg_gen_helper_1_2(do_wsbh, t0, t0, t1); + gen_store_gpr(t0, rd); + break; + case OPC_SEB: + gen_load_gpr(t1, rt); + tcg_gen_ext8s_tl(t0, t1); + gen_store_gpr(t0, rd); + break; + case OPC_SEH: + gen_load_gpr(t1, rt); + tcg_gen_ext16s_tl(t0, t1); + gen_store_gpr(t0, rd); + break; + default: /* Invalid */ + MIPS_INVAL("bshfl"); + generate_exception(ctx, EXCP_RI); + break; + } + tcg_temp_free(t0); + tcg_temp_free(t1); } - gen_store_gpr(cpu_T[0], rd); break; case OPC_RDHWR: check_insn(env, ctx, ISA_MIPS32R2); - switch (rd) { - case 0: - save_cpu_state(ctx, 1); - tcg_gen_helper_1_1(do_rdhwr_cpunum, cpu_T[0], cpu_T[0]); - break; - case 1: - save_cpu_state(ctx, 1); - tcg_gen_helper_1_1(do_rdhwr_synci_step, cpu_T[0], cpu_T[0]); - break; - case 2: - save_cpu_state(ctx, 1); - tcg_gen_helper_1_1(do_rdhwr_cc, cpu_T[0], cpu_T[0]); - break; - case 3: - save_cpu_state(ctx, 1); - tcg_gen_helper_1_1(do_rdhwr_ccres, cpu_T[0], cpu_T[0]); - break; - case 29: + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + switch (rd) { + case 0: + save_cpu_state(ctx, 1); + tcg_gen_helper_1_1(do_rdhwr_cpunum, t0, t0); + break; + case 1: + save_cpu_state(ctx, 1); + tcg_gen_helper_1_1(do_rdhwr_synci_step, t0, t0); + break; + case 2: + save_cpu_state(ctx, 1); + tcg_gen_helper_1_1(do_rdhwr_cc, t0, t0); + break; + case 3: + save_cpu_state(ctx, 1); + tcg_gen_helper_1_1(do_rdhwr_ccres, t0, t0); + break; + case 29: #if defined (CONFIG_USER_ONLY) - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, tls_value)); - break; + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value)); + break; #else - /* XXX: Some CPUs implement this in hardware. Not supported yet. */ + /* XXX: Some CPUs implement this in hardware. Not supported yet. */ #endif - default: /* Invalid */ - MIPS_INVAL("rdhwr"); - generate_exception(ctx, EXCP_RI); - break; + default: /* Invalid */ + MIPS_INVAL("rdhwr"); + generate_exception(ctx, EXCP_RI); + break; + } + gen_store_gpr(t0, rt); + tcg_temp_free(t0); } - gen_store_gpr(cpu_T[0], rt); break; case OPC_FORK: check_insn(env, ctx, ASE_MT); - gen_load_gpr(cpu_T[0], rt); - gen_load_gpr(cpu_T[1], rs); - tcg_gen_helper_1_2(do_fork, cpu_T[0], cpu_T[0], cpu_T[1]); + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, rt); + gen_load_gpr(t1, rs); + tcg_gen_helper_0_2(do_fork, t0, t1); + tcg_temp_free(t0); + tcg_temp_free(t1); + } break; case OPC_YIELD: check_insn(env, ctx, ASE_MT); - gen_load_gpr(cpu_T[0], rs); - tcg_gen_helper_1_1(do_yield, cpu_T[0], cpu_T[0]); - gen_store_gpr(cpu_T[0], rd); + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, rs); + tcg_gen_helper_1_1(do_yield, t0, t0); + gen_store_gpr(t0, rd); + tcg_temp_free(t0); + } break; #if defined(TARGET_MIPS64) case OPC_DEXTM ... OPC_DEXT: @@ -7323,21 +7416,28 @@ static void decode_opc (CPUState *env, DisasContext *ctx) check_insn(env, ctx, ISA_MIPS64R2); check_mips_64(ctx); op2 = MASK_DBSHFL(ctx->opcode); - switch (op2) { - case OPC_DSBH: - gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_1_2(do_dsbh, cpu_T[0], cpu_T[0], cpu_T[1]); - break; - case OPC_DSHD: - gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_1_2(do_dshd, cpu_T[0], cpu_T[0], cpu_T[1]); - break; - default: /* Invalid */ - MIPS_INVAL("dbshfl"); - generate_exception(ctx, EXCP_RI); - break; + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); + + switch (op2) { + case OPC_DSBH: + gen_load_gpr(t1, rt); + tcg_gen_helper_1_2(do_dsbh, t0, t0, t1); + break; + case OPC_DSHD: + gen_load_gpr(t1, rt); + tcg_gen_helper_1_2(do_dshd, t0, t0, t1); + break; + default: /* Invalid */ + MIPS_INVAL("dbshfl"); + generate_exception(ctx, EXCP_RI); + break; + } + gen_store_gpr(t0, rd); + tcg_temp_free(t0); + tcg_temp_free(t1); } - gen_store_gpr(cpu_T[0], rd); break; #endif default: /* Invalid */ @@ -7390,43 +7490,48 @@ static void decode_opc (CPUState *env, DisasContext *ctx) break; case OPC_MFMC0: op2 = MASK_MFMC0(ctx->opcode); - switch (op2) { - case OPC_DMT: - check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_dmt, cpu_T[0], cpu_T[0]); - break; - case OPC_EMT: - check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_emt, cpu_T[0], cpu_T[0]); - break; - case OPC_DVPE: - check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_dvpe, cpu_T[0], cpu_T[0]); - break; - case OPC_EVPE: - check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_evpe, cpu_T[0], cpu_T[0]); - break; - case OPC_DI: - check_insn(env, ctx, ISA_MIPS32R2); - save_cpu_state(ctx, 1); - tcg_gen_helper_1_1(do_di, cpu_T[0], cpu_T[0]); - /* Stop translation as we may have switched the execution mode */ - ctx->bstate = BS_STOP; - break; - case OPC_EI: - check_insn(env, ctx, ISA_MIPS32R2); - save_cpu_state(ctx, 1); - tcg_gen_helper_1_1(do_ei, cpu_T[0], cpu_T[0]); - /* Stop translation as we may have switched the execution mode */ - ctx->bstate = BS_STOP; - break; - default: /* Invalid */ - MIPS_INVAL("mfmc0"); - generate_exception(ctx, EXCP_RI); - break; + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + switch (op2) { + case OPC_DMT: + check_insn(env, ctx, ASE_MT); + tcg_gen_helper_1_1(do_dmt, t0, t0); + break; + case OPC_EMT: + check_insn(env, ctx, ASE_MT); + tcg_gen_helper_1_1(do_emt, t0, t0); + break; + case OPC_DVPE: + check_insn(env, ctx, ASE_MT); + tcg_gen_helper_1_1(do_dvpe, t0, t0); + break; + case OPC_EVPE: + check_insn(env, ctx, ASE_MT); + tcg_gen_helper_1_1(do_evpe, t0, t0); + break; + case OPC_DI: + check_insn(env, ctx, ISA_MIPS32R2); + save_cpu_state(ctx, 1); + tcg_gen_helper_1_1(do_di, t0, t0); + /* Stop translation as we may have switched the execution mode */ + ctx->bstate = BS_STOP; + break; + case OPC_EI: + check_insn(env, ctx, ISA_MIPS32R2); + save_cpu_state(ctx, 1); + tcg_gen_helper_1_1(do_ei, t0, t0); + /* Stop translation as we may have switched the execution mode */ + ctx->bstate = BS_STOP; + break; + default: /* Invalid */ + MIPS_INVAL("mfmc0"); + generate_exception(ctx, EXCP_RI); + break; + } + gen_store_gpr(t0, rt); + tcg_temp_free(t0); } - gen_store_gpr(cpu_T[0], rt); break; case OPC_RDPGPR: check_insn(env, ctx, ISA_MIPS32R2); -- cgit v1.2.3 From a764a566beb5783de0617a8cb1105283c50b616d Mon Sep 17 00:00:00 2001 From: blueswir1 Date: Tue, 24 Jun 2008 19:08:28 +0000 Subject: Fix Sparc mmu bug seen with NetBSD, based on patch by Cliff Wright git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4785 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-sparc/helper.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/target-sparc/helper.c b/target-sparc/helper.c index 7b87d592c..a3e50bd4c 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -87,14 +87,14 @@ int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw, * Sparc V8 Reference MMU (SRMMU) */ static const int access_table[8][8] = { - { 0, 0, 0, 0, 2, 0, 3, 3 }, - { 0, 0, 0, 0, 2, 0, 0, 0 }, - { 2, 2, 0, 0, 0, 2, 3, 3 }, - { 2, 2, 0, 0, 0, 2, 0, 0 }, - { 2, 0, 2, 0, 2, 2, 3, 3 }, - { 2, 0, 2, 0, 2, 0, 2, 0 }, - { 2, 2, 2, 0, 2, 2, 3, 3 }, - { 2, 2, 2, 0, 2, 2, 2, 0 } + { 0, 0, 0, 0, 8, 0, 12, 12 }, + { 0, 0, 0, 0, 8, 0, 0, 0 }, + { 8, 8, 0, 0, 0, 8, 12, 12 }, + { 8, 8, 0, 0, 0, 8, 0, 0 }, + { 8, 0, 8, 0, 8, 8, 12, 12 }, + { 8, 0, 8, 0, 8, 0, 8, 0 }, + { 8, 8, 8, 0, 8, 8, 12, 12 }, + { 8, 8, 8, 0, 8, 8, 8, 0 } }; static const int perm_table[2][8] = { -- cgit v1.2.3 From 7872368461d25d14229b72fbe4b9b557c5f75a87 Mon Sep 17 00:00:00 2001 From: ths Date: Tue, 24 Jun 2008 20:12:33 +0000 Subject: Reduce use of fixed registers a bit more. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4786 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/translate.c | 685 +++++++++++++++++++++++++----------------------- 1 file changed, 356 insertions(+), 329 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 75fa404d8..de2ee2183 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -1088,158 +1088,163 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, int base, int16_t offset) { const char *opn = "ldst"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); if (base == 0) { - tcg_gen_movi_tl(cpu_T[0], offset); + tcg_gen_movi_tl(t0, offset); } else if (offset == 0) { - gen_load_gpr(cpu_T[0], base); + gen_load_gpr(t0, base); } else { - gen_load_gpr(cpu_T[0], base); - tcg_gen_movi_tl(cpu_T[1], offset); - gen_op_addr_add(cpu_T[0], cpu_T[1]); + gen_load_gpr(t0, base); + tcg_gen_movi_tl(t1, offset); + gen_op_addr_add(t0, t1); } /* Don't do NOP if destination is zero: we must perform the actual memory access. */ switch (opc) { #if defined(TARGET_MIPS64) case OPC_LWU: - op_ldst_lwu(cpu_T[0], ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_lwu(t0, ctx); + gen_store_gpr(t0, rt); opn = "lwu"; break; case OPC_LD: - op_ldst_ld(cpu_T[0], ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_ld(t0, ctx); + gen_store_gpr(t0, rt); opn = "ld"; break; case OPC_LLD: - op_ldst_lld(cpu_T[0], cpu_T[1], ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_lld(t0, t1, ctx); + gen_store_gpr(t0, rt); opn = "lld"; break; case OPC_SD: - gen_load_gpr(cpu_T[1], rt); - op_ldst_sd(cpu_T[0], cpu_T[1], ctx); + gen_load_gpr(t1, rt); + op_ldst_sd(t0, t1, ctx); opn = "sd"; break; case OPC_SCD: save_cpu_state(ctx, 1); - gen_load_gpr(cpu_T[1], rt); - op_ldst_scd(cpu_T[0], cpu_T[1], ctx); - gen_store_gpr(cpu_T[0], rt); + gen_load_gpr(t1, rt); + op_ldst_scd(t0, t1, ctx); + gen_store_gpr(t0, rt); opn = "scd"; break; case OPC_LDL: save_cpu_state(ctx, 1); - gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_1_2i(do_ldl, cpu_T[1], cpu_T[0], cpu_T[1], ctx->mem_idx); - gen_store_gpr(cpu_T[1], rt); + gen_load_gpr(t1, rt); + tcg_gen_helper_1_2i(do_ldl, t1, t0, t1, ctx->mem_idx); + gen_store_gpr(t1, rt); opn = "ldl"; break; case OPC_SDL: save_cpu_state(ctx, 1); - gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_2i(do_sdl, cpu_T[0], cpu_T[1], ctx->mem_idx); + gen_load_gpr(t1, rt); + tcg_gen_helper_0_2i(do_sdl, t0, t1, ctx->mem_idx); opn = "sdl"; break; case OPC_LDR: save_cpu_state(ctx, 1); - gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_1_2i(do_ldr, cpu_T[1], cpu_T[0], cpu_T[1], ctx->mem_idx); - gen_store_gpr(cpu_T[1], rt); + gen_load_gpr(t1, rt); + tcg_gen_helper_1_2i(do_ldr, t1, t0, t1, ctx->mem_idx); + gen_store_gpr(t1, rt); opn = "ldr"; break; case OPC_SDR: save_cpu_state(ctx, 1); - gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_2i(do_sdr, cpu_T[0], cpu_T[1], ctx->mem_idx); + gen_load_gpr(t1, rt); + tcg_gen_helper_0_2i(do_sdr, t0, t1, ctx->mem_idx); opn = "sdr"; break; #endif case OPC_LW: - op_ldst_lw(cpu_T[0], ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_lw(t0, ctx); + gen_store_gpr(t0, rt); opn = "lw"; break; case OPC_SW: - gen_load_gpr(cpu_T[1], rt); - op_ldst_sw(cpu_T[0], cpu_T[1], ctx); + gen_load_gpr(t1, rt); + op_ldst_sw(t0, t1, ctx); opn = "sw"; break; case OPC_LH: - op_ldst_lh(cpu_T[0], ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_lh(t0, ctx); + gen_store_gpr(t0, rt); opn = "lh"; break; case OPC_SH: - gen_load_gpr(cpu_T[1], rt); - op_ldst_sh(cpu_T[0], cpu_T[1], ctx); + gen_load_gpr(t1, rt); + op_ldst_sh(t0, t1, ctx); opn = "sh"; break; case OPC_LHU: - op_ldst_lhu(cpu_T[0], ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_lhu(t0, ctx); + gen_store_gpr(t0, rt); opn = "lhu"; break; case OPC_LB: - op_ldst_lb(cpu_T[0], ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_lb(t0, ctx); + gen_store_gpr(t0, rt); opn = "lb"; break; case OPC_SB: - gen_load_gpr(cpu_T[1], rt); - op_ldst_sb(cpu_T[0], cpu_T[1], ctx); + gen_load_gpr(t1, rt); + op_ldst_sb(t0, t1, ctx); opn = "sb"; break; case OPC_LBU: - op_ldst_lbu(cpu_T[0], ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_lbu(t0, ctx); + gen_store_gpr(t0, rt); opn = "lbu"; break; case OPC_LWL: save_cpu_state(ctx, 1); - gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_1_2i(do_lwl, cpu_T[1], cpu_T[0], cpu_T[1], ctx->mem_idx); - gen_store_gpr(cpu_T[1], rt); + gen_load_gpr(t1, rt); + tcg_gen_helper_1_2i(do_lwl, t1, t0, t1, ctx->mem_idx); + gen_store_gpr(t1, rt); opn = "lwl"; break; case OPC_SWL: save_cpu_state(ctx, 1); - gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_2i(do_swl, cpu_T[0], cpu_T[1], ctx->mem_idx); + gen_load_gpr(t1, rt); + tcg_gen_helper_0_2i(do_swl, t0, t1, ctx->mem_idx); opn = "swr"; break; case OPC_LWR: save_cpu_state(ctx, 1); - gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_1_2i(do_lwr, cpu_T[1], cpu_T[0], cpu_T[1], ctx->mem_idx); - gen_store_gpr(cpu_T[1], rt); + gen_load_gpr(t1, rt); + tcg_gen_helper_1_2i(do_lwr, t1, t0, t1, ctx->mem_idx); + gen_store_gpr(t1, rt); opn = "lwr"; break; case OPC_SWR: save_cpu_state(ctx, 1); - gen_load_gpr(cpu_T[1], rt); - tcg_gen_helper_0_2i(do_swr, cpu_T[0], cpu_T[1], ctx->mem_idx); + gen_load_gpr(t1, rt); + tcg_gen_helper_0_2i(do_swr, t0, t1, ctx->mem_idx); opn = "swr"; break; case OPC_LL: - op_ldst_ll(cpu_T[0], cpu_T[1], ctx); - gen_store_gpr(cpu_T[0], rt); + op_ldst_ll(t0, t1, ctx); + gen_store_gpr(t0, rt); opn = "ll"; break; case OPC_SC: save_cpu_state(ctx, 1); - gen_load_gpr(cpu_T[1], rt); - op_ldst_sc(cpu_T[0], cpu_T[1], ctx); - gen_store_gpr(cpu_T[0], rt); + gen_load_gpr(t1, rt); + op_ldst_sc(t0, t1, ctx); + gen_store_gpr(t0, rt); opn = "sc"; break; default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); - return; + goto out; } MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); + out: + tcg_temp_free(t0); + tcg_temp_free(t1); } /* Load and store */ @@ -1247,45 +1252,51 @@ static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft, int base, int16_t offset) { const char *opn = "flt_ldst"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); if (base == 0) { - tcg_gen_movi_tl(cpu_T[0], offset); + tcg_gen_movi_tl(t0, offset); } else if (offset == 0) { - gen_load_gpr(cpu_T[0], base); + gen_load_gpr(t0, base); } else { - gen_load_gpr(cpu_T[0], base); - tcg_gen_movi_tl(cpu_T[1], offset); - gen_op_addr_add(cpu_T[0], cpu_T[1]); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, base); + tcg_gen_movi_tl(t1, offset); + gen_op_addr_add(t0, t1); + tcg_temp_free(t1); } /* Don't do NOP if destination is zero: we must perform the actual memory access. */ switch (opc) { case OPC_LWC1: - tcg_gen_qemu_ld32s(fpu32_T[0], cpu_T[0], ctx->mem_idx); + tcg_gen_qemu_ld32s(fpu32_T[0], t0, ctx->mem_idx); gen_store_fpr32(fpu32_T[0], ft); opn = "lwc1"; break; case OPC_SWC1: gen_load_fpr32(fpu32_T[0], ft); - tcg_gen_qemu_st32(fpu32_T[0], cpu_T[0], ctx->mem_idx); + tcg_gen_qemu_st32(fpu32_T[0], t0, ctx->mem_idx); opn = "swc1"; break; case OPC_LDC1: - tcg_gen_qemu_ld64(fpu64_T[0], cpu_T[0], ctx->mem_idx); + tcg_gen_qemu_ld64(fpu64_T[0], t0, ctx->mem_idx); gen_store_fpr64(ctx, fpu64_T[0], ft); opn = "ldc1"; break; case OPC_SDC1: gen_load_fpr64(ctx, fpu64_T[0], ft); - tcg_gen_qemu_st64(fpu64_T[0], cpu_T[0], ctx->mem_idx); + tcg_gen_qemu_st64(fpu64_T[0], t0, ctx->mem_idx); opn = "sdc1"; break; default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); - return; + goto out; } MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]); + out: + tcg_temp_free(t0); } /* Arithmetic with immediate operand */ @@ -1294,12 +1305,13 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, { target_ulong uimm; const char *opn = "imm arith"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) { /* If no destination, treat it as a NOP. For addi, we must generate the overflow exception when needed. */ MIPS_DEBUG("NOP"); - return; + goto out; } uimm = (uint16_t)imm; switch (opc) { @@ -1316,10 +1328,10 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, case OPC_ANDI: case OPC_ORI: case OPC_XORI: - gen_load_gpr(cpu_T[0], rs); + gen_load_gpr(t0, rs); break; case OPC_LUI: - tcg_gen_movi_tl(cpu_T[0], imm << 16); + tcg_gen_movi_tl(t0, imm << 16); break; case OPC_SLL: case OPC_SRA: @@ -1333,7 +1345,7 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, case OPC_DSRL32: #endif uimm &= 0x1f; - gen_load_gpr(cpu_T[0], rs); + gen_load_gpr(t0, rs); break; } switch (opc) { @@ -1344,12 +1356,12 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); save_cpu_state(ctx, 1); - tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]); - tcg_gen_addi_tl(cpu_T[0], r_tmp1, uimm); + tcg_gen_ext32s_tl(r_tmp1, t0); + tcg_gen_addi_tl(t0, r_tmp1, uimm); tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm); tcg_gen_xori_tl(r_tmp1, r_tmp1, -1); - tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm); + tcg_gen_xori_tl(r_tmp2, t0, uimm); tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); tcg_gen_shri_tl(r_tmp1, r_tmp1, 31); @@ -1359,14 +1371,14 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, generate_exception(ctx, EXCP_OVERFLOW); gen_set_label(l1); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); } opn = "addi"; break; case OPC_ADDIU: - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_addi_tl(t0, t0, uimm); + tcg_gen_ext32s_tl(t0, t0); opn = "addiu"; break; #if defined(TARGET_MIPS64) @@ -1377,12 +1389,12 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); save_cpu_state(ctx, 1); - tcg_gen_mov_tl(r_tmp1, cpu_T[0]); - tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_mov_tl(r_tmp1, t0); + tcg_gen_addi_tl(t0, t0, uimm); tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm); tcg_gen_xori_tl(r_tmp1, r_tmp1, -1); - tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm); + tcg_gen_xori_tl(r_tmp2, t0, uimm); tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); tcg_gen_shri_tl(r_tmp1, r_tmp1, 63); @@ -1395,51 +1407,51 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, opn = "daddi"; break; case OPC_DADDIU: - tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_addi_tl(t0, t0, uimm); opn = "daddiu"; break; #endif case OPC_SLTI: - gen_op_lti(cpu_T[0], uimm); + gen_op_lti(t0, uimm); opn = "slti"; break; case OPC_SLTIU: - gen_op_ltiu(cpu_T[0], uimm); + gen_op_ltiu(t0, uimm); opn = "sltiu"; break; case OPC_ANDI: - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_andi_tl(t0, t0, uimm); opn = "andi"; break; case OPC_ORI: - tcg_gen_ori_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_ori_tl(t0, t0, uimm); opn = "ori"; break; case OPC_XORI: - tcg_gen_xori_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_xori_tl(t0, t0, uimm); opn = "xori"; break; case OPC_LUI: opn = "lui"; break; case OPC_SLL: - tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); - tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_shli_tl(t0, t0, uimm); + tcg_gen_ext32s_tl(t0, t0); opn = "sll"; break; case OPC_SRA: - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_sari_tl(t0, t0, uimm); + tcg_gen_ext32s_tl(t0, t0); opn = "sra"; break; case OPC_SRL: switch ((ctx->opcode >> 21) & 0x1f) { case 0: - tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); - tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_shri_tl(t0, t0, uimm); + tcg_gen_ext32s_tl(t0, t0); opn = "srl"; break; case 1: @@ -1449,21 +1461,21 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); - tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]); + tcg_gen_trunc_tl_i32(r_tmp1, t0); tcg_gen_movi_i32(r_tmp2, 0x20); tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm); tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2); tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm); tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2); - tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); tcg_temp_free(r_tmp1); tcg_temp_free(r_tmp2); } opn = "rotr"; } else { - tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); - tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_shri_tl(t0, t0, uimm); + tcg_gen_ext32s_tl(t0, t0); opn = "srl"; } break; @@ -1475,17 +1487,17 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, break; #if defined(TARGET_MIPS64) case OPC_DSLL: - tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_shli_tl(t0, t0, uimm); opn = "dsll"; break; case OPC_DSRA: - tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_sari_tl(t0, t0, uimm); opn = "dsra"; break; case OPC_DSRL: switch ((ctx->opcode >> 21) & 0x1f) { case 0: - tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_shri_tl(t0, t0, uimm); opn = "dsrl"; break; case 1: @@ -1496,14 +1508,14 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, tcg_gen_movi_tl(r_tmp1, 0x40); tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm); - tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1); - tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm); - tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1); + tcg_gen_shl_tl(r_tmp1, t0, r_tmp1); + tcg_gen_shri_tl(t0, t0, uimm); + tcg_gen_or_tl(t0, t0, r_tmp1); tcg_temp_free(r_tmp1); } opn = "drotr"; } else { - tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm); + tcg_gen_shri_tl(t0, t0, uimm); opn = "dsrl"; } break; @@ -1514,17 +1526,17 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, } break; case OPC_DSLL32: - tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm + 32); + tcg_gen_shli_tl(t0, t0, uimm + 32); opn = "dsll32"; break; case OPC_DSRA32: - tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm + 32); + tcg_gen_sari_tl(t0, t0, uimm + 32); opn = "dsra32"; break; case OPC_DSRL32: switch ((ctx->opcode >> 21) & 0x1f) { case 0: - tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32); + tcg_gen_shri_tl(t0, t0, uimm + 32); opn = "dsrl32"; break; case 1: @@ -1537,14 +1549,14 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, tcg_gen_movi_tl(r_tmp2, 32); tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm); tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2); - tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1); - tcg_gen_shr_tl(cpu_T[0], cpu_T[0], r_tmp2); - tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1); + tcg_gen_shl_tl(r_tmp1, t0, r_tmp1); + tcg_gen_shr_tl(t0, t0, r_tmp2); + tcg_gen_or_tl(t0, t0, r_tmp1); tcg_temp_free(r_tmp1); tcg_temp_free(r_tmp2); opn = "drotr32"; } else { - tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32); + tcg_gen_shri_tl(t0, t0, uimm + 32); opn = "dsrl32"; } break; @@ -1558,10 +1570,12 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); - return; + goto out; } - gen_store_gpr(cpu_T[0], rt); + gen_store_gpr(t0, rt); MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm); + out: + tcg_temp_free(t0); } /* Arithmetic */ @@ -1569,22 +1583,24 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int rd, int rs, int rt) { const char *opn = "arith"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB && opc != OPC_DADD && opc != OPC_DSUB) { /* If no destination, treat it as a NOP. For add & sub, we must generate the overflow exception when needed. */ MIPS_DEBUG("NOP"); - return; + goto out; } - gen_load_gpr(cpu_T[0], rs); + gen_load_gpr(t0, rs); /* Specialcase the conventional move operation. */ if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU || opc == OPC_SUBU || opc == OPC_DSUBU)) { - gen_store_gpr(cpu_T[0], rd); - return; + gen_store_gpr(t0, rd); + goto out; } - gen_load_gpr(cpu_T[1], rt); + gen_load_gpr(t1, rt); switch (opc) { case OPC_ADD: { @@ -1593,13 +1609,13 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); save_cpu_state(ctx, 1); - tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]); - tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]); - tcg_gen_add_tl(cpu_T[0], r_tmp1, r_tmp2); + tcg_gen_ext32s_tl(r_tmp1, t0); + tcg_gen_ext32s_tl(r_tmp2, t1); + tcg_gen_add_tl(t0, r_tmp1, r_tmp2); - tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]); + tcg_gen_xor_tl(r_tmp1, r_tmp1, t1); tcg_gen_xori_tl(r_tmp1, r_tmp1, -1); - tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]); + tcg_gen_xor_tl(r_tmp2, t0, t1); tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); tcg_gen_shri_tl(r_tmp1, r_tmp1, 31); @@ -1609,15 +1625,15 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, generate_exception(ctx, EXCP_OVERFLOW); gen_set_label(l1); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); } opn = "add"; break; case OPC_ADDU: - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_add_tl(t0, t0, t1); + tcg_gen_ext32s_tl(t0, t0); opn = "addu"; break; case OPC_SUB: @@ -1627,12 +1643,12 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); save_cpu_state(ctx, 1); - tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]); - tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]); - tcg_gen_sub_tl(cpu_T[0], r_tmp1, r_tmp2); + tcg_gen_ext32s_tl(r_tmp1, t0); + tcg_gen_ext32s_tl(r_tmp2, t1); + tcg_gen_sub_tl(t0, r_tmp1, r_tmp2); - tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]); - tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]); + tcg_gen_xor_tl(r_tmp2, r_tmp1, t1); + tcg_gen_xor_tl(r_tmp1, r_tmp1, t0); tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); tcg_gen_shri_tl(r_tmp1, r_tmp1, 31); @@ -1642,15 +1658,15 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, generate_exception(ctx, EXCP_OVERFLOW); gen_set_label(l1); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); } opn = "sub"; break; case OPC_SUBU: - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_sub_tl(t0, t0, t1); + tcg_gen_ext32s_tl(t0, t0); opn = "subu"; break; #if defined(TARGET_MIPS64) @@ -1661,12 +1677,12 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); save_cpu_state(ctx, 1); - tcg_gen_mov_tl(r_tmp1, cpu_T[0]); - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(r_tmp1, t0); + tcg_gen_add_tl(t0, t0, t1); - tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]); + tcg_gen_xor_tl(r_tmp1, r_tmp1, t1); tcg_gen_xori_tl(r_tmp1, r_tmp1, -1); - tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]); + tcg_gen_xor_tl(r_tmp2, t0, t1); tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); tcg_gen_shri_tl(r_tmp1, r_tmp1, 63); @@ -1679,7 +1695,7 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, opn = "dadd"; break; case OPC_DADDU: - tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_add_tl(t0, t0, t1); opn = "daddu"; break; case OPC_DSUB: @@ -1689,11 +1705,11 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); save_cpu_state(ctx, 1); - tcg_gen_mov_tl(r_tmp1, cpu_T[0]); - tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(r_tmp1, t0); + tcg_gen_sub_tl(t0, t0, t1); - tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]); - tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]); + tcg_gen_xor_tl(r_tmp2, r_tmp1, t1); + tcg_gen_xor_tl(r_tmp1, r_tmp1, t0); tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); tcg_gen_shri_tl(r_tmp1, r_tmp1, 63); @@ -1706,48 +1722,48 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, opn = "dsub"; break; case OPC_DSUBU: - tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_sub_tl(t0, t0, t1); opn = "dsubu"; break; #endif case OPC_SLT: - gen_op_lt(cpu_T[0], cpu_T[1]); + gen_op_lt(t0, t1); opn = "slt"; break; case OPC_SLTU: - gen_op_ltu(cpu_T[0], cpu_T[1]); + gen_op_ltu(t0, t1); opn = "sltu"; break; case OPC_AND: - tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_and_tl(t0, t0, t1); opn = "and"; break; case OPC_NOR: - tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_not_tl(cpu_T[0], cpu_T[0]); + tcg_gen_or_tl(t0, t0, t1); + tcg_gen_not_tl(t0, t0); opn = "nor"; break; case OPC_OR: - tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_or_tl(t0, t0, t1); opn = "or"; break; case OPC_XOR: - tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]); + tcg_gen_xor_tl(t0, t0, t1); opn = "xor"; break; case OPC_MUL: - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_mul_tl(t0, t0, t1); + tcg_gen_ext32s_tl(t0, t0); opn = "mul"; break; case OPC_MOVN: { int l1 = gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1); - gen_store_gpr(cpu_T[0], rd); + tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); + gen_store_gpr(t0, rd); gen_set_label(l1); } opn = "movn"; @@ -1756,34 +1772,34 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, { int l1 = gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], 0, l1); - gen_store_gpr(cpu_T[0], rd); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1); + gen_store_gpr(t0, rd); gen_set_label(l1); } opn = "movz"; goto print; case OPC_SLLV: - tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f); - tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_andi_tl(t0, t0, 0x1f); + tcg_gen_shl_tl(t0, t1, t0); + tcg_gen_ext32s_tl(t0, t0); opn = "sllv"; break; case OPC_SRAV: - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f); - tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_andi_tl(t0, t0, 0x1f); + tcg_gen_sar_tl(t0, t1, t0); + tcg_gen_ext32s_tl(t0, t0); opn = "srav"; break; case OPC_SRLV: switch ((ctx->opcode >> 6) & 0x1f) { case 0: - tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f); - tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_andi_tl(t0, t0, 0x1f); + tcg_gen_shr_tl(t0, t1, t0); + tcg_gen_ext32s_tl(t0, t0); opn = "srlv"; break; case 1: @@ -1792,35 +1808,35 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); int l2 = gen_new_label(); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); + tcg_gen_andi_tl(t0, t0, 0x1f); + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); { TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32); - tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]); - tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]); + tcg_gen_trunc_tl_i32(r_tmp1, t0); + tcg_gen_trunc_tl_i32(r_tmp2, t1); tcg_gen_movi_i32(r_tmp3, 0x20); tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1); tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3); tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1); tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3); - tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp1); tcg_temp_free(r_tmp1); tcg_temp_free(r_tmp2); tcg_temp_free(r_tmp3); tcg_gen_br(l2); } gen_set_label(l1); - tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(t0, t1); gen_set_label(l2); opn = "rotrv"; } else { - tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f); - tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_andi_tl(t0, t0, 0x1f); + tcg_gen_shr_tl(t0, t1, t0); + tcg_gen_ext32s_tl(t0, t0); opn = "srlv"; } break; @@ -1832,20 +1848,20 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, break; #if defined(TARGET_MIPS64) case OPC_DSLLV: - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f); - tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]); + tcg_gen_andi_tl(t0, t0, 0x3f); + tcg_gen_shl_tl(t0, t1, t0); opn = "dsllv"; break; case OPC_DSRAV: - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f); - tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]); + tcg_gen_andi_tl(t0, t0, 0x3f); + tcg_gen_sar_tl(t0, t1, t0); opn = "dsrav"; break; case OPC_DSRLV: switch ((ctx->opcode >> 6) & 0x1f) { case 0: - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f); - tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]); + tcg_gen_andi_tl(t0, t0, 0x3f); + tcg_gen_shr_tl(t0, t1, t0); opn = "dsrlv"; break; case 1: @@ -1854,26 +1870,26 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, int l1 = gen_new_label(); int l2 = gen_new_label(); - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); + tcg_gen_andi_tl(t0, t0, 0x3f); + tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); { TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL); tcg_gen_movi_tl(r_tmp1, 0x40); - tcg_gen_sub_tl(r_tmp1, r_tmp1, cpu_T[0]); - tcg_gen_shl_tl(r_tmp1, cpu_T[1], r_tmp1); - tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]); - tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1); + tcg_gen_sub_tl(r_tmp1, r_tmp1, t0); + tcg_gen_shl_tl(r_tmp1, t1, r_tmp1); + tcg_gen_shr_tl(t0, t1, t0); + tcg_gen_or_tl(t0, t0, r_tmp1); tcg_temp_free(r_tmp1); tcg_gen_br(l2); } gen_set_label(l1); - tcg_gen_mov_tl(cpu_T[0], cpu_T[1]); + tcg_gen_mov_tl(t0, t1); gen_set_label(l2); opn = "drotrv"; } else { - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f); - tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]); + tcg_gen_andi_tl(t0, t0, 0x3f); + tcg_gen_shr_tl(t0, t1, t0); opn = "dsrlv"; } break; @@ -1887,85 +1903,93 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); - return; + goto out; } - gen_store_gpr(cpu_T[0], rd); + gen_store_gpr(t0, rd); print: MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); + out: + tcg_temp_free(t0); + tcg_temp_free(t1); } /* Arithmetic on HI/LO registers */ static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg) { const char *opn = "hilo"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) { /* Treat as NOP. */ MIPS_DEBUG("NOP"); - return; + goto out; } switch (opc) { case OPC_MFHI: - gen_load_HI(cpu_T[0], 0); - gen_store_gpr(cpu_T[0], reg); + gen_load_HI(t0, 0); + gen_store_gpr(t0, reg); opn = "mfhi"; break; case OPC_MFLO: - gen_load_LO(cpu_T[0], 0); - gen_store_gpr(cpu_T[0], reg); + gen_load_LO(t0, 0); + gen_store_gpr(t0, reg); opn = "mflo"; break; case OPC_MTHI: - gen_load_gpr(cpu_T[0], reg); - gen_store_HI(cpu_T[0], 0); + gen_load_gpr(t0, reg); + gen_store_HI(t0, 0); opn = "mthi"; break; case OPC_MTLO: - gen_load_gpr(cpu_T[0], reg); - gen_store_LO(cpu_T[0], 0); + gen_load_gpr(t0, reg); + gen_store_LO(t0, 0); opn = "mtlo"; break; default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); - return; + goto out; } MIPS_DEBUG("%s %s", opn, regnames[reg]); + out: + tcg_temp_free(t0); } static void gen_muldiv (DisasContext *ctx, uint32_t opc, int rs, int rt) { const char *opn = "mul/div"; + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); - gen_load_gpr(cpu_T[0], rs); - gen_load_gpr(cpu_T[1], rt); + gen_load_gpr(t0, rs); + gen_load_gpr(t1, rt); switch (opc) { case OPC_DIV: { int l1 = gen_new_label(); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); { TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); - tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]); - tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]); + tcg_gen_ext_tl_i64(r_tmp1, t0); + tcg_gen_ext_tl_i64(r_tmp2, t1); tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2); tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2); - tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp3); - tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp2); + tcg_gen_trunc_i64_tl(t0, r_tmp3); + tcg_gen_trunc_i64_tl(t1, r_tmp2); tcg_temp_free(r_tmp1); tcg_temp_free(r_tmp2); tcg_temp_free(r_tmp3); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - gen_store_LO(cpu_T[0], 0); - gen_store_HI(cpu_T[1], 0); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); } gen_set_label(l1); } @@ -1975,24 +1999,24 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, { int l1 = gen_new_label(); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); { TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32); - tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]); - tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]); + tcg_gen_trunc_tl_i32(r_tmp1, t0); + tcg_gen_trunc_tl_i32(r_tmp2, t1); tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2); tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2); - tcg_gen_ext_i32_tl(cpu_T[0], r_tmp3); - tcg_gen_ext_i32_tl(cpu_T[1], r_tmp1); + tcg_gen_ext_i32_tl(t0, r_tmp3); + tcg_gen_ext_i32_tl(t1, r_tmp1); tcg_temp_free(r_tmp1); tcg_temp_free(r_tmp2); tcg_temp_free(r_tmp3); - gen_store_LO(cpu_T[0], 0); - gen_store_HI(cpu_T[1], 0); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); } gen_set_label(l1); } @@ -2003,20 +2027,20 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]); - tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_ext_tl_i64(r_tmp1, t0); + tcg_gen_ext_tl_i64(r_tmp2, t1); tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); - tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); + tcg_gen_trunc_i64_tl(t0, r_tmp1); tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); - tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); + tcg_gen_trunc_i64_tl(t1, r_tmp1); tcg_temp_free(r_tmp1); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - gen_store_LO(cpu_T[0], 0); - gen_store_HI(cpu_T[1], 0); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); } opn = "mult"; break; @@ -2025,20 +2049,20 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); - tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); - tcg_gen_extu_tl_i64(r_tmp1, cpu_T[0]); - tcg_gen_extu_tl_i64(r_tmp2, cpu_T[1]); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_extu_tl_i64(r_tmp1, t0); + tcg_gen_extu_tl_i64(r_tmp2, t1); tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); - tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); + tcg_gen_trunc_i64_tl(t0, r_tmp1); tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); - tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); + tcg_gen_trunc_i64_tl(t1, r_tmp1); tcg_temp_free(r_tmp1); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - gen_store_LO(cpu_T[0], 0); - gen_store_HI(cpu_T[1], 0); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); } opn = "multu"; break; @@ -2047,16 +2071,16 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, { int l1 = gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1); + tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); { int l2 = gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], -1LL << 63, l2); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1LL, l2); + tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2); + tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2); { - tcg_gen_movi_tl(cpu_T[1], 0); - gen_store_LO(cpu_T[0], 0); - gen_store_HI(cpu_T[1], 0); + tcg_gen_movi_tl(t1, 0); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); tcg_gen_br(l1); } gen_set_label(l2); @@ -2064,8 +2088,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); - tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]); - tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]); + tcg_gen_div_i64(r_tmp1, t0, t1); + tcg_gen_rem_i64(r_tmp2, t0, t1); gen_store_LO(r_tmp1, 0); gen_store_HI(r_tmp2, 0); tcg_temp_free(r_tmp1); @@ -2080,13 +2104,13 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, { int l1 = gen_new_label(); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1); + tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); { TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64); TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); - tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]); - tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]); + tcg_gen_divu_i64(r_tmp1, t0, t1); + tcg_gen_remu_i64(r_tmp2, t0, t1); tcg_temp_free(r_tmp1); tcg_temp_free(r_tmp2); gen_store_LO(r_tmp1, 0); @@ -2097,11 +2121,11 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, opn = "ddivu"; break; case OPC_DMULT: - tcg_gen_helper_0_2(do_dmult, cpu_T[0], cpu_T[1]); + tcg_gen_helper_0_2(do_dmult, t0, t1); opn = "dmult"; break; case OPC_DMULTU: - tcg_gen_helper_0_2(do_dmultu, cpu_T[0], cpu_T[1]); + tcg_gen_helper_0_2(do_dmultu, t0, t1); opn = "dmultu"; break; #endif @@ -2111,28 +2135,28 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]); - tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_ext_tl_i64(r_tmp1, t0); + tcg_gen_ext_tl_i64(r_tmp2, t1); tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); - gen_load_LO(cpu_T[0], 0); - gen_load_HI(cpu_T[1], 0); - tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]); - tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]); + gen_load_LO(t0, 0); + gen_load_HI(t1, 0); + tcg_gen_extu_tl_i64(r_tmp2, t0); + tcg_gen_extu_tl_i64(r_tmp3, t1); tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); tcg_temp_free(r_tmp3); tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); - tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); + tcg_gen_trunc_i64_tl(t0, r_tmp1); tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); - tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); + tcg_gen_trunc_i64_tl(t1, r_tmp1); tcg_temp_free(r_tmp1); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - gen_store_LO(cpu_T[0], 0); - gen_store_HI(cpu_T[1], 0); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); } opn = "madd"; break; @@ -2142,28 +2166,28 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); - tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); - tcg_gen_extu_tl_i64(r_tmp1, cpu_T[0]); - tcg_gen_extu_tl_i64(r_tmp2, cpu_T[1]); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_extu_tl_i64(r_tmp1, t0); + tcg_gen_extu_tl_i64(r_tmp2, t1); tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); - gen_load_LO(cpu_T[0], 0); - gen_load_HI(cpu_T[1], 0); - tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]); - tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]); + gen_load_LO(t0, 0); + gen_load_HI(t1, 0); + tcg_gen_extu_tl_i64(r_tmp2, t0); + tcg_gen_extu_tl_i64(r_tmp3, t1); tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); tcg_temp_free(r_tmp3); tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); - tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); + tcg_gen_trunc_i64_tl(t0, r_tmp1); tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); - tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); + tcg_gen_trunc_i64_tl(t1, r_tmp1); tcg_temp_free(r_tmp1); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - gen_store_LO(cpu_T[0], 0); - gen_store_HI(cpu_T[1], 0); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); } opn = "maddu"; break; @@ -2173,28 +2197,28 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]); - tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + tcg_gen_ext_tl_i64(r_tmp1, t0); + tcg_gen_ext_tl_i64(r_tmp2, t1); tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); - gen_load_LO(cpu_T[0], 0); - gen_load_HI(cpu_T[1], 0); - tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]); - tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]); + gen_load_LO(t0, 0); + gen_load_HI(t1, 0); + tcg_gen_extu_tl_i64(r_tmp2, t0); + tcg_gen_extu_tl_i64(r_tmp3, t1); tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); tcg_temp_free(r_tmp3); tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); - tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); + tcg_gen_trunc_i64_tl(t0, r_tmp1); tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); - tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); + tcg_gen_trunc_i64_tl(t1, r_tmp1); tcg_temp_free(r_tmp1); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - gen_store_LO(cpu_T[0], 0); - gen_store_HI(cpu_T[1], 0); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); } opn = "msub"; break; @@ -2204,37 +2228,40 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64); TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64); - tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]); - tcg_gen_extu_tl_i64(r_tmp1, cpu_T[0]); - tcg_gen_extu_tl_i64(r_tmp2, cpu_T[1]); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_extu_tl_i64(r_tmp1, t0); + tcg_gen_extu_tl_i64(r_tmp2, t1); tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2); - gen_load_LO(cpu_T[0], 0); - gen_load_HI(cpu_T[1], 0); - tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]); - tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]); + gen_load_LO(t0, 0); + gen_load_HI(t1, 0); + tcg_gen_extu_tl_i64(r_tmp2, t0); + tcg_gen_extu_tl_i64(r_tmp3, t1); tcg_gen_shli_i64(r_tmp3, r_tmp3, 32); tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3); tcg_temp_free(r_tmp3); tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2); tcg_temp_free(r_tmp2); - tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1); + tcg_gen_trunc_i64_tl(t0, r_tmp1); tcg_gen_shri_i64(r_tmp1, r_tmp1, 32); - tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1); + tcg_gen_trunc_i64_tl(t1, r_tmp1); tcg_temp_free(r_tmp1); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); - tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]); - gen_store_LO(cpu_T[0], 0); - gen_store_HI(cpu_T[1], 0); + tcg_gen_ext32s_tl(t0, t0); + tcg_gen_ext32s_tl(t1, t1); + gen_store_LO(t0, 0); + gen_store_HI(t1, 0); } opn = "msubu"; break; default: MIPS_INVAL(opn); generate_exception(ctx, EXCP_RI); - return; + goto out; } MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]); + out: + tcg_temp_free(t0); + tcg_temp_free(t1); } static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc, -- cgit v1.2.3 From e1bf387ec851e56819e4fdd965bc8bdd67167449 Mon Sep 17 00:00:00 2001 From: ths Date: Tue, 24 Jun 2008 20:13:20 +0000 Subject: T1 is now dead. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4787 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/cpu.h | 1 - target-mips/exec.h | 2 -- target-mips/translate.c | 5 +---- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 874ecee5e..cf7043a57 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -142,7 +142,6 @@ struct CPUMIPSState { target_ulong PC[MIPS_TC_MAX]; #if TARGET_LONG_BITS > HOST_LONG_BITS target_ulong t0; - target_ulong t1; #endif /* temporary hack for FP globals */ #ifndef USE_HOST_FLOAT_REGS diff --git a/target-mips/exec.h b/target-mips/exec.h index 2653d34c7..6b351da11 100644 --- a/target-mips/exec.h +++ b/target-mips/exec.h @@ -12,10 +12,8 @@ register struct CPUMIPSState *env asm(AREG0); #if TARGET_LONG_BITS > HOST_LONG_BITS #define T0 (env->t0) -#define T1 (env->t1) #else register target_ulong T0 asm(AREG1); -register target_ulong T1 asm(AREG2); #endif #if defined (USE_HOST_FLOAT_REGS) diff --git a/target-mips/translate.c b/target-mips/translate.c index de2ee2183..106d35592 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -423,7 +423,7 @@ enum { }; /* global register indices */ -static TCGv cpu_env, current_tc_gprs, current_tc_hi, current_fpu, cpu_T[2]; +static TCGv cpu_env, current_tc_gprs, current_tc_hi, current_fpu, cpu_T[1]; /* FPU TNs, global for now. */ static TCGv fpu32_T[3], fpu64_T[3], fpu32h_T[3]; @@ -8072,11 +8072,8 @@ static void mips_tcg_init(void) #if TARGET_LONG_BITS > HOST_LONG_BITS cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0, offsetof(CPUState, t0), "T0"); - cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL, - TCG_AREG0, offsetof(CPUState, t1), "T1"); #else cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0"); - cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1"); #endif /* register helpers */ -- cgit v1.2.3 From 1a3fd9c3da4e2d9434a14168306b2fa0abadce18 Mon Sep 17 00:00:00 2001 From: ths Date: Tue, 24 Jun 2008 21:58:35 +0000 Subject: Remove remaining uses of T0 in the MIPS target. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4788 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/cpu.h | 3 - target-mips/exec.h | 6 - target-mips/helper.h | 66 ++-- target-mips/op_helper.c | 69 ++--- target-mips/translate.c | 778 +++++++++++++++++++++++++----------------------- 5 files changed, 468 insertions(+), 454 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index cf7043a57..fdb05ccfd 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -140,9 +140,6 @@ struct CPUMIPSState { target_ulong gpr[MIPS_SHADOW_SET_MAX][32]; /* Special registers */ target_ulong PC[MIPS_TC_MAX]; -#if TARGET_LONG_BITS > HOST_LONG_BITS - target_ulong t0; -#endif /* temporary hack for FP globals */ #ifndef USE_HOST_FLOAT_REGS fpr_t ft0; diff --git a/target-mips/exec.h b/target-mips/exec.h index 6b351da11..a7014eea1 100644 --- a/target-mips/exec.h +++ b/target-mips/exec.h @@ -10,12 +10,6 @@ register struct CPUMIPSState *env asm(AREG0); -#if TARGET_LONG_BITS > HOST_LONG_BITS -#define T0 (env->t0) -#else -register target_ulong T0 asm(AREG1); -#endif - #if defined (USE_HOST_FLOAT_REGS) #error "implement me." #else diff --git a/target-mips/helper.h b/target-mips/helper.h index 710290883..9fb5d7402 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -43,40 +43,40 @@ DEF_HELPER(target_ulong, do_msachiu, (target_ulong t0, target_ulong t1)) /* CP0 helpers */ #ifndef CONFIG_USER_ONLY -DEF_HELPER(target_ulong, do_mfc0_mvpcontrol, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mfc0_mvpconf0, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mfc0_mvpconf1, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mfc0_random, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mfc0_tcstatus, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mftc0_tcstatus, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mfc0_tcbind, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mftc0_tcbind, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mfc0_tcrestart, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mftc0_tcrestart, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mfc0_tchalt, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mftc0_tchalt, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mfc0_tccontext, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mftc0_tccontext, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mfc0_tcschedule, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mftc0_tcschedule, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mfc0_tcschefback, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mftc0_tcschefback, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mfc0_count, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mftc0_entryhi, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mftc0_status, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mfc0_lladdr, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mfc0_watchlo, (target_ulong t0, uint32_t sel)) -DEF_HELPER(target_ulong, do_mfc0_watchhi, (target_ulong t0, uint32_t sel)) -DEF_HELPER(target_ulong, do_mfc0_debug, (target_ulong t0)) -DEF_HELPER(target_ulong, do_mftc0_debug, (target_ulong t0)) +DEF_HELPER(target_ulong, do_mfc0_mvpcontrol, (void)) +DEF_HELPER(target_ulong, do_mfc0_mvpconf0, (void)) +DEF_HELPER(target_ulong, do_mfc0_mvpconf1, (void)) +DEF_HELPER(target_ulong, do_mfc0_random, (void)) +DEF_HELPER(target_ulong, do_mfc0_tcstatus, (void)) +DEF_HELPER(target_ulong, do_mftc0_tcstatus, (void)) +DEF_HELPER(target_ulong, do_mfc0_tcbind, (void)) +DEF_HELPER(target_ulong, do_mftc0_tcbind, (void)) +DEF_HELPER(target_ulong, do_mfc0_tcrestart, (void)) +DEF_HELPER(target_ulong, do_mftc0_tcrestart, (void)) +DEF_HELPER(target_ulong, do_mfc0_tchalt, (void)) +DEF_HELPER(target_ulong, do_mftc0_tchalt, (void)) +DEF_HELPER(target_ulong, do_mfc0_tccontext, (void)) +DEF_HELPER(target_ulong, do_mftc0_tccontext, (void)) +DEF_HELPER(target_ulong, do_mfc0_tcschedule, (void)) +DEF_HELPER(target_ulong, do_mftc0_tcschedule, (void)) +DEF_HELPER(target_ulong, do_mfc0_tcschefback, (void)) +DEF_HELPER(target_ulong, do_mftc0_tcschefback, (void)) +DEF_HELPER(target_ulong, do_mfc0_count, (void)) +DEF_HELPER(target_ulong, do_mftc0_entryhi, (void)) +DEF_HELPER(target_ulong, do_mftc0_status, (void)) +DEF_HELPER(target_ulong, do_mfc0_lladdr, (void)) +DEF_HELPER(target_ulong, do_mfc0_watchlo, (uint32_t sel)) +DEF_HELPER(target_ulong, do_mfc0_watchhi, (uint32_t sel)) +DEF_HELPER(target_ulong, do_mfc0_debug, (void)) +DEF_HELPER(target_ulong, do_mftc0_debug, (void)) #ifdef TARGET_MIPS64 -DEF_HELPER(target_ulong, do_dmfc0_tcrestart, (target_ulong t0)) -DEF_HELPER(target_ulong, do_dmfc0_tchalt, (target_ulong t0)) -DEF_HELPER(target_ulong, do_dmfc0_tccontext, (target_ulong t0)) -DEF_HELPER(target_ulong, do_dmfc0_tcschedule, (target_ulong t0)) -DEF_HELPER(target_ulong, do_dmfc0_tcschefback, (target_ulong t0)) -DEF_HELPER(target_ulong, do_dmfc0_lladdr, (target_ulong t0)) -DEF_HELPER(target_ulong, do_dmfc0_watchlo, (target_ulong t0, uint32_t sel)) +DEF_HELPER(target_ulong, do_dmfc0_tcrestart, (void)) +DEF_HELPER(target_ulong, do_dmfc0_tchalt, (void)) +DEF_HELPER(target_ulong, do_dmfc0_tccontext, (void)) +DEF_HELPER(target_ulong, do_dmfc0_tcschedule, (void)) +DEF_HELPER(target_ulong, do_dmfc0_tcschefback, (void)) +DEF_HELPER(target_ulong, do_dmfc0_lladdr, (void)) +DEF_HELPER(target_ulong, do_dmfc0_watchlo, (uint32_t sel)) #endif /* TARGET_MIPS64 */ DEF_HELPER(void, do_mtc0_index, (target_ulong t0)) diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index bb3660751..eae5b7489 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -650,126 +650,127 @@ void cpu_mips_tlb_flush (CPUState *env, int flush_global) #else /* CP0 helpers */ -target_ulong do_mfc0_mvpcontrol (target_ulong t0) +target_ulong do_mfc0_mvpcontrol (void) { return env->mvp->CP0_MVPControl; } -target_ulong do_mfc0_mvpconf0 (target_ulong t0) +target_ulong do_mfc0_mvpconf0 (void) { return env->mvp->CP0_MVPConf0; } -target_ulong do_mfc0_mvpconf1 (target_ulong t0) +target_ulong do_mfc0_mvpconf1 (void) { return env->mvp->CP0_MVPConf1; } -target_ulong do_mfc0_random (target_ulong t0) +target_ulong do_mfc0_random (void) { return (int32_t)cpu_mips_get_random(env); } -target_ulong do_mfc0_tcstatus (target_ulong t0) +target_ulong do_mfc0_tcstatus (void) { return env->CP0_TCStatus[env->current_tc]; } -target_ulong do_mftc0_tcstatus(target_ulong t0) +target_ulong do_mftc0_tcstatus(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); return env->CP0_TCStatus[other_tc]; } -target_ulong do_mfc0_tcbind (target_ulong t0) +target_ulong do_mfc0_tcbind (void) { return env->CP0_TCBind[env->current_tc]; } -target_ulong do_mftc0_tcbind(target_ulong t0) +target_ulong do_mftc0_tcbind(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); return env->CP0_TCBind[other_tc]; } -target_ulong do_mfc0_tcrestart (target_ulong t0) +target_ulong do_mfc0_tcrestart (void) { return env->PC[env->current_tc]; } -target_ulong do_mftc0_tcrestart(target_ulong t0) +target_ulong do_mftc0_tcrestart(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); return env->PC[other_tc]; } -target_ulong do_mfc0_tchalt (target_ulong t0) +target_ulong do_mfc0_tchalt (void) { return env->CP0_TCHalt[env->current_tc]; } -target_ulong do_mftc0_tchalt(target_ulong t0) +target_ulong do_mftc0_tchalt(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); return env->CP0_TCHalt[other_tc]; } -target_ulong do_mfc0_tccontext (target_ulong t0) +target_ulong do_mfc0_tccontext (void) { return env->CP0_TCContext[env->current_tc]; } -target_ulong do_mftc0_tccontext(target_ulong t0) +target_ulong do_mftc0_tccontext(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); return env->CP0_TCContext[other_tc]; } -target_ulong do_mfc0_tcschedule (target_ulong t0) +target_ulong do_mfc0_tcschedule (void) { return env->CP0_TCSchedule[env->current_tc]; } -target_ulong do_mftc0_tcschedule(target_ulong t0) +target_ulong do_mftc0_tcschedule(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); return env->CP0_TCSchedule[other_tc]; } -target_ulong do_mfc0_tcschefback (target_ulong t0) +target_ulong do_mfc0_tcschefback (void) { return env->CP0_TCScheFBack[env->current_tc]; } -target_ulong do_mftc0_tcschefback(target_ulong t0) +target_ulong do_mftc0_tcschefback(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); return env->CP0_TCScheFBack[other_tc]; } -target_ulong do_mfc0_count (target_ulong t0) +target_ulong do_mfc0_count (void) { return (int32_t)cpu_mips_get_count(env); } -target_ulong do_mftc0_entryhi(target_ulong t0) +target_ulong do_mftc0_entryhi(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); return (env->CP0_EntryHi & ~0xff) | (env->CP0_TCStatus[other_tc] & 0xff); } -target_ulong do_mftc0_status(target_ulong t0) +target_ulong do_mftc0_status(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); uint32_t tcstatus = env->CP0_TCStatus[other_tc]; + target_ulong t0; t0 = env->CP0_Status & ~0xf1000018; t0 |= tcstatus & (0xf << CP0TCSt_TCU0); @@ -779,31 +780,31 @@ target_ulong do_mftc0_status(target_ulong t0) return t0; } -target_ulong do_mfc0_lladdr (target_ulong t0) +target_ulong do_mfc0_lladdr (void) { return (int32_t)env->CP0_LLAddr >> 4; } -target_ulong do_mfc0_watchlo (target_ulong t0, uint32_t sel) +target_ulong do_mfc0_watchlo (uint32_t sel) { return (int32_t)env->CP0_WatchLo[sel]; } -target_ulong do_mfc0_watchhi (target_ulong t0, uint32_t sel) +target_ulong do_mfc0_watchhi (uint32_t sel) { return env->CP0_WatchHi[sel]; } -target_ulong do_mfc0_debug (target_ulong t0) +target_ulong do_mfc0_debug (void) { - t0 = env->CP0_Debug; + target_ulong t0 = env->CP0_Debug; if (env->hflags & MIPS_HFLAG_DM) t0 |= 1 << CP0DB_DM; return t0; } -target_ulong do_mftc0_debug(target_ulong t0) +target_ulong do_mftc0_debug(void) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); @@ -814,37 +815,37 @@ target_ulong do_mftc0_debug(target_ulong t0) } #if defined(TARGET_MIPS64) -target_ulong do_dmfc0_tcrestart (target_ulong t0) +target_ulong do_dmfc0_tcrestart (void) { return env->PC[env->current_tc]; } -target_ulong do_dmfc0_tchalt (target_ulong t0) +target_ulong do_dmfc0_tchalt (void) { return env->CP0_TCHalt[env->current_tc]; } -target_ulong do_dmfc0_tccontext (target_ulong t0) +target_ulong do_dmfc0_tccontext (void) { return env->CP0_TCContext[env->current_tc]; } -target_ulong do_dmfc0_tcschedule (target_ulong t0) +target_ulong do_dmfc0_tcschedule (void) { return env->CP0_TCSchedule[env->current_tc]; } -target_ulong do_dmfc0_tcschefback (target_ulong t0) +target_ulong do_dmfc0_tcschefback (void) { return env->CP0_TCScheFBack[env->current_tc]; } -target_ulong do_dmfc0_lladdr (target_ulong t0) +target_ulong do_dmfc0_lladdr (void) { return env->CP0_LLAddr >> 4; } -target_ulong do_dmfc0_watchlo (target_ulong t0, uint32_t sel) +target_ulong do_dmfc0_watchlo (uint32_t sel) { return env->CP0_WatchLo[sel]; } diff --git a/target-mips/translate.c b/target-mips/translate.c index 106d35592..41a27b4e2 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -423,7 +423,7 @@ enum { }; /* global register indices */ -static TCGv cpu_env, current_tc_gprs, current_tc_hi, current_fpu, cpu_T[1]; +static TCGv cpu_env, current_tc_gprs, current_tc_hi, current_fpu; /* FPU TNs, global for now. */ static TCGv fpu32_T[3], fpu64_T[3], fpu32h_T[3]; @@ -2856,7 +2856,7 @@ static inline void gen_mtc0_store64 (TCGv t, target_ulong off) tcg_gen_st_tl(t, cpu_env, off); } -static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) +static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel) { const char *rn = "invalid"; @@ -2867,22 +2867,22 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Index)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index)); rn = "Index"; break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_mvpcontrol, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_mvpcontrol, t0); rn = "MVPControl"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_mvpconf0, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_mvpconf0, t0); rn = "MVPConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_mvpconf1, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_mvpconf1, t0); rn = "MVPConf1"; break; default: @@ -2892,42 +2892,42 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 1: switch (sel) { case 0: - tcg_gen_helper_1_1(do_mfc0_random, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_random, t0); rn = "Random"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEControl)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl)); rn = "VPEControl"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0)); rn = "VPEConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf1)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1)); rn = "VPEConf1"; break; case 4: check_insn(env, ctx, ASE_MT); - gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_YQMask)); + gen_mfc0_load64(t0, offsetof(CPUState, CP0_YQMask)); rn = "YQMask"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_VPESchedule)); + gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPESchedule)); rn = "VPESchedule"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_VPEScheFBack)); + gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPEScheFBack)); rn = "VPEScheFBack"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEOpt)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt)); rn = "VPEOpt"; break; default: @@ -2937,43 +2937,43 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0)); + tcg_gen_ext32s_tl(t0, t0); rn = "EntryLo0"; break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_tcstatus, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_tcstatus, t0); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_tcbind, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_tcbind, t0); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_tcrestart, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_tcrestart, t0); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_tchalt, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_tchalt, t0); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_tccontext, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_tccontext, t0); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_tcschedule, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_tcschedule, t0); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_tcschefback, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_tcschefback, t0); rn = "TCScheFBack"; break; default: @@ -2983,8 +2983,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1)); + tcg_gen_ext32s_tl(t0, t0); rn = "EntryLo1"; break; default: @@ -2994,12 +2994,12 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 4: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context)); + tcg_gen_ext32s_tl(t0, t0); rn = "Context"; break; case 1: -// tcg_gen_helper_1_1(do_mfc0_contextconfig, cpu_T[0], cpu_T[0]); /* SmartMIPS ASE */ +// tcg_gen_helper_1_0(do_mfc0_contextconfig, t0); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -3009,12 +3009,12 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 5: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageMask)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask)); rn = "PageMask"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageGrain)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain)); rn = "PageGrain"; break; default: @@ -3024,32 +3024,32 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 6: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Wired)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired)); rn = "Wired"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0)); rn = "SRSConf0"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf1)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1)); rn = "SRSConf1"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf2)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2)); rn = "SRSConf2"; break; case 4: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf3)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3)); rn = "SRSConf3"; break; case 5: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf4)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4)); rn = "SRSConf4"; break; default: @@ -3060,7 +3060,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_HWREna)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna)); rn = "HWREna"; break; default: @@ -3070,8 +3070,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 8: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr)); + tcg_gen_ext32s_tl(t0, t0); rn = "BadVAddr"; break; default: @@ -3081,7 +3081,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - tcg_gen_helper_1_1(do_mfc0_count, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_count, t0); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -3092,8 +3092,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 10: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi)); + tcg_gen_ext32s_tl(t0, t0); rn = "EntryHi"; break; default: @@ -3103,7 +3103,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 11: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Compare)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare)); rn = "Compare"; break; /* 6,7 are implementation dependent */ @@ -3114,22 +3114,22 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 12: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Status)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status)); rn = "Status"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_IntCtl)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl)); rn = "IntCtl"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSCtl)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl)); rn = "SRSCtl"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSMap)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap)); rn = "SRSMap"; break; default: @@ -3139,7 +3139,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 13: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Cause)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause)); rn = "Cause"; break; default: @@ -3149,8 +3149,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 14: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC)); + tcg_gen_ext32s_tl(t0, t0); rn = "EPC"; break; default: @@ -3160,12 +3160,12 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 15: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PRid)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid)); rn = "PRid"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_EBase)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase)); rn = "EBase"; break; default: @@ -3175,29 +3175,29 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 16: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0)); rn = "Config"; break; case 1: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config1)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1)); rn = "Config1"; break; case 2: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config2)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2)); rn = "Config2"; break; case 3: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config3)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3)); rn = "Config3"; break; /* 4,5 are reserved */ /* 6,7 are implementation dependent */ case 6: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config6)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6)); rn = "Config6"; break; case 7: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config7)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7)); rn = "Config7"; break; default: @@ -3207,7 +3207,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 17: switch (sel) { case 0: - tcg_gen_helper_1_1(do_mfc0_lladdr, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_lladdr, t0); rn = "LLAddr"; break; default: @@ -3217,7 +3217,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - tcg_gen_helper_1_1i(do_mfc0_watchlo, cpu_T[0], cpu_T[0], sel); + tcg_gen_helper_1_i(do_mfc0_watchlo, t0, sel); rn = "WatchLo"; break; default: @@ -3227,7 +3227,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ...7: - tcg_gen_helper_1_1i(do_mfc0_watchhi, cpu_T[0], cpu_T[0], sel); + tcg_gen_helper_1_i(do_mfc0_watchhi, t0, sel); rn = "WatchHi"; break; default: @@ -3239,8 +3239,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: #if defined(TARGET_MIPS64) check_insn(env, ctx, ISA_MIPS3); - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext)); + tcg_gen_ext32s_tl(t0, t0); rn = "XContext"; break; #endif @@ -3252,7 +3252,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) /* Officially reserved, but sel 0 is used for R1x000 framemask */ switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Framemask)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask)); rn = "Framemask"; break; default: @@ -3266,23 +3266,23 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - tcg_gen_helper_1_1(do_mfc0_debug, cpu_T[0], cpu_T[0]); /* EJTAG support */ + tcg_gen_helper_1_0(do_mfc0_debug, t0); /* EJTAG support */ rn = "Debug"; break; case 1: -// tcg_gen_helper_1_1(do_mfc0_tracecontrol, cpu_T[0], cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_1_0(do_mfc0_tracecontrol, t0); /* PDtrace support */ rn = "TraceControl"; // break; case 2: -// tcg_gen_helper_1_1(do_mfc0_tracecontrol2, cpu_T[0], cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_1_0(do_mfc0_tracecontrol2, t0); /* PDtrace support */ rn = "TraceControl2"; // break; case 3: -// tcg_gen_helper_1_1(do_mfc0_usertracedata, cpu_T[0], cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_1_0(do_mfc0_usertracedata, t0); /* PDtrace support */ rn = "UserTraceData"; // break; case 4: -// tcg_gen_helper_1_1(do_mfc0_tracebpc, cpu_T[0], cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_1_0(do_mfc0_tracebpc, t0); /* PDtrace support */ rn = "TraceBPC"; // break; default: @@ -3293,8 +3293,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: /* EJTAG support */ - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC)); + tcg_gen_ext32s_tl(t0, t0); rn = "DEPC"; break; default: @@ -3304,35 +3304,35 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 25: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Performance0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0)); rn = "Performance0"; break; case 1: -// tcg_gen_helper_1_1(do_mfc0_performance1, cpu_T[0], cpu_T[0]); +// tcg_gen_helper_1_0(do_mfc0_performance1, t0); rn = "Performance1"; // break; case 2: -// tcg_gen_helper_1_1(do_mfc0_performance2, cpu_T[0], cpu_T[0]); +// tcg_gen_helper_1_0(do_mfc0_performance2, t0); rn = "Performance2"; // break; case 3: -// tcg_gen_helper_1_1(do_mfc0_performance3, cpu_T[0], cpu_T[0]); +// tcg_gen_helper_1_0(do_mfc0_performance3, t0); rn = "Performance3"; // break; case 4: -// tcg_gen_helper_1_1(do_mfc0_performance4, cpu_T[0], cpu_T[0]); +// tcg_gen_helper_1_0(do_mfc0_performance4, t0); rn = "Performance4"; // break; case 5: -// tcg_gen_helper_1_1(do_mfc0_performance5, cpu_T[0], cpu_T[0]); +// tcg_gen_helper_1_0(do_mfc0_performance5, t0); rn = "Performance5"; // break; case 6: -// tcg_gen_helper_1_1(do_mfc0_performance6, cpu_T[0], cpu_T[0]); +// tcg_gen_helper_1_0(do_mfc0_performance6, t0); rn = "Performance6"; // break; case 7: -// tcg_gen_helper_1_1(do_mfc0_performance7, cpu_T[0], cpu_T[0]); +// tcg_gen_helper_1_0(do_mfc0_performance7, t0); rn = "Performance7"; // break; default: @@ -3358,14 +3358,14 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagLo)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo)); rn = "TagLo"; break; case 1: case 3: case 5: case 7: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataLo)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo)); rn = "DataLo"; break; default: @@ -3378,14 +3378,14 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagHi)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi)); rn = "TagHi"; break; case 1: case 3: case 5: case 7: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataHi)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi)); rn = "DataHi"; break; default: @@ -3395,8 +3395,8 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 30: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC)); - tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC)); + tcg_gen_ext32s_tl(t0, t0); rn = "ErrorEPC"; break; default: @@ -3407,7 +3407,7 @@ static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: /* EJTAG support */ - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DESAVE)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE)); rn = "DESAVE"; break; default: @@ -3435,7 +3435,7 @@ die: generate_exception(ctx, EXCP_RI); } -static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) +static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel) { const char *rn = "invalid"; @@ -3446,12 +3446,12 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_index, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_index, t0); rn = "Index"; break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_mvpcontrol, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_mvpcontrol, t0); rn = "MVPControl"; break; case 2: @@ -3476,37 +3476,37 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_vpecontrol, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_vpecontrol, t0); rn = "VPEControl"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_vpeconf0, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_vpeconf0, t0); rn = "VPEConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_vpeconf1, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_vpeconf1, t0); rn = "VPEConf1"; break; case 4: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_yqmask, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_yqmask, t0); rn = "YQMask"; break; case 5: check_insn(env, ctx, ASE_MT); - gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_VPESchedule)); + gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPESchedule)); rn = "VPESchedule"; break; case 6: check_insn(env, ctx, ASE_MT); - gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_VPEScheFBack)); + gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPEScheFBack)); rn = "VPEScheFBack"; break; case 7: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_vpeopt, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_vpeopt, t0); rn = "VPEOpt"; break; default: @@ -3516,42 +3516,42 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_entrylo0, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_entrylo0, t0); rn = "EntryLo0"; break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_tcstatus, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_tcstatus, t0); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_tcbind, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_tcbind, t0); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_tcrestart, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_tcrestart, t0); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_tchalt, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_tchalt, t0); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_tccontext, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_tccontext, t0); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_tcschedule, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_tcschedule, t0); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_tcschefback, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_tcschefback, t0); rn = "TCScheFBack"; break; default: @@ -3561,7 +3561,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_entrylo1, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_entrylo1, t0); rn = "EntryLo1"; break; default: @@ -3571,11 +3571,11 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 4: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_context, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_context, t0); rn = "Context"; break; case 1: -// tcg_gen_helper_0_1(do_mtc0_contextconfig, cpu_T[0]); /* SmartMIPS ASE */ +// tcg_gen_helper_0_1(do_mtc0_contextconfig, t0); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -3585,12 +3585,12 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 5: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_pagemask, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_pagemask, t0); rn = "PageMask"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_pagegrain, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_pagegrain, t0); rn = "PageGrain"; break; default: @@ -3600,32 +3600,32 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 6: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_wired, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_wired, t0); rn = "Wired"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_srsconf0, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_srsconf0, t0); rn = "SRSConf0"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_srsconf1, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_srsconf1, t0); rn = "SRSConf1"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_srsconf2, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_srsconf2, t0); rn = "SRSConf2"; break; case 4: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_srsconf3, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_srsconf3, t0); rn = "SRSConf3"; break; case 5: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_srsconf4, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_srsconf4, t0); rn = "SRSConf4"; break; default: @@ -3636,7 +3636,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_hwrena, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_hwrena, t0); rn = "HWREna"; break; default: @@ -3650,7 +3650,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_count, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_count, t0); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -3663,7 +3663,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 10: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_entryhi, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_entryhi, t0); rn = "EntryHi"; break; default: @@ -3673,7 +3673,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 11: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_compare, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_compare, t0); rn = "Compare"; break; /* 6,7 are implementation dependent */ @@ -3686,7 +3686,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 12: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_status, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_status, t0); /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; @@ -3694,21 +3694,21 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_intctl, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_intctl, t0); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "IntCtl"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_srsctl, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_srsctl, t0); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSCtl"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_SRSMap)); + gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap)); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSMap"; @@ -3720,7 +3720,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 13: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_cause, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_cause, t0); rn = "Cause"; break; default: @@ -3732,7 +3732,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 14: switch (sel) { case 0: - gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_EPC)); + gen_mtc0_store64(t0, offsetof(CPUState, CP0_EPC)); rn = "EPC"; break; default: @@ -3747,7 +3747,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_ebase, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_ebase, t0); rn = "EBase"; break; default: @@ -3757,7 +3757,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 16: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_config0, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_config0, t0); rn = "Config"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -3767,7 +3767,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Config1"; break; case 2: - tcg_gen_helper_0_1(do_mtc0_config2, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_config2, t0); rn = "Config2"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -3804,7 +3804,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - tcg_gen_helper_0_1i(do_mtc0_watchlo, cpu_T[0], sel); + tcg_gen_helper_0_1i(do_mtc0_watchlo, t0, sel); rn = "WatchLo"; break; default: @@ -3814,7 +3814,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ... 7: - tcg_gen_helper_0_1i(do_mtc0_watchhi, cpu_T[0], sel); + tcg_gen_helper_0_1i(do_mtc0_watchhi, t0, sel); rn = "WatchHi"; break; default: @@ -3826,7 +3826,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: #if defined(TARGET_MIPS64) check_insn(env, ctx, ISA_MIPS3); - tcg_gen_helper_0_1(do_mtc0_xcontext, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_xcontext, t0); rn = "XContext"; break; #endif @@ -3838,7 +3838,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) /* Officially reserved, but sel 0 is used for R1x000 framemask */ switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_framemask, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_framemask, t0); rn = "Framemask"; break; default: @@ -3852,20 +3852,20 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_debug, cpu_T[0]); /* EJTAG support */ + tcg_gen_helper_0_1(do_mtc0_debug, t0); /* EJTAG support */ /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; rn = "Debug"; break; case 1: -// tcg_gen_helper_0_1(do_mtc0_tracecontrol, cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracecontrol, t0); /* PDtrace support */ rn = "TraceControl"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; // break; case 2: -// tcg_gen_helper_0_1(do_mtc0_tracecontrol2, cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracecontrol2, t0); /* PDtrace support */ rn = "TraceControl2"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -3873,13 +3873,13 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; -// tcg_gen_helper_0_1(do_mtc0_usertracedata, cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_usertracedata, t0); /* PDtrace support */ rn = "UserTraceData"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; // break; case 4: -// tcg_gen_helper_0_1(do_mtc0_tracebpc, cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracebpc, t0); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceBPC"; @@ -3892,7 +3892,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: /* EJTAG support */ - gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_DEPC)); + gen_mtc0_store64(t0, offsetof(CPUState, CP0_DEPC)); rn = "DEPC"; break; default: @@ -3902,35 +3902,35 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 25: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_performance0, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_performance0, t0); rn = "Performance0"; break; case 1: -// tcg_gen_helper_0_1(do_mtc0_performance1, cpu_T[0]); +// tcg_gen_helper_0_1(do_mtc0_performance1, t0); rn = "Performance1"; // break; case 2: -// tcg_gen_helper_0_1(do_mtc0_performance2, cpu_T[0]); +// tcg_gen_helper_0_1(do_mtc0_performance2, t0); rn = "Performance2"; // break; case 3: -// tcg_gen_helper_0_1(do_mtc0_performance3, cpu_T[0]); +// tcg_gen_helper_0_1(do_mtc0_performance3, t0); rn = "Performance3"; // break; case 4: -// tcg_gen_helper_0_1(do_mtc0_performance4, cpu_T[0]); +// tcg_gen_helper_0_1(do_mtc0_performance4, t0); rn = "Performance4"; // break; case 5: -// tcg_gen_helper_0_1(do_mtc0_performance5, cpu_T[0]); +// tcg_gen_helper_0_1(do_mtc0_performance5, t0); rn = "Performance5"; // break; case 6: -// tcg_gen_helper_0_1(do_mtc0_performance6, cpu_T[0]); +// tcg_gen_helper_0_1(do_mtc0_performance6, t0); rn = "Performance6"; // break; case 7: -// tcg_gen_helper_0_1(do_mtc0_performance7, cpu_T[0]); +// tcg_gen_helper_0_1(do_mtc0_performance7, t0); rn = "Performance7"; // break; default: @@ -3957,14 +3957,14 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - tcg_gen_helper_0_1(do_mtc0_taglo, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_taglo, t0); rn = "TagLo"; break; case 1: case 3: case 5: case 7: - tcg_gen_helper_0_1(do_mtc0_datalo, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_datalo, t0); rn = "DataLo"; break; default: @@ -3977,14 +3977,14 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - tcg_gen_helper_0_1(do_mtc0_taghi, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_taghi, t0); rn = "TagHi"; break; case 1: case 3: case 5: case 7: - tcg_gen_helper_0_1(do_mtc0_datahi, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_datahi, t0); rn = "DataHi"; break; default: @@ -3995,7 +3995,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 30: switch (sel) { case 0: - gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_ErrorEPC)); + gen_mtc0_store64(t0, offsetof(CPUState, CP0_ErrorEPC)); rn = "ErrorEPC"; break; default: @@ -4006,7 +4006,7 @@ static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: /* EJTAG support */ - gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_DESAVE)); + gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE)); rn = "DESAVE"; break; default: @@ -4037,7 +4037,7 @@ die: } #if defined(TARGET_MIPS64) -static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) +static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel) { const char *rn = "invalid"; @@ -4048,22 +4048,22 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Index)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index)); rn = "Index"; break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_mvpcontrol, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_mvpcontrol, t0); rn = "MVPControl"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_mvpconf0, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_mvpconf0, t0); rn = "MVPConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_mvpconf1, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_mvpconf1, t0); rn = "MVPConf1"; break; default: @@ -4073,42 +4073,42 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 1: switch (sel) { case 0: - tcg_gen_helper_1_1(do_mfc0_random, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_random, t0); rn = "Random"; break; case 1: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEControl)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl)); rn = "VPEControl"; break; case 2: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0)); rn = "VPEConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf1)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1)); rn = "VPEConf1"; break; case 4: check_insn(env, ctx, ASE_MT); - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_YQMask)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_YQMask)); rn = "YQMask"; break; case 5: check_insn(env, ctx, ASE_MT); - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule)); rn = "VPESchedule"; break; case 6: check_insn(env, ctx, ASE_MT); - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack)); rn = "VPEScheFBack"; break; case 7: check_insn(env, ctx, ASE_MT); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEOpt)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt)); rn = "VPEOpt"; break; default: @@ -4118,42 +4118,42 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0)); rn = "EntryLo0"; break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_tcstatus, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_tcstatus, t0); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_mfc0_tcbind, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_tcbind, t0); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_dmfc0_tcrestart, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_dmfc0_tcrestart, t0); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_dmfc0_tchalt, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_dmfc0_tchalt, t0); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_dmfc0_tccontext, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_dmfc0_tccontext, t0); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_dmfc0_tcschedule, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_dmfc0_tcschedule, t0); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_1_1(do_dmfc0_tcschefback, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_dmfc0_tcschefback, t0); rn = "TCScheFBack"; break; default: @@ -4163,7 +4163,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1)); rn = "EntryLo1"; break; default: @@ -4173,11 +4173,11 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 4: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context)); rn = "Context"; break; case 1: -// tcg_gen_helper_1_1(do_dmfc0_contextconfig, cpu_T[0], cpu_T[0]); /* SmartMIPS ASE */ +// tcg_gen_helper_1_0(do_dmfc0_contextconfig, t0); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -4187,12 +4187,12 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 5: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageMask)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask)); rn = "PageMask"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageGrain)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain)); rn = "PageGrain"; break; default: @@ -4202,32 +4202,32 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 6: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Wired)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired)); rn = "Wired"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0)); rn = "SRSConf0"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf1)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1)); rn = "SRSConf1"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf2)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2)); rn = "SRSConf2"; break; case 4: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf3)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3)); rn = "SRSConf3"; break; case 5: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf4)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4)); rn = "SRSConf4"; break; default: @@ -4238,7 +4238,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_HWREna)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna)); rn = "HWREna"; break; default: @@ -4248,7 +4248,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 8: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr)); rn = "BadVAddr"; break; default: @@ -4258,7 +4258,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - tcg_gen_helper_1_1(do_mfc0_count, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_mfc0_count, t0); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -4269,7 +4269,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 10: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi)); rn = "EntryHi"; break; default: @@ -4279,7 +4279,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 11: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Compare)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare)); rn = "Compare"; break; /* 6,7 are implementation dependent */ @@ -4290,22 +4290,22 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 12: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Status)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status)); rn = "Status"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_IntCtl)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl)); rn = "IntCtl"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSCtl)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl)); rn = "SRSCtl"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSMap)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap)); rn = "SRSMap"; break; default: @@ -4315,7 +4315,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 13: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Cause)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause)); rn = "Cause"; break; default: @@ -4325,7 +4325,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 14: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC)); rn = "EPC"; break; default: @@ -4335,12 +4335,12 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 15: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PRid)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid)); rn = "PRid"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_EBase)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase)); rn = "EBase"; break; default: @@ -4350,28 +4350,28 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 16: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0)); rn = "Config"; break; case 1: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config1)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1)); rn = "Config1"; break; case 2: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config2)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2)); rn = "Config2"; break; case 3: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config3)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3)); rn = "Config3"; break; /* 6,7 are implementation dependent */ case 6: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config6)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6)); rn = "Config6"; break; case 7: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config7)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7)); rn = "Config7"; break; default: @@ -4381,7 +4381,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 17: switch (sel) { case 0: - tcg_gen_helper_1_1(do_dmfc0_lladdr, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_0(do_dmfc0_lladdr, t0); rn = "LLAddr"; break; default: @@ -4391,7 +4391,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - tcg_gen_helper_1_1i(do_dmfc0_watchlo, cpu_T[0], cpu_T[0], sel); + tcg_gen_helper_1_i(do_dmfc0_watchlo, t0, sel); rn = "WatchLo"; break; default: @@ -4401,7 +4401,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ... 7: - tcg_gen_helper_1_1i(do_mfc0_watchhi, cpu_T[0], cpu_T[0], sel); + tcg_gen_helper_1_i(do_mfc0_watchhi, t0, sel); rn = "WatchHi"; break; default: @@ -4412,7 +4412,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS3); - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext)); rn = "XContext"; break; default: @@ -4423,7 +4423,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) /* Officially reserved, but sel 0 is used for R1x000 framemask */ switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Framemask)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask)); rn = "Framemask"; break; default: @@ -4437,23 +4437,23 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - tcg_gen_helper_1_1(do_mfc0_debug, cpu_T[0], cpu_T[0]); /* EJTAG support */ + tcg_gen_helper_1_0(do_mfc0_debug, t0); /* EJTAG support */ rn = "Debug"; break; case 1: -// tcg_gen_helper_1_1(do_dmfc0_tracecontrol, cpu_T[0], cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_1_0(do_dmfc0_tracecontrol, t0); /* PDtrace support */ rn = "TraceControl"; // break; case 2: -// tcg_gen_helper_1_1(do_dmfc0_tracecontrol2, cpu_T[0], cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_1_0(do_dmfc0_tracecontrol2, t0); /* PDtrace support */ rn = "TraceControl2"; // break; case 3: -// tcg_gen_helper_1_1(do_dmfc0_usertracedata, cpu_T[0], cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_1_0(do_dmfc0_usertracedata, t0); /* PDtrace support */ rn = "UserTraceData"; // break; case 4: -// tcg_gen_helper_1_1(do_dmfc0_tracebpc, cpu_T[0], cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_1_0(do_dmfc0_tracebpc, t0); /* PDtrace support */ rn = "TraceBPC"; // break; default: @@ -4464,7 +4464,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: /* EJTAG support */ - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC)); rn = "DEPC"; break; default: @@ -4474,35 +4474,35 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 25: switch (sel) { case 0: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Performance0)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0)); rn = "Performance0"; break; case 1: -// tcg_gen_helper_1_1(do_dmfc0_performance1, cpu_T[0], cpu_T[0]); +// tcg_gen_helper_1_0(do_dmfc0_performance1, t0); rn = "Performance1"; // break; case 2: -// tcg_gen_helper_1_1(do_dmfc0_performance2, cpu_T[0], cpu_T[0]); +// tcg_gen_helper_1_0(do_dmfc0_performance2, t0); rn = "Performance2"; // break; case 3: -// tcg_gen_helper_1_1(do_dmfc0_performance3, cpu_T[0], cpu_T[0]); +// tcg_gen_helper_1_0(do_dmfc0_performance3, t0); rn = "Performance3"; // break; case 4: -// tcg_gen_helper_1_1(do_dmfc0_performance4, cpu_T[0], cpu_T[0]); +// tcg_gen_helper_1_0(do_dmfc0_performance4, t0); rn = "Performance4"; // break; case 5: -// tcg_gen_helper_1_1(do_dmfc0_performance5, cpu_T[0], cpu_T[0]); +// tcg_gen_helper_1_0(do_dmfc0_performance5, t0); rn = "Performance5"; // break; case 6: -// tcg_gen_helper_1_1(do_dmfc0_performance6, cpu_T[0], cpu_T[0]); +// tcg_gen_helper_1_0(do_dmfc0_performance6, t0); rn = "Performance6"; // break; case 7: -// tcg_gen_helper_1_1(do_dmfc0_performance7, cpu_T[0], cpu_T[0]); +// tcg_gen_helper_1_0(do_dmfc0_performance7, t0); rn = "Performance7"; // break; default: @@ -4528,14 +4528,14 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagLo)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo)); rn = "TagLo"; break; case 1: case 3: case 5: case 7: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataLo)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo)); rn = "DataLo"; break; default: @@ -4548,14 +4548,14 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagHi)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi)); rn = "TagHi"; break; case 1: case 3: case 5: case 7: - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataHi)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi)); rn = "DataHi"; break; default: @@ -4565,7 +4565,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 30: switch (sel) { case 0: - tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC)); rn = "ErrorEPC"; break; default: @@ -4576,7 +4576,7 @@ static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: /* EJTAG support */ - gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DESAVE)); + gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE)); rn = "DESAVE"; break; default: @@ -4604,7 +4604,7 @@ die: generate_exception(ctx, EXCP_RI); } -static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) +static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel) { const char *rn = "invalid"; @@ -4615,12 +4615,12 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 0: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_index, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_index, t0); rn = "Index"; break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_mvpcontrol, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_mvpcontrol, t0); rn = "MVPControl"; break; case 2: @@ -4645,37 +4645,37 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_vpecontrol, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_vpecontrol, t0); rn = "VPEControl"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_vpeconf0, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_vpeconf0, t0); rn = "VPEConf0"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_vpeconf1, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_vpeconf1, t0); rn = "VPEConf1"; break; case 4: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_yqmask, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_yqmask, t0); rn = "YQMask"; break; case 5: check_insn(env, ctx, ASE_MT); - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule)); rn = "VPESchedule"; break; case 6: check_insn(env, ctx, ASE_MT); - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack)); rn = "VPEScheFBack"; break; case 7: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_vpeopt, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_vpeopt, t0); rn = "VPEOpt"; break; default: @@ -4685,42 +4685,42 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_entrylo0, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_entrylo0, t0); rn = "EntryLo0"; break; case 1: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_tcstatus, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_tcstatus, t0); rn = "TCStatus"; break; case 2: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_tcbind, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_tcbind, t0); rn = "TCBind"; break; case 3: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_tcrestart, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_tcrestart, t0); rn = "TCRestart"; break; case 4: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_tchalt, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_tchalt, t0); rn = "TCHalt"; break; case 5: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_tccontext, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_tccontext, t0); rn = "TCContext"; break; case 6: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_tcschedule, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_tcschedule, t0); rn = "TCSchedule"; break; case 7: check_insn(env, ctx, ASE_MT); - tcg_gen_helper_0_1(do_mtc0_tcschefback, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_tcschefback, t0); rn = "TCScheFBack"; break; default: @@ -4730,7 +4730,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 3: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_entrylo1, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_entrylo1, t0); rn = "EntryLo1"; break; default: @@ -4740,11 +4740,11 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 4: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_context, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_context, t0); rn = "Context"; break; case 1: -// tcg_gen_helper_0_1(do_mtc0_contextconfig, cpu_T[0]); /* SmartMIPS ASE */ +// tcg_gen_helper_0_1(do_mtc0_contextconfig, t0); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: @@ -4754,12 +4754,12 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 5: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_pagemask, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_pagemask, t0); rn = "PageMask"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_pagegrain, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_pagegrain, t0); rn = "PageGrain"; break; default: @@ -4769,32 +4769,32 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 6: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_wired, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_wired, t0); rn = "Wired"; break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_srsconf0, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_srsconf0, t0); rn = "SRSConf0"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_srsconf1, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_srsconf1, t0); rn = "SRSConf1"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_srsconf2, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_srsconf2, t0); rn = "SRSConf2"; break; case 4: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_srsconf3, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_srsconf3, t0); rn = "SRSConf3"; break; case 5: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_srsconf4, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_srsconf4, t0); rn = "SRSConf4"; break; default: @@ -4805,7 +4805,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_hwrena, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_hwrena, t0); rn = "HWREna"; break; default: @@ -4819,7 +4819,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 9: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_count, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_count, t0); rn = "Count"; break; /* 6,7 are implementation dependent */ @@ -4832,7 +4832,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 10: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_entryhi, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_entryhi, t0); rn = "EntryHi"; break; default: @@ -4842,7 +4842,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 11: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_compare, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_compare, t0); rn = "Compare"; break; /* 6,7 are implementation dependent */ @@ -4855,7 +4855,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 12: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_status, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_status, t0); /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; @@ -4863,21 +4863,21 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_intctl, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_intctl, t0); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "IntCtl"; break; case 2: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_srsctl, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_srsctl, t0); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSCtl"; break; case 3: check_insn(env, ctx, ISA_MIPS32R2); - gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_SRSMap)); + gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap)); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSMap"; @@ -4889,7 +4889,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 13: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_cause, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_cause, t0); rn = "Cause"; break; default: @@ -4901,7 +4901,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 14: switch (sel) { case 0: - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC)); rn = "EPC"; break; default: @@ -4916,7 +4916,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) break; case 1: check_insn(env, ctx, ISA_MIPS32R2); - tcg_gen_helper_0_1(do_mtc0_ebase, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_ebase, t0); rn = "EBase"; break; default: @@ -4926,7 +4926,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 16: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_config0, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_config0, t0); rn = "Config"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -4936,7 +4936,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn = "Config1"; break; case 2: - tcg_gen_helper_0_1(do_mtc0_config2, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_config2, t0); rn = "Config2"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; @@ -4964,7 +4964,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 18: switch (sel) { case 0 ... 7: - tcg_gen_helper_0_1i(do_mtc0_watchlo, cpu_T[0], sel); + tcg_gen_helper_0_1i(do_mtc0_watchlo, t0, sel); rn = "WatchLo"; break; default: @@ -4974,7 +4974,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 19: switch (sel) { case 0 ... 7: - tcg_gen_helper_0_1i(do_mtc0_watchhi, cpu_T[0], sel); + tcg_gen_helper_0_1i(do_mtc0_watchhi, t0, sel); rn = "WatchHi"; break; default: @@ -4985,7 +4985,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: check_insn(env, ctx, ISA_MIPS3); - tcg_gen_helper_0_1(do_mtc0_xcontext, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_xcontext, t0); rn = "XContext"; break; default: @@ -4996,7 +4996,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) /* Officially reserved, but sel 0 is used for R1x000 framemask */ switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_framemask, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_framemask, t0); rn = "Framemask"; break; default: @@ -5010,32 +5010,32 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 23: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_debug, cpu_T[0]); /* EJTAG support */ + tcg_gen_helper_0_1(do_mtc0_debug, t0); /* EJTAG support */ /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; rn = "Debug"; break; case 1: -// tcg_gen_helper_0_1(do_mtc0_tracecontrol, cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracecontrol, t0); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceControl"; // break; case 2: -// tcg_gen_helper_0_1(do_mtc0_tracecontrol2, cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracecontrol2, t0); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceControl2"; // break; case 3: -// tcg_gen_helper_0_1(do_mtc0_usertracedata, cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_usertracedata, t0); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "UserTraceData"; // break; case 4: -// tcg_gen_helper_0_1(do_mtc0_tracebpc, cpu_T[0]); /* PDtrace support */ +// tcg_gen_helper_0_1(do_mtc0_tracebpc, t0); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceBPC"; @@ -5048,7 +5048,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: /* EJTAG support */ - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC)); rn = "DEPC"; break; default: @@ -5058,35 +5058,35 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 25: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mtc0_performance0, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_performance0, t0); rn = "Performance0"; break; case 1: -// tcg_gen_helper_0_1(do_mtc0_performance1, cpu_T[0]); +// tcg_gen_helper_0_1(do_mtc0_performance1, t0); rn = "Performance1"; // break; case 2: -// tcg_gen_helper_0_1(do_mtc0_performance2, cpu_T[0]); +// tcg_gen_helper_0_1(do_mtc0_performance2, t0); rn = "Performance2"; // break; case 3: -// tcg_gen_helper_0_1(do_mtc0_performance3, cpu_T[0]); +// tcg_gen_helper_0_1(do_mtc0_performance3, t0); rn = "Performance3"; // break; case 4: -// tcg_gen_helper_0_1(do_mtc0_performance4, cpu_T[0]); +// tcg_gen_helper_0_1(do_mtc0_performance4, t0); rn = "Performance4"; // break; case 5: -// tcg_gen_helper_0_1(do_mtc0_performance5, cpu_T[0]); +// tcg_gen_helper_0_1(do_mtc0_performance5, t0); rn = "Performance5"; // break; case 6: -// tcg_gen_helper_0_1(do_mtc0_performance6, cpu_T[0]); +// tcg_gen_helper_0_1(do_mtc0_performance6, t0); rn = "Performance6"; // break; case 7: -// tcg_gen_helper_0_1(do_mtc0_performance7, cpu_T[0]); +// tcg_gen_helper_0_1(do_mtc0_performance7, t0); rn = "Performance7"; // break; default: @@ -5113,14 +5113,14 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - tcg_gen_helper_0_1(do_mtc0_taglo, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_taglo, t0); rn = "TagLo"; break; case 1: case 3: case 5: case 7: - tcg_gen_helper_0_1(do_mtc0_datalo, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_datalo, t0); rn = "DataLo"; break; default: @@ -5133,14 +5133,14 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 2: case 4: case 6: - tcg_gen_helper_0_1(do_mtc0_taghi, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_taghi, t0); rn = "TagHi"; break; case 1: case 3: case 5: case 7: - tcg_gen_helper_0_1(do_mtc0_datahi, cpu_T[0]); + tcg_gen_helper_0_1(do_mtc0_datahi, t0); rn = "DataHi"; break; default: @@ -5151,7 +5151,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) case 30: switch (sel) { case 0: - tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC)); rn = "ErrorEPC"; break; default: @@ -5162,7 +5162,7 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) switch (sel) { case 0: /* EJTAG support */ - gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_DESAVE)); + gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE)); rn = "DESAVE"; break; default: @@ -5180,9 +5180,11 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel) rn, reg, sel); } #endif + tcg_temp_free(t0); return; die: + tcg_temp_free(t0); #if defined MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n", @@ -5197,121 +5199,122 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd, int u, int sel, int h) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) != (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE)))) - tcg_gen_movi_tl(cpu_T[0], -1); + tcg_gen_movi_tl(t0, -1); else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) > (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) - tcg_gen_movi_tl(cpu_T[0], -1); + tcg_gen_movi_tl(t0, -1); else if (u == 0) { switch (rt) { case 2: switch (sel) { case 1: - tcg_gen_helper_1_1(do_mftc0_tcstatus, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_mftc0_tcstatus, t0, t0); break; case 2: - tcg_gen_helper_1_1(do_mftc0_tcbind, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_mftc0_tcbind, t0, t0); break; case 3: - tcg_gen_helper_1_1(do_mftc0_tcrestart, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_mftc0_tcrestart, t0, t0); break; case 4: - tcg_gen_helper_1_1(do_mftc0_tchalt, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_mftc0_tchalt, t0, t0); break; case 5: - tcg_gen_helper_1_1(do_mftc0_tccontext, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_mftc0_tccontext, t0, t0); break; case 6: - tcg_gen_helper_1_1(do_mftc0_tcschedule, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_mftc0_tcschedule, t0, t0); break; case 7: - tcg_gen_helper_1_1(do_mftc0_tcschefback, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_mftc0_tcschefback, t0, t0); break; default: - gen_mfc0(env, ctx, rt, sel); + gen_mfc0(env, ctx, t0, rt, sel); break; } break; case 10: switch (sel) { case 0: - tcg_gen_helper_1_1(do_mftc0_entryhi, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_mftc0_entryhi, t0, t0); break; default: - gen_mfc0(env, ctx, rt, sel); + gen_mfc0(env, ctx, t0, rt, sel); break; } case 12: switch (sel) { case 0: - tcg_gen_helper_1_1(do_mftc0_status, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_mftc0_status, t0, t0); break; default: - gen_mfc0(env, ctx, rt, sel); + gen_mfc0(env, ctx, t0, rt, sel); break; } case 23: switch (sel) { case 0: - tcg_gen_helper_1_1(do_mftc0_debug, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_mftc0_debug, t0, t0); break; default: - gen_mfc0(env, ctx, rt, sel); + gen_mfc0(env, ctx, t0, rt, sel); break; } break; default: - gen_mfc0(env, ctx, rt, sel); + gen_mfc0(env, ctx, t0, rt, sel); } } else switch (sel) { /* GPR registers. */ case 0: - tcg_gen_helper_1_1i(do_mftgpr, cpu_T[0], cpu_T[0], rt); + tcg_gen_helper_1_1i(do_mftgpr, t0, t0, rt); break; /* Auxiliary CPU registers */ case 1: switch (rt) { case 0: - tcg_gen_helper_1_1i(do_mftlo, cpu_T[0], cpu_T[0], 0); + tcg_gen_helper_1_1i(do_mftlo, t0, t0, 0); break; case 1: - tcg_gen_helper_1_1i(do_mfthi, cpu_T[0], cpu_T[0], 0); + tcg_gen_helper_1_1i(do_mfthi, t0, t0, 0); break; case 2: - tcg_gen_helper_1_1i(do_mftacx, cpu_T[0], cpu_T[0], 0); + tcg_gen_helper_1_1i(do_mftacx, t0, t0, 0); break; case 4: - tcg_gen_helper_1_1i(do_mftlo, cpu_T[0], cpu_T[0], 1); + tcg_gen_helper_1_1i(do_mftlo, t0, t0, 1); break; case 5: - tcg_gen_helper_1_1i(do_mfthi, cpu_T[0], cpu_T[0], 1); + tcg_gen_helper_1_1i(do_mfthi, t0, t0, 1); break; case 6: - tcg_gen_helper_1_1i(do_mftacx, cpu_T[0], cpu_T[0], 1); + tcg_gen_helper_1_1i(do_mftacx, t0, t0, 1); break; case 8: - tcg_gen_helper_1_1i(do_mftlo, cpu_T[0], cpu_T[0], 2); + tcg_gen_helper_1_1i(do_mftlo, t0, t0, 2); break; case 9: - tcg_gen_helper_1_1i(do_mfthi, cpu_T[0], cpu_T[0], 2); + tcg_gen_helper_1_1i(do_mfthi, t0, t0, 2); break; case 10: - tcg_gen_helper_1_1i(do_mftacx, cpu_T[0], cpu_T[0], 2); + tcg_gen_helper_1_1i(do_mftacx, t0, t0, 2); break; case 12: - tcg_gen_helper_1_1i(do_mftlo, cpu_T[0], cpu_T[0], 3); + tcg_gen_helper_1_1i(do_mftlo, t0, t0, 3); break; case 13: - tcg_gen_helper_1_1i(do_mfthi, cpu_T[0], cpu_T[0], 3); + tcg_gen_helper_1_1i(do_mfthi, t0, t0, 3); break; case 14: - tcg_gen_helper_1_1i(do_mftacx, cpu_T[0], cpu_T[0], 3); + tcg_gen_helper_1_1i(do_mftacx, t0, t0, 3); break; case 16: - tcg_gen_helper_1_1(do_mftdsp, cpu_T[0], cpu_T[0]); + tcg_gen_helper_1_1(do_mftdsp, t0, t0); break; default: goto die; @@ -5322,15 +5325,15 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd, /* XXX: For now we support only a single FPU context. */ if (h == 0) { gen_load_fpr32(fpu32_T[0], rt); - tcg_gen_ext_i32_tl(cpu_T[0], fpu32_T[0]); + tcg_gen_ext_i32_tl(t0, fpu32_T[0]); } else { gen_load_fpr32h(fpu32h_T[0], rt); - tcg_gen_ext_i32_tl(cpu_T[0], fpu32h_T[0]); + tcg_gen_ext_i32_tl(t0, fpu32h_T[0]); } break; case 3: /* XXX: For now we support only a single FPU context. */ - tcg_gen_helper_1_1i(do_cfc1, cpu_T[0], cpu_T[0], rt); + tcg_gen_helper_1_1i(do_cfc1, t0, t0, rt); break; /* COP2: Not implemented. */ case 4: @@ -5345,10 +5348,12 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd, rt, u, sel, h); } #endif - gen_store_gpr(cpu_T[0], rd); + gen_store_gpr(t0, rd); + tcg_temp_free(t0); return; die: + tcg_temp_free(t0); #if defined MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n", @@ -5362,8 +5367,9 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt, int u, int sel, int h) { int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC); + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); - gen_load_gpr(cpu_T[0], rt); + gen_load_gpr(t0, rt); if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 && ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) != (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE)))) @@ -5376,108 +5382,108 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt, case 2: switch (sel) { case 1: - tcg_gen_helper_0_1(do_mttc0_tcstatus, cpu_T[0]); + tcg_gen_helper_0_1(do_mttc0_tcstatus, t0); break; case 2: - tcg_gen_helper_0_1(do_mttc0_tcbind, cpu_T[0]); + tcg_gen_helper_0_1(do_mttc0_tcbind, t0); break; case 3: - tcg_gen_helper_0_1(do_mttc0_tcrestart, cpu_T[0]); + tcg_gen_helper_0_1(do_mttc0_tcrestart, t0); break; case 4: - tcg_gen_helper_0_1(do_mttc0_tchalt, cpu_T[0]); + tcg_gen_helper_0_1(do_mttc0_tchalt, t0); break; case 5: - tcg_gen_helper_0_1(do_mttc0_tccontext, cpu_T[0]); + tcg_gen_helper_0_1(do_mttc0_tccontext, t0); break; case 6: - tcg_gen_helper_0_1(do_mttc0_tcschedule, cpu_T[0]); + tcg_gen_helper_0_1(do_mttc0_tcschedule, t0); break; case 7: - tcg_gen_helper_0_1(do_mttc0_tcschefback, cpu_T[0]); + tcg_gen_helper_0_1(do_mttc0_tcschefback, t0); break; default: - gen_mtc0(env, ctx, rd, sel); + gen_mtc0(env, ctx, t0, rd, sel); break; } break; case 10: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mttc0_entryhi, cpu_T[0]); + tcg_gen_helper_0_1(do_mttc0_entryhi, t0); break; default: - gen_mtc0(env, ctx, rd, sel); + gen_mtc0(env, ctx, t0, rd, sel); break; } case 12: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mttc0_status, cpu_T[0]); + tcg_gen_helper_0_1(do_mttc0_status, t0); break; default: - gen_mtc0(env, ctx, rd, sel); + gen_mtc0(env, ctx, t0, rd, sel); break; } case 23: switch (sel) { case 0: - tcg_gen_helper_0_1(do_mttc0_debug, cpu_T[0]); + tcg_gen_helper_0_1(do_mttc0_debug, t0); break; default: - gen_mtc0(env, ctx, rd, sel); + gen_mtc0(env, ctx, t0, rd, sel); break; } break; default: - gen_mtc0(env, ctx, rd, sel); + gen_mtc0(env, ctx, t0, rd, sel); } } else switch (sel) { /* GPR registers. */ case 0: - tcg_gen_helper_0_1i(do_mttgpr, cpu_T[0], rd); + tcg_gen_helper_0_1i(do_mttgpr, t0, rd); break; /* Auxiliary CPU registers */ case 1: switch (rd) { case 0: - tcg_gen_helper_0_1i(do_mttlo, cpu_T[0], 0); + tcg_gen_helper_0_1i(do_mttlo, t0, 0); break; case 1: - tcg_gen_helper_0_1i(do_mtthi, cpu_T[0], 0); + tcg_gen_helper_0_1i(do_mtthi, t0, 0); break; case 2: - tcg_gen_helper_0_1i(do_mttacx, cpu_T[0], 0); + tcg_gen_helper_0_1i(do_mttacx, t0, 0); break; case 4: - tcg_gen_helper_0_1i(do_mttlo, cpu_T[0], 1); + tcg_gen_helper_0_1i(do_mttlo, t0, 1); break; case 5: - tcg_gen_helper_0_1i(do_mtthi, cpu_T[0], 1); + tcg_gen_helper_0_1i(do_mtthi, t0, 1); break; case 6: - tcg_gen_helper_0_1i(do_mttacx, cpu_T[0], 1); + tcg_gen_helper_0_1i(do_mttacx, t0, 1); break; case 8: - tcg_gen_helper_0_1i(do_mttlo, cpu_T[0], 2); + tcg_gen_helper_0_1i(do_mttlo, t0, 2); break; case 9: - tcg_gen_helper_0_1i(do_mtthi, cpu_T[0], 2); + tcg_gen_helper_0_1i(do_mtthi, t0, 2); break; case 10: - tcg_gen_helper_0_1i(do_mttacx, cpu_T[0], 2); + tcg_gen_helper_0_1i(do_mttacx, t0, 2); break; case 12: - tcg_gen_helper_0_1i(do_mttlo, cpu_T[0], 3); + tcg_gen_helper_0_1i(do_mttlo, t0, 3); break; case 13: - tcg_gen_helper_0_1i(do_mtthi, cpu_T[0], 3); + tcg_gen_helper_0_1i(do_mtthi, t0, 3); break; case 14: - tcg_gen_helper_0_1i(do_mttacx, cpu_T[0], 3); + tcg_gen_helper_0_1i(do_mttacx, t0, 3); break; case 16: - tcg_gen_helper_0_1(do_mttdsp, cpu_T[0]); + tcg_gen_helper_0_1(do_mttdsp, t0); break; default: goto die; @@ -5487,16 +5493,16 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt, case 2: /* XXX: For now we support only a single FPU context. */ if (h == 0) { - tcg_gen_trunc_tl_i32(fpu32_T[0], cpu_T[0]); + tcg_gen_trunc_tl_i32(fpu32_T[0], t0); gen_store_fpr32(fpu32_T[0], rd); } else { - tcg_gen_trunc_tl_i32(fpu32h_T[0], cpu_T[0]); + tcg_gen_trunc_tl_i32(fpu32h_T[0], t0); gen_store_fpr32h(fpu32h_T[0], rd); } break; case 3: /* XXX: For now we support only a single FPU context. */ - tcg_gen_helper_0_1i(do_ctc1, cpu_T[0], rd); + tcg_gen_helper_0_1i(do_ctc1, t0, rd); break; /* COP2: Not implemented. */ case 4: @@ -5511,9 +5517,11 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt, rd, u, sel, h); } #endif + tcg_temp_free(t0); return; die: + tcg_temp_free(t0); #if defined MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n", @@ -5533,14 +5541,24 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int /* Treat as NOP. */ return; } - gen_mfc0(env, ctx, rd, ctx->opcode & 0x7); - gen_store_gpr(cpu_T[0], rt); + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7); + gen_store_gpr(t0, rt); + tcg_temp_free(t0); + } opn = "mfc0"; break; case OPC_MTC0: - gen_load_gpr(cpu_T[0], rt); - save_cpu_state(ctx, 1); - gen_mtc0(env, ctx, rd, ctx->opcode & 0x7); + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, rt); + save_cpu_state(ctx, 1); + gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7); + tcg_temp_free(t0); + } opn = "mtc0"; break; #if defined(TARGET_MIPS64) @@ -5550,15 +5568,25 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int /* Treat as NOP. */ return; } - gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7); - gen_store_gpr(cpu_T[0], rt); + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7); + gen_store_gpr(t0, rt); + tcg_temp_free(t0); + } opn = "dmfc0"; break; case OPC_DMTC0: check_insn(env, ctx, ISA_MIPS3); - gen_load_gpr(cpu_T[0], rt); - save_cpu_state(ctx, 1); - gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7); + { + TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL); + + gen_load_gpr(t0, rt); + save_cpu_state(ctx, 1); + gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7); + tcg_temp_free(t0); + } opn = "dmtc0"; break; #endif @@ -8069,12 +8097,6 @@ static void mips_tcg_init(void) TCG_AREG0, offsetof(CPUState, fpu), "current_fpu"); -#if TARGET_LONG_BITS > HOST_LONG_BITS - cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, - TCG_AREG0, offsetof(CPUState, t0), "T0"); -#else - cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0"); -#endif /* register helpers */ #undef DEF_HELPER -- cgit v1.2.3 From ebbd0ffddd67e70180235561b150aa02897992b1 Mon Sep 17 00:00:00 2001 From: ths Date: Tue, 24 Jun 2008 22:04:41 +0000 Subject: Clarify some TODO items. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4789 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/TODO | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target-mips/TODO b/target-mips/TODO index 6722c20d7..bb18fa8d8 100644 --- a/target-mips/TODO +++ b/target-mips/TODO @@ -32,7 +32,7 @@ General - save/restore of the CPU state is not implemented (see machine.c). - Improve cpu state handling: Step 1) Collect all the TC state in a single struct, so we need only - a single global pointer per TC. + a single global pointer for the active TC. Step 2) Use only a single TC context as working context, and copy the contexts on TC switch. Likewise for FPU contexts. @@ -42,7 +42,8 @@ MIPS64 "Generic" 4Kc system emulation ------------------------------ -- Doesn't correspond to any real hardware. +- Doesn't correspond to any real hardware. Should be removed some day, + U-Boot is the last remaining user. PICA 61 system emulation ------------------------ @@ -51,7 +52,7 @@ PICA 61 system emulation MALTA system emulation ---------------------- - We fake firmware support instead of doing the real thing -- Real firmware falls over when trying to init RAM, presumably due - to lacking system controller emulation. +- Real firmware (YAMON) falls over when trying to init RAM, presumably + due to lacking system controller emulation. - Bonito system controller not implemented - MSC1 system controller not implemented -- cgit v1.2.3