qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] sparc64: fix wrpstate and wrtl on delay slot


From: Blue Swirl
Subject: [Qemu-devel] [PATCH] sparc64: fix wrpstate and wrtl on delay slot
Date: Sat, 30 Apr 2011 18:42:06 +0300

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 <address@hidden>
---
I analyzed the call tree in target-sparc/translate.c for brcond* usage.
In the following lines, first level function uses brcond* directly,
second level calls the first level etc.

gen_add_tv
>gen_op_tadd_ccTV
>>taddcctv

gen_tag_tv
>gen_op_tadd_ccTV
>>taddcctv
>gen_op_tsub_ccTV
>>tsubcctv

gen_sub_tv
>gen_op_tsub_ccTV
>>tsubcctv

gen_op_mulscc
>mulscc

gen_trap_ifdivzero_tl
>gen_op_sdivx
>>sdivx
>udivx

gen_op_sdivx
>sdivx

gen_branch2
>disas_sparc_insn

gen_branch_a
>do_branch
>>bpcc
>>bn+x
>do_fbranch
>>fbpcc
>>fbn+x
>do_branch_reg
>>bpr

gen_generic_branch
>flush_cond
>>do_branch
>>>bpcc
>>>bn+x
>>do_fbranch
>>>fbpcc
>>>fbn+x
>>do_branch_reg
>>>bpr
>save_npc
>>save_state
>>>gen_trap_ifnofpu
>>>trap
>>>flushw
>>>FPU Operations
>>>taddcctv
>>>tsubcctv
>>>wrfprs
>>>wrpsr
>>>wrpstate
>>>wrtl
>>>wrhpstate
>>>return
>>>save
>>>restore
>>>ldd
>>>lda
>>>lduba
>>>lduha
>>>ldda
>>>ldsba
>>>ldsha
>>>ldstuba
>>>swapa
>>>ldswa
>>>ldxa
>>>ldfa
>>>lddfa
>>>ldqfa
>>>ldf
>>>ldfsr
>>>lddqf
>>>lddf
>>>std
>>>sta
>>>stba
>>>stha
>>>stda
>>>stxa
>>>stf
>>>stfsr
>>>stqf
>>>stdf
>>>stfa
>>>stqfa
>>>stdfa
>>>casa
>>>casxa
>>gen_intermediate_code_internal
>gen_mov_pc_npc
>>call
>>return
>>jmpl
>>rett

gen_cond_reg
>do_branch_reg
>>bpr

trap

fmovsr

fmovdr

fmovqr

fmovscc

fmovdcc

fmovqcc

movcc

movr

I only found wrtl in addition to wrpstate discovered earlier, other
use cases looked OK.

 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);
-- 
1.6.2.4



reply via email to

[Prev in Thread] Current Thread [Next in Thread]