root / gen-icount.h @ 61c04807
History | View | Annotate | Download (1.5 kB)
1 | bf20dc07 | ths | /* Helpers for instruction counting code generation. */
|
---|---|---|---|
2 | dd5d6fe9 | pbrook | |
3 | dd5d6fe9 | pbrook | static TCGArg *icount_arg;
|
4 | dd5d6fe9 | pbrook | static int icount_label; |
5 | dd5d6fe9 | pbrook | |
6 | dd5d6fe9 | pbrook | static inline void gen_icount_start(void) |
7 | dd5d6fe9 | pbrook | { |
8 | dd5d6fe9 | pbrook | TCGv count; |
9 | dd5d6fe9 | pbrook | |
10 | dd5d6fe9 | pbrook | if (!use_icount)
|
11 | dd5d6fe9 | pbrook | return;
|
12 | dd5d6fe9 | pbrook | |
13 | dd5d6fe9 | pbrook | icount_label = gen_new_label(); |
14 | dd5d6fe9 | pbrook | /* FIXME: This generates lousy code. We can't use tcg_new_temp because
|
15 | dd5d6fe9 | pbrook | count needs to live over the conditional branch. To workaround this
|
16 | dd5d6fe9 | pbrook | we allow the target to supply a convenient register temporary. */
|
17 | dd5d6fe9 | pbrook | #ifndef ICOUNT_TEMP
|
18 | dd5d6fe9 | pbrook | count = tcg_temp_local_new(TCG_TYPE_I32); |
19 | dd5d6fe9 | pbrook | #else
|
20 | dd5d6fe9 | pbrook | count = ICOUNT_TEMP; |
21 | dd5d6fe9 | pbrook | #endif
|
22 | dd5d6fe9 | pbrook | tcg_gen_ld_i32(count, cpu_env, offsetof(CPUState, icount_decr.u32)); |
23 | dd5d6fe9 | pbrook | /* This is a horrid hack to allow fixing up the value later. */
|
24 | dd5d6fe9 | pbrook | icount_arg = gen_opparam_ptr + 1;
|
25 | dd5d6fe9 | pbrook | tcg_gen_subi_i32(count, count, 0xdeadbeef);
|
26 | dd5d6fe9 | pbrook | |
27 | dd5d6fe9 | pbrook | tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, icount_label);
|
28 | dd5d6fe9 | pbrook | tcg_gen_st16_i32(count, cpu_env, offsetof(CPUState, icount_decr.u16.low)); |
29 | dd5d6fe9 | pbrook | #ifndef ICOUNT_TEMP
|
30 | dd5d6fe9 | pbrook | tcg_temp_free(count); |
31 | dd5d6fe9 | pbrook | #endif
|
32 | dd5d6fe9 | pbrook | } |
33 | dd5d6fe9 | pbrook | |
34 | dd5d6fe9 | pbrook | static void gen_icount_end(TranslationBlock *tb, int num_insns) |
35 | dd5d6fe9 | pbrook | { |
36 | dd5d6fe9 | pbrook | if (use_icount) {
|
37 | dd5d6fe9 | pbrook | *icount_arg = num_insns; |
38 | dd5d6fe9 | pbrook | gen_set_label(icount_label); |
39 | dd5d6fe9 | pbrook | tcg_gen_exit_tb((long)tb + 2); |
40 | dd5d6fe9 | pbrook | } |
41 | dd5d6fe9 | pbrook | } |
42 | dd5d6fe9 | pbrook | |
43 | dd5d6fe9 | pbrook | static void inline gen_io_start(void) |
44 | dd5d6fe9 | pbrook | { |
45 | dd5d6fe9 | pbrook | TCGv tmp = tcg_const_i32(1);
|
46 | dd5d6fe9 | pbrook | tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, can_do_io)); |
47 | dd5d6fe9 | pbrook | tcg_temp_free(tmp); |
48 | dd5d6fe9 | pbrook | } |
49 | dd5d6fe9 | pbrook | |
50 | dd5d6fe9 | pbrook | static inline void gen_io_end(void) |
51 | dd5d6fe9 | pbrook | { |
52 | dd5d6fe9 | pbrook | TCGv tmp = tcg_const_i32(0);
|
53 | dd5d6fe9 | pbrook | tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, can_do_io)); |
54 | dd5d6fe9 | pbrook | tcg_temp_free(tmp); |
55 | dd5d6fe9 | pbrook | } |