[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~
- Re: About hardfloat in ppc, (continued)