Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
[qemu/qmp-unstable.git] / include / exec / gen-icount.h
blob05d89d358fb4d98c0f6e51385b056253858e5e81
1 #ifndef GEN_ICOUNT_H
2 #define GEN_ICOUNT_H 1
4 #include "qemu/timer.h"
6 /* Helpers for instruction counting code generation. */
8 static TCGArg *icount_arg;
9 static TCGLabel *icount_label;
10 static TCGLabel *exitreq_label;
12 static inline void gen_tb_start(TranslationBlock *tb)
14 TCGv_i32 count, flag, imm;
15 int i;
17 exitreq_label = gen_new_label();
18 flag = tcg_temp_new_i32();
19 tcg_gen_ld_i32(flag, cpu_env,
20 offsetof(CPUState, tcg_exit_req) - ENV_OFFSET);
21 tcg_gen_brcondi_i32(TCG_COND_NE, flag, 0, exitreq_label);
22 tcg_temp_free_i32(flag);
24 if (!(tb->cflags & CF_USE_ICOUNT)) {
25 return;
28 icount_label = gen_new_label();
29 count = tcg_temp_local_new_i32();
30 tcg_gen_ld_i32(count, cpu_env,
31 -ENV_OFFSET + offsetof(CPUState, icount_decr.u32));
33 imm = tcg_temp_new_i32();
34 tcg_gen_movi_i32(imm, 0xdeadbeef);
36 /* This is a horrid hack to allow fixing up the value later. */
37 i = tcg_ctx.gen_last_op_idx;
38 i = tcg_ctx.gen_op_buf[i].args;
39 icount_arg = &tcg_ctx.gen_opparam_buf[i + 1];
41 tcg_gen_sub_i32(count, count, imm);
42 tcg_temp_free_i32(imm);
44 tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, icount_label);
45 tcg_gen_st16_i32(count, cpu_env,
46 -ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low));
47 tcg_temp_free_i32(count);
50 static void gen_tb_end(TranslationBlock *tb, int num_insns)
52 gen_set_label(exitreq_label);
53 tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_REQUESTED);
55 if (tb->cflags & CF_USE_ICOUNT) {
56 *icount_arg = num_insns;
57 gen_set_label(icount_label);
58 tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_ICOUNT_EXPIRED);
61 /* Terminate the linked list. */
62 tcg_ctx.gen_op_buf[tcg_ctx.gen_last_op_idx].next = -1;
65 static inline void gen_io_start(void)
67 TCGv_i32 tmp = tcg_const_i32(1);
68 tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io));
69 tcg_temp_free_i32(tmp);
72 static inline void gen_io_end(void)
74 TCGv_i32 tmp = tcg_const_i32(0);
75 tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io));
76 tcg_temp_free_i32(tmp);
79 #endif