aboutsummaryrefslogtreecommitdiff
path: root/include/exec/gen-icount.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/exec/gen-icount.h')
-rw-r--r--include/exec/gen-icount.h44
1 files changed, 26 insertions, 18 deletions
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index f7669b6841..822c43cfd3 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -7,6 +7,31 @@
static TCGOp *icount_start_insn;
+static inline void gen_io_start(void)
+{
+ TCGv_i32 tmp = tcg_const_i32(1);
+ tcg_gen_st_i32(tmp, cpu_env,
+ offsetof(ArchCPU, parent_obj.can_do_io) -
+ offsetof(ArchCPU, env));
+ tcg_temp_free_i32(tmp);
+}
+
+/*
+ * cpu->can_do_io is cleared automatically at the beginning of
+ * each translation block. The cost is minimal and only paid
+ * for -icount, plus it would be very easy to forget doing it
+ * in the translator. Therefore, backends only need to call
+ * gen_io_start.
+ */
+static inline void gen_io_end(void)
+{
+ TCGv_i32 tmp = tcg_const_i32(0);
+ tcg_gen_st_i32(tmp, cpu_env,
+ offsetof(ArchCPU, parent_obj.can_do_io) -
+ offsetof(ArchCPU, env));
+ tcg_temp_free_i32(tmp);
+}
+
static inline void gen_tb_start(TranslationBlock *tb)
{
TCGv_i32 count, imm;
@@ -40,6 +65,7 @@ static inline void gen_tb_start(TranslationBlock *tb)
tcg_gen_st16_i32(count, cpu_env,
offsetof(ArchCPU, neg.icount_decr.u16.low) -
offsetof(ArchCPU, env));
+ gen_io_end();
}
tcg_temp_free_i32(count);
@@ -57,22 +83,4 @@ static inline void gen_tb_end(TranslationBlock *tb, int num_insns)
tcg_gen_exit_tb(tb, TB_EXIT_REQUESTED);
}
-static inline void gen_io_start(void)
-{
- TCGv_i32 tmp = tcg_const_i32(1);
- tcg_gen_st_i32(tmp, cpu_env,
- offsetof(ArchCPU, parent_obj.can_do_io) -
- offsetof(ArchCPU, env));
- tcg_temp_free_i32(tmp);
-}
-
-static inline void gen_io_end(void)
-{
- TCGv_i32 tmp = tcg_const_i32(0);
- tcg_gen_st_i32(tmp, cpu_env,
- offsetof(ArchCPU, parent_obj.can_do_io) -
- offsetof(ArchCPU, env));
- tcg_temp_free_i32(tmp);
-}
-
#endif