Skip to content

Commit

Permalink
target/ppc: Tidy helper_fadd, helper_fsub
Browse files Browse the repository at this point in the history
Tidy the invalid exception checking so that we rely on softfloat for
initial argument validation, and select the kind of invalid operand
exception only when we know we must.  Pass and return float64 values
directly rather than bounce through the CPU_DoubleU union.

Note that because we know float_flag_invalid was set, we do not have
to re-check the signs of the infinities.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
  • Loading branch information
rth7680 authored and dgibson committed Aug 21, 2018
1 parent 79f9163 commit ac43cec
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 31 deletions.
50 changes: 21 additions & 29 deletions target/ppc/fpu_helper.c
Expand Up @@ -587,51 +587,43 @@ void helper_reset_fpstatus(CPUPPCState *env)
}

/* fadd - fadd. */
uint64_t helper_fadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
float64 helper_fadd(CPUPPCState *env, float64 arg1, float64 arg2)
{
CPU_DoubleU farg1, farg2;

farg1.ll = arg1;
farg2.ll = arg2;
float64 ret = float64_add(arg1, arg2, &env->fp_status);
int status = get_float_exception_flags(&env->fp_status);

if (unlikely(float64_is_infinity(farg1.d) && float64_is_infinity(farg2.d) &&
float64_is_neg(farg1.d) != float64_is_neg(farg2.d))) {
/* Magnitude subtraction of infinities */
farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
} else {
if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
float64_is_signaling_nan(farg2.d, &env->fp_status))) {
if (unlikely(status & float_flag_invalid)) {
if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) {
/* Magnitude subtraction of infinities */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
} else if (float64_is_signaling_nan(arg1, &env->fp_status) ||
float64_is_signaling_nan(arg2, &env->fp_status)) {
/* sNaN addition */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
}
farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status);
}

return farg1.ll;
return ret;
}

/* fsub - fsub. */
uint64_t helper_fsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
float64 helper_fsub(CPUPPCState *env, float64 arg1, float64 arg2)
{
CPU_DoubleU farg1, farg2;

farg1.ll = arg1;
farg2.ll = arg2;
float64 ret = float64_sub(arg1, arg2, &env->fp_status);
int status = get_float_exception_flags(&env->fp_status);

if (unlikely(float64_is_infinity(farg1.d) && float64_is_infinity(farg2.d) &&
float64_is_neg(farg1.d) == float64_is_neg(farg2.d))) {
/* Magnitude subtraction of infinities */
farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
} else {
if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
float64_is_signaling_nan(farg2.d, &env->fp_status))) {
/* sNaN subtraction */
if (unlikely(status & float_flag_invalid)) {
if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) {
/* Magnitude subtraction of infinities */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
} else if (float64_is_signaling_nan(arg1, &env->fp_status) ||
float64_is_signaling_nan(arg2, &env->fp_status)) {
/* sNaN addition */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
}
farg1.d = float64_sub(farg1.d, farg2.d, &env->fp_status);
}

return farg1.ll;
return ret;
}

/* fmul - fmul. */
Expand Down
4 changes: 2 additions & 2 deletions target/ppc/helper.h
Expand Up @@ -85,8 +85,8 @@ DEF_HELPER_2(friz, i64, env, i64)
DEF_HELPER_2(frip, i64, env, i64)
DEF_HELPER_2(frim, i64, env, i64)

DEF_HELPER_3(fadd, i64, env, i64, i64)
DEF_HELPER_3(fsub, i64, env, i64, i64)
DEF_HELPER_3(fadd, f64, env, f64, f64)
DEF_HELPER_3(fsub, f64, env, f64, f64)
DEF_HELPER_3(fmul, f64, env, f64, f64)
DEF_HELPER_3(fdiv, f64, env, f64, f64)
DEF_HELPER_4(fmadd, i64, env, i64, i64, i64)
Expand Down

0 comments on commit ac43cec

Please sign in to comment.