Commit 17218d1fd9b33a94028bdca3c4e9481f05e0a318

Authored by aurel32
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,17 +563,7 @@ static always_inline int isden (float64 d)
563 return ((u.ll >> 52) & 0x7FF) == 0; 563 return ((u.ll >> 52) & 0x7FF) == 0;
564 } 564 }
565 565
566 -  
567 #ifdef CONFIG_SOFTFLOAT 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 static always_inline int isnormal (float64 d) 567 static always_inline int isnormal (float64 d)
578 { 568 {
579 CPU_DoubleU u; 569 CPU_DoubleU u;
@@ -1028,12 +1018,12 @@ uint64_t helper_fadd (uint64_t arg1, uint64_t arg2) @@ -1028,12 +1018,12 @@ uint64_t helper_fadd (uint64_t arg1, uint64_t arg2)
1028 float64_is_signaling_nan(farg2.d))) { 1018 float64_is_signaling_nan(farg2.d))) {
1029 /* sNaN addition */ 1019 /* sNaN addition */
1030 farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); 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 /* Magnitude subtraction of infinities */ 1023 /* Magnitude subtraction of infinities */
1036 farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXISI); 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 #else 1028 #else
1039 farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status); 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,12 +1044,12 @@ uint64_t helper_fsub (uint64_t arg1, uint64_t arg2)
1054 float64_is_signaling_nan(farg2.d))) { 1044 float64_is_signaling_nan(farg2.d))) {
1055 /* sNaN subtraction */ 1045 /* sNaN subtraction */
1056 farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); 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 /* Magnitude subtraction of infinities */ 1049 /* Magnitude subtraction of infinities */
1062 farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXISI); 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 #else 1055 #else