]>
Commit | Line | Data |
---|---|---|
cb9c377f PB |
1 | #ifndef GEN_ICOUNT_H |
2 | #define GEN_ICOUNT_H 1 | |
3 | ||
1de7afc9 | 4 | #include "qemu/timer.h" |
29e922b6 | 5 | |
bf20dc07 | 6 | /* Helpers for instruction counting code generation. */ |
dd5d6fe9 PB |
7 | |
8 | static TCGArg *icount_arg; | |
42a268c2 RH |
9 | static TCGLabel *icount_label; |
10 | static TCGLabel *exitreq_label; | |
dd5d6fe9 | 11 | |
cd42d5b2 | 12 | static inline void gen_tb_start(TranslationBlock *tb) |
dd5d6fe9 | 13 | { |
c45cb8bb RH |
14 | TCGv_i32 count, flag, imm; |
15 | int i; | |
378df4b2 PM |
16 | |
17 | exitreq_label = gen_new_label(); | |
a4960ef3 | 18 | flag = tcg_temp_new_i32(); |
378df4b2 PM |
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); | |
dd5d6fe9 | 23 | |
c45cb8bb | 24 | if (!(tb->cflags & CF_USE_ICOUNT)) { |
dd5d6fe9 | 25 | return; |
c45cb8bb | 26 | } |
dd5d6fe9 PB |
27 | |
28 | icount_label = gen_new_label(); | |
a7812ae4 | 29 | count = tcg_temp_local_new_i32(); |
28ecfd7a AF |
30 | tcg_gen_ld_i32(count, cpu_env, |
31 | -ENV_OFFSET + offsetof(CPUState, icount_decr.u32)); | |
c45cb8bb RH |
32 | |
33 | imm = tcg_temp_new_i32(); | |
34 | tcg_gen_movi_i32(imm, 0xdeadbeef); | |
35 | ||
dd5d6fe9 | 36 | /* This is a horrid hack to allow fixing up the value later. */ |
c45cb8bb RH |
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]; | |
40 | ||
41 | tcg_gen_sub_i32(count, count, imm); | |
42 | tcg_temp_free_i32(imm); | |
dd5d6fe9 PB |
43 | |
44 | tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, icount_label); | |
28ecfd7a AF |
45 | tcg_gen_st16_i32(count, cpu_env, |
46 | -ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low)); | |
a7812ae4 | 47 | tcg_temp_free_i32(count); |
dd5d6fe9 PB |
48 | } |
49 | ||
806f352d | 50 | static void gen_tb_end(TranslationBlock *tb, int num_insns) |
dd5d6fe9 | 51 | { |
378df4b2 | 52 | gen_set_label(exitreq_label); |
8cfd0495 | 53 | tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_REQUESTED); |
378df4b2 | 54 | |
cd42d5b2 | 55 | if (tb->cflags & CF_USE_ICOUNT) { |
dd5d6fe9 PB |
56 | *icount_arg = num_insns; |
57 | gen_set_label(icount_label); | |
8cfd0495 | 58 | tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_ICOUNT_EXPIRED); |
dd5d6fe9 | 59 | } |
0a7df5da | 60 | |
c45cb8bb RH |
61 | /* Terminate the linked list. */ |
62 | tcg_ctx.gen_op_buf[tcg_ctx.gen_last_op_idx].next = -1; | |
dd5d6fe9 PB |
63 | } |
64 | ||
86178a57 | 65 | static inline void gen_io_start(void) |
dd5d6fe9 | 66 | { |
a7812ae4 | 67 | TCGv_i32 tmp = tcg_const_i32(1); |
99df7dce | 68 | tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io)); |
a7812ae4 | 69 | tcg_temp_free_i32(tmp); |
dd5d6fe9 PB |
70 | } |
71 | ||
72 | static inline void gen_io_end(void) | |
73 | { | |
a7812ae4 | 74 | TCGv_i32 tmp = tcg_const_i32(0); |
99df7dce | 75 | tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io)); |
a7812ae4 | 76 | tcg_temp_free_i32(tmp); |
dd5d6fe9 | 77 | } |
cb9c377f PB |
78 | |
79 | #endif |