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 | } | ... | ... |