]>
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, |
5e140196 RH |
22 | offsetof(ArchCPU, neg.icount_decr.u32) - |
23 | offsetof(ArchCPU, env)); | |
c45cb8bb | 24 | |
c5a49c63 | 25 | if (tb_cflags(tb) & CF_USE_ICOUNT) { |
1aab16c2 PB |
26 | imm = tcg_temp_new_i32(); |
27 | /* We emit a movi with a dummy immediate argument. Keep the insn index | |
28 | * of the movi so that we later (when we know the actual insn count) | |
29 | * can update the immediate argument with the actual insn count. */ | |
1aab16c2 | 30 | tcg_gen_movi_i32(imm, 0xdeadbeef); |
15fa08f8 | 31 | icount_start_insn = tcg_last_op(); |
1aab16c2 PB |
32 | |
33 | tcg_gen_sub_i32(count, count, imm); | |
34 | tcg_temp_free_i32(imm); | |
35 | } | |
36 | ||
26689780 | 37 | tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, tcg_ctx->exitreq_label); |
c45cb8bb | 38 | |
c5a49c63 | 39 | if (tb_cflags(tb) & CF_USE_ICOUNT) { |
1c2adb95 | 40 | tcg_gen_st16_i32(count, cpu_env, |
5e140196 RH |
41 | offsetof(ArchCPU, neg.icount_decr.u16.low) - |
42 | offsetof(ArchCPU, env)); | |
1aab16c2 | 43 | } |
dd5d6fe9 | 44 | |
a7812ae4 | 45 | tcg_temp_free_i32(count); |
dd5d6fe9 PB |
46 | } |
47 | ||
ae06cb46 | 48 | static inline void gen_tb_end(TranslationBlock *tb, int num_insns) |
dd5d6fe9 | 49 | { |
c5a49c63 | 50 | if (tb_cflags(tb) & CF_USE_ICOUNT) { |
25caa94c EI |
51 | /* Update the num_insn immediate parameter now that we know |
52 | * the actual insn count. */ | |
15fa08f8 | 53 | tcg_set_insn_param(icount_start_insn, 1, num_insns); |
dd5d6fe9 | 54 | } |
0a7df5da | 55 | |
26689780 | 56 | gen_set_label(tcg_ctx->exitreq_label); |
07ea28b4 | 57 | tcg_gen_exit_tb(tb, TB_EXIT_REQUESTED); |
dd5d6fe9 PB |
58 | } |
59 | ||
86178a57 | 60 | static inline void gen_io_start(void) |
dd5d6fe9 | 61 | { |
a7812ae4 | 62 | TCGv_i32 tmp = tcg_const_i32(1); |
5e140196 RH |
63 | tcg_gen_st_i32(tmp, cpu_env, |
64 | offsetof(ArchCPU, parent_obj.can_do_io) - | |
65 | offsetof(ArchCPU, env)); | |
a7812ae4 | 66 | tcg_temp_free_i32(tmp); |
dd5d6fe9 PB |
67 | } |
68 | ||
69 | static inline void gen_io_end(void) | |
70 | { | |
a7812ae4 | 71 | TCGv_i32 tmp = tcg_const_i32(0); |
5e140196 RH |
72 | tcg_gen_st_i32(tmp, cpu_env, |
73 | offsetof(ArchCPU, parent_obj.can_do_io) - | |
74 | offsetof(ArchCPU, env)); | |
a7812ae4 | 75 | tcg_temp_free_i32(tmp); |
dd5d6fe9 | 76 | } |
cb9c377f PB |
77 | |
78 | #endif |