4 #include "qemu/timer.h"
6 /* Helpers for instruction counting code generation. */
8 static int icount_start_insn_idx
;
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
;
16 exitreq_label
= gen_new_label();
17 flag
= tcg_temp_new_i32();
18 tcg_gen_ld_i32(flag
, cpu_env
,
19 offsetof(CPUState
, tcg_exit_req
) - ENV_OFFSET
);
20 tcg_gen_brcondi_i32(TCG_COND_NE
, flag
, 0, exitreq_label
);
21 tcg_temp_free_i32(flag
);
23 if (!(tb
->cflags
& CF_USE_ICOUNT
)) {
27 icount_label
= gen_new_label();
28 count
= tcg_temp_local_new_i32();
29 tcg_gen_ld_i32(count
, cpu_env
,
30 -ENV_OFFSET
+ offsetof(CPUState
, icount_decr
.u32
));
32 imm
= tcg_temp_new_i32();
33 /* We emit a movi with a dummy immediate argument. Keep the insn index
34 * of the movi so that we later (when we know the actual insn count)
35 * can update the immediate argument with the actual insn count. */
36 icount_start_insn_idx
= tcg_op_buf_count();
37 tcg_gen_movi_i32(imm
, 0xdeadbeef);
39 tcg_gen_sub_i32(count
, count
, imm
);
40 tcg_temp_free_i32(imm
);
42 tcg_gen_brcondi_i32(TCG_COND_LT
, count
, 0, icount_label
);
43 tcg_gen_st16_i32(count
, cpu_env
,
44 -ENV_OFFSET
+ offsetof(CPUState
, icount_decr
.u16
.low
));
45 tcg_temp_free_i32(count
);
48 static void gen_tb_end(TranslationBlock
*tb
, int num_insns
)
50 gen_set_label(exitreq_label
);
51 tcg_gen_exit_tb((uintptr_t)tb
+ TB_EXIT_REQUESTED
);
53 if (tb
->cflags
& CF_USE_ICOUNT
) {
54 /* Update the num_insn immediate parameter now that we know
55 * the actual insn count. */
56 tcg_set_insn_param(icount_start_insn_idx
, 1, 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_op_buf
[0].prev
].next
= 0;
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
);