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,15 +365,6 @@ dummy_label ## n: ;\ | ||
| 365 | 365 | ||
| 366 | #endif | 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 | extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; | 368 | extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; |
| 378 | extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; | 369 | extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; |
| 379 | extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; | 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,14 +346,14 @@ void OPPROTO op_test_le(void) | ||
| 346 | FORCE_RET(); | 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 | void OPPROTO op_exit_tb(void) | 359 | void OPPROTO op_exit_tb(void) |
target-arm/translate.c
| @@ -43,6 +43,12 @@ typedef struct DisasContext { | @@ -43,6 +43,12 @@ typedef struct DisasContext { | ||
| 43 | 43 | ||
| 44 | #define DISAS_JUMP_NEXT 4 | 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 | /* XXX: move that elsewhere */ | 52 | /* XXX: move that elsewhere */ |
| 47 | static uint16_t *gen_opc_ptr; | 53 | static uint16_t *gen_opc_ptr; |
| 48 | static uint32_t *gen_opparam_ptr; | 54 | static uint32_t *gen_opparam_ptr; |
| @@ -897,6 +903,18 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) | @@ -897,6 +903,18 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) | ||
| 897 | return 0; | 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 | static inline void gen_jmp (DisasContext *s, uint32_t dest) | 918 | static inline void gen_jmp (DisasContext *s, uint32_t dest) |
| 901 | { | 919 | { |
| 902 | if (__builtin_expect(s->singlestep_enabled, 0)) { | 920 | if (__builtin_expect(s->singlestep_enabled, 0)) { |
| @@ -906,7 +924,8 @@ static inline void gen_jmp (DisasContext *s, uint32_t dest) | @@ -906,7 +924,8 @@ static inline void gen_jmp (DisasContext *s, uint32_t dest) | ||
| 906 | gen_op_movl_T0_im(dest); | 924 | gen_op_movl_T0_im(dest); |
| 907 | gen_bx(s); | 925 | gen_bx(s); |
| 908 | } else { | 926 | } else { |
| 909 | - gen_op_jmp0((long)s->tb, dest); | 927 | + long tb = (long)s->tb; |
| 928 | + gen_jmp_tb(tb, 0, dest); | ||
| 910 | s->is_jmp = DISAS_TB_JUMP; | 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,7 +2137,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, | ||
| 2118 | } else { | 2137 | } else { |
| 2119 | switch(dc->is_jmp) { | 2138 | switch(dc->is_jmp) { |
| 2120 | case DISAS_NEXT: | 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 | break; | 2141 | break; |
| 2123 | default: | 2142 | default: |
| 2124 | case DISAS_JUMP: | 2143 | case DISAS_JUMP: |
| @@ -2133,7 +2152,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, | @@ -2133,7 +2152,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, | ||
| 2133 | } | 2152 | } |
| 2134 | if (dc->condjmp) { | 2153 | if (dc->condjmp) { |
| 2135 | gen_set_label(dc->condlabel); | 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 | dc->condjmp = 0; | 2156 | dc->condjmp = 0; |
| 2138 | } | 2157 | } |
| 2139 | } | 2158 | } |
target-mips/op.c
| @@ -487,7 +487,16 @@ OP_COND(ltz, (int32_t)T0 < 0); | @@ -487,7 +487,16 @@ OP_COND(ltz, (int32_t)T0 < 0); | ||
| 487 | 487 | ||
| 488 | /* Branchs */ | 488 | /* Branchs */ |
| 489 | //#undef USE_DIRECT_JUMP | 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 | /* Branch to register */ | 501 | /* Branch to register */ |
| 493 | void op_save_breg_target (void) | 502 | void op_save_breg_target (void) |
| @@ -506,13 +515,6 @@ void op_breg (void) | @@ -506,13 +515,6 @@ void op_breg (void) | ||
| 506 | RETURN(); | 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 | void op_save_btarget (void) | 518 | void op_save_btarget (void) |
| 517 | { | 519 | { |
| 518 | env->btarget = PARAM1; | 520 | env->btarget = PARAM1; |
| @@ -538,24 +540,10 @@ void op_restore_bcond (void) | @@ -538,24 +540,10 @@ void op_restore_bcond (void) | ||
| 538 | RETURN(); | 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 | RETURN(); | 547 | RETURN(); |
| 560 | } | 548 | } |
| 561 | 549 |
target-mips/translate.c
| @@ -31,6 +31,12 @@ | @@ -31,6 +31,12 @@ | ||
| 31 | #define MIPS_DEBUG_DISAS | 31 | #define MIPS_DEBUG_DISAS |
| 32 | //#define MIPS_SINGLE_STEP | 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 | enum { | 40 | enum { |
| 35 | #define DEF(s, n, copy_size) INDEX_op_ ## s, | 41 | #define DEF(s, n, copy_size) INDEX_op_ ## s, |
| 36 | #include "opc.h" | 42 | #include "opc.h" |
| @@ -922,6 +928,17 @@ static void gen_trap (DisasContext *ctx, uint16_t opc, | @@ -922,6 +928,17 @@ static void gen_trap (DisasContext *ctx, uint16_t opc, | ||
| 922 | ctx->bstate = BS_STOP; | 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 | /* Branches (before delay slot) */ | 942 | /* Branches (before delay slot) */ |
| 926 | static void gen_compute_branch (DisasContext *ctx, uint16_t opc, | 943 | static void gen_compute_branch (DisasContext *ctx, uint16_t opc, |
| 927 | int rs, int rt, int32_t offset) | 944 | int rs, int rt, int32_t offset) |
| @@ -1018,7 +1035,7 @@ static void gen_compute_branch (DisasContext *ctx, uint16_t opc, | @@ -1018,7 +1035,7 @@ static void gen_compute_branch (DisasContext *ctx, uint16_t opc, | ||
| 1018 | case OPC_BLTZL: /* 0 < 0 likely */ | 1035 | case OPC_BLTZL: /* 0 < 0 likely */ |
| 1019 | /* Skip the instruction in the delay slot */ | 1036 | /* Skip the instruction in the delay slot */ |
| 1020 | MIPS_DEBUG("bnever and skip"); | 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 | return; | 1039 | return; |
| 1023 | case OPC_J: | 1040 | case OPC_J: |
| 1024 | ctx->hflags |= MIPS_HFLAG_DS | MIPS_HFLAG_B; | 1041 | ctx->hflags |= MIPS_HFLAG_DS | MIPS_HFLAG_B; |
| @@ -1255,6 +1272,15 @@ static void gen_arith64 (DisasContext *ctx, uint16_t opc) | @@ -1255,6 +1272,15 @@ static void gen_arith64 (DisasContext *ctx, uint16_t opc) | ||
| 1255 | 1272 | ||
| 1256 | #endif | 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 | static void decode_opc (DisasContext *ctx) | 1284 | static void decode_opc (DisasContext *ctx) |
| 1259 | { | 1285 | { |
| 1260 | int32_t offset; | 1286 | int32_t offset; |
| @@ -1266,8 +1292,7 @@ static void decode_opc (DisasContext *ctx) | @@ -1266,8 +1292,7 @@ static void decode_opc (DisasContext *ctx) | ||
| 1266 | (ctx->hflags & MIPS_HFLAG_BL)) { | 1292 | (ctx->hflags & MIPS_HFLAG_BL)) { |
| 1267 | /* Handle blikely not taken case */ | 1293 | /* Handle blikely not taken case */ |
| 1268 | MIPS_DEBUG("blikely condition (%08x)", ctx->pc + 4); | 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 | op = ctx->opcode >> 26; | 1297 | op = ctx->opcode >> 26; |
| 1273 | rs = ((ctx->opcode >> 21) & 0x1F); | 1298 | rs = ((ctx->opcode >> 21) & 0x1F); |
| @@ -1477,17 +1502,24 @@ static void decode_opc (DisasContext *ctx) | @@ -1477,17 +1502,24 @@ static void decode_opc (DisasContext *ctx) | ||
| 1477 | case MIPS_HFLAG_B: | 1502 | case MIPS_HFLAG_B: |
| 1478 | /* unconditional branch */ | 1503 | /* unconditional branch */ |
| 1479 | MIPS_DEBUG("unconditional branch"); | 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 | break; | 1506 | break; |
| 1482 | case MIPS_HFLAG_BL: | 1507 | case MIPS_HFLAG_BL: |
| 1483 | /* blikely taken case */ | 1508 | /* blikely taken case */ |
| 1484 | MIPS_DEBUG("blikely branch taken"); | 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 | break; | 1511 | break; |
| 1487 | case MIPS_HFLAG_BC: | 1512 | case MIPS_HFLAG_BC: |
| 1488 | /* Conditional branch */ | 1513 | /* Conditional branch */ |
| 1489 | MIPS_DEBUG("conditional branch"); | 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 | break; | 1523 | break; |
| 1492 | case MIPS_HFLAG_BR: | 1524 | case MIPS_HFLAG_BR: |
| 1493 | /* unconditional branch to register */ | 1525 | /* unconditional branch to register */ |
| @@ -1513,6 +1545,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | @@ -1513,6 +1545,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | ||
| 1513 | gen_opc_ptr = gen_opc_buf; | 1545 | gen_opc_ptr = gen_opc_buf; |
| 1514 | gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; | 1546 | gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; |
| 1515 | gen_opparam_ptr = gen_opparam_buf; | 1547 | gen_opparam_ptr = gen_opparam_buf; |
| 1548 | + nb_gen_labels = 0; | ||
| 1516 | ctx.pc = pc_start; | 1549 | ctx.pc = pc_start; |
| 1517 | ctx.tb = tb; | 1550 | ctx.tb = tb; |
| 1518 | ctx.bstate = BS_NONE; | 1551 | ctx.bstate = BS_NONE; |
| @@ -1570,7 +1603,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | @@ -1570,7 +1603,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | ||
| 1570 | } | 1603 | } |
| 1571 | if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) { | 1604 | if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) { |
| 1572 | save_cpu_state(ctxp, 0); | 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 | gen_op_reset_T0(); | 1608 | gen_op_reset_T0(); |
| 1576 | /* Generate the return instruction */ | 1609 | /* Generate the return instruction */ |
target-ppc/op.c
| @@ -451,9 +451,14 @@ PPC_OP(setlr) | @@ -451,9 +451,14 @@ PPC_OP(setlr) | ||
| 451 | regs->lr = PARAM1; | 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 | PPC_OP(b_T1) | 464 | PPC_OP(b_T1) |
| @@ -461,13 +466,10 @@ PPC_OP(b_T1) | @@ -461,13 +466,10 @@ PPC_OP(b_T1) | ||
| 461 | regs->nip = T1 & ~3; | 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 | RETURN(); | 473 | RETURN(); |
| 472 | } | 474 | } |
| 473 | 475 |
target-ppc/translate.c
| @@ -30,6 +30,12 @@ | @@ -30,6 +30,12 @@ | ||
| 30 | //#define DO_SINGLE_STEP | 30 | //#define DO_SINGLE_STEP |
| 31 | //#define PPC_DEBUG_DISAS | 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 | enum { | 39 | enum { |
| 34 | #define DEF(s, n, copy_size) INDEX_op_ ## s, | 40 | #define DEF(s, n, copy_size) INDEX_op_ ## s, |
| 35 | #include "opc.h" | 41 | #include "opc.h" |
| @@ -1721,6 +1727,18 @@ GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT) | @@ -1721,6 +1727,18 @@ GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT) | ||
| 1721 | 1727 | ||
| 1722 | /*** Branch ***/ | 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 | /* b ba bl bla */ | 1742 | /* b ba bl bla */ |
| 1725 | GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) | 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,7 +1754,7 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) | ||
| 1736 | if (LK(ctx->opcode)) { | 1754 | if (LK(ctx->opcode)) { |
| 1737 | gen_op_setlr(ctx->nip); | 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 | ctx->exception = EXCP_BRANCH; | 1758 | ctx->exception = EXCP_BRANCH; |
| 1741 | } | 1759 | } |
| 1742 | 1760 | ||
| @@ -1787,7 +1805,7 @@ static inline void gen_bcond(DisasContext *ctx, int type) | @@ -1787,7 +1805,7 @@ static inline void gen_bcond(DisasContext *ctx, int type) | ||
| 1787 | case 4: | 1805 | case 4: |
| 1788 | case 6: | 1806 | case 6: |
| 1789 | if (type == BCOND_IM) { | 1807 | if (type == BCOND_IM) { |
| 1790 | - gen_op_b((long)ctx->tb, target); | 1808 | + gen_jmp_tb((long)ctx->tb, 0, target); |
| 1791 | } else { | 1809 | } else { |
| 1792 | gen_op_b_T1(); | 1810 | gen_op_b_T1(); |
| 1793 | } | 1811 | } |
| @@ -1827,7 +1845,11 @@ static inline void gen_bcond(DisasContext *ctx, int type) | @@ -1827,7 +1845,11 @@ static inline void gen_bcond(DisasContext *ctx, int type) | ||
| 1827 | } | 1845 | } |
| 1828 | } | 1846 | } |
| 1829 | if (type == BCOND_IM) { | 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 | } else { | 1853 | } else { |
| 1832 | gen_op_btest_T1(ctx->nip); | 1854 | gen_op_btest_T1(ctx->nip); |
| 1833 | } | 1855 | } |
| @@ -2459,6 +2481,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | @@ -2459,6 +2481,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | ||
| 2459 | gen_opc_ptr = gen_opc_buf; | 2481 | gen_opc_ptr = gen_opc_buf; |
| 2460 | gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; | 2482 | gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; |
| 2461 | gen_opparam_ptr = gen_opparam_buf; | 2483 | gen_opparam_ptr = gen_opparam_buf; |
| 2484 | + nb_gen_labels = 0; | ||
| 2462 | ctx.nip = pc_start; | 2485 | ctx.nip = pc_start; |
| 2463 | ctx.tb = tb; | 2486 | ctx.tb = tb; |
| 2464 | ctx.exception = EXCP_NONE; | 2487 | ctx.exception = EXCP_NONE; |
| @@ -2575,7 +2598,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | @@ -2575,7 +2598,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | ||
| 2575 | #endif | 2598 | #endif |
| 2576 | } | 2599 | } |
| 2577 | if (ctx.exception == EXCP_NONE) { | 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 | } else if (ctx.exception != EXCP_BRANCH) { | 2602 | } else if (ctx.exception != EXCP_BRANCH) { |
| 2580 | gen_op_set_T0(0); | 2603 | gen_op_set_T0(0); |
| 2581 | } | 2604 | } |