пон, 4. мај 2020. у 21:31 <luoyongg...@gmail.com> је написао/ла: > > From: Yonggang Luo <luoyongg...@gmail.com> > > Just post as an idea to improve PPC fp performance. > With this idea, we have no need to adjust the helper orders. > > Signed-off-by: Yonggang Luo <luoyongg...@gmail.com> > --- > target/ppc/fpu_helper.c | 44 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 44 insertions(+) > > diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c > index 2bd49a2cdf..79051e4540 100644 > --- a/target/ppc/fpu_helper.c > +++ b/target/ppc/fpu_helper.c > @@ -926,6 +926,17 @@ static void float_invalid_op_addsub(CPUPPCState *env, > bool set_fpcc, > /* fadd - fadd. */ > float64 helper_fadd(CPUPPCState *env, float64 arg1, float64 arg2) > { > + CPU_DoubleU u1, u2; > + > + u1.d = arg1; > + u2.d = arg2; > + CPU_DoubleU retDouble; > + retDouble.nd = u1.nd + u2.nd;
Besides what Richard mentioned, you neglect here "flush-denormals-to-zero" property of FPUs. You implicitly assume that the host has the same behavior as the target (ppc). But that simply may not be the case, leading to the wrong result. Yours, Aleksandar > + if (likely(float64_is_zero_or_normal(retDouble.d))) > + { > + /* TODO: Handling inexact */ > + return retDouble.d; > + } > float64 ret = float64_add(arg1, arg2, &env->fp_status); > int status = get_float_exception_flags(&env->fp_status); > > @@ -941,6 +952,17 @@ float64 helper_fadd(CPUPPCState *env, float64 arg1, > float64 arg2) > /* fsub - fsub. */ > float64 helper_fsub(CPUPPCState *env, float64 arg1, float64 arg2) > { > + CPU_DoubleU u1, u2; > + > + u1.d = arg1; > + u2.d = arg2; > + CPU_DoubleU retDouble; > + retDouble.nd = u1.nd - u2.nd; > + if (likely(float64_is_zero_or_normal(retDouble.d))) > + { > + /* TODO: Handling inexact */ > + return retDouble.d; > + } > float64 ret = float64_sub(arg1, arg2, &env->fp_status); > int status = get_float_exception_flags(&env->fp_status); > > @@ -967,6 +989,17 @@ static void float_invalid_op_mul(CPUPPCState *env, bool > set_fprc, > /* fmul - fmul. */ > float64 helper_fmul(CPUPPCState *env, float64 arg1, float64 arg2) > { > + CPU_DoubleU u1, u2; > + > + u1.d = arg1; > + u2.d = arg2; > + CPU_DoubleU retDouble; > + retDouble.nd = u1.nd * u2.nd; > + if (likely(float64_is_zero_or_normal(retDouble.d))) > + { > + /* TODO: Handling inexact */ > + return retDouble.d; > + } > float64 ret = float64_mul(arg1, arg2, &env->fp_status); > int status = get_float_exception_flags(&env->fp_status); > > @@ -997,6 +1030,17 @@ static void float_invalid_op_div(CPUPPCState *env, bool > set_fprc, > /* fdiv - fdiv. */ > float64 helper_fdiv(CPUPPCState *env, float64 arg1, float64 arg2) > { > + CPU_DoubleU u1, u2; > + > + u1.d = arg1; > + u2.d = arg2; > + CPU_DoubleU retDouble; > + retDouble.nd = u1.nd / u2.nd; > + if (likely(float64_is_zero_or_normal(retDouble.d))) > + { > + /* TODO: Handling inexact */ > + return retDouble.d; > + } > float64 ret = float64_div(arg1, arg2, &env->fp_status); > int status = get_float_exception_flags(&env->fp_status); > > -- > 2.23.0.windows.1 > >