diff options
-rw-r--r-- | MAINTAINERS | 4 | ||||
-rw-r--r-- | cpu-exec.c | 2 | ||||
-rw-r--r-- | exec.c | 2 | ||||
-rw-r--r-- | include/qemu/log.h | 16 | ||||
-rw-r--r-- | include/sysemu/os-posix.h | 12 | ||||
-rw-r--r-- | include/sysemu/os-win32.h | 15 | ||||
-rw-r--r-- | target-alpha/translate.c | 2 | ||||
-rw-r--r-- | target-arm/translate-a64.c | 2 | ||||
-rw-r--r-- | target-arm/translate.c | 2 | ||||
-rw-r--r-- | target-cris/translate.c | 27 | ||||
-rw-r--r-- | target-i386/translate.c | 4 | ||||
-rw-r--r-- | target-lm32/translate.c | 2 | ||||
-rw-r--r-- | target-m68k/translate.c | 2 | ||||
-rw-r--r-- | target-microblaze/translate.c | 72 | ||||
-rw-r--r-- | target-mips/translate.c | 2 | ||||
-rw-r--r-- | target-openrisc/translate.c | 9 | ||||
-rw-r--r-- | target-ppc/translate.c | 2 | ||||
-rw-r--r-- | target-s390x/translate.c | 2 | ||||
-rw-r--r-- | target-sh4/translate.c | 2 | ||||
-rw-r--r-- | target-sparc/translate.c | 2 | ||||
-rw-r--r-- | target-tilegx/translate.c | 6 | ||||
-rw-r--r-- | target-tricore/translate.c | 2 | ||||
-rw-r--r-- | target-unicore32/translate.c | 2 | ||||
-rw-r--r-- | target-xtensa/translate.c | 2 | ||||
-rw-r--r-- | tcg/tcg-op.c | 45 | ||||
-rw-r--r-- | tcg/tcg-op.h | 4 | ||||
-rw-r--r-- | tcg/tcg.c | 8 | ||||
-rw-r--r-- | tcg/tcg.h | 38 | ||||
-rw-r--r-- | translate-all.c | 2 |
29 files changed, 192 insertions, 100 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 3fecf45..653f52e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1504,8 +1504,8 @@ F: tcg/mips/ F: disas/mips.c PPC -M: Vassili Karpov (malc) <av1474@comtv.ru> -S: Maintained +M: Richard Henderson <rth@twiddle.net> +S: Odd Fixes F: tcg/ppc/ F: disas/ppc.c @@ -150,11 +150,13 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb) #if defined(DEBUG_DISAS) if (qemu_loglevel_mask(CPU_LOG_TB_CPU) && qemu_log_in_addr_range(itb->pc)) { + qemu_log_lock(); #if defined(TARGET_I386) log_cpu_state(cpu, CPU_DUMP_CCOP); #else log_cpu_state(cpu, 0); #endif + qemu_log_unlock(); } #endif /* DEBUG_DISAS */ @@ -911,11 +911,13 @@ void cpu_abort(CPUState *cpu, const char *fmt, ...) fprintf(stderr, "\n"); cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU | CPU_DUMP_CCOP); if (qemu_log_separate()) { + qemu_log_lock(); qemu_log("qemu: fatal: "); qemu_log_vprintf(fmt, ap2); qemu_log("\n"); log_cpu_state(cpu, CPU_DUMP_FPU | CPU_DUMP_CCOP); qemu_log_flush(); + qemu_log_unlock(); qemu_log_close(); } va_end(ap2); diff --git a/include/qemu/log.h b/include/qemu/log.h index 00bf37f..a50e994 100644 --- a/include/qemu/log.h +++ b/include/qemu/log.h @@ -51,6 +51,22 @@ static inline bool qemu_loglevel_mask(int mask) return (qemu_loglevel & mask) != 0; } +/* Lock output for a series of related logs. Since this is not needed + * for a single qemu_log / qemu_log_mask / qemu_log_mask_and_addr, we + * assume that qemu_loglevel_mask has already been tested, and that + * qemu_loglevel is never set when qemu_logfile is unset. + */ + +static inline void qemu_log_lock(void) +{ + qemu_flockfile(qemu_logfile); +} + +static inline void qemu_log_unlock(void) +{ + qemu_funlockfile(qemu_logfile); +} + /* Logging functions: */ /* main logging function diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h index 3cfedbc..b0a6c06 100644 --- a/include/sysemu/os-posix.h +++ b/include/sysemu/os-posix.h @@ -87,4 +87,16 @@ void *qemu_alloc_stack(size_t *sz); */ void qemu_free_stack(void *stack, size_t sz); +/* POSIX and Mingw32 differ in the name of the stdio lock functions. */ + +static inline void qemu_flockfile(FILE *f) +{ + flockfile(f); +} + +static inline void qemu_funlockfile(FILE *f) +{ + funlockfile(f); +} + #endif diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h index 17aad3b..ff18b23 100644 --- a/include/sysemu/os-win32.h +++ b/include/sysemu/os-win32.h @@ -103,6 +103,21 @@ static inline char *realpath(const char *path, char *resolved_path) return resolved_path; } +/* ??? Mingw appears to export _lock_file and _unlock_file as the functions + * with which to lock a stdio handle. But something is wrong in the markup, + * either in the header or the library, such that we get undefined references + * to "_imp___lock_file" etc when linking. Since we seem to have no other + * alternative, and the usage within the logging functions isn't critical, + * ignore FILE locking. + */ + +static inline void qemu_flockfile(FILE *f) +{ +} + +static inline void qemu_funlockfile(FILE *f) +{ +} /* We wrap all the sockets functions so that we can * set errno based on WSAGetLastError() diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 03e4776..114927b 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -2994,9 +2994,11 @@ void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb) #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { + qemu_log_lock(); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, ctx.pc - pc_start, 1); qemu_log("\n"); + qemu_log_unlock(); } #endif } diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index ded924a..de48747 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -11420,11 +11420,13 @@ done_generating: #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { + qemu_log_lock(); qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc->pc - pc_start, 4 | (bswap_code(dc->sctlr_b) ? 2 : 0)); qemu_log("\n"); + qemu_log_unlock(); } #endif tb->size = dc->pc - pc_start; diff --git a/target-arm/translate.c b/target-arm/translate.c index 718f7d0..0ad9070 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -11963,11 +11963,13 @@ done_generating: #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { + qemu_log_lock(); qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc->pc - pc_start, dc->thumb | (dc->sctlr_b << 1)); qemu_log("\n"); + qemu_log_unlock(); } #endif tb->size = dc->pc - pc_start; diff --git a/target-cris/translate.c b/target-cris/translate.c index b5ab0a5..b910427 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -3135,29 +3135,6 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb) dc->cpustate_changed = 0; - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { - qemu_log( - "pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n" - "pid=%x usp=%x\n" - "%x.%x.%x.%x\n" - "%x.%x.%x.%x\n" - "%x.%x.%x.%x\n" - "%x.%x.%x.%x\n", - dc->pc, dc->ppc, - (uint64_t)tb->flags, - env->btarget, (unsigned)tb->flags & 7, - env->pregs[PR_CCS], - env->pregs[PR_PID], env->pregs[PR_USP], - env->regs[0], env->regs[1], env->regs[2], env->regs[3], - env->regs[4], env->regs[5], env->regs[6], env->regs[7], - env->regs[8], env->regs[9], - env->regs[10], env->regs[11], - env->regs[12], env->regs[13], - env->regs[14], env->regs[15]); - qemu_log("--------------\n"); - qemu_log("IN: %s\n", lookup_symbol(pc_start)); - } - next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; num_insns = 0; max_insns = tb->cflags & CF_COUNT_MASK; @@ -3313,10 +3290,14 @@ void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb) #if !DISAS_CRIS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { + qemu_log_lock(); + qemu_log("--------------\n"); + qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc->pc - pc_start, env->pregs[PR_VR]); qemu_log("\nisize=%d osize=%d\n", dc->pc - pc_start, tcg_op_buf_count()); + qemu_log_unlock(); } #endif #endif diff --git a/target-i386/translate.c b/target-i386/translate.c index 927b366..324103c 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -2432,11 +2432,13 @@ static void gen_unknown_opcode(CPUX86State *env, DisasContext *s) if (qemu_loglevel_mask(LOG_UNIMP)) { target_ulong pc = s->pc_start, end = s->pc; + qemu_log_lock(); qemu_log("ILLOPC: " TARGET_FMT_lx ":", pc); for (; pc < end; ++pc) { qemu_log(" %02x", cpu_ldub_code(env, pc)); } qemu_log("\n"); + qemu_log_unlock(); } } @@ -8470,6 +8472,7 @@ done_generating: if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { int disas_flags; + qemu_log_lock(); qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); #ifdef TARGET_X86_64 @@ -8480,6 +8483,7 @@ done_generating: disas_flags = !dc->code32; log_target_disas(cs, pc_start, pc_ptr - pc_start, disas_flags); qemu_log("\n"); + qemu_log_unlock(); } #endif diff --git a/target-lm32/translate.c b/target-lm32/translate.c index 842af63..692882f 100644 --- a/target-lm32/translate.c +++ b/target-lm32/translate.c @@ -1148,10 +1148,12 @@ void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb) #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { + qemu_log_lock(); qemu_log("\n"); log_target_disas(cs, pc_start, dc->pc - pc_start, 0); qemu_log("\nisize=%d osize=%d\n", dc->pc - pc_start, tcg_op_buf_count()); + qemu_log_unlock(); } #endif } diff --git a/target-m68k/translate.c b/target-m68k/translate.c index ee0ffe3..9ad974f 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -3549,10 +3549,12 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb) #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { + qemu_log_lock(); qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc->pc - pc_start, 0); qemu_log("\n"); + qemu_log_unlock(); } #endif tb->size = dc->pc - pc_start; diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index 80098ec..de2090a 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -581,50 +581,10 @@ static void dec_msr(DisasContext *dc) } } -/* 64-bit signed mul, lower result in d and upper in d2. */ -static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b) -{ - TCGv_i64 t0, t1; - - t0 = tcg_temp_new_i64(); - t1 = tcg_temp_new_i64(); - - tcg_gen_ext_i32_i64(t0, a); - tcg_gen_ext_i32_i64(t1, b); - tcg_gen_mul_i64(t0, t0, t1); - - tcg_gen_extrl_i64_i32(d, t0); - tcg_gen_shri_i64(t0, t0, 32); - tcg_gen_extrl_i64_i32(d2, t0); - - tcg_temp_free_i64(t0); - tcg_temp_free_i64(t1); -} - -/* 64-bit unsigned muls, lower result in d and upper in d2. */ -static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b) -{ - TCGv_i64 t0, t1; - - t0 = tcg_temp_new_i64(); - t1 = tcg_temp_new_i64(); - - tcg_gen_extu_i32_i64(t0, a); - tcg_gen_extu_i32_i64(t1, b); - tcg_gen_mul_i64(t0, t0, t1); - - tcg_gen_extrl_i64_i32(d, t0); - tcg_gen_shri_i64(t0, t0, 32); - tcg_gen_extrl_i64_i32(d2, t0); - - tcg_temp_free_i64(t0); - tcg_temp_free_i64(t1); -} - /* Multiplier unit. */ static void dec_mul(DisasContext *dc) { - TCGv d[2]; + TCGv tmp; unsigned int subcode; if ((dc->tb_flags & MSR_EE_FLAG) @@ -636,13 +596,11 @@ static void dec_mul(DisasContext *dc) } subcode = dc->imm & 3; - d[0] = tcg_temp_new(); - d[1] = tcg_temp_new(); if (dc->type_b) { LOG_DIS("muli r%d r%d %x\n", dc->rd, dc->ra, dc->imm); - t_gen_mulu(cpu_R[dc->rd], d[1], cpu_R[dc->ra], *(dec_alu_op_b(dc))); - goto done; + tcg_gen_mul_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc))); + return; } /* mulh, mulhsu and mulhu are not available if C_USE_HW_MUL is < 2. */ @@ -651,30 +609,29 @@ static void dec_mul(DisasContext *dc) /* nop??? */ } + tmp = tcg_temp_new(); switch (subcode) { case 0: LOG_DIS("mul r%d r%d r%d\n", dc->rd, dc->ra, dc->rb); - t_gen_mulu(cpu_R[dc->rd], d[1], cpu_R[dc->ra], cpu_R[dc->rb]); + tcg_gen_mul_tl(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]); break; case 1: LOG_DIS("mulh r%d r%d r%d\n", dc->rd, dc->ra, dc->rb); - t_gen_muls(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]); + tcg_gen_muls2_tl(tmp, cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]); break; case 2: LOG_DIS("mulhsu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb); - t_gen_muls(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]); + tcg_gen_mulsu2_tl(tmp, cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]); break; case 3: LOG_DIS("mulhu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb); - t_gen_mulu(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]); + tcg_gen_mulu2_tl(tmp, cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]); break; default: cpu_abort(CPU(dc->cpu), "unknown MUL insn %x\n", subcode); break; } -done: - tcg_temp_free(d[0]); - tcg_temp_free(d[1]); + tcg_temp_free(tmp); } /* Div unit. */ @@ -1670,13 +1627,6 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb) cpu_abort(cs, "Microblaze: unaligned PC=%x\n", pc_start); } - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { -#if !SIM_COMPAT - qemu_log("--------------\n"); - log_cpu_state(CPU(cpu), 0); -#endif - } - next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; num_insns = 0; max_insns = tb->cflags & CF_COUNT_MASK; @@ -1820,12 +1770,14 @@ void gen_intermediate_code(CPUMBState *env, struct TranslationBlock *tb) #if !SIM_COMPAT if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { - qemu_log("\n"); + qemu_log_lock(); + qemu_log("--------------\n"); #if DISAS_GNU log_target_disas(cs, pc_start, dc->pc - pc_start, 0); #endif qemu_log("\nisize=%d osize=%d\n", dc->pc - pc_start, tcg_op_buf_count()); + qemu_log_unlock(); } #endif #endif diff --git a/target-mips/translate.c b/target-mips/translate.c index 55c2ca0..d8dde7a 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -20043,9 +20043,11 @@ done_generating: LOG_DISAS("\n"); if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { + qemu_log_lock(); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, ctx.pc - pc_start, 0); qemu_log("\n"); + qemu_log_unlock(); } #endif } diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index 28c9446..229361a 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -1651,10 +1651,6 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb) dc->synced_flags = dc->tb_flags = tb->flags; dc->delayed_branch = !!(dc->tb_flags & D_FLAG); dc->singlestep_enabled = cs->singlestep_enabled; - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { - qemu_log("-----------------------------------------\n"); - log_cpu_state(CPU(cpu), 0); - } next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; num_insns = 0; @@ -1754,10 +1750,13 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb) #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { - qemu_log("\n"); + qemu_log_lock(); + qemu_log("----------------\n"); + qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc->pc - pc_start, 0); qemu_log("\nisize=%d osize=%d\n", dc->pc - pc_start, tcg_op_buf_count()); + qemu_log_unlock(); } #endif } diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 43505a9..54f35e9 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7211,9 +7211,11 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb) int flags; flags = env->bfd_mach; flags |= ctx.le_mode << 16; + qemu_log_lock(); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, ctx.nip - pc_start, flags); qemu_log("\n"); + qemu_log_unlock(); } #endif } diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 1a07d70..02bc705 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -5432,9 +5432,11 @@ void gen_intermediate_code(CPUS390XState *env, struct TranslationBlock *tb) #if defined(S390X_DEBUG_DISAS) if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { + qemu_log_lock(); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc.pc - pc_start, 1); qemu_log("\n"); + qemu_log_unlock(); } #endif } diff --git a/target-sh4/translate.c b/target-sh4/translate.c index ca80cf7..c89a147 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -1927,9 +1927,11 @@ void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb) #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { + qemu_log_lock(); qemu_log("IN:\n"); /* , lookup_symbol(pc_start)); */ log_target_disas(cs, pc_start, ctx.pc - pc_start, 0); qemu_log("\n"); + qemu_log_unlock(); } #endif } diff --git a/target-sparc/translate.c b/target-sparc/translate.c index a13b76e..2205f89 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -5796,10 +5796,12 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb) #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { + qemu_log_lock(); qemu_log("--------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, last_pc + 4 - pc_start, 0); qemu_log("\n"); + qemu_log_unlock(); } #endif } diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c index 11c9732..9c734ee 100644 --- a/target-tilegx/translate.c +++ b/target-tilegx/translate.c @@ -2391,6 +2391,7 @@ void gen_intermediate_code(CPUTLGState *env, struct TranslationBlock *tb) TCGV_UNUSED_I64(dc->zero); if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + qemu_log_lock(); qemu_log("IN: %s\n", lookup_symbol(pc_start)); } if (!max_insns) { @@ -2429,7 +2430,10 @@ void gen_intermediate_code(CPUTLGState *env, struct TranslationBlock *tb) tb->size = dc->pc - pc_start; tb->icount = num_insns; - qemu_log_mask(CPU_LOG_TB_IN_ASM, "\n"); + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { + qemu_log("\n"); + qemu_log_unlock(); + } } void restore_state_to_opc(CPUTLGState *env, TranslationBlock *tb, diff --git a/target-tricore/translate.c b/target-tricore/translate.c index 9a50df9..36f734a 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -8789,9 +8789,11 @@ void gen_intermediate_code(CPUTriCoreState *env, struct TranslationBlock *tb) #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { + qemu_log_lock(); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, ctx.pc - pc_start, 0); qemu_log("\n"); + qemu_log_unlock(); } #endif } diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c index 09354f9..514d460 100644 --- a/target-unicore32/translate.c +++ b/target-unicore32/translate.c @@ -2024,10 +2024,12 @@ done_generating: #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { + qemu_log_lock(); qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc->pc - pc_start, 0); qemu_log("\n"); + qemu_log_unlock(); } #endif tb->size = dc->pc - pc_start; diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index fb0fa56..0858c29 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -3155,10 +3155,12 @@ void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb) #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) && qemu_log_in_addr_range(pc_start)) { + qemu_log_lock(); qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(cs, pc_start, dc.pc - pc_start, 0); qemu_log("\n"); + qemu_log_unlock(); } #endif tb->size = dc.pc - pc_start; diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index bb2bfee..6e2fb35 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -678,6 +678,33 @@ void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2) } } +void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2) +{ + if (TCG_TARGET_REG_BITS == 32) { + TCGv_i32 t0 = tcg_temp_new_i32(); + TCGv_i32 t1 = tcg_temp_new_i32(); + TCGv_i32 t2 = tcg_temp_new_i32(); + tcg_gen_mulu2_i32(t0, t1, arg1, arg2); + /* Adjust for negative input for the signed arg1. */ + tcg_gen_sari_i32(t2, arg1, 31); + tcg_gen_and_i32(t2, t2, arg2); + tcg_gen_sub_i32(rh, t1, t2); + tcg_gen_mov_i32(rl, t0); + tcg_temp_free_i32(t0); + tcg_temp_free_i32(t1); + tcg_temp_free_i32(t2); + } else { + TCGv_i64 t0 = tcg_temp_new_i64(); + TCGv_i64 t1 = tcg_temp_new_i64(); + tcg_gen_ext_i32_i64(t0, arg1); + tcg_gen_extu_i32_i64(t1, arg2); + tcg_gen_mul_i64(t0, t0, t1); + tcg_gen_extr_i64_i32(rl, rh, t0); + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); + } +} + void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg) { if (TCG_TARGET_HAS_ext8s_i32) { @@ -790,7 +817,7 @@ void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) { tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset); - tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), 31); + tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); } void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) @@ -1748,6 +1775,22 @@ void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) } } +void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2) +{ + TCGv_i64 t0 = tcg_temp_new_i64(); + TCGv_i64 t1 = tcg_temp_new_i64(); + TCGv_i64 t2 = tcg_temp_new_i64(); + tcg_gen_mulu2_i64(t0, t1, arg1, arg2); + /* Adjust for negative input for the signed arg1. */ + tcg_gen_sari_i64(t2, arg1, 63); + tcg_gen_and_i64(t2, t2, arg2); + tcg_gen_sub_i64(rh, t1, t2); + tcg_gen_mov_i64(rl, t0); + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); + tcg_temp_free_i64(t2); +} + /* Size changing operations. */ void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg) diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index 89b59e8..6d044b7 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -306,6 +306,7 @@ void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al, TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh); void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2); void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2); +void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2); void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg); void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg); void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg); @@ -482,6 +483,7 @@ void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al, TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh); void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2); void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2); +void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2); void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg); void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg); void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg); @@ -956,6 +958,7 @@ void tcg_gen_atomic_xor_fetch_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp); #define tcg_gen_sub2_tl tcg_gen_sub2_i64 #define tcg_gen_mulu2_tl tcg_gen_mulu2_i64 #define tcg_gen_muls2_tl tcg_gen_muls2_i64 +#define tcg_gen_mulsu2_tl tcg_gen_mulsu2_i64 #define tcg_gen_atomic_cmpxchg_tl tcg_gen_atomic_cmpxchg_i64 #define tcg_gen_atomic_xchg_tl tcg_gen_atomic_xchg_i64 #define tcg_gen_atomic_fetch_add_tl tcg_gen_atomic_fetch_add_i64 @@ -1043,6 +1046,7 @@ void tcg_gen_atomic_xor_fetch_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp); #define tcg_gen_sub2_tl tcg_gen_sub2_i32 #define tcg_gen_mulu2_tl tcg_gen_mulu2_i32 #define tcg_gen_muls2_tl tcg_gen_muls2_i32 +#define tcg_gen_mulsu2_tl tcg_gen_mulsu2_i32 #define tcg_gen_atomic_cmpxchg_tl tcg_gen_atomic_cmpxchg_i32 #define tcg_gen_atomic_xchg_tl tcg_gen_atomic_xchg_i32 #define tcg_gen_atomic_fetch_add_tl tcg_gen_atomic_fetch_add_i32 @@ -412,10 +412,12 @@ void tcg_prologue_init(TCGContext *s) #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) { + qemu_log_lock(); qemu_log("PROLOGUE: [size=%zu]\n", prologue_size); log_disas(buf0, prologue_size); qemu_log("\n"); qemu_log_flush(); + qemu_log_unlock(); } #endif } @@ -2542,9 +2544,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) #ifdef DEBUG_DISAS if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP) && qemu_log_in_addr_range(tb->pc))) { + qemu_log_lock(); qemu_log("OP:\n"); tcg_dump_ops(s); qemu_log("\n"); + qemu_log_unlock(); } #endif @@ -2570,9 +2574,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) #ifdef DEBUG_DISAS if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_IND) && qemu_log_in_addr_range(tb->pc))) { + qemu_log_lock(); qemu_log("OP before indirect lowering:\n"); tcg_dump_ops(s); qemu_log("\n"); + qemu_log_unlock(); } #endif /* Replace indirect temps with direct temps. */ @@ -2590,9 +2596,11 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) #ifdef DEBUG_DISAS if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT) && qemu_log_in_addr_range(tb->pc))) { + qemu_log_lock(); qemu_log("OP after optimization and liveness analysis:\n"); tcg_dump_ops(s); qemu_log("\n"); + qemu_log_unlock(); } #endif @@ -376,14 +376,36 @@ static inline unsigned get_alignment_bits(TCGMemOp memop) typedef tcg_target_ulong TCGArg; -/* Define a type and accessor macros for variables. Using pointer types - is nice because it gives some level of type safely. Converting to and - from intptr_t rather than int reduces the number of sign-extension - instructions that get implied on 64-bit hosts. Users of tcg_gen_* don't - need to know about any of this, and should treat TCGv as an opaque type. - In addition we do typechecking for different types of variables. TCGv_i32 - and TCGv_i64 are 32/64-bit variables respectively. TCGv and TCGv_ptr - are aliases for target_ulong and host pointer sized values respectively. */ +/* Define type and accessor macros for TCG variables. + + TCG variables are the inputs and outputs of TCG ops, as described + in tcg/README. Target CPU front-end code uses these types to deal + with TCG variables as it emits TCG code via the tcg_gen_* functions. + They come in several flavours: + * TCGv_i32 : 32 bit integer type + * TCGv_i64 : 64 bit integer type + * TCGv_ptr : a host pointer type + * TCGv : an integer type the same size as target_ulong + (an alias for either TCGv_i32 or TCGv_i64) + The compiler's type checking will complain if you mix them + up and pass the wrong sized TCGv to a function. + + Users of tcg_gen_* don't need to know about any of the internal + details of these, and should treat them as opaque types. + You won't be able to look inside them in a debugger either. + + Internal implementation details follow: + + Note that there is no definition of the structs TCGv_i32_d etc anywhere. + This is deliberate, because the values we store in variables of type + TCGv_i32 are not really pointers-to-structures. They're just small + integers, but keeping them in pointer types like this means that the + compiler will complain if you accidentally pass a TCGv_i32 to a + function which takes a TCGv_i64, and so on. Only the internals of + TCG need to care about the actual contents of the types, and they always + box and unbox via the MAKE_TCGV_* and GET_TCGV_* functions. + Converting to and from intptr_t rather than int reduces the number + of sign-extension instructions that get implied on 64-bit hosts. */ typedef struct TCGv_i32_d *TCGv_i32; typedef struct TCGv_i64_d *TCGv_i64; diff --git a/translate-all.c b/translate-all.c index e6a8b07..3dd9214 100644 --- a/translate-all.c +++ b/translate-all.c @@ -1355,10 +1355,12 @@ TranslationBlock *tb_gen_code(CPUState *cpu, #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) && qemu_log_in_addr_range(tb->pc)) { + qemu_log_lock(); qemu_log("OUT: [size=%d]\n", gen_code_size); log_disas(tb->tc_ptr, gen_code_size); qemu_log("\n"); qemu_log_flush(); + qemu_log_unlock(); } #endif |