1#ifndef GEN_ICOUNT_H
2#define GEN_ICOUNT_H
3
4#include "qemu/timer.h"
5
6
7
8static TCGOp *icount_start_insn;
9
10static inline void gen_tb_start(TranslationBlock *tb)
11{
12 TCGv_i32 count, imm;
13
14 tcg_ctx->exitreq_label = gen_new_label();
15 if (tb_cflags(tb) & CF_USE_ICOUNT) {
16 count = tcg_temp_local_new_i32();
17 } else {
18 count = tcg_temp_new_i32();
19 }
20
21 tcg_gen_ld_i32(count, cpu_env,
22 -ENV_OFFSET + offsetof(CPUState, icount_decr.u32));
23
24 if (tb_cflags(tb) & CF_USE_ICOUNT) {
25 imm = tcg_temp_new_i32();
26
27
28
29 tcg_gen_movi_i32(imm, 0xdeadbeef);
30 icount_start_insn = tcg_last_op();
31
32 tcg_gen_sub_i32(count, count, imm);
33 tcg_temp_free_i32(imm);
34 }
35
36 tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, tcg_ctx->exitreq_label);
37
38 if (tb_cflags(tb) & CF_USE_ICOUNT) {
39 tcg_gen_st16_i32(count, cpu_env,
40 -ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low));
41 }
42
43 tcg_temp_free_i32(count);
44}
45
46static inline void gen_tb_end(TranslationBlock *tb, int num_insns)
47{
48 if (tb_cflags(tb) & CF_USE_ICOUNT) {
49
50
51 tcg_set_insn_param(icount_start_insn, 1, num_insns);
52 }
53
54 gen_set_label(tcg_ctx->exitreq_label);
55 tcg_gen_exit_tb(tb, TB_EXIT_REQUESTED);
56}
57
58static inline void gen_io_start(void)
59{
60 TCGv_i32 tmp = tcg_const_i32(1);
61 tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io));
62 tcg_temp_free_i32(tmp);
63}
64
65static inline void gen_io_end(void)
66{
67 TCGv_i32 tmp = tcg_const_i32(0);
68 tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io));
69 tcg_temp_free_i32(tmp);
70}
71
72#endif
73