use direct jump only for jumps in the same page


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1629 c046a42c-6fe2-441c-8c8c-71466251a162
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 0f6b0eb..dab0378 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -1700,6 +1700,31 @@
         return 4;
 }
 
+static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
+{
+    TranslationBlock *tb;
+    target_ulong pc;
+
+    pc = s->cs_base + eip;
+    tb = s->tb;
+    /* NOTE: we handle the case where the TB spans two pages here */
+    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
+        (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
+        /* jump to same page: we can use a direct jump */
+        if (tb_num == 0)
+            gen_op_goto_tb0(TBPARAM(tb));
+        else
+            gen_op_goto_tb1(TBPARAM(tb));
+        gen_jmp_im(eip);
+        gen_op_movl_T0_im((long)tb + tb_num);
+        gen_op_exit_tb();
+    } else {
+        /* jump to another page: currently not optimized */
+        gen_jmp_im(eip);
+        gen_eob(s);
+    }
+}
+
 static inline void gen_jcc(DisasContext *s, int b, 
                            target_ulong val, target_ulong next_eip)
 {
@@ -1779,8 +1804,10 @@
             break;
         }
 
-        if (s->cc_op != CC_OP_DYNAMIC)
+        if (s->cc_op != CC_OP_DYNAMIC) {
             gen_op_set_cc_op(s->cc_op);
+            s->cc_op = CC_OP_DYNAMIC;
+        }
 
         if (!func) {
             gen_setcc_slow[jcc_op]();
@@ -1797,16 +1824,10 @@
         l1 = gen_new_label();
         func(l1);
 
-        gen_op_goto_tb0(TBPARAM(tb));
-        gen_jmp_im(next_eip);
-        gen_op_movl_T0_im((long)tb + 0);
-        gen_op_exit_tb();
+        gen_goto_tb(s, 0, next_eip);
 
         gen_set_label(l1);
-        gen_op_goto_tb1(TBPARAM(tb));
-        gen_jmp_im(val);
-        gen_op_movl_T0_im((long)tb + 1);
-        gen_op_exit_tb();
+        gen_goto_tb(s, 1, val);
 
         s->is_jmp = 3;
     } else {
@@ -2217,18 +2238,12 @@
    direct call to the next block may occur */
 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
 {
-    TranslationBlock *tb = s->tb;
-
     if (s->jmp_opt) {
-        if (s->cc_op != CC_OP_DYNAMIC)
+        if (s->cc_op != CC_OP_DYNAMIC) {
             gen_op_set_cc_op(s->cc_op);
-        if (tb_num)
-            gen_op_goto_tb1(TBPARAM(tb));
-        else
-            gen_op_goto_tb0(TBPARAM(tb));
-        gen_jmp_im(eip);
-        gen_op_movl_T0_im((long)tb + tb_num);
-        gen_op_exit_tb();
+            s->cc_op = CC_OP_DYNAMIC;
+        }
+        gen_goto_tb(s, tb_num, eip);
         s->is_jmp = 3;
     } else {
         gen_jmp_im(eip);