diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-06 13:03:35 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-06 13:03:35 +0000 |
commit | 6527f6ea9c2ab3116bd363457021b93bd531d858 (patch) | |
tree | 5778a04a73bd3fbb1fcbc6fc5d744081af92e9e7 | |
parent | 22e0e173376d702bdd9757d308924b6df7cd6529 (diff) |
target-ppc: convert msr load/store to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5892 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | target-ppc/helper.h | 1 | ||||
-rw-r--r-- | target-ppc/op.c | 43 | ||||
-rw-r--r-- | target-ppc/op_helper.c | 12 | ||||
-rw-r--r-- | target-ppc/op_helper.h | 4 | ||||
-rw-r--r-- | target-ppc/translate.c | 59 |
5 files changed, 48 insertions, 71 deletions
diff --git a/target-ppc/helper.h b/target-ppc/helper.h index ddd3f28cbb..ced47d0327 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -7,6 +7,7 @@ DEF_HELPER_3(tw, void, tl, tl, i32) DEF_HELPER_3(td, void, tl, tl, i32) #endif #if !defined(CONFIG_USER_ONLY) +DEF_HELPER_1(store_msr, void, tl) DEF_HELPER_0(rfi, void) DEF_HELPER_0(rfsvc, void) DEF_HELPER_0(40x_rfci, void) diff --git a/target-ppc/op.c b/target-ppc/op.c index d3df7fc0c8..18843767f0 100644 --- a/target-ppc/op.c +++ b/target-ppc/op.c @@ -79,38 +79,6 @@ void OPPROTO op_store_asr (void) RETURN(); } #endif - -void OPPROTO op_load_msr (void) -{ - T0 = env->msr; - RETURN(); -} - -void OPPROTO op_store_msr (void) -{ - do_store_msr(); - RETURN(); -} - -#if defined (TARGET_PPC64) -void OPPROTO op_store_msr_32 (void) -{ - T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF); - do_store_msr(); - RETURN(); -} -#endif - -void OPPROTO op_update_riee (void) -{ - /* We don't call do_store_msr here as we won't trigger - * any special case nor change hflags - */ - T0 &= (1 << MSR_RI) | (1 << MSR_EE); - env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE); - env->msr |= T0; - RETURN(); -} #endif /* SPR */ @@ -394,17 +362,6 @@ void OPPROTO op_store_dcr (void) } #if !defined(CONFIG_USER_ONLY) -void OPPROTO op_wrte (void) -{ - /* We don't call do_store_msr here as we won't trigger - * any special case nor change hflags - */ - T0 &= 1 << MSR_EE; - env->msr &= ~(1 << MSR_EE); - env->msr |= T0; - RETURN(); -} - void OPPROTO op_440_tlbre (void) { do_440_tlbre(PARAM1); diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 7f028fa791..6137b0e748 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -1488,17 +1488,17 @@ uint32_t helper_fcmpo (uint64_t arg1, uint64_t arg2) } #if !defined (CONFIG_USER_ONLY) -void cpu_dump_rfi (target_ulong RA, target_ulong msr); - -void do_store_msr (void) +void helper_store_msr (target_ulong val) { - T0 = hreg_store_msr(env, T0, 0); - if (T0 != 0) { + val = hreg_store_msr(env, val, 0); + if (val != 0) { env->interrupt_request |= CPU_INTERRUPT_EXITTB; - raise_exception(env, T0); + raise_exception(env, val); } } +void cpu_dump_rfi (target_ulong RA, target_ulong msr); + static always_inline void do_rfi (target_ulong nip, target_ulong msr, target_ulong msrm, int keep_msrh) { diff --git a/target-ppc/op_helper.h b/target-ppc/op_helper.h index e79526b3d7..1cb0772ff1 100644 --- a/target-ppc/op_helper.h +++ b/target-ppc/op_helper.h @@ -28,10 +28,6 @@ target_ulong ppc_load_dump_spr (int sprn); void ppc_store_dump_spr (int sprn, target_ulong val); /* Misc */ -#if !defined(CONFIG_USER_ONLY) -void do_store_msr (void); -#endif - /* POWER / PowerPC 601 specific helpers */ #if !defined(CONFIG_USER_ONLY) void do_POWER_rac (void); diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 06d261109a..30a7cb3887 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -63,6 +63,7 @@ static TCGv_i64 cpu_fpr[32]; static TCGv_i64 cpu_avrh[32], cpu_avrl[32]; static TCGv_i32 cpu_crf[8]; static TCGv cpu_nip; +static TCGv cpu_msr; static TCGv cpu_ctr; static TCGv cpu_lr; static TCGv cpu_xer; @@ -153,6 +154,9 @@ void ppc_translate_init(void) cpu_nip = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, nip), "nip"); + cpu_msr = tcg_global_mem_new(TCG_AREG0, + offsetof(CPUState, msr), "msr"); + cpu_ctr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, ctr), "ctr"); @@ -3876,8 +3880,7 @@ GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC) GEN_EXCP_PRIVREG(ctx); return; } - gen_op_load_msr(); - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr); #endif } @@ -3984,14 +3987,18 @@ GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B) tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); if (ctx->opcode & 0x00010000) { /* Special form that does not need any synchronisation */ - gen_op_update_riee(); + TCGv t0 = tcg_temp_new(); + tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE)); + tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE))); + tcg_gen_or_tl(cpu_msr, cpu_msr, t0); + tcg_temp_free(t0); } else { /* XXX: we need to update nip before the store * if we enter power saving mode, we will exit the loop * directly from ppc_store_msr */ gen_update_nip(ctx, ctx->nip); - gen_op_store_msr(); + gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]); /* Must stop the translation as machine state (may have) changed */ /* Note that mtmsr is not always defined as context-synchronizing */ ctx->exception = POWERPC_EXCP_STOP; @@ -4012,7 +4019,11 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); if (ctx->opcode & 0x00010000) { /* Special form that does not need any synchronisation */ - gen_op_update_riee(); + TCGv t0 = tcg_temp_new(); + tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE)); + tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE))); + tcg_gen_or_tl(cpu_msr, cpu_msr, t0); + tcg_temp_free(t0); } else { /* XXX: we need to update nip before the store * if we enter power saving mode, we will exit the loop @@ -4020,13 +4031,20 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) */ gen_update_nip(ctx, ctx->nip); #if defined(TARGET_PPC64) - if (!ctx->sf_mode) - gen_op_store_msr_32(); - else + if (!ctx->sf_mode) { + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + tcg_gen_andi_tl(t0, cpu_msr, 0xFFFFFFFF00000000ULL); + tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]); + tcg_gen_or_tl(t0, t0, t1); + tcg_temp_free(t1); + gen_helper_store_msr(t0); + tcg_temp_free(t0); + } else #endif - gen_op_store_msr(); + gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]); /* Must stop the translation as machine state (may have) changed */ - /* Note that mtmsrd is not always defined as context-synchronizing */ + /* Note that mtmsr is not always defined as context-synchronizing */ ctx->exception = POWERPC_EXCP_STOP; } #endif @@ -5978,12 +5996,16 @@ GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE) #if defined(CONFIG_USER_ONLY) GEN_EXCP_PRIVOPC(ctx); #else + TCGv t0; if (unlikely(!ctx->supervisor)) { GEN_EXCP_PRIVOPC(ctx); return; } - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rD(ctx->opcode)]); - gen_op_wrte(); + t0 = tcg_temp_new(); + tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE)); + tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE)); + tcg_gen_or_tl(cpu_msr, cpu_msr, t0); + tcg_temp_free(t0); /* Stop translation to have a chance to raise an exception * if we just set msr_ee to 1 */ @@ -6001,12 +6023,13 @@ GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE) GEN_EXCP_PRIVOPC(ctx); return; } - tcg_gen_movi_tl(cpu_T[0], ctx->opcode & 0x00010000); - gen_op_wrte(); - /* Stop translation to have a chance to raise an exception - * if we just set msr_ee to 1 - */ - GEN_STOP(ctx); + if (ctx->opcode & 0x00010000) { + tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE)); + /* Stop translation to have a chance to raise an exception */ + GEN_STOP(ctx); + } else { + tcg_gen_andi_tl(cpu_msr, cpu_msr, (1 << MSR_EE)); + } #endif } |