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
This commit is contained in:
parent
22e0e17337
commit
6527f6ea9c
|
@ -7,6 +7,7 @@ DEF_HELPER_3(tw, void, tl, tl, i32)
|
||||||
DEF_HELPER_3(td, void, tl, tl, i32)
|
DEF_HELPER_3(td, void, tl, tl, i32)
|
||||||
#endif
|
#endif
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
DEF_HELPER_1(store_msr, void, tl)
|
||||||
DEF_HELPER_0(rfi, void)
|
DEF_HELPER_0(rfi, void)
|
||||||
DEF_HELPER_0(rfsvc, void)
|
DEF_HELPER_0(rfsvc, void)
|
||||||
DEF_HELPER_0(40x_rfci, void)
|
DEF_HELPER_0(40x_rfci, void)
|
||||||
|
|
|
@ -79,38 +79,6 @@ void OPPROTO op_store_asr (void)
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#endif
|
||||||
|
|
||||||
/* SPR */
|
/* SPR */
|
||||||
|
@ -394,17 +362,6 @@ void OPPROTO op_store_dcr (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#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)
|
void OPPROTO op_440_tlbre (void)
|
||||||
{
|
{
|
||||||
do_440_tlbre(PARAM1);
|
do_440_tlbre(PARAM1);
|
||||||
|
|
|
@ -1488,17 +1488,17 @@ uint32_t helper_fcmpo (uint64_t arg1, uint64_t arg2)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined (CONFIG_USER_ONLY)
|
#if !defined (CONFIG_USER_ONLY)
|
||||||
void cpu_dump_rfi (target_ulong RA, target_ulong msr);
|
void helper_store_msr (target_ulong val)
|
||||||
|
|
||||||
void do_store_msr (void)
|
|
||||||
{
|
{
|
||||||
T0 = hreg_store_msr(env, T0, 0);
|
val = hreg_store_msr(env, val, 0);
|
||||||
if (T0 != 0) {
|
if (val != 0) {
|
||||||
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
|
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,
|
static always_inline void do_rfi (target_ulong nip, target_ulong msr,
|
||||||
target_ulong msrm, int keep_msrh)
|
target_ulong msrm, int keep_msrh)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,10 +28,6 @@ target_ulong ppc_load_dump_spr (int sprn);
|
||||||
void ppc_store_dump_spr (int sprn, target_ulong val);
|
void ppc_store_dump_spr (int sprn, target_ulong val);
|
||||||
|
|
||||||
/* Misc */
|
/* Misc */
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
|
||||||
void do_store_msr (void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* POWER / PowerPC 601 specific helpers */
|
/* POWER / PowerPC 601 specific helpers */
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
void do_POWER_rac (void);
|
void do_POWER_rac (void);
|
||||||
|
|
|
@ -63,6 +63,7 @@ static TCGv_i64 cpu_fpr[32];
|
||||||
static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
|
static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
|
||||||
static TCGv_i32 cpu_crf[8];
|
static TCGv_i32 cpu_crf[8];
|
||||||
static TCGv cpu_nip;
|
static TCGv cpu_nip;
|
||||||
|
static TCGv cpu_msr;
|
||||||
static TCGv cpu_ctr;
|
static TCGv cpu_ctr;
|
||||||
static TCGv cpu_lr;
|
static TCGv cpu_lr;
|
||||||
static TCGv cpu_xer;
|
static TCGv cpu_xer;
|
||||||
|
@ -153,6 +154,9 @@ void ppc_translate_init(void)
|
||||||
cpu_nip = tcg_global_mem_new(TCG_AREG0,
|
cpu_nip = tcg_global_mem_new(TCG_AREG0,
|
||||||
offsetof(CPUState, nip), "nip");
|
offsetof(CPUState, nip), "nip");
|
||||||
|
|
||||||
|
cpu_msr = tcg_global_mem_new(TCG_AREG0,
|
||||||
|
offsetof(CPUState, msr), "msr");
|
||||||
|
|
||||||
cpu_ctr = tcg_global_mem_new(TCG_AREG0,
|
cpu_ctr = tcg_global_mem_new(TCG_AREG0,
|
||||||
offsetof(CPUState, ctr), "ctr");
|
offsetof(CPUState, ctr), "ctr");
|
||||||
|
|
||||||
|
@ -3876,8 +3880,7 @@ GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
|
||||||
GEN_EXCP_PRIVREG(ctx);
|
GEN_EXCP_PRIVREG(ctx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gen_op_load_msr();
|
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
|
||||||
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
|
|
||||||
#endif
|
#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)]);
|
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
|
||||||
if (ctx->opcode & 0x00010000) {
|
if (ctx->opcode & 0x00010000) {
|
||||||
/* Special form that does not need any synchronisation */
|
/* 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 {
|
} else {
|
||||||
/* XXX: we need to update nip before the store
|
/* XXX: we need to update nip before the store
|
||||||
* if we enter power saving mode, we will exit the loop
|
* if we enter power saving mode, we will exit the loop
|
||||||
* directly from ppc_store_msr
|
* directly from ppc_store_msr
|
||||||
*/
|
*/
|
||||||
gen_update_nip(ctx, ctx->nip);
|
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 */
|
/* Must stop the translation as machine state (may have) changed */
|
||||||
/* Note that mtmsr is not always defined as context-synchronizing */
|
/* Note that mtmsr is not always defined as context-synchronizing */
|
||||||
ctx->exception = POWERPC_EXCP_STOP;
|
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)]);
|
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
|
||||||
if (ctx->opcode & 0x00010000) {
|
if (ctx->opcode & 0x00010000) {
|
||||||
/* Special form that does not need any synchronisation */
|
/* 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 {
|
} else {
|
||||||
/* XXX: we need to update nip before the store
|
/* XXX: we need to update nip before the store
|
||||||
* if we enter power saving mode, we will exit the loop
|
* 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);
|
gen_update_nip(ctx, ctx->nip);
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
if (!ctx->sf_mode)
|
if (!ctx->sf_mode) {
|
||||||
gen_op_store_msr_32();
|
TCGv t0 = tcg_temp_new();
|
||||||
else
|
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
|
#endif
|
||||||
gen_op_store_msr();
|
gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]);
|
||||||
/* Must stop the translation as machine state (may have) changed */
|
/* 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;
|
ctx->exception = POWERPC_EXCP_STOP;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -5978,12 +5996,16 @@ GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE)
|
||||||
#if defined(CONFIG_USER_ONLY)
|
#if defined(CONFIG_USER_ONLY)
|
||||||
GEN_EXCP_PRIVOPC(ctx);
|
GEN_EXCP_PRIVOPC(ctx);
|
||||||
#else
|
#else
|
||||||
|
TCGv t0;
|
||||||
if (unlikely(!ctx->supervisor)) {
|
if (unlikely(!ctx->supervisor)) {
|
||||||
GEN_EXCP_PRIVOPC(ctx);
|
GEN_EXCP_PRIVOPC(ctx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rD(ctx->opcode)]);
|
t0 = tcg_temp_new();
|
||||||
gen_op_wrte();
|
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
|
/* Stop translation to have a chance to raise an exception
|
||||||
* if we just set msr_ee to 1
|
* 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);
|
GEN_EXCP_PRIVOPC(ctx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tcg_gen_movi_tl(cpu_T[0], ctx->opcode & 0x00010000);
|
if (ctx->opcode & 0x00010000) {
|
||||||
gen_op_wrte();
|
tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
|
||||||
/* Stop translation to have a chance to raise an exception
|
/* Stop translation to have a chance to raise an exception */
|
||||||
* if we just set msr_ee to 1
|
|
||||||
*/
|
|
||||||
GEN_STOP(ctx);
|
GEN_STOP(ctx);
|
||||||
|
} else {
|
||||||
|
tcg_gen_andi_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue