Commit 6e256c935cbd5ce9bf1891477188549bbb43e55b

Authored by bellard
1 parent c1942362

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
target-arm/translate.c
@@ -903,16 +903,26 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) @@ -903,16 +903,26 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
903 return 0; 903 return 0;
904 } 904 }
905 905
906 -static inline void gen_jmp_tb(long tb, int n, uint32_t dest) 906 +static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
907 { 907 {
908 - if (n == 0)  
909 - gen_op_goto_tb0(TBPARAM(tb));  
910 - else  
911 - gen_op_goto_tb1(TBPARAM(tb));  
912 - gen_op_movl_T0_im(dest);  
913 - gen_op_movl_r15_T0();  
914 - gen_op_movl_T0_im(tb + n);  
915 - gen_op_exit_tb(); 908 + TranslationBlock *tb;
  909 +
  910 + tb = s->tb;
  911 + if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
  912 + if (n == 0)
  913 + gen_op_goto_tb0(TBPARAM(tb));
  914 + else
  915 + gen_op_goto_tb1(TBPARAM(tb));
  916 + gen_op_movl_T0_im(dest);
  917 + gen_op_movl_r15_T0();
  918 + gen_op_movl_T0_im((long)tb + n);
  919 + gen_op_exit_tb();
  920 + } else {
  921 + gen_op_movl_T0_im(dest);
  922 + gen_op_movl_r15_T0();
  923 + gen_op_movl_T0_0();
  924 + gen_op_exit_tb();
  925 + }
916 } 926 }
917 927
918 static inline void gen_jmp (DisasContext *s, uint32_t dest) 928 static inline void gen_jmp (DisasContext *s, uint32_t dest)
@@ -924,8 +934,7 @@ static inline void gen_jmp (DisasContext *s, uint32_t dest) @@ -924,8 +934,7 @@ static inline void gen_jmp (DisasContext *s, uint32_t dest)
924 gen_op_movl_T0_im(dest); 934 gen_op_movl_T0_im(dest);
925 gen_bx(s); 935 gen_bx(s);
926 } else { 936 } else {
927 - long tb = (long)s->tb;  
928 - gen_jmp_tb(tb, 0, dest); 937 + gen_goto_tb(s, 0, dest);
929 s->is_jmp = DISAS_TB_JUMP; 938 s->is_jmp = DISAS_TB_JUMP;
930 } 939 }
931 } 940 }
@@ -2137,7 +2146,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, @@ -2137,7 +2146,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
2137 } else { 2146 } else {
2138 switch(dc->is_jmp) { 2147 switch(dc->is_jmp) {
2139 case DISAS_NEXT: 2148 case DISAS_NEXT:
2140 - gen_jmp_tb((long)dc->tb, 1, dc->pc); 2149 + gen_goto_tb(dc, 1, dc->pc);
2141 break; 2150 break;
2142 default: 2151 default:
2143 case DISAS_JUMP: 2152 case DISAS_JUMP:
@@ -2152,7 +2161,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, @@ -2152,7 +2161,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
2152 } 2161 }
2153 if (dc->condjmp) { 2162 if (dc->condjmp) {
2154 gen_set_label(dc->condlabel); 2163 gen_set_label(dc->condlabel);
2155 - gen_jmp_tb((long)dc->tb, 1, dc->pc); 2164 + gen_goto_tb(dc, 1, dc->pc);
2156 dc->condjmp = 0; 2165 dc->condjmp = 0;
2157 } 2166 }
2158 } 2167 }
target-i386/translate.c
@@ -1700,6 +1700,31 @@ static inline int insn_const_size(unsigned int ot) @@ -1700,6 +1700,31 @@ static inline int insn_const_size(unsigned int ot)
1700 return 4; 1700 return 4;
1701 } 1701 }
1702 1702
  1703 +static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
  1704 +{
  1705 + TranslationBlock *tb;
  1706 + target_ulong pc;
  1707 +
  1708 + pc = s->cs_base + eip;
  1709 + tb = s->tb;
  1710 + /* NOTE: we handle the case where the TB spans two pages here */
  1711 + if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
  1712 + (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) {
  1713 + /* jump to same page: we can use a direct jump */
  1714 + if (tb_num == 0)
  1715 + gen_op_goto_tb0(TBPARAM(tb));
  1716 + else
  1717 + gen_op_goto_tb1(TBPARAM(tb));
  1718 + gen_jmp_im(eip);
  1719 + gen_op_movl_T0_im((long)tb + tb_num);
  1720 + gen_op_exit_tb();
  1721 + } else {
  1722 + /* jump to another page: currently not optimized */
  1723 + gen_jmp_im(eip);
  1724 + gen_eob(s);
  1725 + }
  1726 +}
  1727 +
