Patchwork sparc64: fix wrpstate and wrtl on delay slot

login
register
mail settings
Submitter Blue Swirl
Date April 30, 2011, 3:42 p.m.
Message ID <BANLkTimFrQ12ZhpfdCyS3HvCd9kYHm7bRA@mail.gmail.com>
Download mbox | patch
Permalink /patch/93504/
State New
Headers show

Comments

Blue Swirl - April 30, 2011, 3:42 p.m.
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>
---
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(-)

                                 gen_helper_wrpil(cpu_tmp0);
Igor V. Kovalenko - April 30, 2011, 7:32 p.m.
On Sat, Apr 30, 2011 at 7:42 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
> 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>
> ---
> 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.
>

I want to be able to do exhaustive searches as well :)
Have you used recently posted gcc save-temps method?
Super Bisquit - April 30, 2011, 7:48 p.m.
Just curious, is this for host or guest?
On Sat, Apr 30, 2011 at 3:32 PM, Igor Kovalenko
<igor.v.kovalenko@gmail.com>wrote:

> On Sat, Apr 30, 2011 at 7:42 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
> > 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>
> > ---
> > 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.
> >
>
> I want to be able to do exhaustive searches as well :)
> Have you used recently posted gcc save-temps method?
>
> --
> Kind regards,
> Igor V. Kovalenko
>
>
Artyom Tarasenko - April 30, 2011, 7:53 p.m.
On Sat, Apr 30, 2011 at 9:48 PM, Super Bisquit <superbisquit@gmail.com> wrote:
>
> Just curious, is this for host or guest?

Guest (aka target)

> On Sat, Apr 30, 2011 at 3:32 PM, Igor Kovalenko <igor.v.kovalenko@gmail.com>
> wrote:
>>
>> On Sat, Apr 30, 2011 at 7:42 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
>> > 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>
>> > ---
>> > 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.
>> >
>>
>> I want to be able to do exhaustive searches as well :)
>> Have you used recently posted gcc save-temps method?
>>
>> --
>> Kind regards,
>> Igor V. Kovalenko
>>
>
>
Blue Swirl - May 1, 2011, 7:27 a.m.
On Sat, Apr 30, 2011 at 10:32 PM, Igor Kovalenko
<igor.v.kovalenko@gmail.com> wrote:
> On Sat, Apr 30, 2011 at 7:42 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
>> 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>
>> ---
>> 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.
>>
>
> I want to be able to do exhaustive searches as well :)
> Have you used recently posted gcc save-temps method?

No, I just used the search facilities of the editor. First, search for
brcond, examine the function for correctness and copy the function
names to scratch buffer. Next, search for the function names just
found, examine callers and copy their function names with prefix to
scratch etc. About one hour's work.

Patch

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