Commit c53be3347484b0f73deebcfa2e5faf538d6fa7c0
1 parent
d5d11eac
suppressed JUMP_TB (Paul Brook)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1594 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
7 changed files
with
116 additions
and
60 deletions
exec-all.h
| ... | ... | @@ -365,15 +365,6 @@ dummy_label ## n: ;\ |
| 365 | 365 | |
| 366 | 366 | #endif |
| 367 | 367 | |
| 368 | -/* XXX: will be suppressed */ | |
| 369 | -#define JUMP_TB(opname, tbparam, n, eip)\ | |
| 370 | -do {\ | |
| 371 | - GOTO_TB(opname, tbparam, n);\ | |
| 372 | - T0 = (long)(tbparam) + (n);\ | |
| 373 | - EIP = (int32_t)eip;\ | |
| 374 | - EXIT_TB();\ | |
| 375 | -} while (0) | |
| 376 | - | |
| 377 | 368 | extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; |
| 378 | 369 | extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; |
| 379 | 370 | extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; | ... | ... |
target-arm/op.c
| ... | ... | @@ -346,14 +346,14 @@ void OPPROTO op_test_le(void) |
| 346 | 346 | FORCE_RET(); |
| 347 | 347 | } |
| 348 | 348 | |
| 349 | -void OPPROTO op_jmp0(void) | |
| 349 | +void OPPROTO op_goto_tb0(void) | |
| 350 | 350 | { |
| 351 | - JUMP_TB(op_jmp0, PARAM1, 0, PARAM2); | |
| 351 | + GOTO_TB(op_goto_tb0, PARAM1, 0); | |
| 352 | 352 | } |
| 353 | 353 | |
| 354 | -void OPPROTO op_jmp1(void) | |
| 354 | +void OPPROTO op_goto_tb1(void) | |
| 355 | 355 | { |
| 356 | - JUMP_TB(op_jmp1, PARAM1, 1, PARAM2); | |
| 356 | + GOTO_TB(op_goto_tb1, PARAM1, 1); | |
| 357 | 357 | } |
| 358 | 358 | |
| 359 | 359 | void OPPROTO op_exit_tb(void) | ... | ... |
target-arm/translate.c
| ... | ... | @@ -43,6 +43,12 @@ typedef struct DisasContext { |
| 43 | 43 | |
| 44 | 44 | #define DISAS_JUMP_NEXT 4 |
| 45 | 45 | |
| 46 | +#ifdef USE_DIRECT_JUMP | |
| 47 | +#define TBPARAM(x) | |
| 48 | +#else | |
| 49 | +#define TBPARAM(x) (long)(x) | |
| 50 | +#endif | |
| 51 | + | |
| 46 | 52 | /* XXX: move that elsewhere */ |
| 47 | 53 | static uint16_t *gen_opc_ptr; |
| 48 | 54 | static uint32_t *gen_opparam_ptr; |
| ... | ... | @@ -897,6 +903,18 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) |
| 897 | 903 | return 0; |
| 898 | 904 | } |
| 899 | 905 | |
| 906 | +static inline void gen_jmp_tb(long tb, int n, uint32_t dest) | |
| 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(); | |
| 916 | +} | |
| 917 | + | |
| 900 | 918 | static inline void gen_jmp (DisasContext *s, uint32_t dest) |
| 901 | 919 | { |
| 902 | 920 | if (__builtin_expect(s->singlestep_enabled, 0)) { |
| ... | ... | @@ -906,7 +924,8 @@ static inline void gen_jmp (DisasContext *s, uint32_t dest) |
| 906 | 924 | gen_op_movl_T0_im(dest); |
| 907 | 925 | gen_bx(s); |
| 908 | 926 | } else { |
| 909 | - gen_op_jmp0((long)s->tb, dest); | |
| 927 | + long tb = (long)s->tb; | |
| 928 | + gen_jmp_tb(tb, 0, dest); | |
| 910 | 929 | s->is_jmp = DISAS_TB_JUMP; |
| 911 | 930 | } |
| 912 | 931 | } |
| ... | ... | @@ -2118,7 +2137,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, |
| 2118 | 2137 | } else { |
| 2119 | 2138 | switch(dc->is_jmp) { |
| 2120 | 2139 | case DISAS_NEXT: |
| 2121 | - gen_op_jmp1((long)dc->tb, (long)dc->pc); | |
| 2140 | + gen_jmp_tb((long)dc->tb, 1, dc->pc); | |
| 2122 | 2141 | break; |
| 2123 | 2142 | default: |
| 2124 | 2143 | case DISAS_JUMP: |
| ... | ... | @@ -2133,7 +2152,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, |
| 2133 | 2152 | } |
| 2134 | 2153 | if (dc->condjmp) { |
| 2135 | 2154 | gen_set_label(dc->condlabel); |
| 2136 | - gen_op_jmp1((long)dc->tb, (long)dc->pc); | |
| 2155 | + gen_jmp_tb((long)dc->tb, 1, dc->pc); | |
| 2137 | 2156 | dc->condjmp = 0; |
| 2138 | 2157 | } |
| 2139 | 2158 | } | ... | ... |
target-mips/op.c
| ... | ... | @@ -487,7 +487,16 @@ OP_COND(ltz, (int32_t)T0 < 0); |
| 487 | 487 | |
| 488 | 488 | /* Branchs */ |
| 489 | 489 | //#undef USE_DIRECT_JUMP |
| 490 | -#define EIP env->PC | |
| 490 | + | |
| 491 | +void OPPROTO op_goto_tb0(void) | |
| 492 | +{ | |
| 493 | + GOTO_TB(op_goto_tb0, PARAM1, 0); | |
| 494 | +} | |
| 495 | + | |
| 496 | +void OPPROTO op_goto_tb1(void) | |
| 497 | +{ | |
| 498 | + GOTO_TB(op_goto_tb1, PARAM1, 1); | |
| 499 | +} | |
| 491 | 500 | |
| 492 | 501 | /* Branch to register */ |
| 493 | 502 | void op_save_breg_target (void) |
| ... | ... | @@ -506,13 +515,6 @@ void op_breg (void) |
| 506 | 515 | RETURN(); |
| 507 | 516 | } |
| 508 | 517 | |
| 509 | -/* Unconditional branch */ | |
| 510 | -void op_branch (void) | |
| 511 | -{ | |
| 512 | - JUMP_TB(branch, PARAM1, 0, PARAM2); | |
| 513 | - RETURN(); | |
| 514 | -} | |
| 515 | - | |
| 516 | 518 | void op_save_btarget (void) |
| 517 | 519 | { |
| 518 | 520 | env->btarget = PARAM1; |
| ... | ... | @@ -538,24 +540,10 @@ void op_restore_bcond (void) |
| 538 | 540 | RETURN(); |
| 539 | 541 | } |
| 540 | 542 | |
| 541 | -void op_bcond (void) | |
| 542 | -{ | |
| 543 | - if (T2) { | |
| 544 | - JUMP_TB(bcond, PARAM1, 0, PARAM2); | |
| 545 | - } else { | |
| 546 | - JUMP_TB(bcond, PARAM1, 1, PARAM3); | |
| 547 | - } | |
| 548 | - RETURN(); | |
| 549 | -} | |
| 550 | - | |
| 551 | -/* Likely branch (used to skip the delay slot) */ | |
| 552 | -void op_blikely (void) | |
| 543 | +void op_jnz_T2 (void) | |
| 553 | 544 | { |
| 554 | - /* If the test is false, skip the delay slot */ | |
| 555 | - if (T2 == 0) { | |
| 556 | - env->hflags = PARAM3; | |
| 557 | - JUMP_TB(blikely, PARAM1, 1, PARAM2); | |
| 558 | - } | |
| 545 | + if (T2) | |
| 546 | + GOTO_LABEL_PARAM(1); | |
| 559 | 547 | RETURN(); |
| 560 | 548 | } |
| 561 | 549 | ... | ... |
target-mips/translate.c
| ... | ... | @@ -31,6 +31,12 @@ |
| 31 | 31 | #define MIPS_DEBUG_DISAS |
| 32 | 32 | //#define MIPS_SINGLE_STEP |
| 33 | 33 | |
| 34 | +#ifdef USE_DIRECT_JUMP | |
| 35 | +#define TBPARAM(x) | |
| 36 | +#else | |
| 37 | +#define TBPARAM(x) (long)(x) | |
| 38 | +#endif | |
| 39 | + | |
| 34 | 40 | enum { |
| 35 | 41 | #define DEF(s, n, copy_size) INDEX_op_ ## s, |
| 36 | 42 | #include "opc.h" |
| ... | ... | @@ -922,6 +928,17 @@ static void gen_trap (DisasContext *ctx, uint16_t opc, |
| 922 | 928 | ctx->bstate = BS_STOP; |
| 923 | 929 | } |
| 924 | 930 | |
| 931 | +static inline void gen_jmp_tb(long tb, int n, uint32_t dest) | |
| 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(); | |
| 940 | +} | |
| 941 | + | |
| 925 | 942 | /* Branches (before delay slot) */ |
| 926 | 943 | static void gen_compute_branch (DisasContext *ctx, uint16_t opc, |
| 927 | 944 | int rs, int rt, int32_t offset) |
| ... | ... | @@ -1018,7 +1035,7 @@ static void gen_compute_branch (DisasContext *ctx, uint16_t opc, |
| 1018 | 1035 | case OPC_BLTZL: /* 0 < 0 likely */ |
| 1019 | 1036 | /* Skip the instruction in the delay slot */ |
| 1020 | 1037 | MIPS_DEBUG("bnever and skip"); |
| 1021 | - gen_op_branch((long)ctx->tb, ctx->pc + 4); | |
| 1038 | + gen_jmp_tb((long)ctx->tb, 0, ctx->pc + 4); | |
| 1022 | 1039 | return; |
| 1023 | 1040 | case OPC_J: |
| 1024 | 1041 | ctx->hflags |= MIPS_HFLAG_DS | MIPS_HFLAG_B; |
| ... | ... | @@ -1255,6 +1272,15 @@ static void gen_arith64 (DisasContext *ctx, uint16_t opc) |
| 1255 | 1272 | |
| 1256 | 1273 | #endif |
| 1257 | 1274 | |
| 1275 | +static void gen_blikely(DisasContext *ctx) | |
| 1276 | +{ | |
| 1277 | + int l1; | |
| 1278 | + l1 = gen_new_label(); | |
| 1279 | + gen_op_jnz_T2(l1); | |
| 1280 | + gen_op_save_state(ctx->hflags & ~(MIPS_HFLAG_BMASK | MIPS_HFLAG_DS)); | |
| 1281 | + gen_jmp_tb((long)ctx->tb, 1, ctx->pc + 4); | |
| 1282 | +} | |
| 1283 | + | |
| 1258 | 1284 | static void decode_opc (DisasContext *ctx) |
| 1259 | 1285 | { |
| 1260 | 1286 | int32_t offset; |
| ... | ... | @@ -1266,8 +1292,7 @@ static void decode_opc (DisasContext *ctx) |
| 1266 | 1292 | (ctx->hflags & MIPS_HFLAG_BL)) { |
| 1267 | 1293 | /* Handle blikely not taken case */ |
| 1268 | 1294 | MIPS_DEBUG("blikely condition (%08x)", ctx->pc + 4); |
| 1269 | - gen_op_blikely((long)ctx->tb, ctx->pc + 4, | |
| 1270 | - ctx->hflags & ~(MIPS_HFLAG_BMASK | MIPS_HFLAG_DS)); | |
| 1295 | + gen_blikely(ctx); | |
| 1271 | 1296 | } |
| 1272 | 1297 | op = ctx->opcode >> 26; |
| 1273 | 1298 | rs = ((ctx->opcode >> 21) & 0x1F); |
| ... | ... | @@ -1477,17 +1502,24 @@ static void decode_opc (DisasContext *ctx) |
| 1477 | 1502 | case MIPS_HFLAG_B: |
| 1478 | 1503 | /* unconditional branch */ |
| 1479 | 1504 | MIPS_DEBUG("unconditional branch"); |
| 1480 | - gen_op_branch((long)ctx->tb, ctx->btarget); | |
| 1505 | + gen_jmp_tb((long)ctx->tb, 0, ctx->btarget); | |
| 1481 | 1506 | break; |
| 1482 | 1507 | case MIPS_HFLAG_BL: |
| 1483 | 1508 | /* blikely taken case */ |
| 1484 | 1509 | MIPS_DEBUG("blikely branch taken"); |
| 1485 | - gen_op_branch((long)ctx->tb, ctx->btarget); | |
| 1510 | + gen_jmp_tb((long)ctx->tb, 0, ctx->btarget); | |
| 1486 | 1511 | break; |
| 1487 | 1512 | case MIPS_HFLAG_BC: |
| 1488 | 1513 | /* Conditional branch */ |
| 1489 | 1514 | MIPS_DEBUG("conditional branch"); |
| 1490 | - gen_op_bcond((long)ctx->tb, ctx->btarget, ctx->pc + 4); | |
| 1515 | + { | |
| 1516 | + int l1; | |
| 1517 | + l1 = gen_new_label(); | |
| 1518 | + gen_op_jnz_T2(l1); | |
| 1519 | + gen_jmp_tb((long)ctx->tb, 0, ctx->btarget); | |
| 1520 | + gen_set_label(l1); | |
| 1521 | + gen_jmp_tb((long)ctx->tb, 1, ctx->pc + 4); | |
| 1522 | + } | |
| 1491 | 1523 | break; |
| 1492 | 1524 | case MIPS_HFLAG_BR: |
| 1493 | 1525 | /* unconditional branch to register */ |
| ... | ... | @@ -1513,6 +1545,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
| 1513 | 1545 | gen_opc_ptr = gen_opc_buf; |
| 1514 | 1546 | gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; |
| 1515 | 1547 | gen_opparam_ptr = gen_opparam_buf; |
| 1548 | + nb_gen_labels = 0; | |
| 1516 | 1549 | ctx.pc = pc_start; |
| 1517 | 1550 | ctx.tb = tb; |
| 1518 | 1551 | ctx.bstate = BS_NONE; |
| ... | ... | @@ -1570,7 +1603,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
| 1570 | 1603 | } |
| 1571 | 1604 | if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) { |
| 1572 | 1605 | save_cpu_state(ctxp, 0); |
| 1573 | - gen_op_branch((long)ctx.tb, ctx.pc); | |
| 1606 | + gen_jmp_tb((long)ctx.tb, 0, ctx.pc); | |
| 1574 | 1607 | } |
| 1575 | 1608 | gen_op_reset_T0(); |
| 1576 | 1609 | /* Generate the return instruction */ | ... | ... |
target-ppc/op.c
| ... | ... | @@ -451,9 +451,14 @@ PPC_OP(setlr) |
| 451 | 451 | regs->lr = PARAM1; |
| 452 | 452 | } |
| 453 | 453 | |
| 454 | -PPC_OP(b) | |
| 454 | +PPC_OP(goto_tb0) | |
| 455 | 455 | { |
| 456 | - JUMP_TB(b1, PARAM1, 0, PARAM2); | |
| 456 | + GOTO_TB(op_goto_tb0, PARAM1, 0); | |
| 457 | +} | |
| 458 | + | |
| 459 | +PPC_OP(goto_tb1) | |
| 460 | +{ | |
| 461 | + GOTO_TB(op_goto_tb1, PARAM1, 1); | |
| 457 | 462 | } |
| 458 | 463 | |
| 459 | 464 | PPC_OP(b_T1) |
| ... | ... | @@ -461,13 +466,10 @@ PPC_OP(b_T1) |
| 461 | 466 | regs->nip = T1 & ~3; |
| 462 | 467 | } |
| 463 | 468 | |
| 464 | -PPC_OP(btest) | |
| 469 | +PPC_OP(jz_T0) | |
| 465 | 470 | { |
| 466 | - if (T0) { | |
| 467 | - JUMP_TB(btest, PARAM1, 0, PARAM2); | |
| 468 | - } else { | |
| 469 | - JUMP_TB(btest, PARAM1, 1, PARAM3); | |
| 470 | - } | |
| 471 | + if (!T0) | |
| 472 | + GOTO_LABEL_PARAM(1); | |
| 471 | 473 | RETURN(); |
| 472 | 474 | } |
| 473 | 475 | ... | ... |
target-ppc/translate.c
| ... | ... | @@ -30,6 +30,12 @@ |
| 30 | 30 | //#define DO_SINGLE_STEP |
| 31 | 31 | //#define PPC_DEBUG_DISAS |
| 32 | 32 | |
| 33 | +#ifdef USE_DIRECT_JUMP | |
| 34 | +#define TBPARAM(x) | |
| 35 | +#else | |
| 36 | +#define TBPARAM(x) (long)(x) | |
| 37 | +#endif | |
| 38 | + | |
| 33 | 39 | enum { |
| 34 | 40 | #define DEF(s, n, copy_size) INDEX_op_ ## s, |
| 35 | 41 | #include "opc.h" |
| ... | ... | @@ -1721,6 +1727,18 @@ GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT) |
| 1721 | 1727 | |
| 1722 | 1728 | /*** Branch ***/ |
| 1723 | 1729 | |
| 1730 | +static inline void gen_jmp_tb(long tb, int n, uint32_t dest) | |
| 1731 | +{ | |
| 1732 | + if (n == 0) | |
| 1733 | + gen_op_goto_tb0(TBPARAM(tb)); | |
| 1734 | + else | |
| 1735 | + gen_op_goto_tb1(TBPARAM(tb)); | |
| 1736 | + gen_op_set_T1(dest); | |
| 1737 | + gen_op_b_T1(); | |
| 1738 | + gen_op_set_T0(tb + n); | |
| 1739 | + gen_op_exit_tb(); | |
| 1740 | +} | |
| 1741 | + | |
| 1724 | 1742 | /* b ba bl bla */ |
| 1725 | 1743 | GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) |
| 1726 | 1744 | { |
| ... | ... | @@ -1736,7 +1754,7 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) |
| 1736 | 1754 | if (LK(ctx->opcode)) { |
| 1737 | 1755 | gen_op_setlr(ctx->nip); |
| 1738 | 1756 | } |
| 1739 | - gen_op_b((long)ctx->tb, target); | |
| 1757 | + gen_jmp_tb((long)ctx->tb, 0, target); | |
| 1740 | 1758 | ctx->exception = EXCP_BRANCH; |
| 1741 | 1759 | } |
| 1742 | 1760 | |
| ... | ... | @@ -1787,7 +1805,7 @@ static inline void gen_bcond(DisasContext *ctx, int type) |
| 1787 | 1805 | case 4: |
| 1788 | 1806 | case 6: |
| 1789 | 1807 | if (type == BCOND_IM) { |
| 1790 | - gen_op_b((long)ctx->tb, target); | |
| 1808 | + gen_jmp_tb((long)ctx->tb, 0, target); | |
| 1791 | 1809 | } else { |
| 1792 | 1810 | gen_op_b_T1(); |
| 1793 | 1811 | } |
| ... | ... | @@ -1827,7 +1845,11 @@ static inline void gen_bcond(DisasContext *ctx, int type) |
| 1827 | 1845 | } |
| 1828 | 1846 | } |
| 1829 | 1847 | if (type == BCOND_IM) { |
| 1830 | - gen_op_btest((long)ctx->tb, target, ctx->nip); | |
| 1848 | + int l1 = gen_new_label(); | |
| 1849 | + gen_op_jz_T0(l1); | |
| 1850 | + gen_jmp_tb((long)ctx->tb, 0, target); | |
| 1851 | + gen_set_label(l1); | |
| 1852 | + gen_jmp_tb((long)ctx->tb, 1, ctx->nip); | |
| 1831 | 1853 | } else { |
| 1832 | 1854 | gen_op_btest_T1(ctx->nip); |
| 1833 | 1855 | } |
| ... | ... | @@ -2459,6 +2481,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
| 2459 | 2481 | gen_opc_ptr = gen_opc_buf; |
| 2460 | 2482 | gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; |
| 2461 | 2483 | gen_opparam_ptr = gen_opparam_buf; |
| 2484 | + nb_gen_labels = 0; | |
| 2462 | 2485 | ctx.nip = pc_start; |
| 2463 | 2486 | ctx.tb = tb; |
| 2464 | 2487 | ctx.exception = EXCP_NONE; |
| ... | ... | @@ -2575,7 +2598,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, |
| 2575 | 2598 | #endif |
| 2576 | 2599 | } |
| 2577 | 2600 | if (ctx.exception == EXCP_NONE) { |
| 2578 | - gen_op_b((unsigned long)ctx.tb, ctx.nip); | |
| 2601 | + gen_jmp_tb((long)ctx.tb, 0, ctx.nip); | |
| 2579 | 2602 | } else if (ctx.exception != EXCP_BRANCH) { |
| 2580 | 2603 | gen_op_set_T0(0); |
| 2581 | 2604 | } | ... | ... |