1703 static inline void gen_jcc(DisasContext *s, int b, 1728 static inline void gen_jcc(DisasContext *s, int b,
1704 target_ulong val, target_ulong next_eip) 1729 target_ulong val, target_ulong next_eip)
1705 { 1730 {
@@ -1779,8 +1804,10 @@ static inline void gen_jcc(DisasContext *s, int b, @@ -1779,8 +1804,10 @@ static inline void gen_jcc(DisasContext *s, int b,
1779 break; 1804 break;
1780 } 1805 }
1781 1806
1782 - if (s->cc_op != CC_OP_DYNAMIC) 1807 + if (s->cc_op != CC_OP_DYNAMIC) {
1783 gen_op_set_cc_op(s->cc_op); 1808 gen_op_set_cc_op(s->cc_op);
  1809 + s->cc_op = CC_OP_DYNAMIC;
  1810 + }
1784 1811
1785 if (!func) { 1812 if (!func) {
1786 gen_setcc_slow[jcc_op](); 1813 gen_setcc_slow[jcc_op]();
@@ -1797,16 +1824,10 @@ static inline void gen_jcc(DisasContext *s, int b, @@ -1797,16 +1824,10 @@ static inline void gen_jcc(DisasContext *s, int b,
1797 l1 = gen_new_label(); 1824 l1 = gen_new_label();
1798 func(l1); 1825 func(l1);
1799 1826
1800 - gen_op_goto_tb0(TBPARAM(tb));  
1801 - gen_jmp_im(next_eip);  
1802 - gen_op_movl_T0_im((long)tb + 0);  
1803 - gen_op_exit_tb(); 1827 + gen_goto_tb(s, 0, next_eip);
1804 1828
1805 gen_set_label(l1); 1829 gen_set_label(l1);
1806 - gen_op_goto_tb1(TBPARAM(tb));  
1807 - gen_jmp_im(val);  
1808 - gen_op_movl_T0_im((long)tb + 1);  
1809 - gen_op_exit_tb(); 1830 + gen_goto_tb(s, 1, val);
1810 1831
1811 s->is_jmp = 3; 1832 s->is_jmp = 3;
1812 } else { 1833 } else {
@@ -2217,18 +2238,12 @@ static void gen_eob(DisasContext *s) @@ -2217,18 +2238,12 @@ static void gen_eob(DisasContext *s)
2217 direct call to the next block may occur */ 2238 direct call to the next block may occur */
2218 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num) 2239 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2219 { 2240 {
2220 - TranslationBlock *tb = s->tb;  
2221 -  
2222 if (s->jmp_opt) { 2241 if (s->jmp_opt) {
2223 - if (s->cc_op != CC_OP_DYNAMIC) 2242 + if (s->cc_op != CC_OP_DYNAMIC) {
2224 gen_op_set_cc_op(s->cc_op); 2243 gen_op_set_cc_op(s->cc_op);
2225 - if (tb_num)  
2226 - gen_op_goto_tb1(TBPARAM(tb));  
2227 - else  
2228 - gen_op_goto_tb0(TBPARAM(tb));  
2229 - gen_jmp_im(eip);  
2230 - gen_op_movl_T0_im((long)tb + tb_num);  
2231 - gen_op_exit_tb(); 2244 + s->cc_op = CC_OP_DYNAMIC;
  2245 + }
  2246 + gen_goto_tb(s, tb_num, eip);
2232 s->is_jmp = 3; 2247 s->is_jmp = 3;
2233 } else { 2248 } else {
2234 gen_jmp_im(eip); 2249 gen_jmp_im(eip);
target-mips/translate.c
@@ -928,15 +928,23 @@ static void gen_trap (DisasContext *ctx, uint16_t opc, @@ -928,15 +928,23 @@ static void gen_trap (DisasContext *ctx, uint16_t opc,
928 ctx->bstate = BS_STOP; 928 ctx->bstate = BS_STOP;
929 } 929 }
930 930
931 -static inline void gen_jmp_tb(long tb, int n, uint32_t dest) 931 +static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
932 { 932 {
933 - if (n == 0)  
934 - gen_op_goto_tb0(TBPARAM(tb));  
935 - else  
936 - gen_op_goto_tb1(TBPARAM(tb));  
937 - gen_op_save_pc(dest);  
938 - gen_op_set_T0(tb + n);  
939 - gen_op_exit_tb(); 933 + TranslationBlock *tb;
  934 + tb = ctx->tb;
  935 + if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
  936 + if (n == 0)
  937 + gen_op_goto_tb0(TBPARAM(tb));
  938 + else
  939 + gen_op_goto_tb1(TBPARAM(tb));
  940 + gen_op_save_pc(dest);
  941 + gen_op_set_T0((long)tb + n);
  942 + gen_op_exit_tb();
  943 + } else {
  944 + gen_op_save_pc(dest);
  945 + gen_op_set_T0(0);
  946 + gen_op_exit_tb();
  947 + }
940 } 948 }
941 949
942 /* Branches (before delay slot) */ 950 /* Branches (before delay slot) */
@@ -1035,7 +1043,7 @@ static void gen_compute_branch (DisasContext *ctx, uint16_t opc, @@ -1035,7 +1043,7 @@ static void gen_compute_branch (DisasContext *ctx, uint16_t opc,
1035 case OPC_BLTZL: /* 0 < 0 likely */ 1043 case OPC_BLTZL: /* 0 < 0 likely */
1036 /* Skip the instruction in the delay slot */ 1044 /* Skip the instruction in the delay slot */
1037 MIPS_DEBUG("bnever and skip"); 1045 MIPS_DEBUG("bnever and skip");
1038 - gen_jmp_tb((long)ctx->tb, 0, ctx->pc + 4); 1046 + gen_goto_tb(ctx, 0, ctx->pc + 4);
1039 return; 1047 return;
1040 case OPC_J: 1048 case OPC_J:
1041 ctx->hflags |= MIPS_HFLAG_DS | MIPS_HFLAG_B; 1049 ctx->hflags |= MIPS_HFLAG_DS | MIPS_HFLAG_B;
@@ -1278,7 +1286,7 @@ static void gen_blikely(DisasContext *ctx) @@ -1278,7 +1286,7 @@ static void gen_blikely(DisasContext *ctx)
1278 l1 = gen_new_label(); 1286 l1 = gen_new_label();
1279 gen_op_jnz_T2(l1); 1287 gen_op_jnz_T2(l1);
1280 gen_op_save_state(ctx->hflags & ~(MIPS_HFLAG_BMASK | MIPS_HFLAG_DS)); 1288 gen_op_save_state(ctx->hflags & ~(MIPS_HFLAG_BMASK | MIPS_HFLAG_DS));
1281 - gen_jmp_tb((long)ctx->tb, 1, ctx->pc + 4); 1289 + gen_goto_tb(ctx, 1, ctx->pc + 4);
1282 } 1290 }
1283 1291
1284 static void decode_opc (DisasContext *ctx) 1292 static void decode_opc (DisasContext *ctx)
@@ -1502,12 +1510,12 @@ static void decode_opc (DisasContext *ctx) @@ -1502,12 +1510,12 @@ static void decode_opc (DisasContext *ctx)
1502 case MIPS_HFLAG_B: 1510 case MIPS_HFLAG_B:
1503 /* unconditional branch */ 1511 /* unconditional branch */
1504 MIPS_DEBUG("unconditional branch"); 1512 MIPS_DEBUG("unconditional branch");
1505 - gen_jmp_tb((long)ctx->tb, 0, ctx->btarget); 1513 + gen_goto_tb(ctx, 0, ctx->btarget);
1506 break; 1514 break;
1507 case MIPS_HFLAG_BL: 1515 case MIPS_HFLAG_BL:
1508 /* blikely taken case */ 1516 /* blikely taken case */
1509 MIPS_DEBUG("blikely branch taken"); 1517 MIPS_DEBUG("blikely branch taken");
1510 - gen_jmp_tb((long)ctx->tb, 0, ctx->btarget); 1518 + gen_goto_tb(ctx, 0, ctx->btarget);
1511 break; 1519 break;
1512 case MIPS_HFLAG_BC: 1520 case MIPS_HFLAG_BC:
1513 /* Conditional branch */ 1521 /* Conditional branch */
@@ -1516,9 +1524,9 @@ static void decode_opc (DisasContext *ctx) @@ -1516,9 +1524,9 @@ static void decode_opc (DisasContext *ctx)
1516 int l1; 1524 int l1;
1517 l1 = gen_new_label(); 1525 l1 = gen_new_label();
1518 gen_op_jnz_T2(l1); 1526 gen_op_jnz_T2(l1);
1519 - gen_jmp_tb((long)ctx->tb, 0, ctx->btarget); 1527 + gen_goto_tb(ctx, 0, ctx->btarget);
1520 gen_set_label(l1); 1528 gen_set_label(l1);
1521 - gen_jmp_tb((long)ctx->tb, 1, ctx->pc + 4); 1529 + gen_goto_tb(ctx, 1, ctx->pc + 4);
1522 } 1530 }
1523 break; 1531 break;
1524 case MIPS_HFLAG_BR: 1532 case MIPS_HFLAG_BR:
@@ -1603,7 +1611,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, @@ -1603,7 +1611,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
1603 } 1611 }
1604 if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) { 1612 if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) {
1605 save_cpu_state(ctxp, 0); 1613 save_cpu_state(ctxp, 0);
1606 - gen_jmp_tb((long)ctx.tb, 0, ctx.pc); 1614 + gen_goto_tb(&ctx, 0, ctx.pc);
1607 } 1615 }
1608 gen_op_reset_T0(); 1616 gen_op_reset_T0();
1609 /* Generate the return instruction */ 1617 /* Generate the return instruction */
target-sparc/translate.c
@@ -561,6 +561,32 @@ static inline void gen_movl_npc_im(target_ulong npc) @@ -561,6 +561,32 @@ static inline void gen_movl_npc_im(target_ulong npc)
561 #endif 561 #endif
562 } 562 }
563 563
  564 +static inline void gen_goto_tb(DisasContext *s, int tb_num,
  565 + target_ulong pc, target_ulong npc)
  566 +{
  567 + TranslationBlock *tb;
  568 +
  569 + tb = s->tb;
  570 + if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
  571 + (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK)) {
  572 + /* jump to same page: we can use a direct jump */
  573 + if (tb_num == 0)
  574 + gen_op_goto_tb0(TBPARAM(tb));
  575 + else
  576 + gen_op_goto_tb1(TBPARAM(tb));
  577 + gen_jmp_im(pc);
  578 + gen_movl_npc_im(npc);
  579 + gen_op_movl_T0_im((long)tb + tb_num);
  580 + gen_op_exit_tb();
  581 + } else {
  582 + /* jump to another page: currently not optimized */
  583 + gen_jmp_im(pc);
  584 + gen_movl_npc_im(npc);
  585 + gen_op_movl_T0_0();
  586 + gen_op_exit_tb();
  587 + }
  588 +}
  589 +
