]> Git Repo - qemu.git/blame - include/exec/gen-icount.h
Merge remote-tracking branch 'remotes/kraxel/tags/vga-20200605-pull-request' into...
[qemu.git] / include / exec / gen-icount.h
CommitLineData
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 8static TCGOp *icount_start_insn;
dd5d6fe9 9
ba3e7926
PD
10static inline void gen_io_start(void)
11{
12 TCGv_i32 tmp = tcg_const_i32(1);
13 tcg_gen_st_i32(tmp, cpu_env,
14 offsetof(ArchCPU, parent_obj.can_do_io) -
15 offsetof(ArchCPU, env));
16 tcg_temp_free_i32(tmp);
17}
18
9e9b10c6
PD
19/*
20 * cpu->can_do_io is cleared automatically at the beginning of
21 * each translation block. The cost is minimal and only paid
22 * for -icount, plus it would be very easy to forget doing it
23 * in the translator. Therefore, backends only need to call
24 * gen_io_start.
25 */
ba3e7926
PD
26static inline void gen_io_end(void)
27{
28 TCGv_i32 tmp = tcg_const_i32(0);
29 tcg_gen_st_i32(tmp, cpu_env,
30 offsetof(ArchCPU, parent_obj.can_do_io) -
31 offsetof(ArchCPU, env));
32 tcg_temp_free_i32(tmp);
33}
34
cd42d5b2 35static inline void gen_tb_start(TranslationBlock *tb)
dd5d6fe9 36{
1aab16c2 37 TCGv_i32 count, imm;
378df4b2 38
26689780 39 tcg_ctx->exitreq_label = gen_new_label();
c5a49c63 40 if (tb_cflags(tb) & CF_USE_ICOUNT) {
1aab16c2
PB
41 count = tcg_temp_local_new_i32();
42 } else {
43 count = tcg_temp_new_i32();
c45cb8bb 44 }
dd5d6fe9 45
1c2adb95 46 tcg_gen_ld_i32(count, cpu_env,
5e140196
RH
47 offsetof(ArchCPU, neg.icount_decr.u32) -
48 offsetof(ArchCPU, env));
c45cb8bb 49
c5a49c63 50 if (tb_cflags(tb) & CF_USE_ICOUNT) {
1aab16c2
PB
51 imm = tcg_temp_new_i32();
52 /* We emit a movi with a dummy immediate argument. Keep the insn index
53 * of the movi so that we later (when we know the actual insn count)
54 * can update the immediate argument with the actual insn count. */
1aab16c2 55 tcg_gen_movi_i32(imm, 0xdeadbeef);
15fa08f8 56 icount_start_insn = tcg_last_op();
1aab16c2
PB
57
58 tcg_gen_sub_i32(count, count, imm);
59 tcg_temp_free_i32(imm);
60 }
61
26689780 62 tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, tcg_ctx->exitreq_label);
c45cb8bb 63
c5a49c63 64 if (tb_cflags(tb) & CF_USE_ICOUNT) {
1c2adb95 65 tcg_gen_st16_i32(count, cpu_env,
5e140196
RH
66 offsetof(ArchCPU, neg.icount_decr.u16.low) -
67 offsetof(ArchCPU, env));
ba3e7926 68 gen_io_end();
1aab16c2 69 }
dd5d6fe9 70
a7812ae4 71 tcg_temp_free_i32(count);
dd5d6fe9
PB
72}
73
ae06cb46 74static inline void gen_tb_end(TranslationBlock *tb, int num_insns)
dd5d6fe9 75{
c5a49c63 76 if (tb_cflags(tb) & CF_USE_ICOUNT) {
25caa94c
EI
77 /* Update the num_insn immediate parameter now that we know
78 * the actual insn count. */
15fa08f8 79 tcg_set_insn_param(icount_start_insn, 1, num_insns);
dd5d6fe9 80 }
0a7df5da 81
26689780 82 gen_set_label(tcg_ctx->exitreq_label);
07ea28b4 83 tcg_gen_exit_tb(tb, TB_EXIT_REQUESTED);
dd5d6fe9
PB
84}
85
cb9c377f 86#endif
This page took 0.66939 seconds and 4 git commands to generate.