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 | ... | ... |