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
| @@ -7,6 +7,7 @@ DEF_HELPER_3(tw, void, tl, tl, i32) | @@ -7,6 +7,7 @@ DEF_HELPER_3(tw, void, tl, tl, i32) | ||
| 7 | DEF_HELPER_3(td, void, tl, tl, i32) | 7 | DEF_HELPER_3(td, void, tl, tl, i32) |
| 8 | #endif | 8 | #endif |
| 9 | #if !defined(CONFIG_USER_ONLY) | 9 | #if !defined(CONFIG_USER_ONLY) |
| 10 | +DEF_HELPER_1(store_msr, void, tl) | ||
| 10 | DEF_HELPER_0(rfi, void) | 11 | DEF_HELPER_0(rfi, void) |
| 11 | DEF_HELPER_0(rfsvc, void) | 12 | DEF_HELPER_0(rfsvc, void) |
| 12 | DEF_HELPER_0(40x_rfci, void) | 13 | DEF_HELPER_0(40x_rfci, void) |
target-ppc/op.c
| @@ -79,38 +79,6 @@ void OPPROTO op_store_asr (void) | @@ -79,38 +79,6 @@ void OPPROTO op_store_asr (void) | ||
| 79 | RETURN(); | 79 | RETURN(); |
| 80 | } | 80 | } |
| 81 | #endif | 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 | #endif | 82 | #endif |
| 115 | 83 | ||
| 116 | /* SPR */ | 84 | /* SPR */ |
| @@ -394,17 +362,6 @@ void OPPROTO op_store_dcr (void) | @@ -394,17 +362,6 @@ void OPPROTO op_store_dcr (void) | ||
| 394 | } | 362 | } |
| 395 | 363 | ||
| 396 | #if !defined(CONFIG_USER_ONLY) | 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 | void OPPROTO op_440_tlbre (void) | 365 | void OPPROTO op_440_tlbre (void) |
| 409 | { | 366 | { |
| 410 | do_440_tlbre(PARAM1); | 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,17 +1488,17 @@ uint32_t helper_fcmpo (uint64_t arg1, uint64_t arg2) | ||
| 1488 | } | 1488 | } |
| 1489 | 1489 | ||
| 1490 | #if !defined (CONFIG_USER_ONLY) | 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 | env->interrupt_request |= CPU_INTERRUPT_EXITTB; | 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 | static always_inline void do_rfi (target_ulong nip, target_ulong msr, | 1502 | static always_inline void do_rfi (target_ulong nip, target_ulong msr, |
| 1503 | target_ulong msrm, int keep_msrh) | 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,10 +28,6 @@ target_ulong ppc_load_dump_spr (int sprn); | ||
| 28 | void ppc_store_dump_spr (int sprn, target_ulong val); | 28 | void ppc_store_dump_spr (int sprn, target_ulong val); |
| 29 | 29 | ||
| 30 | /* Misc */ | 30 | /* Misc */ |
| 31 | -#if !defined(CONFIG_USER_ONLY) | ||
| 32 | -void do_store_msr (void); | ||
| 33 | -#endif | ||
| 34 | - | ||
| 35 | /* POWER / PowerPC 601 specific helpers */ | 31 | /* POWER / PowerPC 601 specific helpers */ |
| 36 | #if !defined(CONFIG_USER_ONLY) | 32 | #if !defined(CONFIG_USER_ONLY) |
| 37 | void do_POWER_rac (void); | 33 | void do_POWER_rac (void); |
target-ppc/translate.c
| @@ -63,6 +63,7 @@ static TCGv_i64 cpu_fpr[32]; | @@ -63,6 +63,7 @@ static TCGv_i64 cpu_fpr[32]; | ||
| 63 | static TCGv_i64 cpu_avrh[32], cpu_avrl[32]; | 63 | static TCGv_i64 cpu_avrh[32], cpu_avrl[32]; |
| 64 | static TCGv_i32 cpu_crf[8]; | 64 | static TCGv_i32 cpu_crf[8]; |
| 65 | static TCGv cpu_nip; | 65 | static TCGv cpu_nip; |
| 66 | +static TCGv cpu_msr; | ||
| 66 | static TCGv cpu_ctr; | 67 | static TCGv cpu_ctr; |
| 67 | static TCGv cpu_lr; | 68 | static TCGv cpu_lr; |
| 68 | static TCGv cpu_xer; | 69 | static TCGv cpu_xer; |
| @@ -153,6 +154,9 @@ void ppc_translate_init(void) | @@ -153,6 +154,9 @@ void ppc_translate_init(void) | ||
| 153 | cpu_nip = tcg_global_mem_new(TCG_AREG0, | 154 | cpu_nip = tcg_global_mem_new(TCG_AREG0, |
| 154 | offsetof(CPUState, nip), "nip"); | 155 | offsetof(CPUState, nip), "nip"); |
| 155 | 156 | ||
| 157 | + cpu_msr = tcg_global_mem_new(TCG_AREG0, | ||
| 158 | + offsetof(CPUState, msr), "msr"); | ||
| 159 | + | ||
| 156 | cpu_ctr = tcg_global_mem_new(TCG_AREG0, | 160 | cpu_ctr = tcg_global_mem_new(TCG_AREG0, |
| 157 | offsetof(CPUState, ctr), "ctr"); | 161 | offsetof(CPUState, ctr), "ctr"); |
| 158 | 162 | ||
| @@ -3876,8 +3880,7 @@ GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC) | @@ -3876,8 +3880,7 @@ GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC) | ||
| 3876 | GEN_EXCP_PRIVREG(ctx); | 3880 | GEN_EXCP_PRIVREG(ctx); |
| 3877 | return; | 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 | #endif | 3884 | #endif |
| 3882 | } | 3885 | } |
| 3883 | 3886 | ||
| @@ -3984,14 +3987,18 @@ GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B) | @@ -3984,14 +3987,18 @@ GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B) | ||
| 3984 | tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | 3987 | tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); |
| 3985 | if (ctx->opcode & 0x00010000) { | 3988 | if (ctx->opcode & 0x00010000) { |
| 3986 | /* Special form that does not need any synchronisation */ | 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 | } else { | 3995 | } else { |
| 3989 | /* XXX: we need to update nip before the store | 3996 | /* XXX: we need to update nip before the store |
| 3990 | * if we enter power saving mode, we will exit the loop | 3997 | * if we enter power saving mode, we will exit the loop |
| 3991 | * directly from ppc_store_msr | 3998 | * directly from ppc_store_msr |
| 3992 | */ | 3999 | */ |
| 3993 | gen_update_nip(ctx, ctx->nip); | 4000 | gen_update_nip(ctx, ctx->nip); |
| 3994 | - gen_op_store_msr(); | 4001 | + gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]); |
| 3995 | /* Must stop the translation as machine state (may have) changed */ | 4002 | /* Must stop the translation as machine state (may have) changed */ |
| 3996 | /* Note that mtmsr is not always defined as context-synchronizing */ | 4003 | /* Note that mtmsr is not always defined as context-synchronizing */ |
| 3997 | ctx->exception = POWERPC_EXCP_STOP; | 4004 | ctx->exception = POWERPC_EXCP_STOP; |
| @@ -4012,7 +4019,11 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) | @@ -4012,7 +4019,11 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) | ||
| 4012 | tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | 4019 | tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); |
| 4013 | if (ctx->opcode & 0x00010000) { | 4020 | if (ctx->opcode & 0x00010000) { |
| 4014 | /* Special form that does not need any synchronisation */ | 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 | } else { | 4027 | } else { |
| 4017 | /* XXX: we need to update nip before the store | 4028 | /* XXX: we need to update nip before the store |
| 4018 | * if we enter power saving mode, we will exit the loop | 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,13 +4031,20 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) | ||
| 4020 | */ | 4031 | */ |
| 4021 | gen_update_nip(ctx, ctx->nip); | 4032 | gen_update_nip(ctx, ctx->nip); |
| 4022 | #if defined(TARGET_PPC64) | 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 | #endif | 4044 | #endif |
| 4027 | - gen_op_store_msr(); | 4045 | + gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]); |
| 4028 | /* Must stop the translation as machine state (may have) changed */ | 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 | ctx->exception = POWERPC_EXCP_STOP; | 4048 | ctx->exception = POWERPC_EXCP_STOP; |
| 4031 | } | 4049 | } |
| 4032 | #endif | 4050 | #endif |
| @@ -5978,12 +5996,16 @@ GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE) | @@ -5978,12 +5996,16 @@ GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE) | ||
| 5978 | #if defined(CONFIG_USER_ONLY) | 5996 | #if defined(CONFIG_USER_ONLY) |
| 5979 | GEN_EXCP_PRIVOPC(ctx); | 5997 | GEN_EXCP_PRIVOPC(ctx); |
| 5980 | #else | 5998 | #else |
| 5999 | + TCGv t0; | ||
| 5981 | if (unlikely(!ctx->supervisor)) { | 6000 | if (unlikely(!ctx->supervisor)) { |
| 5982 | GEN_EXCP_PRIVOPC(ctx); | 6001 | GEN_EXCP_PRIVOPC(ctx); |
| 5983 | return; | 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 | /* Stop translation to have a chance to raise an exception | 6009 | /* Stop translation to have a chance to raise an exception |
| 5988 | * if we just set msr_ee to 1 | 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,12 +6023,13 @@ GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE) | ||
| 6001 | GEN_EXCP_PRIVOPC(ctx); | 6023 | GEN_EXCP_PRIVOPC(ctx); |
| 6002 | return; | 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 | #endif | 6033 | #endif |
| 6011 | } | 6034 | } |
| 6012 | 6035 |