Commit 6527f6ea9c2ab3116bd363457021b93bd531d858
1 parent
22e0e173
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
Showing
5 changed files
with
48 additions
and
71 deletions
target-ppc/helper.h
target-ppc/op.c
| ... | ... | @@ -79,38 +79,6 @@ void OPPROTO op_store_asr (void) |
| 79 | 79 | RETURN(); |
| 80 | 80 | } |
| 81 | 81 | #endif |
| 82 | - | |
| 83 | -void OPPROTO op_load_msr (void) | |
| 84 | -{ | |
| 85 | - T0 = env->msr; | |
| 86 | - RETURN(); | |
| 87 | -} | |
| 88 | - | |
| 89 | -void OPPROTO op_store_msr (void) | |
| 90 | -{ | |
| 91 | - do_store_msr(); | |
| 92 | - RETURN(); | |
| 93 | -} | |
| 94 | - | |
| 95 | -#if defined (TARGET_PPC64) | |
| 96 | -void OPPROTO op_store_msr_32 (void) | |
| 97 | -{ | |
| 98 | - T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF); | |
| 99 | - do_store_msr(); | |
| 100 | - RETURN(); | |
| 101 | -} | |
| 102 | -#endif | |
| 103 | - | |
| 104 | -void OPPROTO op_update_riee (void) | |
| 105 | -{ | |
| 106 | - /* We don't call do_store_msr here as we won't trigger | |
| 107 | - * any special case nor change hflags | |
| 108 | - */ | |
| 109 | - T0 &= (1 << MSR_RI) | (1 << MSR_EE); | |
| 110 | - env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE); | |
| 111 | - env->msr |= T0; | |
| 112 | - RETURN(); | |
| 113 | -} | |
| 114 | 82 | #endif |
| 115 | 83 | |
| 116 | 84 | /* SPR */ |
| ... | ... | @@ -394,17 +362,6 @@ void OPPROTO op_store_dcr (void) |
| 394 | 362 | } |
| 395 | 363 | |
| 396 | 364 | #if !defined(CONFIG_USER_ONLY) |
| 397 | -void OPPROTO op_wrte (void) | |
| 398 | -{ | |
| 399 | - /* We don't call do_store_msr here as we won't trigger | |
| 400 | - * any special case nor change hflags | |
| 401 | - */ | |
| 402 | - T0 &= 1 << MSR_EE; | |
| 403 | - env->msr &= ~(1 << MSR_EE); | |
| 404 | - env->msr |= T0; | |
| 405 | - RETURN(); | |
| 406 | -} | |
| 407 | - | |
| 408 | 365 | void OPPROTO op_440_tlbre (void) |
| 409 | 366 | { |
| 410 | 367 | do_440_tlbre(PARAM1); | ... | ... |
target-ppc/op_helper.c
| ... | ... | @@ -1488,17 +1488,17 @@ uint32_t helper_fcmpo (uint64_t arg1, uint64_t arg2) |
| 1488 | 1488 | } |
| 1489 | 1489 | |
| 1490 | 1490 | #if !defined (CONFIG_USER_ONLY) |
| 1491 | -void cpu_dump_rfi (target_ulong RA, target_ulong msr); | |
| 1492 | - | |
| 1493 | -void do_store_msr (void) | |
| 1491 | +void helper_store_msr (target_ulong val) | |
| 1494 | 1492 | { |
| 1495 | - T0 = hreg_store_msr(env, T0, 0); | |
| 1496 | - if (T0 != 0) { | |
| 1493 | + val = hreg_store_msr(env, val, 0); | |
| 1494 | + if (val != 0) { | |
| 1497 | 1495 | env->interrupt_request |= CPU_INTERRUPT_EXITTB; |
| 1498 | - raise_exception(env, T0); | |
| 1496 | + raise_exception(env, val); | |
| 1499 | 1497 | } |
| 1500 | 1498 | } |
| 1501 | 1499 | |
| 1500 | +void cpu_dump_rfi (target_ulong RA, target_ulong msr); | |
| 1501 | + | |
| 1502 | 1502 | static always_inline void do_rfi (target_ulong nip, target_ulong msr, |
| 1503 | 1503 | target_ulong msrm, int keep_msrh) |
| 1504 | 1504 | { | ... | ... |
target-ppc/op_helper.h
| ... | ... | @@ -28,10 +28,6 @@ target_ulong ppc_load_dump_spr (int sprn); |
| 28 | 28 | void ppc_store_dump_spr (int sprn, target_ulong val); |
| 29 | 29 | |
| 30 | 30 | /* Misc */ |
| 31 | -#if !defined(CONFIG_USER_ONLY) | |
| 32 | -void do_store_msr (void); | |
| 33 | -#endif | |
| 34 | - | |
| 35 | 31 | /* POWER / PowerPC 601 specific helpers */ |
| 36 | 32 | #if !defined(CONFIG_USER_ONLY) |
| 37 | 33 | void do_POWER_rac (void); | ... | ... |
target-ppc/translate.c
| ... | ... | @@ -63,6 +63,7 @@ static TCGv_i64 cpu_fpr[32]; |
| 63 | 63 | static TCGv_i64 cpu_avrh[32], cpu_avrl[32]; |
| 64 | 64 | static TCGv_i32 cpu_crf[8]; |
| 65 | 65 | static TCGv cpu_nip; |
| 66 | +static TCGv cpu_msr; | |
| 66 | 67 | static TCGv cpu_ctr; |
| 67 | 68 | static TCGv cpu_lr; |
| 68 | 69 | static TCGv cpu_xer; |
| ... | ... | @@ -153,6 +154,9 @@ void ppc_translate_init(void) |
| 153 | 154 | cpu_nip = tcg_global_mem_new(TCG_AREG0, |
| 154 | 155 | offsetof(CPUState, nip), "nip"); |
| 155 | 156 | |
| 157 | + cpu_msr = tcg_global_mem_new(TCG_AREG0, | |
| 158 | + offsetof(CPUState, msr), "msr"); | |
| 159 | + | |
| 156 | 160 | cpu_ctr = tcg_global_mem_new(TCG_AREG0, |
| 157 | 161 | offsetof(CPUState, ctr), "ctr"); |
| 158 | 162 | |
| ... | ... | @@ -3876,8 +3880,7 @@ GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC) |
| 3876 | 3880 | GEN_EXCP_PRIVREG(ctx); |
| 3877 | 3881 | return; |
| 3878 | 3882 | } |
| 3879 | - gen_op_load_msr(); | |
| 3880 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 3883 | + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr); | |
| 3881 | 3884 | #endif |
| 3882 | 3885 | } |
| 3883 | 3886 | |
| ... | ... | @@ -3984,14 +3987,18 @@ GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B) |
| 3984 | 3987 | tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); |
| 3985 | 3988 | if (ctx->opcode & 0x00010000) { |
| 3986 | 3989 | /* Special form that does not need any synchronisation */ |
| 3987 | - gen_op_update_riee(); | |
| 3990 | + TCGv t0 = tcg_temp_new(); | |
| 3991 | + tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE)); | |
| 3992 | + tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE))); | |
| 3993 | + tcg_gen_or_tl(cpu_msr, cpu_msr, t0); | |
| 3994 | + tcg_temp_free(t0); | |
| 3988 | 3995 | } else { |
| 3989 | 3996 | /* XXX: we need to update nip before the store |
| 3990 | 3997 | * if we enter power saving mode, we will exit the loop |
| 3991 | 3998 | * directly from ppc_store_msr |
| 3992 | 3999 | */ |
| 3993 | 4000 | gen_update_nip(ctx, ctx->nip); |
| 3994 | - gen_op_store_msr(); | |
| 4001 | + gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]); | |
| 3995 | 4002 | /* Must stop the translation as machine state (may have) changed */ |
| 3996 | 4003 | /* Note that mtmsr is not always defined as context-synchronizing */ |
| 3997 | 4004 | ctx->exception = POWERPC_EXCP_STOP; |
| ... | ... | @@ -4012,7 +4019,11 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) |
| 4012 | 4019 | tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); |
| 4013 | 4020 | if (ctx->opcode & 0x00010000) { |
| 4014 | 4021 | /* Special form that does not need any synchronisation */ |
| 4015 | - gen_op_update_riee(); | |
| 4022 | + TCGv t0 = tcg_temp_new(); | |
| 4023 | + tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE)); | |
| 4024 | + tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE))); | |
| 4025 | + tcg_gen_or_tl(cpu_msr, cpu_msr, t0); | |
| 4026 | + tcg_temp_free(t0); | |
| 4016 | 4027 | } else { |
| 4017 | 4028 | /* XXX: we need to update nip before the store |
| 4018 | 4029 | * if we enter power saving mode, we will exit the loop |
| ... | ... | @@ -4020,13 +4031,20 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) |
| 4020 | 4031 | */ |
| 4021 | 4032 | gen_update_nip(ctx, ctx->nip); |
| 4022 | 4033 | #if defined(TARGET_PPC64) |
| 4023 | - if (!ctx->sf_mode) | |
| 4024 | - gen_op_store_msr_32(); | |
| 4025 | - else | |
| 4034 | + if (!ctx->sf_mode) { | |
| 4035 | + TCGv t0 = tcg_temp_new(); | |
| 4036 | + TCGv t1 = tcg_temp_new(); | |
| 4037 | + tcg_gen_andi_tl(t0, cpu_msr, 0xFFFFFFFF00000000ULL); | |
| 4038 | + tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]); | |
| 4039 | + tcg_gen_or_tl(t0, t0, t1); | |
| 4040 | + tcg_temp_free(t1); | |
| 4041 | + gen_helper_store_msr(t0); | |
| 4042 | + tcg_temp_free(t0); | |
| 4043 | + } else | |
| 4026 | 4044 | #endif |
| 4027 | - gen_op_store_msr(); | |
| 4045 | + gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]); | |
| 4028 | 4046 | /* Must stop the translation as machine state (may have) changed */ |
| 4029 | - /* Note that mtmsrd is not always defined as context-synchronizing */ | |
| 4047 | + /* Note that mtmsr is not always defined as context-synchronizing */ | |
| 4030 | 4048 | ctx->exception = POWERPC_EXCP_STOP; |
| 4031 | 4049 | } |
| 4032 | 4050 | #endif |
| ... | ... | @@ -5978,12 +5996,16 @@ GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE) |
| 5978 | 5996 | #if defined(CONFIG_USER_ONLY) |
| 5979 | 5997 | GEN_EXCP_PRIVOPC(ctx); |
| 5980 | 5998 | #else |
| 5999 | + TCGv t0; | |
| 5981 | 6000 | if (unlikely(!ctx->supervisor)) { |
| 5982 | 6001 | GEN_EXCP_PRIVOPC(ctx); |
| 5983 | 6002 | return; |
| 5984 | 6003 | } |
| 5985 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rD(ctx->opcode)]); | |
| 5986 | - gen_op_wrte(); | |
| 6004 | + t0 = tcg_temp_new(); | |
| 6005 | + tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE)); | |
| 6006 | + tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE)); | |
| 6007 | + tcg_gen_or_tl(cpu_msr, cpu_msr, t0); | |
| 6008 | + tcg_temp_free(t0); | |
| 5987 | 6009 | /* Stop translation to have a chance to raise an exception |
| 5988 | 6010 | * if we just set msr_ee to 1 |
| 5989 | 6011 | */ |
| ... | ... | @@ -6001,12 +6023,13 @@ GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE) |
| 6001 | 6023 | GEN_EXCP_PRIVOPC(ctx); |
| 6002 | 6024 | return; |
| 6003 | 6025 | } |
| 6004 | - tcg_gen_movi_tl(cpu_T[0], ctx->opcode & 0x00010000); | |
| 6005 | - gen_op_wrte(); | |
| 6006 | - /* Stop translation to have a chance to raise an exception | |
| 6007 | - * if we just set msr_ee to 1 | |
| 6008 | - */ | |
| 6009 | - GEN_STOP(ctx); | |
| 6026 | + if (ctx->opcode & 0x00010000) { | |
| 6027 | + tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE)); | |
| 6028 | + /* Stop translation to have a chance to raise an exception */ | |
| 6029 | + GEN_STOP(ctx); | |
| 6030 | + } else { | |
| 6031 | + tcg_gen_andi_tl(cpu_msr, cpu_msr, (1 << MSR_EE)); | |
| 6032 | + } | |
| 6010 | 6033 | #endif |
| 6011 | 6034 | } |
| 6012 | 6035 | ... | ... |