diff options
author | Avi Kivity <avi@redhat.com> | 2009-03-31 15:23:26 +0300 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-03-31 15:23:26 +0300 |
commit | b9c2ce62747c62c95a6c0ef4c0e12858a9bb8070 (patch) | |
tree | 079d093b6aafb37cbdeecf305b1700fbf749bbca | |
parent | bae1eb4578ba77a68ea2a19574750b3e39724d64 (diff) | |
parent | bbeea539aa7bb7c31c5dceccdfd0d6493134ae67 (diff) |
Merge commit 'qemu-svn/trunk'kvm-85rc2
* commit 'qemu-svn/trunk':
Fix wrong return value
Remove dead AIO code for win32
target-mips: optimize gen_movcf_*()
target-mips: optimize gen_movci()
target-mips: optimize gen_compute_branch1()
Misc scsi disk/cdrom fixes/improvements 4/4
misc scsi disk/cdrom fixes/improvements 3/4
misc scsi disk/cdrom fixes/improvements 2/4
misc scsi disk/cdrom fixes/improvements 1/4
target-mips: don't map FP registers as TCG global variables
target-mips: fix divu instruction
tcg: fix _tl aliases for divu/remu
target-ppc: Explain why the whole TLB is flushed on SR write
Fix hxtool eating backslash sequences for sh != bash
-rw-r--r-- | block-raw-posix.c | 2 | ||||
-rw-r--r-- | block-raw-win32.c | 146 | ||||
-rw-r--r-- | hw/scsi-disk.c | 18 | ||||
-rw-r--r-- | hxtool | 2 | ||||
-rw-r--r-- | target-mips/translate.c | 337 | ||||
-rw-r--r-- | target-ppc/helper.c | 2 | ||||
-rw-r--r-- | tcg/tcg-op.h | 8 |
7 files changed, 158 insertions, 357 deletions
diff --git a/block-raw-posix.c b/block-raw-posix.c index 2c2e48840..6d617bb3a 100644 --- a/block-raw-posix.c +++ b/block-raw-posix.c @@ -1371,7 +1371,7 @@ static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs, unsigned long int req, void *buf, BlockDriverCompletionFunc *cb, void *opaque) { - return -ENOTSUP; + return NULL; } #endif /* !linux && !FreeBSD */ diff --git a/block-raw-win32.c b/block-raw-win32.c index d034b4a06..11638b8d4 100644 --- a/block-raw-win32.c +++ b/block-raw-win32.c @@ -28,8 +28,6 @@ #include <windows.h> #include <winioctl.h> -//#define WIN32_AIO - #define FTYPE_FILE 0 #define FTYPE_CD 1 #define FTYPE_HARDDISK 2 @@ -40,13 +38,6 @@ typedef struct BDRVRawState { char drive_path[16]; /* format: "d:\" */ } BDRVRawState; -typedef struct RawAIOCB { - BlockDriverAIOCB common; - HANDLE hEvent; - OVERLAPPED ov; - int count; -} RawAIOCB; - int qemu_ftruncate64(int fd, int64_t length) { LARGE_INTEGER li; @@ -100,11 +91,7 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags) } else { create_flags = OPEN_EXISTING; } -#ifdef WIN32_AIO - overlapped = FILE_FLAG_OVERLAPPED; -#else overlapped = FILE_ATTRIBUTE_NORMAL; -#endif if ((flags & BDRV_O_NOCACHE)) overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH; else if (!(flags & BDRV_O_CACHE_WB)) @@ -136,15 +123,8 @@ static int raw_read(BlockDriverState *bs, int64_t sector_num, ov.Offset = offset; ov.OffsetHigh = offset >> 32; ret = ReadFile(s->hfile, buf, count, &ret_count, &ov); - if (!ret) { -#ifdef WIN32_AIO - ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE); - if (!ret) - return -EIO; - else -#endif - return ret_count; - } + if (!ret) + return ret_count; if (ret_count == count) ret_count = 0; return ret_count; @@ -164,115 +144,13 @@ static int raw_write(BlockDriverState *bs, int64_t sector_num, ov.Offset = offset; ov.OffsetHigh = offset >> 32; ret = WriteFile(s->hfile, buf, count, &ret_count, &ov); - if (!ret) { -#ifdef WIN32_AIO - ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE); - if (!ret) - return -EIO; - else -#endif - return ret_count; - } + if (!ret) + return ret_count; if (ret_count == count) ret_count = 0; return ret_count; } -#ifdef WIN32_AIO -static void raw_aio_cb(void *opaque) -{ - RawAIOCB *acb = opaque; - BlockDriverState *bs = acb->common.bs; - BDRVRawState *s = bs->opaque; - DWORD ret_count; - int ret; - - ret = GetOverlappedResult(s->hfile, &acb->ov, &ret_count, TRUE); - if (!ret || ret_count != acb->count) { - acb->common.cb(acb->common.opaque, -EIO); - } else { - acb->common.cb(acb->common.opaque, 0); - } -} - -static RawAIOCB *raw_aio_setup(BlockDriverState *bs, - int64_t sector_num, uint8_t *buf, int nb_sectors, - BlockDriverCompletionFunc *cb, void *opaque) -{ - RawAIOCB *acb; - int64_t offset; - - acb = qemu_aio_get(bs, cb, opaque); - if (acb->hEvent) { - acb->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!acb->hEvent) { - qemu_aio_release(acb); - return NULL; - } - } - memset(&acb->ov, 0, sizeof(acb->ov)); - offset = sector_num * 512; - acb->ov.Offset = offset; - acb->ov.OffsetHigh = offset >> 32; - acb->ov.hEvent = acb->hEvent; - acb->count = nb_sectors * 512; - qemu_add_wait_object(acb->ov.hEvent, raw_aio_cb, acb); - return acb; -} - -static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs, - int64_t sector_num, uint8_t *buf, int nb_sectors, - BlockDriverCompletionFunc *cb, void *opaque) -{ - BDRVRawState *s = bs->opaque; - RawAIOCB *acb; - int ret; - - acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque); - if (!acb) - return NULL; - ret = ReadFile(s->hfile, buf, acb->count, NULL, &acb->ov); - if (!ret) { - qemu_aio_release(acb); - return NULL; - } - qemu_aio_release(acb); - return (BlockDriverAIOCB *)acb; -} - -static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs, - int64_t sector_num, uint8_t *buf, int nb_sectors, - BlockDriverCompletionFunc *cb, void *opaque) -{ - BDRVRawState *s = bs->opaque; - RawAIOCB *acb; - int ret; - - acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque); - if (!acb) - return NULL; - ret = WriteFile(s->hfile, buf, acb->count, NULL, &acb->ov); - if (!ret) { - qemu_aio_release(acb); - return NULL; - } - qemu_aio_release(acb); - return (BlockDriverAIOCB *)acb; -} - -static void raw_aio_cancel(BlockDriverAIOCB *blockacb) -{ - RawAIOCB *acb = (RawAIOCB *)blockacb; - BlockDriverState *bs = acb->common.bs; - BDRVRawState *s = bs->opaque; - - qemu_del_wait_object(acb->ov.hEvent, raw_aio_cb, acb); - /* XXX: if more than one async I/O it is not correct */ - CancelIo(s->hfile); - qemu_aio_release(acb); -} -#endif /* #if WIN32_AIO */ - static void raw_flush(BlockDriverState *bs) { BDRVRawState *s = bs->opaque; @@ -361,12 +239,6 @@ BlockDriver bdrv_raw = { raw_create, raw_flush, -#ifdef WIN32_AIO - .bdrv_aio_read = raw_aio_read, - .bdrv_aio_write = raw_aio_write, - .bdrv_aio_cancel = raw_aio_cancel, - .aiocb_size = sizeof(RawAIOCB); -#endif .bdrv_read = raw_read, .bdrv_write = raw_write, .bdrv_truncate = raw_truncate, @@ -446,11 +318,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) } create_flags = OPEN_EXISTING; -#ifdef WIN32_AIO - overlapped = FILE_FLAG_OVERLAPPED; -#else overlapped = FILE_ATTRIBUTE_NORMAL; -#endif if ((flags & BDRV_O_NOCACHE)) overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH; else if (!(flags & BDRV_O_CACHE_WB)) @@ -510,12 +378,6 @@ BlockDriver bdrv_host_device = { .bdrv_close = raw_close, .bdrv_flush = raw_flush, -#ifdef WIN32_AIO - .bdrv_aio_read = raw_aio_read, - .bdrv_aio_write = raw_aio_write, - .bdrv_aio_cancel = raw_aio_cancel, - .aiocb_size = sizeof(RawAIOCB); -#endif .bdrv_read = raw_read, .bdrv_write = raw_write, .bdrv_getlength = raw_getlength, diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index c4d7d520b..c7b2febd8 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -417,16 +417,26 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, switch (command) { case 0x0: DPRINTF("Test Unit Ready\n"); + if (!bdrv_is_inserted(s->bdrv)) + goto notready; break; case 0x03: DPRINTF("Request Sense (len %d)\n", len); if (len < 4) goto fail; memset(outbuf, 0, 4); + r->buf_len = 4; + if (s->sense == SENSE_NOT_READY && len >= 18) { + memset(outbuf, 0, 18); + r->buf_len = 18; + outbuf[7] = 10; + /* asc 0x3a, ascq 0: Medium not present */ + outbuf[12] = 0x3a; + outbuf[13] = 0; + } outbuf[0] = 0xf0; outbuf[1] = 0; outbuf[2] = s->sense; - r->buf_len = 4; break; case 0x12: DPRINTF("Inquiry (len %d)\n", len); @@ -725,6 +735,10 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, break; case 0x1b: DPRINTF("Start Stop Unit\n"); + if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM && + (buf[4] & 2)) + /* load/eject medium */ + bdrv_eject(s->bdrv, !(buf[4] & 1)); break; case 0x1e: DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3); @@ -754,6 +768,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, outbuf[7] = 0; r->buf_len = 8; } else { + notready: scsi_command_complete(r, STATUS_CHECK_CONDITION, SENSE_NOT_READY); return 0; } @@ -790,6 +805,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, start_track = buf[6]; bdrv_get_geometry(s->bdrv, &nb_sectors); DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1); + nb_sectors /= s->cluster_size; switch(format) { case 0: toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track); @@ -10,7 +10,7 @@ hxtoh() STEXI*|ETEXI*) flag=$(($flag^1)) ;; *) - test $flag -eq 1 && echo "$str" + test $flag -eq 1 && printf "%s\n" "$str" ;; esac done diff --git a/target-mips/translate.c b/target-mips/translate.c index d8638a63a..8adc89cff 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -431,7 +431,6 @@ static TCGv cpu_gpr[32], cpu_PC; static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC]; static TCGv cpu_dspctrl, btarget, bcond; static TCGv_i32 hflags; -static TCGv_i32 fpu_fpr32[32], fpu_fpr32h[32]; static TCGv_i32 fpu_fcr0, fpu_fcr31; #include "gen-icount.h" @@ -500,12 +499,6 @@ static const char *fregnames[] = "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", }; -static const char *fregnames_h[] = - { "h0", "h1", "h2", "h3", "h4", "h5", "h6", "h7", - "h8", "h9", "h10", "h11", "h12", "h13", "h14", "h15", - "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23", - "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31", }; - #ifdef MIPS_DEBUG_DISAS #define MIPS_DEBUG(fmt, args...) \ qemu_log_mask(CPU_LOG_TB_IN_ASM, \ @@ -600,58 +593,62 @@ static inline void gen_store_srsgpr (int from, int to) /* Floating point register moves. */ static inline void gen_load_fpr32 (TCGv_i32 t, int reg) { - tcg_gen_mov_i32(t, fpu_fpr32[reg]); + tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX])); } static inline void gen_store_fpr32 (TCGv_i32 t, int reg) { - tcg_gen_mov_i32(fpu_fpr32[reg], t); + tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX])); +} + +static inline void gen_load_fpr32h (TCGv_i32 t, int reg) +{ + tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX])); +} + +static inline void gen_store_fpr32h (TCGv_i32 t, int reg) +{ + tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX])); } static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg) { if (ctx->hflags & MIPS_HFLAG_F64) { - tcg_gen_concat_i32_i64(t, fpu_fpr32[reg], fpu_fpr32h[reg]); + tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d)); } else { - tcg_gen_concat_i32_i64(t, fpu_fpr32[reg & ~1], fpu_fpr32[reg | 1]); + TCGv_i32 t0 = tcg_temp_new_i32(); + TCGv_i32 t1 = tcg_temp_new_i32(); + gen_load_fpr32(t0, reg & ~1); + gen_load_fpr32(t1, reg | 1); + tcg_gen_concat_i32_i64(t, t0, t1); + tcg_temp_free_i32(t0); + tcg_temp_free_i32(t1); } } static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg) { if (ctx->hflags & MIPS_HFLAG_F64) { - tcg_gen_trunc_i64_i32(fpu_fpr32[reg], t); - tcg_gen_shri_i64(t, t, 32); - tcg_gen_trunc_i64_i32(fpu_fpr32h[reg], t); + tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d)); } else { - tcg_gen_trunc_i64_i32(fpu_fpr32[reg & ~1], t); - tcg_gen_shri_i64(t, t, 32); - tcg_gen_trunc_i64_i32(fpu_fpr32[reg | 1], t); + TCGv_i64 t0 = tcg_temp_new_i64(); + TCGv_i32 t1 = tcg_temp_new_i32(); + tcg_gen_trunc_i64_i32(t1, t); + gen_store_fpr32(t1, reg & ~1); + tcg_gen_shri_i64(t0, t, 32); + tcg_gen_trunc_i64_i32(t1, t0); + gen_store_fpr32(t1, reg | 1); + tcg_temp_free_i32(t1); + tcg_temp_free_i64(t0); } } -static inline void gen_load_fpr32h (TCGv_i32 t, int reg) +static inline int get_fp_bit (int cc) { - tcg_gen_mov_i32(t, fpu_fpr32h[reg]); -} - -static inline void gen_store_fpr32h (TCGv_i32 t, int reg) -{ - tcg_gen_mov_i32(fpu_fpr32h[reg], t); -} - -static inline void get_fp_cond (TCGv_i32 t) -{ - TCGv_i32 r_tmp1 = tcg_temp_new_i32(); - TCGv_i32 r_tmp2 = tcg_temp_new_i32(); - - tcg_gen_shri_i32(r_tmp2, fpu_fcr31, 24); - tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe); - tcg_gen_shri_i32(r_tmp1, fpu_fcr31, 23); - tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1); - tcg_gen_or_i32(t, r_tmp1, r_tmp2); - tcg_temp_free_i32(r_tmp1); - tcg_temp_free_i32(r_tmp2); + if (cc) + return 24 + cc; + else + return 23; } #define FOP_CONDS(type, fmt, bits) \ @@ -1847,6 +1844,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc, { int l1 = gen_new_label(); + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1); tcg_gen_divu_tl(cpu_LO[0], t0, t1); tcg_gen_remu_tl(cpu_HI[0], t0, t1); @@ -5495,132 +5494,88 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, switch (op) { case OPC_BC1F: - { - int l1 = gen_new_label(); - int l2 = gen_new_label(); - - get_fp_cond(t0); - tcg_gen_andi_i32(t0, t0, 0x1 << cc); - tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1); - tcg_gen_movi_tl(bcond, 0); - tcg_gen_br(l2); - gen_set_label(l1); - tcg_gen_movi_tl(bcond, 1); - gen_set_label(l2); - } + tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); + tcg_gen_not_i32(t0, t0); + tcg_gen_andi_i32(t0, t0, 1); + tcg_gen_extu_i32_tl(bcond, t0); opn = "bc1f"; goto not_likely; case OPC_BC1FL: - { - int l1 = gen_new_label(); - int l2 = gen_new_label(); - - get_fp_cond(t0); - tcg_gen_andi_i32(t0, t0, 0x1 << cc); - tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1); - tcg_gen_movi_tl(bcond, 0); - tcg_gen_br(l2); - gen_set_label(l1); - tcg_gen_movi_tl(bcond, 1); - gen_set_label(l2); - } + tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); + tcg_gen_not_i32(t0, t0); + tcg_gen_andi_i32(t0, t0, 1); + tcg_gen_extu_i32_tl(bcond, t0); opn = "bc1fl"; goto likely; case OPC_BC1T: - { - int l1 = gen_new_label(); - int l2 = gen_new_label(); - - get_fp_cond(t0); - tcg_gen_andi_i32(t0, t0, 0x1 << cc); - tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1); - tcg_gen_movi_tl(bcond, 0); - tcg_gen_br(l2); - gen_set_label(l1); - tcg_gen_movi_tl(bcond, 1); - gen_set_label(l2); - } + tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); + tcg_gen_andi_i32(t0, t0, 1); + tcg_gen_extu_i32_tl(bcond, t0); opn = "bc1t"; goto not_likely; case OPC_BC1TL: - { - int l1 = gen_new_label(); - int l2 = gen_new_label(); - - get_fp_cond(t0); - tcg_gen_andi_i32(t0, t0, 0x1 << cc); - tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1); - tcg_gen_movi_tl(bcond, 0); - tcg_gen_br(l2); - gen_set_label(l1); - tcg_gen_movi_tl(bcond, 1); - gen_set_label(l2); - } + tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); + tcg_gen_andi_i32(t0, t0, 1); + tcg_gen_extu_i32_tl(bcond, t0); opn = "bc1tl"; likely: ctx->hflags |= MIPS_HFLAG_BL; break; case OPC_BC1FANY2: { - int l1 = gen_new_label(); - int l2 = gen_new_label(); - - get_fp_cond(t0); - tcg_gen_andi_i32(t0, t0, 0x3 << cc); - tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1); - tcg_gen_movi_tl(bcond, 0); - tcg_gen_br(l2); - gen_set_label(l1); - tcg_gen_movi_tl(bcond, 1); - gen_set_label(l2); + TCGv_i32 t1 = tcg_temp_new_i32(); + tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); + tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1)); + tcg_gen_or_i32(t0, t0, t1); + tcg_temp_free_i32(t1); + tcg_gen_not_i32(t0, t0); + tcg_gen_andi_i32(t0, t0, 1); + tcg_gen_extu_i32_tl(bcond, t0); } opn = "bc1any2f"; goto not_likely; case OPC_BC1TANY2: { - int l1 = gen_new_label(); - int l2 = gen_new_label(); - - get_fp_cond(t0); - tcg_gen_andi_i32(t0, t0, 0x3 << cc); - tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1); - tcg_gen_movi_tl(bcond, 0); - tcg_gen_br(l2); - gen_set_label(l1); - tcg_gen_movi_tl(bcond, 1); - gen_set_label(l2); + TCGv_i32 t1 = tcg_temp_new_i32(); + tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); + tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1)); + tcg_gen_or_i32(t0, t0, t1); + tcg_temp_free_i32(t1); + tcg_gen_andi_i32(t0, t0, 1); + tcg_gen_extu_i32_tl(bcond, t0); } opn = "bc1any2t"; goto not_likely; case OPC_BC1FANY4: { - int l1 = gen_new_label(); - int l2 = gen_new_label(); - - get_fp_cond(t0); - tcg_gen_andi_i32(t0, t0, 0xf << cc); - tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1); - tcg_gen_movi_tl(bcond, 0); - tcg_gen_br(l2); - gen_set_label(l1); - tcg_gen_movi_tl(bcond, 1); - gen_set_label(l2); + TCGv_i32 t1 = tcg_temp_new_i32(); + tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); + tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1)); + tcg_gen_or_i32(t0, t0, t1); + tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2)); + tcg_gen_or_i32(t0, t0, t1); + tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3)); + tcg_gen_or_i32(t0, t0, t1); + tcg_temp_free_i32(t1); + tcg_gen_not_i32(t0, t0); + tcg_gen_andi_i32(t0, t0, 1); + tcg_gen_extu_i32_tl(bcond, t0); } opn = "bc1any4f"; goto not_likely; case OPC_BC1TANY4: { - int l1 = gen_new_label(); - int l2 = gen_new_label(); - - get_fp_cond(t0); - tcg_gen_andi_i32(t0, t0, 0xf << cc); - tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1); - tcg_gen_movi_tl(bcond, 0); - tcg_gen_br(l2); - gen_set_label(l1); - tcg_gen_movi_tl(bcond, 1); - gen_set_label(l2); + TCGv_i32 t1 = tcg_temp_new_i32(); + tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc)); + tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1)); + tcg_gen_or_i32(t0, t0, t1); + tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2)); + tcg_gen_or_i32(t0, t0, t1); + tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3)); + tcg_gen_or_i32(t0, t0, t1); + tcg_temp_free_i32(t1); + tcg_gen_andi_i32(t0, t0, 1); + tcg_gen_extu_i32_tl(bcond, t0); } opn = "bc1any4t"; not_likely: @@ -5738,125 +5693,99 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) { - int l1 = gen_new_label(); - uint32_t ccbit; + int l1; TCGCond cond; - TCGv t0 = tcg_temp_local_new(); - TCGv_i32 r_tmp = tcg_temp_new_i32(); + TCGv_i32 t0; + + if (rd == 0) { + /* Treat as NOP. */ + return; + } - if (cc) - ccbit = 1 << (24 + cc); - else - ccbit = 1 << 23; if (tf) cond = TCG_COND_EQ; else cond = TCG_COND_NE; - gen_load_gpr(t0, rd); - tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit); - tcg_gen_brcondi_i32(cond, r_tmp, 0, l1); - tcg_temp_free_i32(r_tmp); - gen_load_gpr(t0, rs); + l1 = gen_new_label(); + t0 = tcg_temp_new_i32(); + tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc)); + tcg_gen_brcondi_i32(cond, t0, 0, l1); + if (rs == 0) { + tcg_gen_movi_tl(cpu_gpr[rd], 0); + } else { + tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); + } gen_set_label(l1); - gen_store_gpr(t0, rd); - tcg_temp_free(t0); + tcg_temp_free_i32(t0); } static inline void gen_movcf_s (int fs, int fd, int cc, int tf) { - uint32_t ccbit; int cond; - TCGv_i32 r_tmp1 = tcg_temp_new_i32(); - TCGv_i32 fp0 = tcg_temp_local_new_i32(); + TCGv_i32 t0 = tcg_temp_new_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; - gen_load_fpr32(fp0, fd); - tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit); - tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1); - tcg_temp_free_i32(r_tmp1); - gen_load_fpr32(fp0, fs); + tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc)); + tcg_gen_brcondi_i32(cond, t0, 0, l1); + gen_load_fpr32(t0, fs); + gen_store_fpr32(t0, fd); gen_set_label(l1); - gen_store_fpr32(fp0, fd); - tcg_temp_free_i32(fp0); + tcg_temp_free_i32(t0); } static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf) { - uint32_t ccbit; int cond; - TCGv_i32 r_tmp1 = tcg_temp_new_i32(); - TCGv_i64 fp0 = tcg_temp_local_new_i64(); + TCGv_i32 t0 = tcg_temp_new_i32(); + TCGv_i64 fp0; 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; - gen_load_fpr64(ctx, fp0, fd); - tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit); - tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1); - tcg_temp_free_i32(r_tmp1); + tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc)); + tcg_gen_brcondi_i32(cond, t0, 0, l1); + fp0 = tcg_temp_local_new_i64(); gen_load_fpr64(ctx, fp0, fs); - gen_set_label(l1); gen_store_fpr64(ctx, fp0, fd); tcg_temp_free_i64(fp0); + gen_set_label(l1); + tcg_temp_free_i32(t0); } static inline void gen_movcf_ps (int fs, int fd, int cc, int tf) { - uint32_t ccbit1, ccbit2; int cond; - TCGv_i32 r_tmp1 = tcg_temp_new_i32(); - TCGv_i32 fp0 = tcg_temp_local_new_i32(); + TCGv_i32 t0 = tcg_temp_new_i32(); int l1 = gen_new_label(); int l2 = gen_new_label(); - if (cc) { - ccbit1 = 1 << (24 + cc); - ccbit2 = 1 << (25 + cc); - } else { - ccbit1 = 1 << 23; - ccbit2 = 1 << 25; - } - if (tf) cond = TCG_COND_EQ; else cond = TCG_COND_NE; - gen_load_fpr32(fp0, fd); - tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit1); - tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1); - gen_load_fpr32(fp0, fs); + tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc)); + tcg_gen_brcondi_i32(cond, t0, 0, l1); + gen_load_fpr32(t0, fs); + gen_store_fpr32(t0, fd); gen_set_label(l1); - gen_store_fpr32(fp0, fd); - gen_load_fpr32h(fp0, fd); - tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit2); - tcg_gen_brcondi_i32(cond, r_tmp1, 0, l2); - gen_load_fpr32h(fp0, fs); + tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc+1)); + tcg_gen_brcondi_i32(cond, t0, 0, l2); + gen_load_fpr32h(t0, fs); + gen_store_fpr32h(t0, fd); gen_set_label(l2); - gen_store_fpr32h(fp0, fd); - tcg_temp_free_i32(r_tmp1); - tcg_temp_free_i32(fp0); + tcg_temp_free_i32(t0); } @@ -8406,14 +8335,6 @@ static void mips_tcg_init(void) hflags = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, hflags), "hflags"); - for (i = 0; i < 32; i++) - fpu_fpr32[i] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUState, active_fpu.fpr[i].w[FP_ENDIAN_IDX]), - fregnames[i]); - for (i = 0; i < 32; i++) - fpu_fpr32h[i] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUState, active_fpu.fpr[i].w[!FP_ENDIAN_IDX]), - fregnames_h[i]); fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, active_fpu.fcr0), "fcr0"); diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 80b53ebcb..a0d884ee1 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -2009,6 +2009,8 @@ void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value) #endif if (env->sr[srnum] != value) { env->sr[srnum] = value; +/* Invalidating 256MB of virtual memory in 4kB pages is way longer than + flusing the whole TLB. */ #if !defined(FLUSH_ALL_TLBS) && 0 { target_ulong page, end; diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index 052ef455c..daeb025a6 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -2054,8 +2054,8 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index) #define tcg_gen_muli_tl tcg_gen_muli_i64 #define tcg_gen_div_tl tcg_gen_div_i64 #define tcg_gen_rem_tl tcg_gen_rem_i64 -#define tcg_gen_divu_tl tcg_gen_div_i64 -#define tcg_gen_remu_tl tcg_gen_rem_i64 +#define tcg_gen_divu_tl tcg_gen_divu_i64 +#define tcg_gen_remu_tl tcg_gen_remu_i64 #define tcg_gen_discard_tl tcg_gen_discard_i64 #define tcg_gen_trunc_tl_i32 tcg_gen_trunc_i64_i32 #define tcg_gen_trunc_i64_tl tcg_gen_mov_i64 @@ -2124,8 +2124,8 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index) #define tcg_gen_muli_tl tcg_gen_muli_i32 #define tcg_gen_div_tl tcg_gen_div_i32 #define tcg_gen_rem_tl tcg_gen_rem_i32 -#define tcg_gen_divu_tl tcg_gen_div_i32 -#define tcg_gen_remu_tl tcg_gen_rem_i32 +#define tcg_gen_divu_tl tcg_gen_divu_i32 +#define tcg_gen_remu_tl tcg_gen_remu_i32 #define tcg_gen_discard_tl tcg_gen_discard_i32 #define tcg_gen_trunc_tl_i32 tcg_gen_mov_i32 #define tcg_gen_trunc_i64_tl tcg_gen_trunc_i64_i32 |