diff options
46 files changed, 217 insertions, 439 deletions
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index ad1279d2ed..e22bcb99f7 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -38,8 +38,8 @@ #include "exec/cpu-all.h" #include "sysemu/cpu-timers.h" #include "sysemu/replay.h" +#include "exec/helper-proto.h" #include "tb-hash.h" -#include "tb-lookup.h" #include "tb-context.h" #include "internal.h" @@ -145,6 +145,93 @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu) } #endif /* CONFIG USER ONLY */ +/* Might cause an exception, so have a longjmp destination ready */ +static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc, + target_ulong cs_base, + uint32_t flags, uint32_t cflags) +{ + TranslationBlock *tb; + uint32_t hash; + + /* we should never be trying to look up an INVALID tb */ + tcg_debug_assert(!(cflags & CF_INVALID)); + + hash = tb_jmp_cache_hash_func(pc); + tb = qatomic_rcu_read(&cpu->tb_jmp_cache[hash]); + + if (likely(tb && + tb->pc == pc && + tb->cs_base == cs_base && + tb->flags == flags && + tb->trace_vcpu_dstate == *cpu->trace_dstate && + tb_cflags(tb) == cflags)) { + return tb; + } + tb = tb_htable_lookup(cpu, pc, cs_base, flags, cflags); + if (tb == NULL) { + return NULL; + } + qatomic_set(&cpu->tb_jmp_cache[hash], tb); + return tb; +} + +static inline void log_cpu_exec(target_ulong pc, CPUState *cpu, + const TranslationBlock *tb) +{ + if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_CPU | CPU_LOG_EXEC)) + && qemu_log_in_addr_range(pc)) { + + qemu_log_mask(CPU_LOG_EXEC, + "Trace %d: %p [" TARGET_FMT_lx + "/" TARGET_FMT_lx "/%08x/%08x] %s\n", + cpu->cpu_index, tb->tc.ptr, tb->cs_base, pc, + tb->flags, tb->cflags, lookup_symbol(pc)); + +#if defined(DEBUG_DISAS) + if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) { + FILE *logfile = qemu_log_lock(); + int flags = 0; + + if (qemu_loglevel_mask(CPU_LOG_TB_FPU)) { + flags |= CPU_DUMP_FPU; + } +#if defined(TARGET_I386) + flags |= CPU_DUMP_CCOP; +#endif + log_cpu_state(cpu, flags); + qemu_log_unlock(logfile); + } +#endif /* DEBUG_DISAS */ + } +} + +/** + * helper_lookup_tb_ptr: quick check for next tb + * @env: current cpu state + * + * Look for an existing TB matching the current cpu state. + * If found, return the code pointer. If not found, return + * the tcg epilogue so that we return into cpu_tb_exec. + */ +const void *HELPER(lookup_tb_ptr)(CPUArchState *env) +{ + CPUState *cpu = env_cpu(env); + TranslationBlock *tb; + target_ulong cs_base, pc; + uint32_t flags; + + cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); + + tb = tb_lookup(cpu, pc, cs_base, flags, curr_cflags(cpu)); + if (tb == NULL) { + return tcg_code_gen_epilogue; + } + + log_cpu_exec(pc, cpu, tb); + + return tb->tc.ptr; +} + /* Execute a TB, and fix up the CPU state afterwards if necessary */ /* * Disable CFI checks. @@ -163,28 +250,7 @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit) TranslationBlock *last_tb; const void *tb_ptr = itb->tc.ptr; - qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc, - "Trace %d: %p [" - TARGET_FMT_lx "/" TARGET_FMT_lx "/%#x] %s\n", - cpu->cpu_index, itb->tc.ptr, - itb->cs_base, itb->pc, itb->flags, - lookup_symbol(itb->pc)); - -#if defined(DEBUG_DISAS) - if (qemu_loglevel_mask(CPU_LOG_TB_CPU) - && qemu_log_in_addr_range(itb->pc)) { - FILE *logfile = qemu_log_lock(); - int flags = 0; - if (qemu_loglevel_mask(CPU_LOG_TB_FPU)) { - flags |= CPU_DUMP_FPU; - } -#if defined(TARGET_I386) - flags |= CPU_DUMP_CCOP; -#endif - log_cpu_state(cpu, flags); - qemu_log_unlock(logfile); - } -#endif /* DEBUG_DISAS */ + log_cpu_exec(itb->pc, cpu, itb); qemu_thread_jit_execute(); ret = tcg_qemu_tb_exec(env, tb_ptr); diff --git a/accel/tcg/tb-context.h b/accel/tcg/tb-context.h index cc33979113..cac62d9749 100644 --- a/accel/tcg/tb-context.h +++ b/accel/tcg/tb-context.h @@ -34,6 +34,7 @@ struct TBContext { /* statistics */ unsigned tb_flush_count; + unsigned tb_phys_invalidate_count; }; extern TBContext tb_ctx; diff --git a/accel/tcg/tb-lookup.h b/accel/tcg/tb-lookup.h deleted file mode 100644 index 9c9e0079da..0000000000 --- a/accel/tcg/tb-lookup.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2017, Emilio G. Cota <cota@braap.org> - * - * License: GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ -#ifndef EXEC_TB_LOOKUP_H -#define EXEC_TB_LOOKUP_H - -#ifdef NEED_CPU_H -#include "cpu.h" -#else -#include "exec/poison.h" -#endif - -#include "exec/exec-all.h" -#include "tb-hash.h" - -/* Might cause an exception, so have a longjmp destination ready */ -static inline TranslationBlock *tb_lookup(CPUState *cpu, target_ulong pc, - target_ulong cs_base, - uint32_t flags, uint32_t cflags) -{ - TranslationBlock *tb; - uint32_t hash; - - /* we should never be trying to look up an INVALID tb */ - tcg_debug_assert(!(cflags & CF_INVALID)); - - hash = tb_jmp_cache_hash_func(pc); - tb = qatomic_rcu_read(&cpu->tb_jmp_cache[hash]); - - if (likely(tb && - tb->pc == pc && - tb->cs_base == cs_base && - tb->flags == flags && - tb->trace_vcpu_dstate == *cpu->trace_dstate && - tb_cflags(tb) == cflags)) { - return tb; - } - tb = tb_htable_lookup(cpu, pc, cs_base, flags, cflags); - if (tb == NULL) { - return NULL; - } - qatomic_set(&cpu->tb_jmp_cache[hash], tb); - return tb; -} - -#endif /* EXEC_TB_LOOKUP_H */ diff --git a/accel/tcg/tcg-runtime.c b/accel/tcg/tcg-runtime.c index 66ac830e2f..e4e030043f 100644 --- a/accel/tcg/tcg-runtime.c +++ b/accel/tcg/tcg-runtime.c @@ -30,7 +30,6 @@ #include "disas/disas.h" #include "exec/log.h" #include "tcg/tcg.h" -#include "tb-lookup.h" /* 32-bit helpers */ @@ -145,27 +144,6 @@ uint64_t HELPER(ctpop_i64)(uint64_t arg) return ctpop64(arg); } -const void *HELPER(lookup_tb_ptr)(CPUArchState *env) -{ - CPUState *cpu = env_cpu(env); - TranslationBlock *tb; - target_ulong cs_base, pc; - uint32_t flags; - - cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); - - tb = tb_lookup(cpu, pc, cs_base, flags, curr_cflags(cpu)); - if (tb == NULL) { - return tcg_code_gen_epilogue; - } - qemu_log_mask_and_addr(CPU_LOG_EXEC, pc, - "Chain %d: %p [" - TARGET_FMT_lx "/" TARGET_FMT_lx "/%#x] %s\n", - cpu->cpu_index, tb->tc.ptr, cs_base, pc, flags, - lookup_symbol(pc)); - return tb->tc.ptr; -} - void HELPER(exit_atomic)(CPUArchState *env) { cpu_loop_exit_atomic(env_cpu(env), GETPC()); diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 7929a7e320..4df26de858 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -378,11 +378,6 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, return 0; } -void tb_destroy(TranslationBlock *tb) -{ - qemu_spin_destroy(&tb->jmp_lock); -} - bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit) { /* @@ -1224,8 +1219,8 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list) /* suppress any remaining jumps to this TB */ tb_jmp_unlink(tb); - qatomic_set(&tcg_ctx->tb_phys_invalidate_count, - tcg_ctx->tb_phys_invalidate_count + 1); + qatomic_set(&tb_ctx.tb_phys_invalidate_count, + tb_ctx.tb_phys_invalidate_count + 1); } static void tb_phys_invalidate__locked(TranslationBlock *tb) @@ -1657,6 +1652,13 @@ TranslationBlock *tb_gen_code(CPUState *cpu, return tb; } + /* + * Insert TB into the corresponding region tree before publishing it + * through QHT. Otherwise rewinding happened in the TB might fail to + * lookup itself using host PC. + */ + tcg_tb_insert(tb); + /* check next page if needed */ virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK; phys_page2 = -1; @@ -1674,10 +1676,9 @@ TranslationBlock *tb_gen_code(CPUState *cpu, orig_aligned -= ROUND_UP(sizeof(*tb), qemu_icache_linesize); qatomic_set(&tcg_ctx->code_gen_ptr, (void *)orig_aligned); - tb_destroy(tb); + tcg_tb_remove(tb); return existing_tb; } - tcg_tb_insert(tb); return tb; } @@ -2127,8 +2128,8 @@ void dump_exec_info(void) qemu_printf("\nStatistics:\n"); qemu_printf("TB flush count %u\n", qatomic_read(&tb_ctx.tb_flush_count)); - qemu_printf("TB invalidate count %zu\n", - tcg_tb_phys_invalidate_count()); + qemu_printf("TB invalidate count %u\n", + qatomic_read(&tb_ctx.tb_phys_invalidate_count)); tlb_flush_counts(&flush_full, &flush_part, &flush_elide); qemu_printf("TLB full flushes %zu\n", flush_full); diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c index 1d32732198..59804af37b 100644 --- a/accel/tcg/translator.c +++ b/accel/tcg/translator.c @@ -31,6 +31,17 @@ void translator_loop_temp_check(DisasContextBase *db) } } +bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest) +{ + /* Suppress goto_tb in the case of single-steping. */ + if (db->singlestep_enabled || singlestep) { + return false; + } + + /* Check for the dest on the same page as the start of the TB. */ + return ((db->pc_first ^ dest) & TARGET_PAGE_MASK) == 0; +} + void translator_loop(const TranslatorOps *ops, DisasContextBase *db, CPUState *cpu, TranslationBlock *tb, int max_insns) { @@ -38,6 +38,7 @@ #include "exec/translate-all.h" #include "exec/log.h" #include "hw/core/accel-cpu.h" +#include "trace/trace-root.h" uintptr_t qemu_host_page_size; intptr_t qemu_host_page_mask; @@ -285,6 +286,8 @@ int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags, if (breakpoint) { *breakpoint = bp; } + + trace_breakpoint_insert(cpu->cpu_index, pc, flags); return 0; } @@ -303,13 +306,14 @@ int cpu_breakpoint_remove(CPUState *cpu, vaddr pc, int flags) } /* Remove a specific breakpoint by reference. */ -void cpu_breakpoint_remove_by_ref(CPUState *cpu, CPUBreakpoint *breakpoint) +void cpu_breakpoint_remove_by_ref(CPUState *cpu, CPUBreakpoint *bp) { - QTAILQ_REMOVE(&cpu->breakpoints, breakpoint, entry); + QTAILQ_REMOVE(&cpu->breakpoints, bp, entry); - breakpoint_invalidate(cpu, breakpoint->pc); + breakpoint_invalidate(cpu, bp->pc); - g_free(breakpoint); + trace_breakpoint_remove(cpu->cpu_index, bp->pc, bp->flags); + g_free(bp); } /* Remove all matching breakpoints. */ @@ -337,6 +341,7 @@ void cpu_single_step(CPUState *cpu, int enabled) /* XXX: only flush what is necessary */ tb_flush(cpu); } + trace_breakpoint_singlestep(cpu->cpu_index, enabled); } } diff --git a/include/exec/translator.h b/include/exec/translator.h index 24232ead41..dd9c06d40d 100644 --- a/include/exec/translator.h +++ b/include/exec/translator.h @@ -145,6 +145,16 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db, void translator_loop_temp_check(DisasContextBase *db); +/** + * translator_use_goto_tb + * @db: Disassembly context + * @dest: target pc of the goto + * + * Return true if goto_tb is allowed between the current TB + * and the destination PC. + */ +bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest); + /* * Translator Load Functions * diff --git a/include/tcg/tcg-opc.h b/include/tcg/tcg-opc.h index 993992373e..675873e200 100644 --- a/include/tcg/tcg-opc.h +++ b/include/tcg/tcg-opc.h @@ -194,8 +194,7 @@ DEF(insn_start, 0, 0, TLADDR_ARGS * TARGET_INSN_START_WORDS, TCG_OPF_NOT_PRESENT) DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END) DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END) -DEF(goto_ptr, 0, 1, 0, - TCG_OPF_BB_EXIT | TCG_OPF_BB_END | IMPL(TCG_TARGET_HAS_goto_ptr)) +DEF(goto_ptr, 0, 1, 0, TCG_OPF_BB_EXIT | TCG_OPF_BB_END) DEF(plugin_cb_start, 0, 0, 3, TCG_OPF_NOT_PRESENT) DEF(plugin_cb_end, 0, 0, 0, TCG_OPF_NOT_PRESENT) diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index 899493701c..25dd19d6e1 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -579,8 +579,6 @@ struct TCGContext { /* Threshold to flush the translated code buffer. */ void *code_gen_highwater; - size_t tb_phys_invalidate_count; - /* Track which vCPU triggers events */ CPUState *cpu; /* *_trans */ @@ -808,7 +806,6 @@ void *tcg_malloc_internal(TCGContext *s, int size); void tcg_pool_reset(TCGContext *s); TranslationBlock *tcg_tb_alloc(TCGContext *s); -void tb_destroy(TranslationBlock *tb); void tcg_region_reset_all(void); size_t tcg_code_size(void); @@ -816,7 +813,6 @@ size_t tcg_code_capacity(void); void tcg_tb_insert(TranslationBlock *tb); void tcg_tb_remove(TranslationBlock *tb); -size_t tcg_tb_phys_invalidate_count(void); TranslationBlock *tcg_tb_lookup(uintptr_t tc_ptr); void tcg_tb_foreach(GTraverseFunc func, gpointer user_data); size_t tcg_nb_tbs(void); diff --git a/target/alpha/translate.c b/target/alpha/translate.c index f2922f5f8c..833d3baa7b 100644 --- a/target/alpha/translate.c +++ b/target/alpha/translate.c @@ -28,7 +28,6 @@ #include "exec/cpu_ldst.h" #include "exec/helper-proto.h" #include "exec/helper-gen.h" -#include "trace-tcg.h" #include "exec/translator.h" #include "exec/log.h" @@ -439,40 +438,9 @@ static DisasJumpType gen_store_conditional(DisasContext *ctx, int ra, int rb, return DISAS_NEXT; } -static bool in_superpage(DisasContext *ctx, int64_t addr) -{ -#ifndef CONFIG_USER_ONLY - return ((ctx->tbflags & ENV_FLAG_PS_USER) == 0 - && addr >> TARGET_VIRT_ADDR_SPACE_BITS == -1 - && ((addr >> 41) & 3) == 2); -#else - return false; -#endif -} - -static bool use_exit_tb(DisasContext *ctx) -{ - return ((tb_cflags(ctx->base.tb) & CF_LAST_IO) - || ctx->base.singlestep_enabled - || singlestep); -} - static bool use_goto_tb(DisasContext *ctx, uint64_t dest) { - /* Suppress goto_tb in the case of single-steping and IO. */ - if (unlikely(use_exit_tb(ctx))) { - return false; - } -#ifndef CONFIG_USER_ONLY - /* If the destination is in the superpage, the page perms can't change. */ - if (in_superpage(ctx, dest)) { - return true; - } - /* Check for the dest on the same page as the start of the TB. */ - return ((ctx->base.tb->pc ^ dest) & TARGET_PAGE_MASK) == 0; -#else - return true; -#endif + return translator_use_goto_tb(&ctx->base, dest); } static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp) @@ -1271,7 +1239,7 @@ static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode) need the page permissions check. We'll see the existence of the page when we create the TB, and we'll flush all TBs if we change the PAL base register. */ - if (!use_exit_tb(ctx)) { + if (!ctx->base.singlestep_enabled) { tcg_gen_goto_tb(0); tcg_gen_movi_i64(cpu_pc, entry); tcg_gen_exit_tb(ctx->base.tb, 0); @@ -3002,7 +2970,7 @@ static void alpha_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) { DisasContext *ctx = container_of(dcbase, DisasContext, base); CPUAlphaState *env = cpu->env_ptr; - int64_t bound, mask; + int64_t bound; ctx->tbflags = ctx->base.tb->flags; ctx->mem_idx = cpu_mmu_index(env, false); @@ -3031,12 +2999,7 @@ static void alpha_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu) ctx->lit = NULL; /* Bound the number of insns to execute to those left on the page. */ - if (in_superpage(ctx, ctx->base.pc_first)) { - mask = -1ULL << 41; - } else { - mask = TARGET_PAGE_MASK; - } - bound = -(ctx->base.pc_first | mask) / 4; + bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; ctx->base.max_insns = MIN(ctx->base.max_insns, bound); } @@ -3095,7 +3058,7 @@ static void alpha_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next); /* FALLTHRU */ case DISAS_PC_UPDATED: - if (!use_exit_tb(ctx)) { + if (!ctx->base.singlestep_enabled) { tcg_gen_lookup_and_goto_ptr(); break; } diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index e81cc20d04..ca11a5fecd 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -35,7 +35,6 @@ #include "exec/helper-gen.h" #include "exec/log.h" -#include "trace-tcg.h" #include "translate-a64.h" #include "qemu/atomic128.h" @@ -386,35 +385,20 @@ static void gen_step_complete_exception(DisasContext *s) s->base.is_jmp = DISAS_NORETURN; } -static inline bool use_goto_tb(DisasContext *s, int n, uint64_t dest) +static inline bool use_goto_tb(DisasContext *s, uint64_t dest) { - /* No direct tb linking with singlestep (either QEMU's or the ARM - * debug architecture kind) or deterministic io - */ - if (s->base.singlestep_enabled || s->ss_active || - (tb_cflags(s->base.tb) & CF_LAST_IO)) { - return false; - } - -#ifndef CONFIG_USER_ONLY - /* Only link tbs from inside the same guest page */ - if ((s->base.tb->pc & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) { + if (s->ss_active) { return false; } -#endif - - return true; + return translator_use_goto_tb(&s->base, dest); } static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest) { - const TranslationBlock *tb; - - tb = s->base.tb; - if (use_goto_tb(s, n, dest)) { + if (use_goto_tb(s, dest)) { tcg_gen_goto_tb(n); gen_a64_set_pc_im(dest); - tcg_gen_exit_tb(tb, n); + tcg_gen_exit_tb(s->base.tb, n); s->base.is_jmp = DISAS_NORETURN; } else { gen_a64_set_pc_im(dest); diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c index 46210eb696..35d838aa06 100644 --- a/target/arm/translate-sve.c +++ b/target/arm/translate-sve.c @@ -30,7 +30,6 @@ #include "exec/helper-proto.h" #include "exec/helper-gen.h" #include "exec/log.h" -#include "trace-tcg.h" #include "translate-a64.h" #include "fpu/softfloat.h" diff --git a/target/arm/translate.c b/target/arm/translate.c index 28e478927d..e1a8152598 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -34,7 +34,6 @@ #include "exec/helper-proto.h" #include "exec/helper-gen.h" -#include "trace-tcg.h" #include "exec/log.h" @@ -2579,16 +2578,6 @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn) return 1; } -static inline bool use_goto_tb(DisasContext *s, target_ulong dest) -{ -#ifndef CONFIG_USER_ONLY - return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) || - ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); -#else - return true; -#endif -} - static void gen_goto_ptr(void) { tcg_gen_lookup_and_goto_ptr(); @@ -2600,7 +2589,7 @@ static void gen_goto_ptr(void) */ static void gen_goto_tb(DisasContext *s, int n, target_ulong dest) { - if (use_goto_tb(s, dest)) { + if (translator_use_goto_tb(&s->base, dest)) { tcg_gen_goto_tb(n); gen_set_pc_im(s, dest); tcg_gen_exit_tb(s->base.tb, n); @@ -8905,7 +8894,7 @@ static bool trans_ISB(DisasContext *s, arg_ISB *a) * self-modifying code correctly and also to take * any pending interrupts immediately. */ - gen_goto_tb(s, 0, s->base.pc_next); + s->base.is_jmp = DISAS_TOO_MANY; return true; } @@ -8919,7 +8908,7 @@ static bool trans_SB(DisasContext *s, arg_SB *a) * for TCG; MB and end the TB instead. */ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); - gen_goto_tb(s, 0, s->base.pc_next); + s->base.is_jmp = DISAS_TOO_MANY; return true; } diff --git a/target/avr/helper.h b/target/avr/helper.h index 8e1ae7fda0..4d02e648fa 100644 --- a/target/avr/helper.h +++ b/target/avr/helper.h @@ -19,10 +19,10 @@ */ DEF_HELPER_1(wdr, void, env) -DEF_HELPER_1(debug, void, env) -DEF_HELPER_1(break, void, env) -DEF_HELPER_1(sleep, void, env) -DEF_HELPER_1(unsupported, void, env) +DEF_HELPER_1(debug, noreturn, env) +DEF_HELPER_1(break, noreturn, env) +DEF_HELPER_1(sleep, noreturn, env) +DEF_HELPER_1(unsupported, noreturn, env) DEF_HELPER_3(outb, void, env, i32, i32) DEF_HELPER_2(inb, tl, env, i32) DEF_HELPER_3(fullwr, void, env, i32, i32) diff --git a/target/avr/translate.c b/target/avr/translate.c index c06ce45bc7..8237a03c23 100644 --- a/target/avr/translate.c +++ b/target/avr/translate.c @@ -1083,14 +1083,17 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) { const TranslationBlock *tb = ctx->base.tb; - if (!ctx->base.singlestep_enabled) { + if (translator_use_goto_tb(&ctx->base, dest)) { tcg_gen_goto_tb(n); tcg_gen_movi_i32(cpu_pc, dest); tcg_gen_exit_tb(tb, n); } else { tcg_gen_movi_i32(cpu_pc, dest); - gen_helper_debug(cpu_env); - tcg_gen_exit_tb(NULL, 0); + if (ctx->base.singlestep_enabled) { + gen_helper_debug(cpu_env); + } else { + tcg_gen_lookup_and_goto_ptr(); + } } ctx->base.is_jmp = DISAS_NORETURN; } diff --git a/target/cris/translate.c b/target/cris/translate.c index 4cfe5c86d9..9258c13e9f 100644 --- a/target/cris/translate.c +++ b/target/cris/translate.c @@ -37,7 +37,6 @@ #include "exec/helper-gen.h" -#include "trace-tcg.h" #include "exec/log.h" @@ -482,7 +481,7 @@ static void t_gen_swapr(TCGv d, TCGv s) static bool use_goto_tb(DisasContext *dc, target_ulong dest) { - return ((dest ^ dc->base.pc_first) & TARGET_PAGE_MASK) == 0; + return translator_use_goto_tb(&dc->base, dest); } static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) @@ -3235,8 +3234,7 @@ static void cris_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) * Use a conditional branch if either taken or not-taken path * can use goto_tb. If neither can, then treat it as indirect. */ - if (likely(!dc->base.singlestep_enabled) - && likely(!dc->cpustate_changed) + if (likely(!dc->cpustate_changed) && (use_goto_tb(dc, dc->jmp_pc) || use_goto_tb(dc, npc))) { TCGLabel *not_taken = gen_new_label(); diff --git a/target/hppa/translate.c b/target/hppa/translate.c index 64af1e0d5c..835120c038 100644 --- a/target/hppa/translate.c +++ b/target/hppa/translate.c @@ -27,7 +27,6 @@ #include "exec/helper-proto.h" #include "exec/helper-gen.h" #include "exec/translator.h" -#include "trace-tcg.h" #include "exec/log.h" /* Since we have a distinction between register size and address size, @@ -817,10 +816,7 @@ static bool gen_illegal(DisasContext *ctx) static bool use_goto_tb(DisasContext *ctx, target_ureg dest) { - /* Suppress goto_tb for page crossing, IO, or single-steping. */ - return !(((ctx->base.pc_first ^ dest) & TARGET_PAGE_MASK) - || (tb_cflags(ctx->base.tb) & CF_LAST_IO) - || ctx->base.singlestep_enabled); + return translator_use_goto_tb(&ctx->base, dest); } /* If the next insn is to be nullified, and it's on the same page, diff --git a/target/i386/tcg/sysemu/bpt_helper.c b/target/i386/tcg/sysemu/bpt_helper.c index 805118c6b5..624f90b789 100644 --- a/target/i386/tcg/sysemu/bpt_helper.c +++ b/target/i386/tcg/sysemu/bpt_helper.c @@ -210,7 +210,6 @@ void breakpoint_handler(CPUState *cs) { X86CPU *cpu = X86_CPU(cs); CPUX86State *env = &cpu->env; - CPUBreakpoint *bp; if (cs->watchpoint_hit) { if (cs->watchpoint_hit->flags & BP_CPU) { @@ -222,14 +221,9 @@ void breakpoint_handler(CPUState *cs) } } } else { - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { - if (bp->pc == env->eip) { - if (bp->flags & BP_CPU) { - check_hw_breakpoints(env, true); - raise_exception(env, EXCP01_DB); - } - break; - } + if (cpu_breakpoint_test(cs, env->eip, BP_CPU)) { + check_hw_breakpoints(env, true); + raise_exception(env, EXCP01_DB); } } } diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 9e445b9bf0..3814ce2a3e 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -30,7 +30,6 @@ #include "exec/helper-gen.h" #include "helper-tcg.h" -#include "trace-tcg.h" #include "exec/log.h" #define PREFIX_REPZ 0x01 @@ -2315,21 +2314,11 @@ static inline int insn_const_size(MemOp ot) } } -static inline bool use_goto_tb(DisasContext *s, target_ulong pc) -{ -#ifndef CONFIG_USER_ONLY - return (pc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) || - (pc & TARGET_PAGE_MASK) == (s->pc_start & TARGET_PAGE_MASK); -#else - return true; -#endif -} - -static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip) +static void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip) { target_ulong pc = s->cs_base + eip; - if (use_goto_tb(s, pc)) { + if (translator_use_goto_tb(&s->base, pc)) { /* jump to same page: we can use a direct jump */ tcg_gen_goto_tb(tb_num); gen_jmp_im(s, eip); diff --git a/target/m68k/translate.c b/target/m68k/translate.c index f0c5bf9154..1fee04b8dd 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -31,7 +31,6 @@ #include "exec/helper-proto.h" #include "exec/helper-gen.h" -#include "trace-tcg.h" #include "exec/log.h" #include "fpu/softfloat.h" @@ -1520,16 +1519,6 @@ static void gen_exit_tb(DisasContext *s) } \ } while (0) -static inline bool use_goto_tb(DisasContext *s, uint32_t dest) -{ -#ifndef CONFIG_USER_ONLY - return (s->base.pc_first & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) - || (s->base.pc_next & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); -#else - return true; -#endif -} - /* Generate a jump to an immediate address. */ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest) { @@ -1537,7 +1526,7 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest) update_cc_op(s); tcg_gen_movi_i32(QREG_PC, dest); gen_singlestep_exception(s); - } else if (use_goto_tb(s, dest)) { + } else if (translator_use_goto_tb(&s->base, dest)) { tcg_gen_goto_tb(n); tcg_gen_movi_i32(QREG_PC, dest); tcg_gen_exit_tb(s->base.tb, n); diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c index c1b13f4c7d..c68a84a219 100644 --- a/target/microblaze/translate.c +++ b/target/microblaze/translate.c @@ -29,7 +29,6 @@ #include "exec/translator.h" #include "qemu/qemu-print.h" -#include "trace-tcg.h" #include "exec/log.h" #define EXTRACT_FIELD(src, start, end) \ @@ -125,15 +124,6 @@ static void gen_raise_hw_excp(DisasContext *dc, uint32_t esr_ec) gen_raise_exception_sync(dc, EXCP_HW_EXCP); } -static inline bool use_goto_tb(DisasContext *dc, target_ulong dest) -{ -#ifndef CONFIG_USER_ONLY - return (dc->base.pc_first & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); -#else - return true; -#endif -} - static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) { if (dc->base.singlestep_enabled) { @@ -141,7 +131,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) tcg_gen_movi_i32(cpu_pc, dest); gen_helper_raise_exception(cpu_env, tmp); tcg_temp_free_i32(tmp); - } else if (use_goto_tb(dc, dest)) { + } else if (translator_use_goto_tb(&dc->base, dest)) { tcg_gen_goto_tb(n); tcg_gen_movi_i32(cpu_pc, dest); tcg_gen_exit_tb(dc->base.tb, n); diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index ae33c75f08..47c967acbf 100644 --- a/target/mips/tcg/translate.c +++ b/target/mips/tcg/translate.c @@ -32,7 +32,6 @@ #include "semihosting/semihost.h" #include "trace.h" -#include "trace-tcg.h" #include "exec/translator.h" #include "exec/log.h" #include "qemu/qemu-print.h" @@ -4948,22 +4947,9 @@ static void gen_trap(DisasContext *ctx, uint32_t opc, tcg_temp_free(t1); } -static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) +static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) { - if (unlikely(ctx->base.singlestep_enabled)) { - return false; - } - -#ifndef CONFIG_USER_ONLY - return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); -#else - return true; -#endif -} - -static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) -{ - if (use_goto_tb(ctx, dest)) { + if (translator_use_goto_tb(&ctx->base, dest)) { tcg_gen_goto_tb(n); gen_save_pc(dest); tcg_gen_exit_tb(ctx->base.tb, n); @@ -4972,8 +4958,9 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) if (ctx->base.singlestep_enabled) { save_cpu_state(ctx, 0); gen_helper_raise_exception_debug(cpu_env); + } else { + tcg_gen_lookup_and_goto_ptr(); } - tcg_gen_lookup_and_goto_ptr(); } } diff --git a/target/nios2/translate.c b/target/nios2/translate.c index 930f3d3395..17742cebc7 100644 --- a/target/nios2/translate.c +++ b/target/nios2/translate.c @@ -150,24 +150,11 @@ static void t_gen_helper_raise_exception(DisasContext *dc, dc->base.is_jmp = DISAS_NORETURN; } -static bool use_goto_tb(DisasContext *dc, uint32_t dest) -{ - if (unlikely(dc->base.singlestep_enabled)) { - return false; - } - -#ifndef CONFIG_USER_ONLY - return (dc->base.pc_first & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); -#else - return true; -#endif -} - static void gen_goto_tb(DisasContext *dc, int n, uint32_t dest) { const TranslationBlock *tb = dc->base.tb; - if (use_goto_tb(dc, dest)) { + if (translator_use_goto_tb(&dc->base, dest)) { tcg_gen_goto_tb(n); tcg_gen_movi_tl(cpu_R[R_PC], dest); tcg_gen_exit_tb(tb, n); diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c index a9c81f8bd5..37c3e3e0a3 100644 --- a/target/openrisc/translate.c +++ b/target/openrisc/translate.c @@ -33,7 +33,6 @@ #include "exec/helper-gen.h" #include "exec/gen-icount.h" -#include "trace-tcg.h" #include "exec/log.h" /* is_jmp field values */ @@ -1720,16 +1719,17 @@ static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) /* fallthru */ case DISAS_TOO_MANY: - if (unlikely(dc->base.singlestep_enabled)) { - tcg_gen_movi_tl(cpu_pc, jmp_dest); - gen_exception(dc, EXCP_DEBUG); - } else if ((dc->base.pc_first ^ jmp_dest) & TARGET_PAGE_MASK) { - tcg_gen_movi_tl(cpu_pc, jmp_dest); - tcg_gen_lookup_and_goto_ptr(); - } else { + if (translator_use_goto_tb(&dc->base, jmp_dest)) { tcg_gen_goto_tb(0); tcg_gen_movi_tl(cpu_pc, jmp_dest); tcg_gen_exit_tb(dc->base.tb, 0); + break; + } + tcg_gen_movi_tl(cpu_pc, jmp_dest); + if (unlikely(dc->base.singlestep_enabled)) { + gen_exception(dc, EXCP_DEBUG); + } else { + tcg_gen_lookup_and_goto_ptr(); } break; diff --git a/target/ppc/translate.c b/target/ppc/translate.c index d1f482b0f3..0a55cb7181 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -32,7 +32,6 @@ #include "exec/helper-proto.h" #include "exec/helper-gen.h" -#include "trace-tcg.h" #include "exec/translator.h" #include "exec/log.h" #include "qemu/atomic128.h" @@ -4302,15 +4301,7 @@ static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip) static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) { - if (unlikely(ctx->singlestep_enabled)) { - return false; - } - -#ifndef CONFIG_USER_ONLY - return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); -#else - return true; -#endif + return translator_use_goto_tb(&ctx->base, dest); } static void gen_lookup_and_goto_ptr(DisasContext *ctx) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 62a7d7e4c7..deda0c8a44 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -168,29 +168,11 @@ static void gen_exception_inst_addr_mis(DisasContext *ctx) generate_exception_mtval(ctx, RISCV_EXCP_INST_ADDR_MIS); } -static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) -{ - if (unlikely(ctx->base.singlestep_enabled)) { - return false; - } - -#ifndef CONFIG_USER_ONLY - return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); -#else - return true; -#endif -} - static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) { - if (use_goto_tb(ctx, dest)) { - /* chaining is only allowed when the jump is to the same page */ + if (translator_use_goto_tb(&ctx->base, dest)) { tcg_gen_goto_tb(n); tcg_gen_movi_tl(cpu_pc, dest); - - /* No need to check for single stepping here as use_goto_tb() will - * return false in case of single stepping. - */ tcg_gen_exit_tb(ctx->base.tb, n); } else { tcg_gen_movi_tl(cpu_pc, dest); diff --git a/target/rx/translate.c b/target/rx/translate.c index 9ea941c630..23a626438a 100644 --- a/target/rx/translate.c +++ b/target/rx/translate.c @@ -26,7 +26,6 @@ #include "exec/helper-proto.h" #include "exec/helper-gen.h" #include "exec/translator.h" -#include "trace-tcg.h" #include "exec/log.h" typedef struct DisasContext { @@ -143,18 +142,9 @@ void rx_cpu_dump_state(CPUState *cs, FILE *f, int flags) } } -static bool use_goto_tb(DisasContext *dc, target_ulong dest) -{ - if (unlikely(dc->base.singlestep_enabled)) { - return false; - } else { - return true; - } -} - static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) { - if (use_goto_tb(dc, dest)) { + if (translator_use_goto_tb(&dc->base, dest)) { tcg_gen_goto_tb(n); tcg_gen_movi_i32(cpu_pc, dest); tcg_gen_exit_tb(dc->base.tb, n); diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 8822603a6e..c8d55d1f83 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -42,7 +42,6 @@ #include "exec/helper-proto.h" #include "exec/helper-gen.h" -#include "trace-tcg.h" #include "exec/translator.h" #include "exec/log.h" #include "qemu/atomic128.h" @@ -685,24 +684,12 @@ static void gen_op_calc_cc(DisasContext *s) set_cc_static(s); } -static bool use_exit_tb(DisasContext *s) -{ - return s->base.singlestep_enabled || - (tb_cflags(s->base.tb) & CF_LAST_IO) || - (s->base.tb->flags & FLAG_MASK_PER); -} - static bool use_goto_tb(DisasContext *s, uint64_t dest) { - if (unlikely(use_exit_tb(s))) { + if (unlikely(s->base.tb->flags & FLAG_MASK_PER)) { return false; } -#ifndef CONFIG_USER_ONLY - return (dest & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) || - (dest & TARGET_PAGE_MASK) == (s->base.pc_next & TARGET_PAGE_MASK); -#else - return true; -#endif + return translator_use_goto_tb(&s->base, dest); } static void account_noninline_branch(DisasContext *s, int cc_op) @@ -6641,7 +6628,7 @@ static void s390x_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) /* Exit the TB, either by raising a debug exception or by return. */ if (dc->do_debug) { gen_exception(EXCP_DEBUG); - } else if (use_exit_tb(dc) || + } else if ((dc->base.tb->flags & FLAG_MASK_PER) || dc->base.is_jmp == DISAS_PC_STALE_NOCHAIN) { tcg_gen_exit_tb(NULL, 0); } else { diff --git a/target/sh4/translate.c b/target/sh4/translate.c index 4dcfff81f6..40898e2393 100644 --- a/target/sh4/translate.c +++ b/target/sh4/translate.c @@ -28,7 +28,6 @@ #include "exec/helper-proto.h" #include "exec/helper-gen.h" #include "exec/translator.h" -#include "trace-tcg.h" #include "exec/log.h" #include "qemu/qemu-print.h" @@ -225,17 +224,12 @@ static inline bool use_exit_tb(DisasContext *ctx) return (ctx->tbflags & GUSA_EXCLUSIVE) != 0; } -static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) +static bool use_goto_tb(DisasContext *ctx, target_ulong dest) { - /* Use a direct jump if in same page and singlestep not enabled */ - if (unlikely(ctx->base.singlestep_enabled || use_exit_tb(ctx))) { + if (use_exit_tb(ctx)) { return false; } -#ifndef CONFIG_USER_ONLY - return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); -#else - return true; -#endif + return translator_use_goto_tb(&ctx->base, dest); } static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 4bfa3179f8..e530cb4aa8 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -29,7 +29,6 @@ #include "exec/helper-gen.h" -#include "trace-tcg.h" #include "exec/translator.h" #include "exec/log.h" #include "asi.h" @@ -339,23 +338,14 @@ static inline TCGv gen_dest_gpr(DisasContext *dc, int reg) } } -static inline bool use_goto_tb(DisasContext *s, target_ulong pc, - target_ulong npc) +static bool use_goto_tb(DisasContext *s, target_ulong pc, target_ulong npc) { - if (unlikely(s->base.singlestep_enabled || singlestep)) { - return false; - } - -#ifndef CONFIG_USER_ONLY - return (pc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) && - (npc & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK); -#else - return true; -#endif + return translator_use_goto_tb(&s->base, pc) && + translator_use_goto_tb(&s->base, npc); } -static inline void gen_goto_tb(DisasContext *s, int tb_num, - target_ulong pc, target_ulong npc) +static void gen_goto_tb(DisasContext *s, int tb_num, + target_ulong pc, target_ulong npc) { if (use_goto_tb(s, pc, npc)) { /* jump to same page: we can use a direct jump */ diff --git a/target/tricore/translate.c b/target/tricore/translate.c index 2a814263de..865020754d 100644 --- a/target/tricore/translate.c +++ b/target/tricore/translate.c @@ -3225,19 +3225,6 @@ static inline void gen_save_pc(target_ulong pc) tcg_gen_movi_tl(cpu_PC, pc); } -static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest) -{ - if (unlikely(ctx->base.singlestep_enabled)) { - return false; - } - -#ifndef CONFIG_USER_ONLY - return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK); -#else - return true; -#endif -} - static void generate_qemu_excp(DisasContext *ctx, int excp) { TCGv_i32 tmp = tcg_const_i32(excp); @@ -3246,9 +3233,9 @@ static void generate_qemu_excp(DisasContext *ctx, int excp) tcg_temp_free(tmp); } -static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) +static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) { - if (use_goto_tb(ctx, dest)) { + if (translator_use_goto_tb(&ctx->base, dest)) { tcg_gen_goto_tb(n); gen_save_pc(dest); tcg_gen_exit_tb(ctx->base.tb, n); @@ -3256,8 +3243,9 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) gen_save_pc(dest); if (ctx->base.singlestep_enabled) { generate_qemu_excp(ctx, EXCP_DEBUG); + } else { + tcg_gen_lookup_and_goto_ptr(); } - tcg_gen_exit_tb(NULL, 0); } } diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index 14028d307d..7094cfcf1d 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -43,7 +43,6 @@ #include "exec/helper-proto.h" #include "exec/helper-gen.h" -#include "trace-tcg.h" #include "exec/log.h" @@ -406,11 +405,7 @@ static void gen_jump(DisasContext *dc, TCGv dest) static int adjust_jump_slot(DisasContext *dc, uint32_t dest, int slot) { - if (((dc->base.pc_first ^ dest) & TARGET_PAGE_MASK) != 0) { - return -1; - } else { - return slot; - } + return translator_use_goto_tb(&dc->base, dest) ? slot : -1; } static void gen_jumpi(DisasContext *dc, uint32_t dest, int slot) diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h index 551baf8da3..7a93ac8023 100644 --- a/tcg/aarch64/tcg-target.h +++ b/tcg/aarch64/tcg-target.h @@ -88,7 +88,6 @@ typedef enum { #define TCG_TARGET_HAS_mulsh_i32 0 #define TCG_TARGET_HAS_extrl_i64_i32 0 #define TCG_TARGET_HAS_extrh_i64_i32 0 -#define TCG_TARGET_HAS_goto_ptr 1 #define TCG_TARGET_HAS_qemu_st8_i32 0 #define TCG_TARGET_HAS_div_i64 1 diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h index 95fcef33bc..d113b7f8db 100644 --- a/tcg/arm/tcg-target.h +++ b/tcg/arm/tcg-target.h @@ -148,7 +148,6 @@ extern bool use_neon_instructions; #define TCG_TARGET_HAS_mulsh_i32 0 #define TCG_TARGET_HAS_div_i32 use_idiv_instructions #define TCG_TARGET_HAS_rem_i32 0 -#define TCG_TARGET_HAS_goto_ptr 1 #define TCG_TARGET_HAS_direct_jump 0 #define TCG_TARGET_HAS_qemu_st8_i32 0 diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h index ac10066c3e..b00a6da293 100644 --- a/tcg/i386/tcg-target.h +++ b/tcg/i386/tcg-target.h @@ -135,7 +135,6 @@ extern bool have_movbe; #define TCG_TARGET_HAS_muls2_i32 1 #define TCG_TARGET_HAS_muluh_i32 0 #define TCG_TARGET_HAS_mulsh_i32 0 -#define TCG_TARGET_HAS_goto_ptr 1 #define TCG_TARGET_HAS_direct_jump 1 #if TCG_TARGET_REG_BITS == 64 diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h index e81e824cab..3a62055f04 100644 --- a/tcg/mips/tcg-target.h +++ b/tcg/mips/tcg-target.h @@ -136,7 +136,6 @@ extern bool use_mips32r2_instructions; #define TCG_TARGET_HAS_muluh_i32 1 #define TCG_TARGET_HAS_mulsh_i32 1 #define TCG_TARGET_HAS_bswap32_i32 1 -#define TCG_TARGET_HAS_goto_ptr 1 #define TCG_TARGET_HAS_direct_jump 1 #if TCG_TARGET_REG_BITS == 64 diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h index c13ed5640a..0943192cde 100644 --- a/tcg/ppc/tcg-target.h +++ b/tcg/ppc/tcg-target.h @@ -108,7 +108,6 @@ extern bool have_vsx; #define TCG_TARGET_HAS_muls2_i32 0 #define TCG_TARGET_HAS_muluh_i32 1 #define TCG_TARGET_HAS_mulsh_i32 1 -#define TCG_TARGET_HAS_goto_ptr 1 #define TCG_TARGET_HAS_direct_jump 1 #define TCG_TARGET_HAS_qemu_st8_i32 0 diff --git a/tcg/region.c b/tcg/region.c index 00b0c3b091..e64c3ea230 100644 --- a/tcg/region.c +++ b/tcg/region.c @@ -112,7 +112,7 @@ static int ptr_cmp_tb_tc(const void *ptr, const struct tb_tc *s) return 0; } -static gint tb_tc_cmp(gconstpointer ap, gconstpointer bp) +static gint tb_tc_cmp(gconstpointer ap, gconstpointer bp, gpointer userdata) { const struct tb_tc *a = ap; const struct tb_tc *b = bp; @@ -143,6 +143,12 @@ static gint tb_tc_cmp(gconstpointer ap, gconstpointer bp) return ptr_cmp_tb_tc(b->ptr, a); } +static void tb_destroy(gpointer value) +{ + TranslationBlock *tb = value; + qemu_spin_destroy(&tb->jmp_lock); +} + static void tcg_region_trees_init(void) { size_t i; @@ -153,7 +159,7 @@ static void tcg_region_trees_init(void) struct tcg_region_tree *rt = region_trees + i * tree_size; qemu_mutex_init(&rt->lock); - rt->tree = g_tree_new(tb_tc_cmp); + rt->tree = g_tree_new_full(tb_tc_cmp, NULL, NULL, tb_destroy); } } @@ -277,14 +283,6 @@ size_t tcg_nb_tbs(void) return nb_tbs; } -static gboolean tcg_region_tree_traverse(gpointer k, gpointer v, gpointer data) -{ - TranslationBlock *tb = v; - - tb_destroy(tb); - return FALSE; -} - static void tcg_region_tree_reset_all(void) { size_t i; @@ -293,7 +291,6 @@ static void tcg_region_tree_reset_all(void) for (i = 0; i < region.n; i++) { struct tcg_region_tree *rt = region_trees + i * tree_size; - g_tree_foreach(rt->tree, tcg_region_tree_traverse, NULL); /* Increment the refcount first so that destroy acts as a reset */ g_tree_ref(rt->tree); g_tree_destroy(rt->tree); @@ -983,17 +980,3 @@ size_t tcg_code_capacity(void) return capacity; } - -size_t tcg_tb_phys_invalidate_count(void) -{ - unsigned int n_ctxs = qatomic_read(&tcg_cur_ctxs); - unsigned int i; - size_t total = 0; - - for (i = 0; i < n_ctxs; i++) { - const TCGContext *s = qatomic_read(&tcg_ctxs[i]); - - total += qatomic_read(&s->tb_phys_invalidate_count); - } - return total; -} diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h index 87ea94666b..ef78b99e98 100644 --- a/tcg/riscv/tcg-target.h +++ b/tcg/riscv/tcg-target.h @@ -85,7 +85,6 @@ typedef enum { #define TCG_TARGET_CALL_STACK_OFFSET 0 /* optional instructions */ -#define TCG_TARGET_HAS_goto_ptr 1 #define TCG_TARGET_HAS_movcond_i32 0 #define TCG_TARGET_HAS_div_i32 1 #define TCG_TARGET_HAS_rem_i32 1 diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h index b04b72b7eb..2e4ede2ea2 100644 --- a/tcg/s390/tcg-target.h +++ b/tcg/s390/tcg-target.h @@ -98,7 +98,6 @@ extern uint64_t s390_facilities; #define TCG_TARGET_HAS_mulsh_i32 0 #define TCG_TARGET_HAS_extrl_i64_i32 0 #define TCG_TARGET_HAS_extrh_i64_i32 0 -#define TCG_TARGET_HAS_goto_ptr 1 #define TCG_TARGET_HAS_direct_jump (s390_facilities & FACILITY_GEN_INST_EXT) #define TCG_TARGET_HAS_qemu_st8_i32 0 diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h index 86bb9a2d39..c050763049 100644 --- a/tcg/sparc/tcg-target.h +++ b/tcg/sparc/tcg-target.h @@ -121,7 +121,6 @@ extern bool use_vis3_instructions; #define TCG_TARGET_HAS_muls2_i32 1 #define TCG_TARGET_HAS_muluh_i32 0 #define TCG_TARGET_HAS_mulsh_i32 0 -#define TCG_TARGET_HAS_goto_ptr 1 #define TCG_TARGET_HAS_direct_jump 1 #define TCG_TARGET_HAS_qemu_st8_i32 0 diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index 58a34b5147..0c561fb253 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -2754,7 +2754,7 @@ void tcg_gen_goto_tb(unsigned idx) void tcg_gen_lookup_and_goto_ptr(void) { - if (TCG_TARGET_HAS_goto_ptr && !qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) { + if (!qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) { TCGv_ptr ptr; plugin_gen_disable_mem_helpers(); @@ -752,8 +752,6 @@ void tcg_prologue_init(TCGContext *s) (uintptr_t)s->code_buf, prologue_size); #endif - tcg_region_prologue_set(s); - #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) { FILE *logfile = qemu_log_lock(); @@ -791,10 +789,10 @@ void tcg_prologue_init(TCGContext *s) * For tci, we use NULL as the signal to return from the interpreter, * so skip this check. */ - if (TCG_TARGET_HAS_goto_ptr) { - tcg_debug_assert(tcg_code_gen_epilogue != NULL); - } + tcg_debug_assert(tcg_code_gen_epilogue != NULL); #endif + + tcg_region_prologue_set(s); } void tcg_func_start(TCGContext *s) @@ -1176,6 +1174,7 @@ bool tcg_op_supported(TCGOpcode op) case INDEX_op_insn_start: case INDEX_op_exit_tb: case INDEX_op_goto_tb: + case INDEX_op_goto_ptr: case INDEX_op_qemu_ld_i32: case INDEX_op_qemu_st_i32: case INDEX_op_qemu_ld_i64: @@ -1185,9 +1184,6 @@ bool tcg_op_supported(TCGOpcode op) case INDEX_op_qemu_st8_i32: return TCG_TARGET_HAS_qemu_st8_i32; - case INDEX_op_goto_ptr: - return TCG_TARGET_HAS_goto_ptr; - case INDEX_op_mov_i32: case INDEX_op_setcond_i32: case INDEX_op_brcond_i32: @@ -1849,7 +1845,7 @@ static void tcg_dump_ops(TCGContext *s, bool have_prefs) col += qemu_log("plugin(%p)", func); } - col += qemu_log("$0x%x,$%d", info->flags, nb_oargs); + col += qemu_log(",$0x%x,$%d", info->flags, nb_oargs); for (i = 0; i < nb_oargs; i++) { col += qemu_log(",%s", tcg_get_arg_str(s, buf, sizeof(buf), op->args[i])); diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h index 7b6089f304..033e613f24 100644 --- a/tcg/tci/tcg-target.h +++ b/tcg/tci/tcg-target.h @@ -87,7 +87,6 @@ #define TCG_TARGET_HAS_muls2_i32 1 #define TCG_TARGET_HAS_muluh_i32 0 #define TCG_TARGET_HAS_mulsh_i32 0 -#define TCG_TARGET_HAS_goto_ptr 1 #define TCG_TARGET_HAS_direct_jump 0 #define TCG_TARGET_HAS_qemu_st8_i32 0 diff --git a/trace-events b/trace-events index 765fe251e6..c4cca29939 100644 --- a/trace-events +++ b/trace-events @@ -25,6 +25,11 @@ # # The <format-string> should be a sprintf()-compatible format string. +# cpu.c +breakpoint_insert(int cpu_index, uint64_t pc, int flags) "cpu=%d pc=0x%" PRIx64 " flags=0x%x" +breakpoint_remove(int cpu_index, uint64_t pc, int flags) "cpu=%d pc=0x%" PRIx64 " flags=0x%x" +breakpoint_singlestep(int cpu_index, int enabled) "cpu=%d enable=%d" + # dma-helpers.c dma_blk_io(void *dbs, void *bs, int64_t offset, bool to_dev) "dbs=%p bs=%p offset=%" PRId64 " to_dev=%d" dma_aio_cancel(void *dbs) "dbs=%p" |