summary refs log tree commit diff stats
path: root/include/exec
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2014-09-19 13:49:15 -0700
committerRichard Henderson <rth@twiddle.net>2015-02-12 21:21:38 -0800
commitc45cb8bb89fc798489869982c4c463b26ce43d7b (patch)
tree5d83e8a32cb947fe316b71e72a033d707da7ca50 /include/exec
parentfe700adb3db5b028b504423b946d4ee5200a8f2f (diff)
downloadfocaccia-qemu-c45cb8bb89fc798489869982c4c463b26ce43d7b.tar.gz
focaccia-qemu-c45cb8bb89fc798489869982c4c463b26ce43d7b.zip
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')
-rw-r--r--include/exec/gen-icount.h22
1 files changed, 16 insertions, 6 deletions
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index a37a61d038..6e5b01239b 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)