diff options
author | Blue Swirl <blauwirbel@gmail.com> | 2011-04-26 18:44:20 +0000 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2011-05-14 07:30:28 +0000 |
commit | a2589e5cf288971d66afd0d41f5eefb735419890 (patch) | |
tree | 178cd87661912bcc57f353bc1a13f28b232142db | |
parent | 711c21280b2cb56060859cc574221a8bf40f908a (diff) | |
download | qemu-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.c | 28 |
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); |