aboutsummaryrefslogtreecommitdiff
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)
downloadqemu-a2589e5cf288971d66afd0d41f5eefb735419890.zip
qemu-a2589e5cf288971d66afd0d41f5eefb735419890.tar.gz
qemu-a2589e5cf288971d66afd0d41f5eefb735419890.tar.bz2
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 3c958b2..9222cde 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);