diff options
author | Richard Henderson <rth@twiddle.net> | 2014-09-19 13:49:15 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2015-02-12 21:21:38 -0800 |
commit | c45cb8bb89fc798489869982c4c463b26ce43d7b (patch) | |
tree | 5d83e8a32cb947fe316b71e72a033d707da7ca50 /include/exec/gen-icount.h | |
parent | fe700adb3db5b028b504423b946d4ee5200a8f2f (diff) | |
download | hqemu-c45cb8bb89fc798489869982c4c463b26ce43d7b.zip hqemu-c45cb8bb89fc798489869982c4c463b26ce43d7b.tar.gz |
tcg: Put opcodes in a linked list
The previous setup required ops and args to be completely sequential,
and was error prone when it came to both iteration and optimization.
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'include/exec/gen-icount.h')
-rw-r--r-- | include/exec/gen-icount.h | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h index a37a61d..6e5b012 100644 --- a/include/exec/gen-icount.h +++ b/include/exec/gen-icount.h @@ -11,8 +11,8 @@ static int exitreq_label; static inline void gen_tb_start(TranslationBlock *tb) { - TCGv_i32 count; - TCGv_i32 flag; + TCGv_i32 count, flag, imm; + int i; exitreq_label = gen_new_label(); flag = tcg_temp_new_i32(); @@ -21,16 +21,25 @@ static inline void gen_tb_start(TranslationBlock *tb) tcg_gen_brcondi_i32(TCG_COND_NE, flag, 0, exitreq_label); tcg_temp_free_i32(flag); - if (!(tb->cflags & CF_USE_ICOUNT)) + if (!(tb->cflags & CF_USE_ICOUNT)) { return; + } icount_label = gen_new_label(); count = tcg_temp_local_new_i32(); tcg_gen_ld_i32(count, cpu_env, -ENV_OFFSET + offsetof(CPUState, icount_decr.u32)); + + imm = tcg_temp_new_i32(); + tcg_gen_movi_i32(imm, 0xdeadbeef); + /* This is a horrid hack to allow fixing up the value later. */ - icount_arg = tcg_ctx.gen_opparam_ptr + 1; - tcg_gen_subi_i32(count, count, 0xdeadbeef); + i = tcg_ctx.gen_last_op_idx; + i = tcg_ctx.gen_op_buf[i].args; + icount_arg = &tcg_ctx.gen_opparam_buf[i + 1]; + + tcg_gen_sub_i32(count, count, imm); + tcg_temp_free_i32(imm); tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, icount_label); tcg_gen_st16_i32(count, cpu_env, @@ -49,7 +58,8 @@ static void gen_tb_end(TranslationBlock *tb, int num_insns) tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_ICOUNT_EXPIRED); } - *tcg_ctx.gen_opc_ptr = INDEX_op_end; + /* Terminate the linked list. */ + tcg_ctx.gen_op_buf[tcg_ctx.gen_last_op_idx].next = -1; } static inline void gen_io_start(void) |