mirror of https://github.com/xemu-project/xemu.git
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:
parent
a496352736
commit
e4052bb773
|
@ -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) { \
|
||||||
|
|
Loading…
Reference in New Issue