OSDN Git Service

added JUMP_TB2 for a third basic block exit jump point
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 17 Sep 2003 22:53:29 +0000 (22:53 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 17 Sep 2003 22:53:29 +0000 (22:53 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@380 c046a42c-6fe2-441c-8c8c-71466251a162

exec.h
translate.c

diff --git a/exec.h b/exec.h
index b63a66f..070a162 100644 (file)
--- a/exec.h
+++ b/exec.h
@@ -108,7 +108,7 @@ typedef struct TranslationBlock {
        the code of this one. */
     uint16_t tb_next_offset[2]; /* offset of original jump target */
 #ifdef USE_DIRECT_JUMP
-    uint16_t tb_jmp_offset[2]; /* offset of jump instruction */
+    uint16_t tb_jmp_offset[4]; /* offset of jump instruction */
 #else
     uint32_t tb_next[2]; /* address of jump generated code */
 #endif
@@ -160,18 +160,14 @@ static inline TranslationBlock *tb_find(TranslationBlock ***pptb,
 
 #if defined(__powerpc__)
 
-static inline void tb_set_jmp_target(TranslationBlock *tb, 
-                                     int n, unsigned long addr)
+static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
 {
     uint32_t val, *ptr;
-    unsigned long offset;
-
-    offset = (unsigned long)(tb->tc_ptr + tb->tb_jmp_offset[n]);
 
     /* patch the branch destination */
-    ptr = (uint32_t *)offset;
+    ptr = (uint32_t *)jmp_addr;
     val = *ptr;
-    val = (val & ~0x03fffffc) | ((addr - offset) & 0x03fffffc);
+    val = (val & ~0x03fffffc) | ((addr - jmp_addr) & 0x03fffffc);
     *ptr = val;
     /* flush icache */
     asm volatile ("dcbst 0,%0" : : "r"(ptr) : "memory");
@@ -181,6 +177,18 @@ static inline void tb_set_jmp_target(TranslationBlock *tb,
     asm volatile ("isync" : : : "memory");
 }
 
+static inline void tb_set_jmp_target(TranslationBlock *tb, 
+                                     int n, unsigned long addr)
+{
+    unsigned long offset;
+
+    offset = tb->tb_jmp_offset[n];
+    tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
+    offset = tb->tb_jmp_offset[n + 2];
+    if (offset != 0xffff)
+        tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
+}
+
 #else
 
 /* set the jump target */
@@ -228,6 +236,11 @@ do {\
     EXIT_TB();\
 } while (0)
 
+#define JUMP_TB2(opname, tbparam, n)\
+do {\
+    asm volatile ("b __op_jmp%0\n" : : "i" (n + 2));\
+} while (0)
+
 #else
 
 /* jump to next block operations (more portable code, does not need
@@ -244,6 +257,12 @@ dummy_label ## n:\
     EXIT_TB();\
 } while (0)
 
+/* second jump to same destination 'n' */
+#define JUMP_TB2(opname, tbparam, n)\
+do {\
+    goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\
+} while (0)
+
 #endif
 
 /* physical memory access */
index e9055c0..c9bca64 100644 (file)
@@ -120,6 +120,11 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb,
     tb->tb_next_offset[0] = 0xffff;
     tb->tb_next_offset[1] = 0xffff;
     gen_code_buf = tb->tc_ptr;
+#ifdef USE_DIRECT_JUMP
+    /* the following two entries are optional (only used for string ops) */
+    tb->tb_jmp_offset[2] = 0xffff;
+    tb->tb_jmp_offset[3] = 0xffff;
+#endif
     gen_code_size = dyngen_code(gen_code_buf, tb->tb_next_offset,
 #ifdef USE_DIRECT_JUMP
                                 tb->tb_jmp_offset,