diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-10-21 16:31:31 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-10-21 16:31:31 +0000 |
commit | a2ffb81204ccfb497908773729f8d2f1048a65c4 (patch) | |
tree | 333645a1c2dabf8ab95d4a99ec619c303bb08448 | |
parent | 22babebbaa17c0c0c134ea4f5eaf5cbbd68472ab (diff) | |
download | hqemu-a2ffb81204ccfb497908773729f8d2f1048a65c4.zip hqemu-a2ffb81204ccfb497908773729f8d2f1048a65c4.tar.gz |
target-ppc: convert branch related instructions to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5508 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | target-ppc/op.c | 160 | ||||
-rw-r--r-- | target-ppc/translate.c | 199 |
2 files changed, 63 insertions, 296 deletions
diff --git a/target-ppc/op.c b/target-ppc/op.c index 9a1ec82..2271ed0 100644 --- a/target-ppc/op.c +++ b/target-ppc/op.c @@ -326,166 +326,6 @@ void OPPROTO op_store_fpscr (void) RETURN(); } -/* Branch */ -void OPPROTO op_setlr (void) -{ - env->lr = (uint32_t)PARAM1; - RETURN(); -} - -#if defined (TARGET_PPC64) -void OPPROTO op_setlr_64 (void) -{ - env->lr = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2; - RETURN(); -} -#endif - -void OPPROTO op_jz_T0 (void) -{ - if (!T0) - GOTO_LABEL_PARAM(1); - RETURN(); -} - -void OPPROTO op_btest_T1 (void) -{ - if (T0) { - env->nip = (uint32_t)(T1 & ~3); - } else { - env->nip = (uint32_t)PARAM1; - } - RETURN(); -} - -#if defined (TARGET_PPC64) -void OPPROTO op_btest_T1_64 (void) -{ - if (T0) { - env->nip = (uint64_t)(T1 & ~3); - } else { - env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2; - } - RETURN(); -} -#endif - -void OPPROTO op_movl_T1_ctr (void) -{ - T1 = env->ctr; - RETURN(); -} - -void OPPROTO op_movl_T1_lr (void) -{ - T1 = env->lr; - RETURN(); -} - -/* tests with result in T0 */ -void OPPROTO op_test_ctr (void) -{ - T0 = (uint32_t)env->ctr; - RETURN(); -} - -#if defined(TARGET_PPC64) -void OPPROTO op_test_ctr_64 (void) -{ - T0 = (uint64_t)env->ctr; - RETURN(); -} -#endif - -void OPPROTO op_test_ctr_true (void) -{ - T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) != 0); - RETURN(); -} - -#if defined(TARGET_PPC64) -void OPPROTO op_test_ctr_true_64 (void) -{ - T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) != 0); - RETURN(); -} -#endif - -void OPPROTO op_test_ctr_false (void) -{ - T0 = ((uint32_t)env->ctr != 0 && (T0 & PARAM1) == 0); - RETURN(); -} - -#if defined(TARGET_PPC64) -void OPPROTO op_test_ctr_false_64 (void) -{ - T0 = ((uint64_t)env->ctr != 0 && (T0 & PARAM1) == 0); - RETURN(); -} -#endif - -void OPPROTO op_test_ctrz (void) -{ - T0 = ((uint32_t)env->ctr == 0); - RETURN(); -} - -#if defined(TARGET_PPC64) -void OPPROTO op_test_ctrz_64 (void) -{ - T0 = ((uint64_t)env->ctr == 0); - RETURN(); -} -#endif - -void OPPROTO op_test_ctrz_true (void) -{ - T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) != 0); - RETURN(); -} - -#if defined(TARGET_PPC64) -void OPPROTO op_test_ctrz_true_64 (void) -{ - T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) != 0); - RETURN(); -} -#endif - -void OPPROTO op_test_ctrz_false (void) -{ - T0 = ((uint32_t)env->ctr == 0 && (T0 & PARAM1) == 0); - RETURN(); -} - -#if defined(TARGET_PPC64) -void OPPROTO op_test_ctrz_false_64 (void) -{ - T0 = ((uint64_t)env->ctr == 0 && (T0 & PARAM1) == 0); - RETURN(); -} -#endif - -void OPPROTO op_test_true (void) -{ - T0 = (T0 & PARAM1); - RETURN(); -} - -void OPPROTO op_test_false (void) -{ - T0 = ((T0 & PARAM1) == 0); - RETURN(); -} - -/* CTR maintenance */ -void OPPROTO op_dec_ctr (void) -{ - env->ctr--; - RETURN(); -} - /*** Integer arithmetic ***/ /* add */ void OPPROTO op_check_addo (void) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index e40cae9..94021c8 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -3276,25 +3276,17 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n, { TranslationBlock *tb; tb = ctx->tb; +#if defined(TARGET_PPC64) + if (!ctx->sf_mode) + dest = (uint32_t) dest; +#endif if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) && likely(!ctx->singlestep_enabled)) { tcg_gen_goto_tb(n); - tcg_gen_movi_tl(cpu_T[1], dest); -#if defined(TARGET_PPC64) - if (ctx->sf_mode) - tcg_gen_andi_tl(cpu_nip, cpu_T[1], ~3); - else -#endif - tcg_gen_andi_tl(cpu_nip, cpu_T[1], (uint32_t)~3); + tcg_gen_movi_tl(cpu_nip, dest & ~3); tcg_gen_exit_tb((long)tb + n); } else { - tcg_gen_movi_tl(cpu_T[1], dest); -#if defined(TARGET_PPC64) - if (ctx->sf_mode) - tcg_gen_andi_tl(cpu_nip, cpu_T[1], ~3); - else -#endif - tcg_gen_andi_tl(cpu_nip, cpu_T[1], (uint32_t)~3); + tcg_gen_movi_tl(cpu_nip, dest & ~3); if (unlikely(ctx->singlestep_enabled)) { if ((ctx->singlestep_enabled & (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) && @@ -3316,11 +3308,11 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n, static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip) { #if defined(TARGET_PPC64) - if (ctx->sf_mode != 0 && (nip >> 32)) - gen_op_setlr_64(ctx->nip >> 32, ctx->nip); + if (ctx->sf_mode == 0) + tcg_gen_movi_tl(cpu_lr, (uint32_t)nip); else #endif - gen_op_setlr(ctx->nip); + tcg_gen_movi_tl(cpu_lr, nip); } /* b ba bl bla */ @@ -3340,10 +3332,6 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) target = ctx->nip + li - 4; else target = li; -#if defined(TARGET_PPC64) - if (!ctx->sf_mode) - target = (uint32_t)target; -#endif if (LK(ctx->opcode)) gen_setlr(ctx, ctx->nip); gen_goto_tb(ctx, 0, target); @@ -3355,141 +3343,80 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) static always_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; + int l1 = gen_new_label(); + TCGv target; ctx->exception = POWERPC_EXCP_BRANCH; - 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; - } -#if defined(TARGET_PPC64) - if (!ctx->sf_mode) - target = (uint32_t)target; -#endif - break; - case BCOND_CTR: - gen_op_movl_T1_ctr(); - break; - default: - case BCOND_LR: - gen_op_movl_T1_lr(); - break; + if (type == BCOND_LR || type == BCOND_CTR) { + target = tcg_temp_local_new(TCG_TYPE_TL); + if (type == BCOND_CTR) + tcg_gen_mov_tl(target, cpu_ctr); + else + tcg_gen_mov_tl(target, cpu_lr); } if (LK(ctx->opcode)) gen_setlr(ctx, 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); - return; - } else { + l1 = gen_new_label(); + if ((bo & 0x4) == 0) { + /* Decrement and test CTR */ + TCGv temp = tcg_temp_new(TCG_TYPE_TL); + if (unlikely(type == BCOND_CTR)) { + GEN_EXCP_INVAL(ctx); + return; + } + tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1); #if defined(TARGET_PPC64) - if (ctx->sf_mode) - tcg_gen_andi_tl(cpu_nip, cpu_T[1], ~3); - else + if (!ctx->sf_mode) + tcg_gen_ext32u_tl(temp, cpu_ctr); + else #endif - tcg_gen_andi_tl(cpu_nip, cpu_T[1], (uint32_t)~3); - goto no_test; - } - break; + tcg_gen_mov_tl(temp, cpu_ctr); + if (bo & 0x2) { + tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1); + } else { + tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1); } - } else { - mask = 1 << (3 - (bi & 0x03)); - tcg_gen_mov_i32(cpu_T[0], cpu_crf[bi >> 2]); + } + if ((bo & 0x10) == 0) { + /* Test CR */ + uint32_t bi = BI(ctx->opcode); + uint32_t mask = 1 << (3 - (bi & 0x03)); + TCGv temp = tcg_temp_new(TCG_TYPE_I32); + 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; - } + tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask); + tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1); } 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; - } + tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask); + tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1); } } if (type == BCOND_IM) { - int l1 = gen_new_label(); - gen_op_jz_T0(l1); - gen_goto_tb(ctx, 0, target); + + target_ulong li = (target_long)((int16_t)(BD(ctx->opcode))); + if (likely(AA(ctx->opcode) == 0)) { + gen_goto_tb(ctx, 0, ctx->nip + li - 4); + } else { + gen_goto_tb(ctx, 0, li); + } 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); + if (!(ctx->sf_mode)) + tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3); + else +#endif + tcg_gen_andi_tl(cpu_nip, target, ~3); + tcg_gen_exit_tb(0); + gen_set_label(l1); +#if defined(TARGET_PPC64) + if (!(ctx->sf_mode)) + tcg_gen_movi_tl(cpu_nip, (uint32_t)ctx->nip); else #endif - gen_op_btest_T1(ctx->nip); - no_test: + tcg_gen_movi_tl(cpu_nip, ctx->nip); tcg_gen_exit_tb(0); } } |