PPC: Only set lower 32bits with mtmsr

As Nathan pointed out correctly, the mtmsr instruction does not modify
the high 32 bits of MSR. It also doesn't matter if SF is set or not,
the instruction always behaves the same.

This patch moves it a bit closer to the spec.

Reported-by: Nathan Whitehorn <nwhitehorn@freebsd.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
Alexander Graf 2011-06-16 10:44:23 +02:00
parent a59106cbbb
commit 8018dc63aa

View file

@ -3878,24 +3878,19 @@ static void gen_mtmsr(DisasContext *ctx)
tcg_gen_or_tl(cpu_msr, cpu_msr, t0); tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
tcg_temp_free(t0); tcg_temp_free(t0);
} else { } else {
TCGv msr = tcg_temp_new();
/* 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);
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
if (!ctx->sf_mode) { tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32);
TCGv t0 = tcg_temp_new(); #else
TCGv t1 = tcg_temp_new(); tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]);
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_helper_store_msr(cpu_gpr[rS(ctx->opcode)]); gen_helper_store_msr(msr);
/* 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 */
gen_stop_exception(ctx); gen_stop_exception(ctx);