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 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 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 934 gen_op_movl_T0_im(dest);
925 935 gen_bx(s);
926 936 } else {
927   - long tb = (long)s->tb;
928   - gen_jmp_tb(tb, 0, dest);
  937 + gen_goto_tb(s, 0, dest);
929 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 2146 } else {
2138 2147 switch(dc->is_jmp) {
2139 2148 case DISAS_NEXT:
2140   - gen_jmp_tb((long)dc->tb, 1, dc->pc);
  2149 + gen_goto_tb(dc, 1, dc->pc);
2141 2150 break;
2142 2151 default:
2143 2152 case DISAS_JUMP:
... ... @@ -2152,7 +2161,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
2152 2161 }
2153 2162 if (dc->condjmp) {
2154 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 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 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 1728 static inline void gen_jcc(DisasContext *s, int b,
1704 1729 target_ulong val, target_ulong next_eip)
1705 1730 {
... ... @@ -1779,8 +1804,10 @@ static inline void gen_jcc(DisasContext *s, int b,
1779 1804 break;
1780 1805 }
1781 1806  
1782   - if (s->cc_op != CC_OP_DYNAMIC)
  1807 + if (s->cc_op != CC_OP_DYNAMIC) {
1783 1808 gen_op_set_cc_op(s->cc_op);
  1809 + s->cc_op = CC_OP_DYNAMIC;
  1810 + }
1784 1811  
1785 1812 if (!func) {
1786 1813 gen_setcc_slow[jcc_op]();
... ... @@ -1797,16 +1824,10 @@ static inline void gen_jcc(DisasContext *s, int b,
1797 1824 l1 = gen_new_label();
1798 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 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 1832 s->is_jmp = 3;
1812 1833 } else {
... ... @@ -2217,18 +2238,12 @@ static void gen_eob(DisasContext *s)
2217 2238 direct call to the next block may occur */
2218 2239 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num)
2219 2240 {
2220   - TranslationBlock *tb = s->tb;
2221   -
2222 2241 if (s->jmp_opt) {
2223   - if (s->cc_op != CC_OP_DYNAMIC)
  2242 + if (s->cc_op != CC_OP_DYNAMIC) {
2224 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 2247 s->is_jmp = 3;
2233 2248 } else {
2234 2249 gen_jmp_im(eip);
... ...
target-mips/translate.c
... ... @@ -928,15 +928,23 @@ static void gen_trap (DisasContext *ctx, uint16_t opc,
928 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 950 /* Branches (before delay slot) */
... ... @@ -1035,7 +1043,7 @@ static void gen_compute_branch (DisasContext *ctx, uint16_t opc,
1035 1043 case OPC_BLTZL: /* 0 < 0 likely */
1036 1044 /* Skip the instruction in the delay slot */
1037 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 1047 return;
1040 1048 case OPC_J:
1041 1049 ctx->hflags |= MIPS_HFLAG_DS | MIPS_HFLAG_B;
... ... @@ -1278,7 +1286,7 @@ static void gen_blikely(DisasContext *ctx)
1278 1286 l1 = gen_new_label();
1279 1287 gen_op_jnz_T2(l1);
1280 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 1292 static void decode_opc (DisasContext *ctx)
... ... @@ -1502,12 +1510,12 @@ static void decode_opc (DisasContext *ctx)
1502 1510 case MIPS_HFLAG_B:
1503 1511 /* unconditional branch */
1504 1512 MIPS_DEBUG("unconditional branch");
1505   - gen_jmp_tb((long)ctx->tb, 0, ctx->btarget);
  1513 + gen_goto_tb(ctx, 0, ctx->btarget);
1506 1514 break;
1507 1515 case MIPS_HFLAG_BL:
1508 1516 /* blikely taken case */
1509 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 1519 break;
1512 1520 case MIPS_HFLAG_BC:
1513 1521 /* Conditional branch */
... ... @@ -1516,9 +1524,9 @@ static void decode_opc (DisasContext *ctx)
1516 1524 int l1;
1517 1525 l1 = gen_new_label();
1518 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 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 1531 break;
1524 1532 case MIPS_HFLAG_BR:
... ... @@ -1603,7 +1611,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
1603 1611 }
1604 1612 if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) {
1605 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 1616 gen_op_reset_T0();
1609 1617 /* Generate the return instruction */
... ...
target-sparc/translate.c
... ... @@ -561,6 +561,32 @@ static inline void gen_movl_npc_im(target_ulong npc)
561 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 590 static inline void gen_branch2(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
565 591 {
566 592 int l1;
... ... @@ -569,18 +595,10 @@ static inline void gen_branch2(DisasContext *dc, long tb, target_ulong pc1, targ
569 595  
570 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 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 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 609  
592 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 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 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 623 static inline void gen_generic_branch(DisasContext *dc, target_ulong npc1, target_ulong npc2)
... ...