564 static inline void gen_branch2(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2) 590 static inline void gen_branch2(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
565 { 591 {
566 int l1; 592 int l1;
@@ -569,18 +595,10 @@ static inline void gen_branch2(DisasContext *dc, long tb, target_ulong pc1, targ @@ -569,18 +595,10 @@ static inline void gen_branch2(DisasContext *dc, long tb, target_ulong pc1, targ
569 595
570 gen_op_jz_T2_label(l1); 596 gen_op_jz_T2_label(l1);
571 597
572 - gen_op_goto_tb0(TBPARAM(tb));  
573 - gen_jmp_im(pc1);  
574 - gen_movl_npc_im(pc1 + 4);  
575 - gen_op_movl_T0_im((long)tb + 0);  
576 - gen_op_exit_tb(); 598 + gen_goto_tb(dc, 0, pc1, pc1 + 4);
577 599
578 gen_set_label(l1); 600 gen_set_label(l1);
579 - gen_op_goto_tb1(TBPARAM(tb));  
580 - gen_jmp_im(pc2);  
581 - gen_movl_npc_im(pc2 + 4);  
582 - gen_op_movl_T0_im((long)tb + 1);  
583 - gen_op_exit_tb(); 601 + gen_goto_tb(dc, 1, pc2, pc2 + 4);
584 } 602 }
585 603
586 static inline void gen_branch_a(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2) 604 static inline void gen_branch_a(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
@@ -591,27 +609,15 @@ static inline void gen_branch_a(DisasContext *dc, long tb, target_ulong pc1, tar @@ -591,27 +609,15 @@ static inline void gen_branch_a(DisasContext *dc, long tb, target_ulong pc1, tar
591 609
592 gen_op_jz_T2_label(l1); 610 gen_op_jz_T2_label(l1);
593 611
594 - gen_op_goto_tb0(TBPARAM(tb));  
595 - gen_jmp_im(pc2);  
596 - gen_movl_npc_im(pc1);  
597 - gen_op_movl_T0_im((long)tb + 0);  
598 - gen_op_exit_tb(); 612 + gen_goto_tb(dc, 0, pc2, pc1);
599 613
600 gen_set_label(l1); 614 gen_set_label(l1);
601 - gen_op_goto_tb1(TBPARAM(tb));  
602 - gen_jmp_im(pc2 + 4);  
603 - gen_movl_npc_im(pc2 + 8);  
604 - gen_op_movl_T0_im((long)tb + 1);  
605 - gen_op_exit_tb(); 615 + gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
606 } 616 }
607 617
608 static inline void gen_branch(DisasContext *dc, long tb, target_ulong pc, target_ulong npc) 618 static inline void gen_branch(DisasContext *dc, long tb, target_ulong pc, target_ulong npc)
609 { 619 {
610 - gen_op_goto_tb0(TBPARAM(tb));  
611 - gen_jmp_im(pc);  
612 - gen_movl_npc_im(npc);  
613 - gen_op_movl_T0_im((long)tb + 0);  
614 - gen_op_exit_tb(); 620 + gen_goto_tb(dc, 0, pc, npc);
615 } 621 }
616 622
617 static inline void gen_generic_branch(DisasContext *dc, target_ulong npc1, target_ulong npc2) 623 static inline void gen_generic_branch(DisasContext *dc, target_ulong npc1, target_ulong npc2)