summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorBlue Swirl <blauwirbel@gmail.com>2011-04-26 18:44:20 +0000
committerBlue Swirl <blauwirbel@gmail.com>2011-05-14 07:30:28 +0000
commita2589e5cf288971d66afd0d41f5eefb735419890 (patch)
tree178cd87661912bcc57f353bc1a13f28b232142db
parent711c21280b2cb56060859cc574221a8bf40f908a (diff)
downloadfocaccia-qemu-a2589e5cf288971d66afd0d41f5eefb735419890.tar.gz
focaccia-qemu-a2589e5cf288971d66afd0d41f5eefb735419890.zip
sparc64: fix wrpstate and wrtl on delay slot
Use TCG local to work around TCG register flush due to a branch.

Thanks to Artyom Tarasenko, Igor Kovalenko and Aurelien Jarno.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
-rw-r--r--target-sparc/translate.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 3c958b26d6..9222cde160 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -3505,16 +3505,28 @@ static void disas_sparc_insn(DisasContext * dc)
                                 tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
                                 break;
                             case 6: // pstate
-                                save_state(dc, cpu_cond);
-                                gen_helper_wrpstate(cpu_tmp0);
-                                dc->npc = DYNAMIC_PC;
+                                {
+                                    TCGv r_tmp = tcg_temp_local_new();
+
+                                    tcg_gen_mov_tl(r_tmp, cpu_tmp0);
+                                    save_state(dc, cpu_cond);
+                                    gen_helper_wrpstate(r_tmp);
+                                    tcg_temp_free(r_tmp);
+                                    dc->npc = DYNAMIC_PC;
+                                }
                                 break;
                             case 7: // tl
-                                save_state(dc, cpu_cond);
-                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
-                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
-                                               offsetof(CPUSPARCState, tl));
-                                dc->npc = DYNAMIC_PC;
+                                {
+                                    TCGv r_tmp = tcg_temp_local_new();
+
+                                    tcg_gen_mov_tl(r_tmp, cpu_tmp0);
+                                    save_state(dc, cpu_cond);
+                                    tcg_gen_trunc_tl_i32(cpu_tmp32, r_tmp);
+                                    tcg_temp_free(r_tmp);
+                                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
+                                                   offsetof(CPUSPARCState, tl));
+                                    dc->npc = DYNAMIC_PC;
+                                }
                                 break;
                             case 8: // pil
                                 gen_helper_wrpil(cpu_tmp0);