This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix E500 unordered comparisons


E500 processors lack instructions to do unordered comparisons.  For the 
simple case (__builtin_isunordered) this causes libcalls to be generated.  
For TFmode this is unfortunately __unordtf2, which isn't defined; this 
patch makes it use the same __gcc_qunord used for soft-float in that case.  
For the compound case (testing unordered-or-something-else), the E500 
compares quietly ignore the "unordered" part of the testing.  Fixed by 
disabling relevant instruction patterns for E500 (as bunordered/sunordered 
already are disabled) so the core compiler will generate the composition 
of a libcall to test unordered and a comparison for the rest.

Tested with cross to powerpc-none-linux-gnuspe, with 
gcc.c-torture/execute/ieee/ieee.exp enabled.  (Running the IEEE tests on 
E500 requires kernel trap handlers from Freescale, and it seems these 
still have some bugs in the version I have so there are still some 
ieee.exp failures after this patch.)  OK to commit?

2007-05-01  Joseph Myers  <joseph@codesourcery.com>

	* config/rs6000/darwin-ldouble.c (__gcc_qunord): Define if
	__NO_FPRS__, not just if _SOFT_DOUBLE.
	* config/rs6000/libgcc-ppc-glibc.ver (__gcc_qunord): Likewise.
	* config/rs6000/rs6000.c (rs6000_init_libfuncs): Use __gcc_qunord
	also for E500 double.
	* config/rs6000/rs6000.md (buneq, bunge, bungt, bunle, bunlt,
	suneq, sunge, sungt, sunle, sunlt): Disable for (TARGET_HARD_FLOAT
	&& !TARGET_FPRS).

Index: config/rs6000/darwin-ldouble.c
===================================================================
--- config/rs6000/darwin-ldouble.c	(revision 124330)
+++ config/rs6000/darwin-ldouble.c	(working copy)
@@ -225,7 +225,6 @@
 int __gcc_qne (double, double, double, double);
 int __gcc_qge (double, double, double, double);
 int __gcc_qle (double, double, double, double);
-int __gcc_qunord (double, double, double, double);
 long double __gcc_stoq (float);
 long double __gcc_dtoq (double);
 float __gcc_qtos (double, double);
@@ -238,7 +237,6 @@
 extern int __eqdf2 (double, double);
 extern int __ledf2 (double, double);
 extern int __gedf2 (double, double);
-extern int __unorddf2 (double, double);
 
 /* Negate 'long double' value and return the result.	*/
 long double
@@ -284,15 +282,6 @@
 
 strong_alias (__gcc_qge, __gcc_qgt);
 
-/* Compare two 'long double' values for unordered.  */
-int
-__gcc_qunord (double a, double aa, double c, double cc)
-{
-  if (__eqdf2 (a, c) == 0)
-    return __unorddf2 (aa, cc);
-  return __unorddf2 (a, c);
-}
-
 /* Convert single to long double.  */
 long double
 __gcc_stoq (float a)
@@ -365,6 +354,20 @@
 
 #ifdef __NO_FPRS__
 
+int __gcc_qunord (double, double, double, double);
+
+extern int __eqdf2 (double, double);
+extern int __unorddf2 (double, double);
+
+/* Compare two 'long double' values for unordered.  */
+int
+__gcc_qunord (double a, double aa, double c, double cc)
+{
+  if (__eqdf2 (a, c) == 0)
+    return __unorddf2 (aa, cc);
+  return __unorddf2 (a, c);
+}
+
 #include "config/soft-fp/soft-fp.h"
 #include "config/soft-fp/double.h"
 #include "config/soft-fp/quad.h"
Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c	(revision 124330)
+++ config/rs6000/rs6000.c	(working copy)
@@ -9587,7 +9587,6 @@
 	    set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
 	    set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
 	    set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
-	    set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
 
 	    set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
 	    set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
@@ -9598,6 +9597,9 @@
 	    set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
 	    set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
 	  }
+
+	if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
+	  set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
       }
     else
       {
Index: config/rs6000/libgcc-ppc-glibc.ver
===================================================================
--- config/rs6000/libgcc-ppc-glibc.ver	(revision 124330)
+++ config/rs6000/libgcc-ppc-glibc.ver	(working copy)
@@ -39,7 +39,6 @@
   __gcc_qge
   __gcc_qlt
   __gcc_qle
-  __gcc_qunord
   __gcc_stoq
   __gcc_dtoq
   __gcc_qtos
@@ -49,4 +48,8 @@
   __gcc_itoq
   __gcc_utoq
 %endif
+
+%ifdef __NO_FPRS__
+  __gcc_qunord
+%endif
 }
Index: config/rs6000/rs6000.md
===================================================================
--- config/rs6000/rs6000.md	(revision 124330)
+++ config/rs6000/rs6000.md	(working copy)
@@ -11530,27 +11530,27 @@
 
 (define_expand "buneq"
   [(use (match_operand 0 "" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_cbranch (UNEQ, operands[0]); DONE; }")
 
 (define_expand "bunge"
   [(use (match_operand 0 "" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_cbranch (UNGE, operands[0]); DONE; }")
 
 (define_expand "bungt"
   [(use (match_operand 0 "" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_cbranch (UNGT, operands[0]); DONE; }")
 
 (define_expand "bunle"
   [(use (match_operand 0 "" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_cbranch (UNLE, operands[0]); DONE; }")
 
 (define_expand "bunlt"
   [(use (match_operand 0 "" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_cbranch (UNLT, operands[0]); DONE; }")
 
 (define_expand "bltgt"
@@ -11664,27 +11664,27 @@
 
 (define_expand "suneq"
   [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_sCOND (UNEQ, operands[0]); DONE; }")
 
 (define_expand "sunge"
   [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_sCOND (UNGE, operands[0]); DONE; }")
 
 (define_expand "sungt"
   [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_sCOND (UNGT, operands[0]); DONE; }")
 
 (define_expand "sunle"
   [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_sCOND (UNLE, operands[0]); DONE; }")
 
 (define_expand "sunlt"
   [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
+  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
   "{ rs6000_emit_sCOND (UNLT, operands[0]); DONE; }")
 
 (define_expand "sltgt"

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]