diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2017-03-03 16:39:18 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2017-03-03 16:39:18 +0100 |
commit | 30f3dda24b2a4cd30f8fbf984ab08ef08eaf5020 (patch) | |
tree | 5d70d2f93f28b4935c68b48482cdba5302b410ba /include | |
parent | 508e038a5d725f2aa729f58a1f5209b9be4227de (diff) | |
parent | 55ac0a9bf4e1b1adfc7d73586a7aa085f58c9851 (diff) | |
download | qemu-30f3dda24b2a4cd30f8fbf984ab08ef08eaf5020.zip qemu-30f3dda24b2a4cd30f8fbf984ab08ef08eaf5020.tar.gz qemu-30f3dda24b2a4cd30f8fbf984ab08ef08eaf5020.tar.bz2 |
Merge branch 'icount-update' into HEAD
Merge the original development branch due to breakage caused by the
MTTCG merge.
Conflicts:
cpu-exec.c
translate-common.c
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/exec/gen-icount.h | 53 | ||||
-rw-r--r-- | include/qom/cpu.h | 15 |
2 files changed, 32 insertions, 36 deletions
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h index 050de59..62d462e 100644 --- a/include/exec/gen-icount.h +++ b/include/exec/gen-icount.h @@ -6,58 +6,55 @@ /* Helpers for instruction counting code generation. */ static int icount_start_insn_idx; -static TCGLabel *icount_label; static TCGLabel *exitreq_label; static inline void gen_tb_start(TranslationBlock *tb) { - TCGv_i32 count, flag, imm; + TCGv_i32 count, imm; exitreq_label = gen_new_label(); - flag = tcg_temp_new_i32(); - tcg_gen_ld_i32(flag, cpu_env, - offsetof(CPUState, tcg_exit_req) - ENV_OFFSET); - tcg_gen_brcondi_i32(TCG_COND_NE, flag, 0, exitreq_label); - tcg_temp_free_i32(flag); - - if (!(tb->cflags & CF_USE_ICOUNT)) { - return; + if (tb->cflags & CF_USE_ICOUNT) { + count = tcg_temp_local_new_i32(); + } else { + count = tcg_temp_new_i32(); } - icount_label = gen_new_label(); - count = tcg_temp_local_new_i32(); tcg_gen_ld_i32(count, cpu_env, -ENV_OFFSET + offsetof(CPUState, icount_decr.u32)); - imm = tcg_temp_new_i32(); - /* We emit a movi with a dummy immediate argument. Keep the insn index - * of the movi so that we later (when we know the actual insn count) - * can update the immediate argument with the actual insn count. */ - icount_start_insn_idx = tcg_op_buf_count(); - tcg_gen_movi_i32(imm, 0xdeadbeef); + if (tb->cflags & CF_USE_ICOUNT) { + imm = tcg_temp_new_i32(); + /* We emit a movi with a dummy immediate argument. Keep the insn index + * of the movi so that we later (when we know the actual insn count) + * can update the immediate argument with the actual insn count. */ + icount_start_insn_idx = tcg_op_buf_count(); + tcg_gen_movi_i32(imm, 0xdeadbeef); + + tcg_gen_sub_i32(count, count, imm); + tcg_temp_free_i32(imm); + } + + tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, exitreq_label); - tcg_gen_sub_i32(count, count, imm); - tcg_temp_free_i32(imm); + if (tb->cflags & CF_USE_ICOUNT) { + tcg_gen_st16_i32(count, cpu_env, + -ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low)); + } - tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, icount_label); - tcg_gen_st16_i32(count, cpu_env, - -ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low)); tcg_temp_free_i32(count); } static void gen_tb_end(TranslationBlock *tb, int num_insns) { - gen_set_label(exitreq_label); - tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_REQUESTED); - if (tb->cflags & CF_USE_ICOUNT) { /* Update the num_insn immediate parameter now that we know * the actual insn count. */ tcg_set_insn_param(icount_start_insn_idx, 1, num_insns); - gen_set_label(icount_label); - tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_ICOUNT_EXPIRED); } + gen_set_label(exitreq_label); + tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_REQUESTED); + /* Terminate the linked list. */ tcg_ctx.gen_op_buf[tcg_ctx.gen_op_buf[0].prev].next = 0; } diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 3e61c88..c3292ef 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -275,11 +275,11 @@ struct qemu_work_item; * @stopped: Indicates the CPU has been artificially stopped. * @unplug: Indicates a pending CPU unplug request. * @crash_occurred: Indicates the OS reported a crash (panic) for this CPU - * @tcg_exit_req: Set to force TCG to stop executing linked TBs for this - * CPU and return to its top level loop. * @singlestep_enabled: Flags for single-stepping. * @icount_extra: Instructions until next timer event. - * @icount_decr: Number of cycles left, with interrupt flag in high bit. + * @icount_decr: Low 16 bits: number of cycles left, only used in icount mode. + * High 16 bits: Set to -1 to force TCG to stop executing linked TBs for this + * CPU and return to its top level loop (even in non-icount mode). * This allows a single read-compare-cbranch-write sequence to test * for both decrementer underflow and exceptions. * @can_do_io: Nonzero if memory-mapped IO is safe. Deterministic execution @@ -382,10 +382,6 @@ struct CPUState { /* TODO Move common fields from CPUArchState here. */ int cpu_index; /* used by alpha TCG */ uint32_t halted; /* used by alpha, cris, ppc TCG */ - union { - uint32_t u32; - icount_decr_u16 u16; - } icount_decr; uint32_t can_do_io; int32_t exception_index; /* used by m68k TCG */ @@ -398,7 +394,10 @@ struct CPUState { offset from AREG0. Leave this field at the end so as to make the (absolute value) offset as small as possible. This reduces code size, especially for hosts without large memory offsets. */ - uint32_t tcg_exit_req; + union { + uint32_t u32; + icount_decr_u16 u16; + } icount_decr; bool hax_vcpu_dirty; struct hax_vcpu_state *hax_vcpu; |