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 */
}
#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);
}
#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)
{
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;
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");
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
}
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;
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
*/
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
#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
*/
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
}