Commit 17218d1fd9b33a94028bdca3c4e9481f05e0a318
1 parent
f23c346e
target-ppc: fadd/fsub: correctly propagate NaN
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6052 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
8 additions
and
18 deletions
target-ppc/op_helper.c
... | ... | @@ -563,17 +563,7 @@ static always_inline int isden (float64 d) |
563 | 563 | return ((u.ll >> 52) & 0x7FF) == 0; |
564 | 564 | } |
565 | 565 | |
566 | - | |
567 | 566 | #ifdef CONFIG_SOFTFLOAT |
568 | -static always_inline int isfinite (float64 d) | |
569 | -{ | |
570 | - CPU_DoubleU u; | |
571 | - | |
572 | - u.d = d; | |
573 | - | |
574 | - return (((u.ll >> 52) & 0x7FF) != 0x7FF); | |
575 | -} | |
576 | - | |
577 | 567 | static always_inline int isnormal (float64 d) |
578 | 568 | { |
579 | 569 | CPU_DoubleU u; |
... | ... | @@ -1028,12 +1018,12 @@ uint64_t helper_fadd (uint64_t arg1, uint64_t arg2) |
1028 | 1018 | float64_is_signaling_nan(farg2.d))) { |
1029 | 1019 | /* sNaN addition */ |
1030 | 1020 | farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); |
1031 | - } else if (likely(isfinite(farg1.d) || isfinite(farg2.d) || | |
1032 | - float64_is_neg(farg1.d) == float64_is_neg(farg2.d))) { | |
1033 | - farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status); | |
1034 | - } else { | |
1021 | + } else if (unlikely(float64_is_infinity(farg1.d) && float64_is_infinity(farg2.d) && | |
1022 | + float64_is_neg(farg1.d) != float64_is_neg(farg2.d))) { | |
1035 | 1023 | /* Magnitude subtraction of infinities */ |
1036 | 1024 | farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXISI); |
1025 | + } else { | |
1026 | + farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status); | |
1037 | 1027 | } |
1038 | 1028 | #else |
1039 | 1029 | farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status); |
... | ... | @@ -1054,12 +1044,12 @@ uint64_t helper_fsub (uint64_t arg1, uint64_t arg2) |
1054 | 1044 | float64_is_signaling_nan(farg2.d))) { |
1055 | 1045 | /* sNaN subtraction */ |
1056 | 1046 | farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); |
1057 | - } else if (likely(isfinite(farg1.d) || isfinite(farg2.d) || | |
1058 | - float64_is_neg(farg1.d) != float64_is_neg(farg2.d))) { | |
1059 | - farg1.d = float64_sub(farg1.d, farg2.d, &env->fp_status); | |
1060 | - } else { | |
1047 | + } else if (unlikely(float64_is_infinity(farg1.d) && float64_is_infinity(farg2.d) && | |
1048 | + float64_is_neg(farg1.d) == float64_is_neg(farg2.d))) { | |
1061 | 1049 | /* Magnitude subtraction of infinities */ |
1062 | 1050 | farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXISI); |
1051 | + } else { | |
1052 | + farg1.d = float64_sub(farg1.d, farg2.d, &env->fp_status); | |
1063 | 1053 | } |
1064 | 1054 | } |
1065 | 1055 | #else | ... | ... |