From: Sergey Fedorov <serge.fdrv@gmail.com>
To: Richard Henderson <rth@twiddle.net>, qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org
Subject: Re: [Qemu-devel] [PULL 04/26] target-*: Introduce and use cpu_breakpoint_test
Date: Fri, 9 Oct 2015 16:34:10 +0300 [thread overview]
Message-ID: <5617C252.6070104@gmail.com> (raw)
In-Reply-To: <1444211031-11624-5-git-send-email-rth@twiddle.net>
On 07.10.2015 12:43, Richard Henderson wrote:
> Reduce the boilerplate required for each target. At the same time,
> move the test for breakpoint after calling tcg_gen_insn_start.
>
> Note that arm and aarch64 do not use cpu_breakpoint_test, but still
> move the inline test down after tcg_gen_insn_start.
>
> Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
> include/qom/cpu.h | 16 ++++++++++++++++
> target-alpha/translate.c | 13 ++++---------
> target-arm/translate-a64.c | 26 +++++++++++++-------------
> target-arm/translate.c | 31 ++++++++++++++++---------------
> target-cris/translate.c | 27 ++++++++-------------------
> target-i386/translate.c | 17 +++++++----------
> target-lm32/translate.c | 25 +++++++------------------
> target-m68k/translate.c | 18 ++++++------------
> target-microblaze/translate.c | 36 +++++++++++++-----------------------
> target-mips/translate.c | 25 ++++++++++---------------
> target-moxie/translate.c | 19 +++++++------------
> target-openrisc/translate.c | 24 +++++++-----------------
> target-ppc/translate.c | 14 +++++---------
> target-s390x/translate.c | 16 ++++++----------
> target-sh4/translate.c | 20 ++++++++------------
> target-sparc/translate.c | 23 ++++++++++-------------
> target-unicore32/translate.c | 24 ++++++++++--------------
> target-xtensa/translate.c | 25 +++++++------------------
> 18 files changed, 160 insertions(+), 239 deletions(-)
>
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 9405554..b613ff0 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -721,6 +721,7 @@ void cpu_single_step(CPUState *cpu, int enabled);
> /* 0x08 currently unused */
> #define BP_GDB 0x10
> #define BP_CPU 0x20
> +#define BP_ANY (BP_GDB | BP_CPU)
> #define BP_WATCHPOINT_HIT_READ 0x40
> #define BP_WATCHPOINT_HIT_WRITE 0x80
> #define BP_WATCHPOINT_HIT (BP_WATCHPOINT_HIT_READ | BP_WATCHPOINT_HIT_WRITE)
> @@ -731,6 +732,21 @@ int cpu_breakpoint_remove(CPUState *cpu, vaddr pc, int flags);
> void cpu_breakpoint_remove_by_ref(CPUState *cpu, CPUBreakpoint *breakpoint);
> void cpu_breakpoint_remove_all(CPUState *cpu, int mask);
>
> +/* Return true if PC matches an installed breakpoint. */
> +static inline bool cpu_breakpoint_test(CPUState *cpu, vaddr pc, int mask)
> +{
> + CPUBreakpoint *bp;
> +
> + if (unlikely(!QTAILQ_EMPTY(&cpu->breakpoints))) {
> + QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
> + if (bp->pc == pc && (bp->flags & mask)) {
> + return true;
> + }
> + }
> + }
> + return false;
> +}
> +
> int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
> int flags, CPUWatchpoint **watchpoint);
> int cpu_watchpoint_remove(CPUState *cpu, vaddr addr,
> diff --git a/target-alpha/translate.c b/target-alpha/translate.c
> index fa0ac2d..c10193e 100644
> --- a/target-alpha/translate.c
> +++ b/target-alpha/translate.c
> @@ -2868,7 +2868,6 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
> target_ulong pc_start;
> target_ulong pc_mask;
> uint32_t insn;
> - CPUBreakpoint *bp;
> int j, lj = -1;
> ExitStatus ret;
> int num_insns;
> @@ -2913,14 +2912,6 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
>
> gen_tb_start(tb);
> do {
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (bp->pc == ctx.pc) {
> - gen_excp(&ctx, EXCP_DEBUG, 0);
> - break;
> - }
> - }
> - }
> if (search_pc) {
> j = tcg_op_buf_count();
> if (lj < j) {
> @@ -2936,6 +2927,10 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
> tcg_gen_insn_start(ctx.pc);
> num_insns++;
>
> + if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
> + gen_excp(&ctx, EXCP_DEBUG, 0);
> + break;
> + }
Actually, control logic has changed here. The old code used a break
statement to exit from QTAILQ_FOREACH loop and continue with instruction
translation thus translating at least one instruction. The break
statement in the new code makes exit from the translation loop itself,
effectively producing zero-length TB which won't get invalidated when
clearing the breakpoint. Seems like we should remove the break statement
here and in similar cases below, right?
Best regards,
Sergey
> if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
> gen_io_start();
> }
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index 4670941..bc2040e 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -11007,7 +11007,6 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
> CPUState *cs = CPU(cpu);
> CPUARMState *env = &cpu->env;
> DisasContext dc1, *dc = &dc1;
> - CPUBreakpoint *bp;
> int j, lj;
> target_ulong pc_start;
> target_ulong next_page_start;
> @@ -11079,18 +11078,6 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
> tcg_clear_temp_count();
>
> do {
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (bp->pc == dc->pc) {
> - gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
> - /* Advance PC so that clearing the breakpoint will
> - invalidate this TB. */
> - dc->pc += 2;
> - goto done_generating;
> - }
> - }
> - }
> -
> if (search_pc) {
> j = tcg_op_buf_count();
> if (lj < j) {
> @@ -11106,6 +11093,19 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
> tcg_gen_insn_start(dc->pc);
> num_insns++;
>
> + if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> + CPUBreakpoint *bp;
> + QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> + if (bp->pc == dc->pc) {
> + gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
> + /* Advance PC so that clearing the breakpoint will
> + invalidate this TB. */
> + dc->pc += 2;
> + goto done_generating;
> + }
> + }
> + }
> +
> if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
> gen_io_start();
> }
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index cd88997..44468dc 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -11177,7 +11177,6 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
> CPUState *cs = CPU(cpu);
> CPUARMState *env = &cpu->env;
> DisasContext dc1, *dc = &dc1;
> - CPUBreakpoint *bp;
> int j, lj;
> target_ulong pc_start;
> target_ulong next_page_start;
> @@ -11306,6 +11305,21 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
> store_cpu_field(tmp, condexec_bits);
> }
> do {
> + if (search_pc) {
> + j = tcg_op_buf_count();
> + if (lj < j) {
> + lj++;
> + while (lj < j)
> + tcg_ctx.gen_opc_instr_start[lj++] = 0;
> + }
> + tcg_ctx.gen_opc_pc[lj] = dc->pc;
> + gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
> + tcg_ctx.gen_opc_instr_start[lj] = 1;
> + tcg_ctx.gen_opc_icount[lj] = num_insns;
> + }
> + tcg_gen_insn_start(dc->pc);
> + num_insns++;
> +
> #ifdef CONFIG_USER_ONLY
> /* Intercept jump to the magic kernel page. */
> if (dc->pc >= 0xffff0000) {
> @@ -11326,6 +11340,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
> #endif
>
> if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> + CPUBreakpoint *bp;
> QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> if (bp->pc == dc->pc) {
> gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
> @@ -11336,20 +11351,6 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
> }
> }
> }
> - if (search_pc) {
> - j = tcg_op_buf_count();
> - if (lj < j) {
> - lj++;
> - while (lj < j)
> - tcg_ctx.gen_opc_instr_start[lj++] = 0;
> - }
> - tcg_ctx.gen_opc_pc[lj] = dc->pc;
> - gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
> - tcg_ctx.gen_opc_instr_start[lj] = 1;
> - tcg_ctx.gen_opc_icount[lj] = num_insns;
> - }
> - tcg_gen_insn_start(dc->pc);
> - num_insns++;
>
> if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
> gen_io_start();
> diff --git a/target-cris/translate.c b/target-cris/translate.c
> index bba7217..477bddc 100644
> --- a/target-cris/translate.c
> +++ b/target-cris/translate.c
> @@ -3030,23 +3030,6 @@ static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
> return insn_len;
> }
>
> -static void check_breakpoint(CPUCRISState *env, DisasContext *dc)
> -{
> - CPUState *cs = CPU(cris_env_get_cpu(env));
> - CPUBreakpoint *bp;
> -
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (bp->pc == dc->pc) {
> - cris_evaluate_flags(dc);
> - tcg_gen_movi_tl(env_pc, dc->pc);
> - t_gen_raise_exception(EXCP_DEBUG);
> - dc->is_jmp = DISAS_UPDATE;
> - }
> - }
> - }
> -}
> -
> #include "translate_v10.c"
>
> /*
> @@ -3175,8 +3158,6 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
>
> gen_tb_start(tb);
> do {
> - check_breakpoint(env, dc);
> -
> if (search_pc) {
> j = tcg_op_buf_count();
> if (lj < j) {
> @@ -3196,6 +3177,14 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
> tcg_gen_insn_start(dc->pc);
> num_insns++;
>
> + if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
> + cris_evaluate_flags(dc);
> + tcg_gen_movi_tl(env_pc, dc->pc);
> + t_gen_raise_exception(EXCP_DEBUG);
> + dc->is_jmp = DISAS_UPDATE;
> + break;
> + }
> +
> /* Pretty disas. */
> LOG_DIS("%8.8x:\t", dc->pc);
>
> diff --git a/target-i386/translate.c b/target-i386/translate.c
> index 3d0c23d..9ec9c4c 100644
> --- a/target-i386/translate.c
> +++ b/target-i386/translate.c
> @@ -7849,7 +7849,6 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
> CPUX86State *env = &cpu->env;
> DisasContext dc1, *dc = &dc1;
> target_ulong pc_ptr;
> - CPUBreakpoint *bp;
> int j, lj;
> uint64_t flags;
> target_ulong pc_start;
> @@ -7938,15 +7937,6 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
>
> gen_tb_start(tb);
> for(;;) {
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (bp->pc == pc_ptr &&
> - !((bp->flags & BP_CPU) && (tb->flags & HF_RF_MASK))) {
> - gen_debug(dc, pc_ptr - dc->cs_base);
> - goto done_generating;
> - }
> - }
> - }
> if (search_pc) {
> j = tcg_op_buf_count();
> if (lj < j) {
> @@ -7962,6 +7952,13 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
> tcg_gen_insn_start(pc_ptr);
> num_insns++;
>
> + /* If RF is set, suppress an internally generated breakpoint. */
> + if (unlikely(cpu_breakpoint_test(cs, pc_ptr,
> + tb->flags & HF_RF_MASK
> + ? BP_GDB : BP_ANY))) {
> + gen_debug(dc, pc_ptr - dc->cs_base);
> + goto done_generating;
> + }
> if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
> gen_io_start();
> }
> diff --git a/target-lm32/translate.c b/target-lm32/translate.c
> index a34914a..8ea7929 100644
> --- a/target-lm32/translate.c
> +++ b/target-lm32/translate.c
> @@ -1032,22 +1032,6 @@ static inline void decode(DisasContext *dc, uint32_t ir)
> decinfo[dc->opcode](dc);
> }
>
> -static void check_breakpoint(CPULM32State *env, DisasContext *dc)
> -{
> - CPUState *cs = CPU(lm32_env_get_cpu(env));
> - CPUBreakpoint *bp;
> -
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (bp->pc == dc->pc) {
> - tcg_gen_movi_tl(cpu_pc, dc->pc);
> - t_gen_raise_exception(dc, EXCP_DEBUG);
> - dc->is_jmp = DISAS_UPDATE;
> - }
> - }
> - }
> -}
> -
> /* generate intermediate code for basic block 'tb'. */
> static inline
> void gen_intermediate_code_internal(LM32CPU *cpu,
> @@ -1088,8 +1072,6 @@ void gen_intermediate_code_internal(LM32CPU *cpu,
>
> gen_tb_start(tb);
> do {
> - check_breakpoint(env, dc);
> -
> if (search_pc) {
> j = tcg_op_buf_count();
> if (lj < j) {
> @@ -1105,6 +1087,13 @@ void gen_intermediate_code_internal(LM32CPU *cpu,
> tcg_gen_insn_start(dc->pc);
> num_insns++;
>
> + if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
> + tcg_gen_movi_tl(cpu_pc, dc->pc);
> + t_gen_raise_exception(dc, EXCP_DEBUG);
> + dc->is_jmp = DISAS_UPDATE;
> + break;
> + }
> +
> /* Pretty disas. */
> LOG_DIS("%8.8x:\t", dc->pc);
>
> diff --git a/target-m68k/translate.c b/target-m68k/translate.c
> index 422244e..afef37f 100644
> --- a/target-m68k/translate.c
> +++ b/target-m68k/translate.c
> @@ -2969,7 +2969,6 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
> CPUState *cs = CPU(cpu);
> CPUM68KState *env = &cpu->env;
> DisasContext dc1, *dc = &dc1;
> - CPUBreakpoint *bp;
> int j, lj;
> target_ulong pc_start;
> int pc_offset;
> @@ -2999,17 +2998,6 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
> do {
> pc_offset = dc->pc - pc_start;
> gen_throws_exception = NULL;
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (bp->pc == dc->pc) {
> - gen_exception(dc, dc->pc, EXCP_DEBUG);
> - dc->is_jmp = DISAS_JUMP;
> - break;
> - }
> - }
> - if (dc->is_jmp)
> - break;
> - }
> if (search_pc) {
> j = tcg_op_buf_count();
> if (lj < j) {
> @@ -3024,6 +3012,12 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
> tcg_gen_insn_start(dc->pc);
> num_insns++;
>
> + if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
> + gen_exception(dc, dc->pc, EXCP_DEBUG);
> + dc->is_jmp = DISAS_JUMP;
> + break;
> + }
> +
> if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
> gen_io_start();
> }
> diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
> index a25b042..1224456 100644
> --- a/target-microblaze/translate.c
> +++ b/target-microblaze/translate.c
> @@ -1626,21 +1626,6 @@ static inline void decode(DisasContext *dc, uint32_t ir)
> }
> }
>
> -static void check_breakpoint(CPUMBState *env, DisasContext *dc)
> -{
> - CPUState *cs = CPU(mb_env_get_cpu(env));
> - CPUBreakpoint *bp;
> -
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (bp->pc == dc->pc) {
> - t_gen_raise_exception(dc, EXCP_DEBUG);
> - dc->is_jmp = DISAS_UPDATE;
> - }
> - }
> - }
> -}
> -
> /* generate intermediate code for basic block 'tb'. */
> static inline void
> gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
> @@ -1695,14 +1680,6 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
> gen_tb_start(tb);
> do
> {
> -#if SIM_COMPAT
> - if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
> - tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
> - gen_helper_debug();
> - }
> -#endif
> - check_breakpoint(env, dc);
> -
> if (search_pc) {
> j = tcg_op_buf_count();
> if (lj < j) {
> @@ -1717,6 +1694,19 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
> tcg_gen_insn_start(dc->pc);
> num_insns++;
>
> +#if SIM_COMPAT
> + if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
> + tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
> + gen_helper_debug();
> + }
> +#endif
> +
> + if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
> + t_gen_raise_exception(dc, EXCP_DEBUG);
> + dc->is_jmp = DISAS_UPDATE;
> + break;
> + }
> +
> /* Pretty disas. */
> LOG_DIS("%8.8x:\t", dc->pc);
>
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 66147d8..57e826d 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -19544,7 +19544,6 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
> DisasContext ctx;
> target_ulong pc_start;
> target_ulong next_page_start;
> - CPUBreakpoint *bp;
> int j, lj = -1;
> int num_insns;
> int max_insns;
> @@ -19591,20 +19590,6 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
> LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
> gen_tb_start(tb);
> while (ctx.bstate == BS_NONE) {
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (bp->pc == ctx.pc) {
> - save_cpu_state(&ctx, 1);
> - ctx.bstate = BS_BRANCH;
> - gen_helper_raise_exception_debug(cpu_env);
> - /* Include the breakpoint location or the tb won't
> - * be flushed when it must be. */
> - ctx.pc += 4;
> - goto done_generating;
> - }
> - }
> - }
> -
> if (search_pc) {
> j = tcg_op_buf_count();
> if (lj < j) {
> @@ -19621,6 +19606,16 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
> tcg_gen_insn_start(ctx.pc);
> num_insns++;
>
> + if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
> + save_cpu_state(&ctx, 1);
> + ctx.bstate = BS_BRANCH;
> + gen_helper_raise_exception_debug(cpu_env);
> + /* Include the breakpoint location or the tb won't
> + * be flushed when it must be. */
> + ctx.pc += 4;
> + goto done_generating;
> + }
> +
> if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
> gen_io_start();
> }
> diff --git a/target-moxie/translate.c b/target-moxie/translate.c
> index f71ed24..d71f55b 100644
> --- a/target-moxie/translate.c
> +++ b/target-moxie/translate.c
> @@ -822,7 +822,6 @@ gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
> CPUState *cs = CPU(cpu);
> DisasContext ctx;
> target_ulong pc_start;
> - CPUBreakpoint *bp;
> int j, lj = -1;
> CPUMoxieState *env = &cpu->env;
> int num_insns;
> @@ -838,17 +837,6 @@ gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
>
> gen_tb_start(tb);
> do {
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (ctx.pc == bp->pc) {
> - tcg_gen_movi_i32(cpu_pc, ctx.pc);
> - gen_helper_debug(cpu_env);
> - ctx.bstate = BS_EXCP;
> - goto done_generating;
> - }
> - }
> - }
> -
> if (search_pc) {
> j = tcg_op_buf_count();
> if (lj < j) {
> @@ -864,6 +852,13 @@ gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
> tcg_gen_insn_start(ctx.pc);
> num_insns++;
>
> + if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
> + tcg_gen_movi_i32(cpu_pc, ctx.pc);
> + gen_helper_debug(cpu_env);
> + ctx.bstate = BS_EXCP;
> + goto done_generating;
> + }
> +
> ctx.opcode = cpu_lduw_code(env, ctx.pc);
> ctx.pc += decode_opc(cpu, &ctx);
>
> diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
> index f9b4ed5..9755850 100644
> --- a/target-openrisc/translate.c
> +++ b/target-openrisc/translate.c
> @@ -1618,22 +1618,6 @@ static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu)
> }
> }
>
> -static void check_breakpoint(OpenRISCCPU *cpu, DisasContext *dc)
> -{
> - CPUState *cs = CPU(cpu);
> - CPUBreakpoint *bp;
> -
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (bp->pc == dc->pc) {
> - tcg_gen_movi_tl(cpu_pc, dc->pc);
> - gen_exception(dc, EXCP_DEBUG);
> - dc->is_jmp = DISAS_UPDATE;
> - }
> - }
> - }
> -}
> -
> static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
> TranslationBlock *tb,
> int search_pc)
> @@ -1674,7 +1658,6 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
> gen_tb_start(tb);
>
> do {
> - check_breakpoint(cpu, dc);
> if (search_pc) {
> j = tcg_op_buf_count();
> if (k < j) {
> @@ -1690,6 +1673,13 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
> tcg_gen_insn_start(dc->pc);
> num_insns++;
>
> + if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
> + tcg_gen_movi_tl(cpu_pc, dc->pc);
> + gen_exception(dc, EXCP_DEBUG);
> + dc->is_jmp = DISAS_UPDATE;
> + break;
> + }
> +
> if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
> gen_io_start();
> }
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index 7c288aa..fc234a3 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -11418,7 +11418,6 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
> DisasContext ctx, *ctxp = &ctx;
> opc_handler_t **table, *handler;
> target_ulong pc_start;
> - CPUBreakpoint *bp;
> int j, lj = -1;
> int num_insns;
> int max_insns;
> @@ -11483,14 +11482,6 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
> tcg_clear_temp_count();
> /* Set env in case of segfault during code fetch */
> while (ctx.exception == POWERPC_EXCP_NONE && !tcg_op_buf_full()) {
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (bp->pc == ctx.nip) {
> - gen_debug_exception(ctxp);
> - break;
> - }
> - }
> - }
> if (unlikely(search_pc)) {
> j = tcg_op_buf_count();
> if (lj < j) {
> @@ -11505,6 +11496,11 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
> tcg_gen_insn_start(ctx.nip);
> num_insns++;
>
> + if (unlikely(cpu_breakpoint_test(cs, ctx.nip, BP_ANY))) {
> + gen_debug_exception(ctxp);
> + break;
> + }
> +
> LOG_DISAS("----------------\n");
> LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
> ctx.nip, ctx.mem_idx, (int)msr_ir);
> diff --git a/target-s390x/translate.c b/target-s390x/translate.c
> index 58cf365..4959828 100644
> --- a/target-s390x/translate.c
> +++ b/target-s390x/translate.c
> @@ -5330,7 +5330,6 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu,
> uint64_t next_page_start;
> int j, lj = -1;
> int num_insns, max_insns;
> - CPUBreakpoint *bp;
> ExitStatus status;
> bool do_debug;
>
> @@ -5373,20 +5372,17 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu,
> tcg_gen_insn_start(dc.pc);
> num_insns++;
>
> + if (unlikely(cpu_breakpoint_test(cs, dc.pc, BP_ANY))) {
> + status = EXIT_PC_STALE;
> + do_debug = true;
> + break;
> + }
> +
> if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
> gen_io_start();
> }
>
> status = NO_EXIT;
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (bp->pc == dc.pc) {
> - status = EXIT_PC_STALE;
> - do_debug = true;
> - break;
> - }
> - }
> - }
> if (status == NO_EXIT) {
> status = translate_one(env, &dc);
> }
> diff --git a/target-sh4/translate.c b/target-sh4/translate.c
> index e0294e7..53bf9e8 100644
> --- a/target-sh4/translate.c
> +++ b/target-sh4/translate.c
> @@ -1824,7 +1824,6 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
> CPUSH4State *env = &cpu->env;
> DisasContext ctx;
> target_ulong pc_start;
> - CPUBreakpoint *bp;
> int i, ii;
> int num_insns;
> int max_insns;
> @@ -1849,17 +1848,6 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
> max_insns = CF_COUNT_MASK;
> gen_tb_start(tb);
> while (ctx.bstate == BS_NONE && !tcg_op_buf_full()) {
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (ctx.pc == bp->pc) {
> - /* We have hit a breakpoint - make sure PC is up-to-date */
> - tcg_gen_movi_i32(cpu_pc, ctx.pc);
> - gen_helper_debug(cpu_env);
> - ctx.bstate = BS_BRANCH;
> - break;
> - }
> - }
> - }
> if (search_pc) {
> i = tcg_op_buf_count();
> if (ii < i) {
> @@ -1875,6 +1863,14 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
> tcg_gen_insn_start(ctx.pc);
> num_insns++;
>
> + if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
> + /* We have hit a breakpoint - make sure PC is up-to-date */
> + tcg_gen_movi_i32(cpu_pc, ctx.pc);
> + gen_helper_debug(cpu_env);
> + ctx.bstate = BS_BRANCH;
> + break;
> + }
> +
> if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
> gen_io_start();
> }
> diff --git a/target-sparc/translate.c b/target-sparc/translate.c
> index 762eb9b..f359ac9 100644
> --- a/target-sparc/translate.c
> +++ b/target-sparc/translate.c
> @@ -5217,7 +5217,6 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
> CPUSPARCState *env = &cpu->env;
> target_ulong pc_start, last_pc;
> DisasContext dc1, *dc = &dc1;
> - CPUBreakpoint *bp;
> int j, lj = -1;
> int num_insns;
> int max_insns;
> @@ -5242,18 +5241,6 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
> max_insns = CF_COUNT_MASK;
> gen_tb_start(tb);
> do {
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (bp->pc == dc->pc) {
> - if (dc->pc != pc_start)
> - save_state(dc);
> - gen_helper_debug(cpu_env);
> - tcg_gen_exit_tb(0);
> - dc->is_br = 1;
> - goto exit_gen_loop;
> - }
> - }
> - }
> if (spc) {
> qemu_log("Search PC...\n");
> j = tcg_op_buf_count();
> @@ -5270,6 +5257,16 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
> tcg_gen_insn_start(dc->pc);
> num_insns++;
>
> + if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
> + if (dc->pc != pc_start) {
> + save_state(dc);
> + }
> + gen_helper_debug(cpu_env);
> + tcg_gen_exit_tb(0);
> + dc->is_br = 1;
> + goto exit_gen_loop;
> + }
> +
> if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
> gen_io_start();
> }
> diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
> index 7aad61f..cd23c4b 100644
> --- a/target-unicore32/translate.c
> +++ b/target-unicore32/translate.c
> @@ -1872,7 +1872,6 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
> CPUState *cs = CPU(cpu);
> CPUUniCore32State *env = &cpu->env;
> DisasContext dc1, *dc = &dc1;
> - CPUBreakpoint *bp;
> int j, lj;
> target_ulong pc_start;
> uint32_t next_page_start;
> @@ -1912,19 +1911,6 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
>
> gen_tb_start(tb);
> do {
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (bp->pc == dc->pc) {
> - gen_set_pc_im(dc->pc);
> - gen_exception(EXCP_DEBUG);
> - dc->is_jmp = DISAS_JUMP;
> - /* Advance PC so that clearing the breakpoint will
> - invalidate this TB. */
> - dc->pc += 2; /* FIXME */
> - goto done_generating;
> - }
> - }
> - }
> if (search_pc) {
> j = tcg_op_buf_count();
> if (lj < j) {
> @@ -1940,6 +1926,16 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
> tcg_gen_insn_start(dc->pc);
> num_insns++;
>
> + if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
> + gen_set_pc_im(dc->pc);
> + gen_exception(EXCP_DEBUG);
> + dc->is_jmp = DISAS_JUMP;
> + /* Advance PC so that clearing the breakpoint will
> + invalidate this TB. */
> + dc->pc += 2; /* FIXME */
> + goto done_generating;
> + }
> +
> if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
> gen_io_start();
> }
> diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
> index 3607e41..ea87cb5 100644
> --- a/target-xtensa/translate.c
> +++ b/target-xtensa/translate.c
> @@ -2984,22 +2984,6 @@ static inline unsigned xtensa_insn_len(CPUXtensaState *env, DisasContext *dc)
> return xtensa_op0_insn_len(OP0);
> }
>
> -static void check_breakpoint(CPUXtensaState *env, DisasContext *dc)
> -{
> - CPUState *cs = CPU(xtensa_env_get_cpu(env));
> - CPUBreakpoint *bp;
> -
> - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
> - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
> - if (bp->pc == dc->pc) {
> - tcg_gen_movi_i32(cpu_pc, dc->pc);
> - gen_exception(dc, EXCP_DEBUG);
> - dc->is_jmp = DISAS_UPDATE;
> - }
> - }
> - }
> -}
> -
> static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
> {
> unsigned i;
> @@ -3062,8 +3046,6 @@ void gen_intermediate_code_internal(XtensaCPU *cpu,
> }
>
> do {
> - check_breakpoint(env, &dc);
> -
> if (search_pc) {
> j = tcg_op_buf_count();
> if (lj < j) {
> @@ -3081,6 +3063,13 @@ void gen_intermediate_code_internal(XtensaCPU *cpu,
>
> ++dc.ccount_delta;
>
> + if (unlikely(cpu_breakpoint_test(cs, dc.pc, BP_ANY))) {
> + tcg_gen_movi_i32(cpu_pc, dc.pc);
> + gen_exception(&dc, EXCP_DEBUG);
> + dc.is_jmp = DISAS_UPDATE;
> + break;
> + }
> +
> if (insn_count == max_insns && (tb->cflags & CF_LAST_IO)) {
> gen_io_start();
> }
next prev parent reply other threads:[~2015-10-09 13:34 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-07 9:43 [Qemu-devel] [PULL 00/26] Do away with TB retranslation Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 01/26] tcg: Rename debug_insn_start to insn_start Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 02/26] target-*: Unconditionally emit tcg_gen_insn_start Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 03/26] target-*: Increment num_insns immediately after tcg_gen_insn_start Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 04/26] target-*: Introduce and use cpu_breakpoint_test Richard Henderson
2015-10-09 13:34 ` Sergey Fedorov [this message]
2015-10-13 0:13 ` Richard Henderson
2015-10-13 8:13 ` Peter Maydell
2015-10-13 13:40 ` Sergey Fedorov
2015-10-13 20:44 ` Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 05/26] tcg: Allow extra data to be attached to insn_start Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 06/26] target-arm: Add condexec state " Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 07/26] target-i386: Add cc_op " Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 08/26] target-mips: Add delayed branch " Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 09/26] target-s390x: Add cc_op " Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 10/26] target-sh4: Add flags " Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 11/26] target-cris: Mirror gen_opc_pc into insn_start Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 12/26] target-sparc: Tidy gen_branch_a interface Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 13/26] target-sparc: Split out gen_branch_n Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 14/26] target-sparc: Remove gen_opc_jump_pc Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 15/26] target-sparc: Add npc state to insn_start Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 16/26] tcg: Merge cpu_gen_code into tb_gen_code Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 17/26] target-*: Drop cpu_gen_code define Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 18/26] tcg: Add TCG_MAX_INSNS Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 19/26] tcg: Pass data argument to restore_state_to_opc Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 20/26] tcg: Save insn data and use it in cpu_restore_state_from_tb Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 21/26] tcg: Remove gen_intermediate_code_pc Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 22/26] tcg: Remove tcg_gen_code_search_pc Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 23/26] tcg: Emit prologue to the beginning of code_gen_buffer Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 24/26] tcg: Allocate a guard page after code_gen_buffer Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 25/26] tcg: Check for overflow via highwater mark Richard Henderson
2015-10-07 9:43 ` [Qemu-devel] [PULL 26/26] tcg: Adjust CODE_GEN_AVG_BLOCK_SIZE Richard Henderson
2015-10-08 15:50 ` [Qemu-devel] [PULL 00/26] Do away with TB retranslation Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5617C252.6070104@gmail.com \
--to=serge.fdrv@gmail.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.