On 5/1/20 10:49 AM, 罗勇刚(Yonggang Luo) wrote: > > > On Sat, May 2, 2020 at 12:51 AM Richard Henderson > <richard.hender...@linaro.org > <mailto:richard.hender...@linaro.org>> wrote: > > On 5/1/20 9:29 AM, 罗勇刚(Yonggang Luo) wrote: > > On Fri, May 1, 2020 at 10:18 PM Richard Henderson > <richard.hender...@linaro.org <mailto:richard.hender...@linaro.org> > > 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~