]>
Commit | Line | Data |
---|---|---|
cb9c377f | 1 | #ifndef GEN_ICOUNT_H |
175de524 | 2 | #define GEN_ICOUNT_H |
cb9c377f | 3 | |
1de7afc9 | 4 | #include "qemu/timer.h" |
29e922b6 | 5 | |
bf20dc07 | 6 | /* Helpers for instruction counting code generation. */ |
dd5d6fe9 | 7 | |
15fa08f8 | 8 | static TCGOp *icount_start_insn; |
dd5d6fe9 | 9 | |
cd42d5b2 | 10 | static inline void gen_tb_start(TranslationBlock *tb) |
dd5d6fe9 | 11 | { |
1aab16c2 | 12 | TCGv_i32 count, imm; |
378df4b2 | 13 | |
26689780 | 14 | tcg_ctx->exitreq_label = gen_new_label(); |
c5a49c63 | 15 | if (tb_cflags(tb) & CF_USE_ICOUNT) { |
1aab16c2 PB |
16 | count = tcg_temp_local_new_i32(); |
17 | } else { | |
18 | count = tcg_temp_new_i32(); | |
c45cb8bb | 19 | } |
dd5d6fe9 | 20 | |
1c2adb95 | 21 | tcg_gen_ld_i32(count, cpu_env, |
28ecfd7a | 22 | -ENV_OFFSET + offsetof(CPUState, icount_decr.u32)); |
c45cb8bb | 23 | |
c5a49c63 | 24 | if (tb_cflags(tb) & CF_USE_ICOUNT) { |
1aab16c2 PB |
25 | imm = tcg_temp_new_i32(); |
26 | /* We emit a movi with a dummy immediate argument. Keep the insn index | |
27 | * of the movi so that we later (when we know the actual insn count) | |
28 | * can update the immediate argument with the actual insn count. */ | |
1aab16c2 | 29 | tcg_gen_movi_i32(imm, 0xdeadbeef); |
15fa08f8 | 30 | icount_start_insn = tcg_last_op(); |
1aab16c2 PB |
31 | |
32 | tcg_gen_sub_i32(count, count, imm); | |
33 | tcg_temp_free_i32(imm); | |
34 | } | |
35 | ||
26689780 | 36 | tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, tcg_ctx->exitreq_label); |
c45cb8bb | 37 | |
c5a49c63 | 38 | if (tb_cflags(tb) & CF_USE_ICOUNT) { |
1c2adb95 | 39 | tcg_gen_st16_i32(count, cpu_env, |
1aab16c2 PB |
40 | -ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low)); |
41 | } | |
dd5d6fe9 | 42 | |
a7812ae4 | 43 | tcg_temp_free_i32(count); |
dd5d6fe9 PB |
44 | } |
45 | ||
ae06cb46 | 46 | static inline void gen_tb_end(TranslationBlock *tb, int num_insns) |
dd5d6fe9 | 47 | { |
c5a49c63 | 48 | if (tb_cflags(tb) & CF_USE_ICOUNT) { |
25caa94c EI |
49 | /* Update the num_insn immediate parameter now that we know |
50 | * the actual insn count. */ | |
15fa08f8 | 51 | tcg_set_insn_param(icount_start_insn, 1, num_insns); |
dd5d6fe9 | 52 | } |
0a7df5da | 53 | |
26689780 | 54 | gen_set_label(tcg_ctx->exitreq_label); |
07ea28b4 | 55 | tcg_gen_exit_tb(tb, TB_EXIT_REQUESTED); |
dd5d6fe9 PB |
56 | } |
57 | ||
86178a57 | 58 | static inline void gen_io_start(void) |
dd5d6fe9 | 59 | { |
a7812ae4 | 60 | TCGv_i32 tmp = tcg_const_i32(1); |
1c2adb95 | 61 | tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io)); |
a7812ae4 | 62 | tcg_temp_free_i32(tmp); |
dd5d6fe9 PB |
63 | } |
64 | ||
65 | static inline void gen_io_end(void) | |
66 | { | |
a7812ae4 | 67 | TCGv_i32 tmp = tcg_const_i32(0); |
1c2adb95 | 68 | tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io)); |
a7812ae4 | 69 | tcg_temp_free_i32(tmp); |
dd5d6fe9 | 70 | } |
cb9c377f PB |
71 | |
72 | #endif |