aboutsummaryrefslogtreecommitdiff
path: root/target-ppc/op_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-ppc/op_helper.c')
-rw-r--r--target-ppc/op_helper.c121
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);