target/ppc: Update fmadd for new flags

Now that vximz, vxisi, and vxsnan are computed directly by
softfloat, we don't need to recompute it.  This replaces the
separate float{32,64}_maddsub_update_excp functions with a
single float_invalid_op_madd function.

Fix VSX_MADD by passing sfprf to float_invalid_op_madd,
whereas the previous *_maddsub_update_excp assumed it true.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20211119160502.17432-19-richard.henderson@linaro.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
This commit is contained in:
Richard Henderson 2021-12-17 17:57:15 +01:00 committed by Cédric Le Goater
parent a496352736
commit e4052bb773
1 changed files with 11 additions and 35 deletions

View File

@ -683,38 +683,15 @@ uint64_t helper_frim(CPUPPCState *env, uint64_t arg)
return do_fri(env, arg, float_round_down); return do_fri(env, arg, float_round_down);
} }
#define FPU_MADDSUB_UPDATE(NAME, TP) \ static void float_invalid_op_madd(CPUPPCState *env, int flags,
static void NAME(CPUPPCState *env, TP arg1, TP arg2, TP arg3, \ bool set_fpcc, uintptr_t retaddr)
unsigned int madd_flags, uintptr_t retaddr) \ {
{ \ if (flags & float_flag_invalid_imz) {
if (TP##_is_signaling_nan(arg1, &env->fp_status) || \ float_invalid_op_vximz(env, set_fpcc, retaddr);
TP##_is_signaling_nan(arg2, &env->fp_status) || \ } else {
TP##_is_signaling_nan(arg3, &env->fp_status)) { \ float_invalid_op_addsub(env, flags, set_fpcc, retaddr);
/* sNaN operation */ \ }
float_invalid_op_vxsnan(env, retaddr); \
} \
if ((TP##_is_infinity(arg1) && TP##_is_zero(arg2)) || \
(TP##_is_zero(arg1) && TP##_is_infinity(arg2))) { \
/* Multiplication of zero by infinity */ \
float_invalid_op_vximz(env, 1, retaddr); \
} \
if ((TP##_is_infinity(arg1) || TP##_is_infinity(arg2)) && \
TP##_is_infinity(arg3)) { \
uint8_t aSign, bSign, cSign; \
\
aSign = TP##_is_neg(arg1); \
bSign = TP##_is_neg(arg2); \
cSign = TP##_is_neg(arg3); \
if (madd_flags & float_muladd_negate_c) { \
cSign ^= 1; \
} \
if (aSign ^ bSign ^ cSign) { \
float_invalid_op_vxisi(env, 1, retaddr); \
} \
} \
} }
FPU_MADDSUB_UPDATE(float32_maddsub_update_excp, float32)
FPU_MADDSUB_UPDATE(float64_maddsub_update_excp, float64)
#define FPU_FMADD(op, madd_flags) \ #define FPU_FMADD(op, madd_flags) \
uint64_t helper_##op(CPUPPCState *env, uint64_t arg1, \ uint64_t helper_##op(CPUPPCState *env, uint64_t arg1, \
@ -726,8 +703,7 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg1, \
flags = get_float_exception_flags(&env->fp_status); \ flags = get_float_exception_flags(&env->fp_status); \
if (flags) { \ if (flags) { \
if (flags & float_flag_invalid) { \ if (flags & float_flag_invalid) { \
float64_maddsub_update_excp(env, arg1, arg2, arg3, \ float_invalid_op_madd(env, flags, 1, GETPC()); \
madd_flags, GETPC()); \
} \ } \
do_float_check_status(env, GETPC()); \ do_float_check_status(env, GETPC()); \
} \ } \
@ -2131,8 +2107,8 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, \
env->fp_status.float_exception_flags |= tstat.float_exception_flags; \ env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
\ \
if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
tp##_maddsub_update_excp(env, xa->fld, b->fld, \ float_invalid_op_madd(env, tstat.float_exception_flags, \
c->fld, maddflgs, GETPC()); \ sfprf, GETPC()); \
} \ } \
\ \
if (r2sp) { \ if (r2sp) { \