@@ -635,27 +635,24 @@ uint64_t helper_fsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
}
/* fmul - fmul. */
-uint64_t helper_fmul(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
+float64 helper_fmul(CPUPPCState *env, float64 arg1, float64 arg2)
{
- CPU_DoubleU farg1, farg2;
-
- farg1.ll = arg1;
- farg2.ll = arg2;
+ float64 ret = float64_mul(arg1, arg2, &env->fp_status);
+ int status = get_float_exception_flags(&env->fp_status);
- if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) ||
- (float64_is_zero(farg1.d) && float64_is_infinity(farg2.d)))) {
- /* Multiplication of zero by infinity */
- farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 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_zero(arg2)) ||
+ (float64_is_zero(arg1) && float64_is_infinity(arg2))) {
+ /* Multiplication of zero by infinity */
+ float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
+ } else if (float64_is_signaling_nan(arg1, &env->fp_status) ||
+ float64_is_signaling_nan(arg2, &env->fp_status)) {
/* sNaN multiplication */
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
}
- farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);
}
- return farg1.ll;
+ return ret;
}
/* fdiv - fdiv. */
@@ -87,7 +87,7 @@ 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(fmul, i64, env, i64, i64)
+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)
DEF_HELPER_4(fmsub, i64, env, i64, i64, i64)