diff options
Diffstat (limited to 'target-ppc/op_helper.c')
-rw-r--r-- | target-ppc/op_helper.c | 121 |
1 files changed, 42 insertions, 79 deletions
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index f32a5fffd6..279f345593 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -546,7 +546,7 @@ uint32_t helper_compute_fprf (uint64_t arg, uint32_t set_fprf) int ret; farg.ll = arg; isneg = float64_is_neg(farg.d); - if (unlikely(float64_is_nan(farg.d))) { + if (unlikely(float64_is_quiet_nan(farg.d))) { if (float64_is_signaling_nan(farg.d)) { /* Signaling NaN: flags are undefined */ ret = 0x00; @@ -643,7 +643,7 @@ static inline uint64_t fload_invalid_op_excp(int op) env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI)); if (ve == 0) { /* Set the result to quiet NaN */ - ret = 0xFFF8000000000000ULL; + ret = 0x7FF8000000000000ULL; env->fpscr &= ~(0xF << FPSCR_FPCC); env->fpscr |= 0x11 << FPSCR_FPCC; } @@ -654,7 +654,7 @@ static inline uint64_t fload_invalid_op_excp(int op) env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI)); if (ve == 0) { /* Set the result to quiet NaN */ - ret = 0xFFF8000000000000ULL; + ret = 0x7FF8000000000000ULL; env->fpscr &= ~(0xF << FPSCR_FPCC); env->fpscr |= 0x11 << FPSCR_FPCC; } @@ -974,7 +974,7 @@ uint64_t helper_fadd (uint64_t arg1, uint64_t arg2) farg1.ll = arg1; farg2.ll = arg2; -#if USE_PRECISE_EMULATION + if (unlikely(float64_is_signaling_nan(farg1.d) || float64_is_signaling_nan(farg2.d))) { /* sNaN addition */ @@ -986,9 +986,7 @@ uint64_t helper_fadd (uint64_t arg1, uint64_t arg2) } else { farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status); } -#else - farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status); -#endif + return farg1.ll; } @@ -999,8 +997,7 @@ uint64_t helper_fsub (uint64_t arg1, uint64_t arg2) farg1.ll = arg1; farg2.ll = arg2; -#if USE_PRECISE_EMULATION -{ + if (unlikely(float64_is_signaling_nan(farg1.d) || float64_is_signaling_nan(farg2.d))) { /* sNaN subtraction */ @@ -1012,10 +1009,7 @@ uint64_t helper_fsub (uint64_t arg1, uint64_t arg2) } else { farg1.d = float64_sub(farg1.d, farg2.d, &env->fp_status); } -} -#else - farg1.d = float64_sub(farg1.d, farg2.d, &env->fp_status); -#endif + return farg1.ll; } @@ -1026,7 +1020,7 @@ uint64_t helper_fmul (uint64_t arg1, uint64_t arg2) farg1.ll = arg1; farg2.ll = arg2; -#if USE_PRECISE_EMULATION + if (unlikely(float64_is_signaling_nan(farg1.d) || float64_is_signaling_nan(farg2.d))) { /* sNaN multiplication */ @@ -1038,9 +1032,7 @@ uint64_t helper_fmul (uint64_t arg1, uint64_t arg2) } else { farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status); } -#else - farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status); -#endif + return farg1.ll; } @@ -1051,7 +1043,7 @@ uint64_t helper_fdiv (uint64_t arg1, uint64_t arg2) farg1.ll = arg1; farg2.ll = arg2; -#if USE_PRECISE_EMULATION + if (unlikely(float64_is_signaling_nan(farg1.d) || float64_is_signaling_nan(farg2.d))) { /* sNaN division */ @@ -1065,9 +1057,7 @@ uint64_t helper_fdiv (uint64_t arg1, uint64_t arg2) } else { farg1.d = float64_div(farg1.d, farg2.d, &env->fp_status); } -#else - farg1.d = float64_div(farg1.d, farg2.d, &env->fp_status); -#endif + return farg1.ll; } @@ -1111,17 +1101,15 @@ uint64_t helper_fctiw (uint64_t arg) if (unlikely(float64_is_signaling_nan(farg.d))) { /* sNaN conversion */ farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI); - } else if (unlikely(float64_is_nan(farg.d) || float64_is_infinity(farg.d))) { + } else if (unlikely(float64_is_quiet_nan(farg.d) || float64_is_infinity(farg.d))) { /* qNan / infinity conversion */ farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI); } else { farg.ll = float64_to_int32(farg.d, &env->fp_status); -#if USE_PRECISE_EMULATION /* XXX: higher bits are not supposed to be significant. * to make tests easier, return the same as a real PowerPC 750 */ farg.ll |= 0xFFF80000ULL << 32; -#endif } return farg.ll; } @@ -1135,17 +1123,15 @@ uint64_t helper_fctiwz (uint64_t arg) if (unlikely(float64_is_signaling_nan(farg.d))) { /* sNaN conversion */ farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI); - } else if (unlikely(float64_is_nan(farg.d) || float64_is_infinity(farg.d))) { + } else if (unlikely(float64_is_quiet_nan(farg.d) || float64_is_infinity(farg.d))) { /* qNan / infinity conversion */ farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI); } else { farg.ll = float64_to_int32_round_to_zero(farg.d, &env->fp_status); -#if USE_PRECISE_EMULATION /* XXX: higher bits are not supposed to be significant. * to make tests easier, return the same as a real PowerPC 750 */ farg.ll |= 0xFFF80000ULL << 32; -#endif } return farg.ll; } @@ -1168,7 +1154,7 @@ uint64_t helper_fctid (uint64_t arg) if (unlikely(float64_is_signaling_nan(farg.d))) { /* sNaN conversion */ farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI); - } else if (unlikely(float64_is_nan(farg.d) || float64_is_infinity(farg.d))) { + } else if (unlikely(float64_is_quiet_nan(farg.d) || float64_is_infinity(farg.d))) { /* qNan / infinity conversion */ farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI); } else { @@ -1186,7 +1172,7 @@ uint64_t helper_fctidz (uint64_t arg) if (unlikely(float64_is_signaling_nan(farg.d))) { /* sNaN conversion */ farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI); - } else if (unlikely(float64_is_nan(farg.d) || float64_is_infinity(farg.d))) { + } else if (unlikely(float64_is_quiet_nan(farg.d) || float64_is_infinity(farg.d))) { /* qNan / infinity conversion */ farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI); } else { @@ -1205,7 +1191,7 @@ static inline uint64_t do_fri(uint64_t arg, int rounding_mode) if (unlikely(float64_is_signaling_nan(farg.d))) { /* sNaN round */ farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI); - } else if (unlikely(float64_is_nan(farg.d) || float64_is_infinity(farg.d))) { + } else if (unlikely(float64_is_quiet_nan(farg.d) || float64_is_infinity(farg.d))) { /* qNan / infinity round */ farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI); } else { @@ -1245,7 +1231,7 @@ uint64_t helper_fmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3) farg1.ll = arg1; farg2.ll = arg2; farg3.ll = arg3; -#if USE_PRECISE_EMULATION + if (unlikely(float64_is_signaling_nan(farg1.d) || float64_is_signaling_nan(farg2.d) || float64_is_signaling_nan(farg3.d))) { @@ -1277,10 +1263,7 @@ uint64_t helper_fmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3) farg1.d = (farg1.d * farg2.d) + farg3.d; #endif } -#else - farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status); - farg1.d = float64_add(farg1.d, farg3.d, &env->fp_status); -#endif + return farg1.ll; } @@ -1292,7 +1275,7 @@ uint64_t helper_fmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3) farg1.ll = arg1; farg2.ll = arg2; farg3.ll = arg3; -#if USE_PRECISE_EMULATION + if (unlikely(float64_is_signaling_nan(farg1.d) || float64_is_signaling_nan(farg2.d) || float64_is_signaling_nan(farg3.d))) { @@ -1324,10 +1307,6 @@ uint64_t helper_fmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3) farg1.d = (farg1.d * farg2.d) - farg3.d; #endif } -#else - farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status); - farg1.d = float64_sub(farg1.d, farg3.d, &env->fp_status); -#endif return farg1.ll; } @@ -1350,7 +1329,6 @@ uint64_t helper_fnmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3) /* Multiplication of zero by infinity */ farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXIMZ); } else { -#if USE_PRECISE_EMULATION #ifdef FLOAT128 /* This is the way the PowerPC specification defines it */ float128 ft0_128, ft1_128; @@ -1371,11 +1349,7 @@ uint64_t helper_fnmadd (uint64_t arg1, uint64_t arg2, uint64_t arg3) /* This is OK on x86 hosts */ farg1.d = (farg1.d * farg2.d) + farg3.d; #endif -#else - farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status); - farg1.d = float64_add(farg1.d, farg3.d, &env->fp_status); -#endif - if (likely(!float64_is_nan(farg1.d))) + if (likely(!float64_is_quiet_nan(farg1.d))) farg1.d = float64_chs(farg1.d); } return farg1.ll; @@ -1400,7 +1374,6 @@ uint64_t helper_fnmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3) /* Multiplication of zero by infinity */ farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXIMZ); } else { -#if USE_PRECISE_EMULATION #ifdef FLOAT128 /* This is the way the PowerPC specification defines it */ float128 ft0_128, ft1_128; @@ -1421,11 +1394,7 @@ uint64_t helper_fnmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3) /* This is OK on x86 hosts */ farg1.d = (farg1.d * farg2.d) - farg3.d; #endif -#else - farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status); - farg1.d = float64_sub(farg1.d, farg3.d, &env->fp_status); -#endif - if (likely(!float64_is_nan(farg1.d))) + if (likely(!float64_is_quiet_nan(farg1.d))) farg1.d = float64_chs(farg1.d); } return farg1.ll; @@ -1438,7 +1407,6 @@ uint64_t helper_frsp (uint64_t arg) float32 f32; farg.ll = arg; -#if USE_PRECISE_EMULATION if (unlikely(float64_is_signaling_nan(farg.d))) { /* sNaN square root */ farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); @@ -1446,10 +1414,6 @@ uint64_t helper_frsp (uint64_t arg) f32 = float64_to_float32(farg.d, &env->fp_status); farg.d = float32_to_float64(f32, &env->fp_status); } -#else - f32 = float64_to_float32(farg.d, &env->fp_status); - farg.d = float32_to_float64(f32, &env->fp_status); -#endif return farg.ll; } @@ -1533,7 +1497,7 @@ uint64_t helper_fsel (uint64_t arg1, uint64_t arg2, uint64_t arg3) farg1.ll = arg1; - if ((!float64_is_neg(farg1.d) || float64_is_zero(farg1.d)) && !float64_is_nan(farg1.d)) + if ((!float64_is_neg(farg1.d) || float64_is_zero(farg1.d)) && !float64_is_quiet_nan(farg1.d)) return arg2; else return arg3; @@ -1546,8 +1510,8 @@ void helper_fcmpu (uint64_t arg1, uint64_t arg2, uint32_t crfD) farg1.ll = arg1; farg2.ll = arg2; - if (unlikely(float64_is_nan(farg1.d) || - float64_is_nan(farg2.d))) { + if (unlikely(float64_is_quiet_nan(farg1.d) || + float64_is_quiet_nan(farg2.d))) { ret = 0x01UL; } else if (float64_lt(farg1.d, farg2.d, &env->fp_status)) { ret = 0x08UL; @@ -1575,8 +1539,8 @@ void helper_fcmpo (uint64_t arg1, uint64_t arg2, uint32_t crfD) farg1.ll = arg1; farg2.ll = arg2; - if (unlikely(float64_is_nan(farg1.d) || - float64_is_nan(farg2.d))) { + if (unlikely(float64_is_quiet_nan(farg1.d) || + float64_is_quiet_nan(farg2.d))) { ret = 0x01UL; } else if (float64_lt(farg1.d, farg2.d, &env->fp_status)) { ret = 0x08UL; @@ -1938,7 +1902,7 @@ target_ulong helper_dlmzb (target_ulong high, target_ulong low, uint32_t update_ /* If X is a NaN, store the corresponding QNaN into RESULT. Otherwise, * execute the following block. */ #define DO_HANDLE_NAN(result, x) \ - if (float32_is_nan(x) || float32_is_signaling_nan(x)) { \ + if (float32_is_any_nan(x)) { \ CPU_FloatU __f; \ __f.f = x; \ __f.l = __f.l | (1 << 22); /* Set QNaN bit. */ \ @@ -2283,8 +2247,7 @@ void helper_vcmpbfp_dot (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) float_status s = env->vec_status; \ set_float_rounding_mode(float_round_to_zero, &s); \ for (i = 0; i < ARRAY_SIZE(r->f); i++) { \ - if (float32_is_nan(b->f[i]) || \ - float32_is_signaling_nan(b->f[i])) { \ + if (float32_is_any_nan(b->f[i])) { \ r->element[i] = 0; \ } else { \ float64 t = float32_to_float64(b->f[i], &s); \ @@ -3132,7 +3095,7 @@ static inline int32_t efsctsi(uint32_t val) u.l = val; /* NaN are not treated the same way IEEE 754 does */ - if (unlikely(float32_is_nan(u.f))) + if (unlikely(float32_is_quiet_nan(u.f))) return 0; return float32_to_int32(u.f, &env->vec_status); @@ -3144,7 +3107,7 @@ static inline uint32_t efsctui(uint32_t val) u.l = val; /* NaN are not treated the same way IEEE 754 does */ - if (unlikely(float32_is_nan(u.f))) + if (unlikely(float32_is_quiet_nan(u.f))) return 0; return float32_to_uint32(u.f, &env->vec_status); @@ -3156,7 +3119,7 @@ static inline uint32_t efsctsiz(uint32_t val) u.l = val; /* NaN are not treated the same way IEEE 754 does */ - if (unlikely(float32_is_nan(u.f))) + if (unlikely(float32_is_quiet_nan(u.f))) return 0; return float32_to_int32_round_to_zero(u.f, &env->vec_status); @@ -3168,7 +3131,7 @@ static inline uint32_t efsctuiz(uint32_t val) u.l = val; /* NaN are not treated the same way IEEE 754 does */ - if (unlikely(float32_is_nan(u.f))) + if (unlikely(float32_is_quiet_nan(u.f))) return 0; return float32_to_uint32_round_to_zero(u.f, &env->vec_status); @@ -3205,7 +3168,7 @@ static inline uint32_t efsctsf(uint32_t val) u.l = val; /* NaN are not treated the same way IEEE 754 does */ - if (unlikely(float32_is_nan(u.f))) + if (unlikely(float32_is_quiet_nan(u.f))) return 0; tmp = uint64_to_float32(1ULL << 32, &env->vec_status); u.f = float32_mul(u.f, tmp, &env->vec_status); @@ -3220,7 +3183,7 @@ static inline uint32_t efsctuf(uint32_t val) u.l = val; /* NaN are not treated the same way IEEE 754 does */ - if (unlikely(float32_is_nan(u.f))) + if (unlikely(float32_is_quiet_nan(u.f))) return 0; tmp = uint64_to_float32(1ULL << 32, &env->vec_status); u.f = float32_mul(u.f, tmp, &env->vec_status); @@ -3474,7 +3437,7 @@ uint32_t helper_efdctsi (uint64_t val) u.ll = val; /* NaN are not treated the same way IEEE 754 does */ - if (unlikely(float64_is_nan(u.d))) + if (unlikely(float64_is_quiet_nan(u.d))) return 0; return float64_to_int32(u.d, &env->vec_status); @@ -3486,7 +3449,7 @@ uint32_t helper_efdctui (uint64_t val) u.ll = val; /* NaN are not treated the same way IEEE 754 does */ - if (unlikely(float64_is_nan(u.d))) + if (unlikely(float64_is_quiet_nan(u.d))) return 0; return float64_to_uint32(u.d, &env->vec_status); @@ -3498,7 +3461,7 @@ uint32_t helper_efdctsiz (uint64_t val) u.ll = val; /* NaN are not treated the same way IEEE 754 does */ - if (unlikely(float64_is_nan(u.d))) + if (unlikely(float64_is_quiet_nan(u.d))) return 0; return float64_to_int32_round_to_zero(u.d, &env->vec_status); @@ -3510,7 +3473,7 @@ uint64_t helper_efdctsidz (uint64_t val) u.ll = val; /* NaN are not treated the same way IEEE 754 does */ - if (unlikely(float64_is_nan(u.d))) + if (unlikely(float64_is_quiet_nan(u.d))) return 0; return float64_to_int64_round_to_zero(u.d, &env->vec_status); @@ -3522,7 +3485,7 @@ uint32_t helper_efdctuiz (uint64_t val) u.ll = val; /* NaN are not treated the same way IEEE 754 does */ - if (unlikely(float64_is_nan(u.d))) + if (unlikely(float64_is_quiet_nan(u.d))) return 0; return float64_to_uint32_round_to_zero(u.d, &env->vec_status); @@ -3534,7 +3497,7 @@ uint64_t helper_efdctuidz (uint64_t val) u.ll = val; /* NaN are not treated the same way IEEE 754 does */ - if (unlikely(float64_is_nan(u.d))) + if (unlikely(float64_is_quiet_nan(u.d))) return 0; return float64_to_uint64_round_to_zero(u.d, &env->vec_status); @@ -3571,7 +3534,7 @@ uint32_t helper_efdctsf (uint64_t val) u.ll = val; /* NaN are not treated the same way IEEE 754 does */ - if (unlikely(float64_is_nan(u.d))) + if (unlikely(float64_is_quiet_nan(u.d))) return 0; tmp = uint64_to_float64(1ULL << 32, &env->vec_status); u.d = float64_mul(u.d, tmp, &env->vec_status); @@ -3586,7 +3549,7 @@ uint32_t helper_efdctuf (uint64_t val) u.ll = val; /* NaN are not treated the same way IEEE 754 does */ - if (unlikely(float64_is_nan(u.d))) + if (unlikely(float64_is_quiet_nan(u.d))) return 0; tmp = uint64_to_float64(1ULL << 32, &env->vec_status); u.d = float64_mul(u.d, tmp, &env->vec_status); |