qemu-ppc
[Top][All Lists]
Advanced

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

Re: About hardfloat in ppc


From: Richard Henderson
Subject: Re: About hardfloat in ppc
Date: Fri, 1 May 2020 13:35:57 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0

On 5/1/20 10:49 AM, 罗勇刚(Yonggang Luo) wrote:
> 
> 
> On Sat, May 2, 2020 at 12:51 AM Richard Henderson <address@hidden
> <mailto:address@hidden>> wrote:
> 
>     On 5/1/20 9:29 AM, 罗勇刚(Yonggang Luo) wrote:
>     > On Fri, May 1, 2020 at 10:18 PM Richard Henderson
>     <address@hidden <mailto:address@hidden>
>     >     Step 1 is to rearrange the fp helpers to eliminate
>     helper_reset_fpstatus().
>     >     I've mentioned this before, that it's possible to leave the
>     steady-state of
>     >     env->fp_status.exception_flags == 0, so there's no need for a
>     separate function
>     >     call.  I suspect this is worth a decent speedup by itself.
>     >
>     > Hi Richard, what kinds of rearrange the fp need to be done? Can you 
> give me a
>     > more detailed example? I am still not get the idea.
> 
>     See target/openrisc, helper_update_fpcsr.
> 
>     This is like target/ppc helper_float_check_status, in that it is called 
> after
>     the primary fpu helper, after the fpu result is written back to the
>     architectural register, to process fpu exceptions.
> 
>     Note that if get_float_exception_flags returns non-zero, we immediately 
> reset
>     them to zero.  Thus the exception flags are only ever non-zero in between 
> the
>     primary fpu operation and the update of the fpscr.
> 
> According to 
> ```
> void HELPER(update_fpcsr)(CPUOpenRISCState *env)
> {
>     int tmp = get_float_exception_flags(&env->fp_status);
> 
>     if (tmp) {
>         set_float_exception_flags(0, &env->fp_status);
>         tmp = ieee_ex_to_openrisc(tmp);
>         if (tmp) {
>             env->fpcsr |= tmp;
>             if (env->fpcsr & FPCSR_FPEE) {
>                 helper_exception(env, EXCP_FPE);
>             }
>         }
>     }
> }
> ```
> The openrisc also clearing the flags before each fp operation?

No.  Please re-read my description above.

OpenRISC is clearing the flags *after* each fp operation, at the same time that
it processes the flags from the current fp operation.

There are two calls at runtime for openrisc, e.g. do_fp2:

    fn(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->a));
    gen_helper_update_fpcsr(cpu_env);

Whereas for ppc there are between 2 and 5 calls at runtime, e.g. in 
_GEN_FLOAT_ACB:

>     gen_reset_fpstatus();                           [1]
>     get_fpr(t0, rA(ctx->opcode));                   
>     get_fpr(t1, rC(ctx->opcode));                   
>     get_fpr(t2, rB(ctx->opcode));                   
>     gen_helper_f##op(t3, cpu_env, t0, t1, t2);      [2]
>     if (isfloat) {                                  
>         gen_helper_frsp(t3, cpu_env, t3);           [3]
>     }                                               
>     set_fpr(rD(ctx->opcode), t3);                   
>     if (set_fprf) {                                 
>         gen_compute_fprf_float64(t3);               [4]
>     }                                               
>     if (unlikely(Rc(ctx->opcode) != 0)) {           
>         gen_set_cr1_from_fpscr(ctx);                [5]
>     }                                               

For step 1, we're talking about removing the call to gen_reset_fpstatus.

It might be worth adding a debugging check to the beginning of each helper of
the form [2] to assert that the exception flags are in fact zero.  This check
might be removed later, in relation to future improvements, but it can help
ensure that the value of set_fprf is correct, and validate that step 1 isn't
breaking anything.


r~



reply via email to

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