static inline void gen_bcond (DisasContext *ctx, int type) { target_ulong target = 0; target_ulong li; uint32_t bo = BO(ctx->opcode); uint32_t bi = BI(ctx->opcode); uint32_t mask; if ((bo & 0x4) == 0) gen_op_dec_ctr(); switch(type) { case BCOND_IM: li = (target_long)((int16_t)(BD(ctx->opcode))); if (likely(AA(ctx->opcode) == 0)) { target = ctx->nip + li - 4; } else { target = li; } break; case BCOND_CTR: gen_op_movl_T1_ctr(); break; default: case BCOND_LR: gen_op_movl_T1_lr(); break; } if (LK(ctx->opcode)) { #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_setlr_64(ctx->nip >> 32, ctx->nip); else #endif gen_op_setlr(ctx->nip); } if (bo & 0x10) { /* No CR condition */ switch (bo & 0x6) { case 0: #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_test_ctr_64(); else #endif gen_op_test_ctr(); break; case 2: #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_test_ctrz_64(); else #endif gen_op_test_ctrz(); break; default: case 4: case 6: if (type == BCOND_IM) { gen_goto_tb(ctx, 0, target); } else { #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_b_T1_64(); else #endif gen_op_b_T1(); gen_op_reset_T0(); } goto no_test; } } else { mask = 1 << (3 - (bi & 0x03)); gen_op_load_crf_T0(bi >> 2); if (bo & 0x8) { switch (bo & 0x6) { case 0: #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_test_ctr_true_64(mask); else #endif gen_op_test_ctr_true(mask); break; case 2: #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_test_ctrz_true_64(mask); else #endif gen_op_test_ctrz_true(mask); break; default: case 4: case 6: gen_op_test_true(mask); break; } } else { switch (bo & 0x6) { case 0: #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_test_ctr_false_64(mask); else #endif gen_op_test_ctr_false(mask); break; case 2: #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_test_ctrz_false_64(mask); else #endif gen_op_test_ctrz_false(mask); break; default: case 4: case 6: gen_op_test_false(mask); break; } } } if (type == BCOND_IM) { int l1 = gen_new_label(); gen_op_jz_T0(l1); gen_goto_tb(ctx, 0, target); gen_set_label(l1); gen_goto_tb(ctx, 1, ctx->nip); } else { #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip); else #endif gen_op_btest_T1(ctx->nip); gen_op_reset_T0(); no_test: if (ctx->singlestep_enabled) gen_op_debug(); gen_op_exit_tb(); } ctx->exception = EXCP_BRANCH; }
static inline void gen_bcond (DisasContext *ctx, int type) { target_ulong target = 0; target_ulong li; uint32_t bo = BO(ctx->opcode); uint32_t bi = BI(ctx->opcode); uint32_t mask; if ((bo & 0x4) == 0) gen_op_dec_ctr(); switch(type) { case BCOND_IM: li = (target_long)((int16_t)(BD(ctx->opcode))); if (likely(AA(ctx->opcode) == 0)) { target = ctx->nip + li - 4; } else { target = li; } break; case BCOND_CTR: gen_op_movl_T1_ctr(); break; default: case BCOND_LR: gen_op_movl_T1_lr(); break; } if (LK(ctx->opcode)) { #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_setlr_64(ctx->nip >> 32, ctx->nip); else #endif gen_op_setlr(ctx->nip); } if (bo & 0x10) {   switch (bo & 0x6) { case 0: #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_test_ctr_64(); else #endif gen_op_test_ctr(); break; case 2: #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_test_ctrz_64(); else #endif gen_op_test_ctrz(); break; default: case 4: case 6: if (type == BCOND_IM) { gen_goto_tb(ctx, 0, target); } else { #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_b_T1_64(); else #endif gen_op_b_T1(); gen_op_reset_T0(); } goto no_test; } } else { mask = 1 << (3 - (bi & 0x03)); gen_op_load_crf_T0(bi >> 2); if (bo & 0x8) { switch (bo & 0x6) { case 0: #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_test_ctr_true_64(mask); else #endif gen_op_test_ctr_true(mask); break; case 2: #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_test_ctrz_true_64(mask); else #endif gen_op_test_ctrz_true(mask); break; default: case 4: case 6: gen_op_test_true(mask); break; } } else { switch (bo & 0x6) { case 0: #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_test_ctr_false_64(mask); else #endif gen_op_test_ctr_false(mask); break; case 2: #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_test_ctrz_false_64(mask); else #endif gen_op_test_ctrz_false(mask); break; default: case 4: case 6: gen_op_test_false(mask); break; } } } if (type == BCOND_IM) { int l1 = gen_new_label(); gen_op_jz_T0(l1); gen_goto_tb(ctx, 0, target); gen_set_label(l1); gen_goto_tb(ctx, 1, ctx->nip); } else { #if defined(TARGET_PPC64) if (ctx->sf_mode) gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip); else #endif gen_op_btest_T1(ctx->nip); gen_op_reset_T0(); no_test: if (ctx->singlestep_enabled) gen_op_debug(); gen_op_exit_tb(); } ctx->exception = EXCP_BRANCH; }