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 | ... | ... |