PPC: Only set lower 32bits with mtmsr
authorAlexander Graf <agraf@suse.de>
Thu, 16 Jun 2011 08:44:23 +0000 (10:44 +0200)
committerAlexander Graf <agraf@suse.de>
Fri, 17 Jun 2011 00:58:31 +0000 (02:58 +0200)
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>
target-ppc/translate.c

index 59aef855d42b4c7895c7685e67308b02cd6b8a8f..7e318e397a56c29984e4344d4ff0d9729cf1aeba 100644 (file)
@@ -3878,24 +3878,19 @@ static void gen_mtmsr(DisasContext *ctx)
         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
         tcg_temp_free(t0);
     } else {
+        TCGv msr = tcg_temp_new();
+
         /* 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);
 #if defined(TARGET_PPC64)
-        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
+        tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32);
+#else
+        tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]);
 #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 */
         /* Note that mtmsr is not always defined as context-synchronizing */
         gen_stop_exception(ctx);