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]

A new patch for floating point conditional mov on PPo


Hi,

Here is a new patch for PPro FP conditional moves. I hope it fixes
all the unsigned integer comparison bugs.


H.J.
----
Tue Jun  9 08:08:49 1998  H.J. Lu  (hjl@gnu.org)

	* config/i386/i386.md (tstsi_fcmov, tsthi_fcmov, tstqi_fcmov,
	cmpsi_fcmov, cmphi_fcmov, cmpqi_fcmov): New patterns for
	setting CC for floating point conditional move.
	(movsfcc, movsfcc+1, movsfcc+2, movsfcc+3, movsfcc+4,
	movdfcc, movdfcc+1, movdfcc+2, movdfcc+3, movdfcc+4,
	movxfcc, movxfcc+1, movxfcc+2, movxfcc+3, movxfcc+4): Add
	a clobber HI operand and use test?i_fcmov/cmp?i_fcmov.

	* config/i386/i386.c (put_condition_code): When generating
	condition code for floating point condtional move, check if
	the previous CC is set by an integer comparison.
	(output_int_test_compare_for_fcmov): New.
	(output_fp_conditional_move): Check GT, LE, GE and LT if
	cc_prev_status.flags & CC_NO_OVERFLOW is non-zero.

Index: config/i386/i386.md
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.1.1.18
diff -u -p -r1.1.1.18 i386.md
--- i386.md	1998/06/06 03:23:23	1.1.1.18
+++ i386.md	1998/06/09 14:34:23
@@ -143,6 +143,27 @@
 (define_attr "cpu" "i386,i486,pentium,pentiumpro"
   (const (symbol_ref "ix86_cpu")))
 
+(define_insn "tstsi_fcmov"
+  [(set (cc0)
+	(match_operand:SI 0 "nonimmediate_operand" "rm"))
+   (clobber (match_scratch:HI 1 "=q"))]
+  ""
+  "* return output_int_test_compare_for_fcmov (insn, operands, 1);")
+
+(define_insn "tsthi_fcmov"
+  [(set (cc0)
+	(match_operand:HI 0 "nonimmediate_operand" "rm"))
+   (clobber (match_scratch:HI 1 "=q"))]
+  ""
+  "* return output_int_test_compare_for_fcmov (insn, operands, 1);")
+
+(define_insn "tstqi_fcmov"
+  [(set (cc0)
+	(match_operand:QI 0 "nonimmediate_operand" "rm"))
+   (clobber (match_scratch:HI 1 "=q"))]
+  ""
+  "* return output_int_test_compare_for_fcmov (insn, operands, 1);")
+
 (define_insn "tstsi_1"
   [(set (cc0)
 	(match_operand:SI 0 "nonimmediate_operand" "rm"))]
@@ -323,6 +344,30 @@
 ;;- compare instructions.  See comments above tstM patterns about
 ;;  expansion of these insns.
 
+(define_insn "cmpsi_fcmov"
+  [(set (cc0)
+	(compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
+		 (match_operand:SI 1 "general_operand" "ri,mr")))
+   (clobber (match_scratch:HI 2 "=q,q"))]
+  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
+  "* return output_int_test_compare_for_fcmov (insn, operands, 0);")
+
+(define_insn "cmphi_fcmov"
+  [(set (cc0)
+	(compare (match_operand:HI 0 "nonimmediate_operand" "mr,r")
+		 (match_operand:HI 1 "general_operand" "ri,mr")))
+   (clobber (match_scratch:HI 2 "=q,q"))]
+  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
+  "* return output_int_test_compare_for_fcmov (insn, operands, 0);")
+
+(define_insn "cmpqi_fcmov"
+  [(set (cc0)
+	(compare (match_operand:QI 0 "nonimmediate_operand" "q,mq")
+		 (match_operand:QI 1 "general_operand" "qm,nq")))
+   (clobber (match_scratch:HI 2 "=q,q"))]
+  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
+  "* return output_int_test_compare_for_fcmov (insn, operands, 0);")
+
 (define_insn "cmpsi_1"
   [(set (cc0)
 	(compare (match_operand:SI 0 "nonimmediate_operand" "mr,r")
@@ -7385,10 +7431,12 @@ byte_xor_operation:
   "* return output_int_conditional_move (which_alternative, operands);")
 
 (define_expand "movsfcc"
-  [(set (match_operand:SF 0 "register_operand" "")
-	(if_then_else:SF (match_operand 1 "comparison_operator" "")
-			 (match_operand:SF 2 "register_operand" "")
-			 (match_operand:SF 3 "register_operand" "")))]
+  [(parallel
+    [(set (match_operand:SF 0 "register_operand" "")
+	  (if_then_else:SF (match_operand 1 "comparison_operator" "")
+			   (match_operand:SF 2 "register_operand" "")
+			   (match_operand:SF 3 "register_operand" "")))
+     (clobber (match_scratch:HI 4 ""))])]
   "TARGET_CMOVE"
   "
 {
@@ -7401,49 +7449,58 @@ byte_xor_operation:
 }")
 
 (define_insn ""
-  [(set (match_operand:SF 0 "register_operand" "=f,f,f,f,f,f")
-	(if_then_else:SF (match_operator 1 "comparison_operator" 
+  [(parallel
+    [(set (match_operand:SF 0 "register_operand" "=f,f,f,f,f,f")
+	  (if_then_else:SF (match_operator 1 "comparison_operator" 
 	      [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
 		(match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
 	      (match_operand:SF 4 "register_operand" "f,f,0,0,f,f")
-	      (match_operand:SF 5 "register_operand" "0,0,f,f,f,f")))]
+	      (match_operand:SF 5 "register_operand" "0,0,f,f,f,f")))
+     (clobber (match_scratch:HI 6 "=q,q,q,q,q,q"))])]
   "TARGET_CMOVE"
   "#")
 
 (define_insn ""
-  [(set (match_operand:SF 0 "register_operand" "=f,f,f,f,f,f")
-	(if_then_else:SF (match_operator 1 "comparison_operator" 
+  [(parallel
+    [(set (match_operand:SF 0 "register_operand" "=f,f,f,f,f,f")
+	  (if_then_else:SF (match_operator 1 "comparison_operator" 
 		[(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
 		 (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
 	      (match_operand:SF 4 "register_operand" "f,f,0,0,f,f")
-	      (match_operand:SF 5 "register_operand" "0,0,f,f,f,f")))]
+	      (match_operand:SF 5 "register_operand" "0,0,f,f,f,f")))
+     (clobber (match_scratch:HI 6 "=q,q,q,q,q,q"))])]
   "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
   "#")
 
 (define_split
-  [(set (match_operand:SF 0 "register_operand" "=f,f,f")
-	(if_then_else:SF (match_operator 1 "comparison_operator" 
+  [(parallel
+    [(set (match_operand:SF 0 "register_operand" "=f,f,f")
+	  (if_then_else:SF (match_operator 1 "comparison_operator" 
 				[(match_operand 2 "nonimmediate_operand" "")
 				 (const_int 0)])
 		      (match_operand:SF 3 "register_operand" "f,0,f")
-		      (match_operand:SF 4 "register_operand" "0,f,f")))]
+		      (match_operand:SF 4 "register_operand" "0,f,f")))
+     (clobber (match_scratch:HI 5 "=q,q,q"))])]
   "TARGET_CMOVE && reload_completed"
-  [(set (cc0)
-	(match_dup 2))
+  [(parallel [(set (cc0) (match_dup 2))
+	      (clobber (match_dup 6))])
    (set (match_dup 0)
 	(if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
 		      (match_dup 3) (match_dup 4)))]
   "")
 
 (define_split
-  [(set (match_operand:SF 0 "register_operand" "=f,f,f")
-	(if_then_else:SF (match_operator 1 "comparison_operator" 
+  [(parallel
+    [(set (match_operand:SF 0 "register_operand" "=f,f,f")
+	  (if_then_else:SF (match_operator 1 "comparison_operator" 
 				[(match_operand 2 "nonimmediate_operand" "")
 				 (match_operand 3 "general_operand" "")])
 		      (match_operand:SF 4 "register_operand" "f,0,f")
-		      (match_operand:SF 5 "register_operand" "0,f,f")))]
+		      (match_operand:SF 5 "register_operand" "0,f,f")))
+     (clobber (match_scratch:HI 6 "=q,q,q"))])]
   "TARGET_CMOVE && reload_completed"
-  [(set (cc0) (compare (match_dup 2) (match_dup 3)))
+  [(parallel [(set (cc0) (compare (match_dup 2) (match_dup 3)))
+	      (clobber (match_dup 6))])
    (set (match_dup 0)
 	(if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
 		      (match_dup 4) (match_dup 5)))]
@@ -7459,10 +7516,12 @@ byte_xor_operation:
   "* return output_fp_conditional_move (which_alternative, operands);")
 
 (define_expand "movdfcc"
-  [(set (match_operand:DF 0 "register_operand" "")
-	(if_then_else:DF (match_operand 1 "comparison_operator" "")
-			 (match_operand:DF 2 "register_operand" "")
-			 (match_operand:DF 3 "register_operand" "")))]
+  [(parallel
+    [(set (match_operand:DF 0 "register_operand" "")
+	  (if_then_else:DF (match_operand 1 "comparison_operator" "")
+			   (match_operand:DF 2 "register_operand" "")
+			   (match_operand:DF 3 "register_operand" "")))
+     (clobber (match_scratch:HI 4 ""))])]
   "TARGET_CMOVE"
   "
 {
@@ -7475,49 +7534,58 @@ byte_xor_operation:
 }")
 
 (define_insn ""
-  [(set (match_operand:DF 0 "register_operand" "=f,f,f,f,f,f")
-	(if_then_else:DF (match_operator 1 "comparison_operator" 
+  [(parallel
+    [(set (match_operand:DF 0 "register_operand" "=f,f,f,f,f,f")
+	  (if_then_else:DF (match_operator 1 "comparison_operator" 
 	      [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
 		(match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
 	      (match_operand:DF 4 "register_operand" "f,f,0,0,f,f")
-	      (match_operand:DF 5 "register_operand" "0,0,f,f,f,f")))]
+	      (match_operand:DF 5 "register_operand" "0,0,f,f,f,f")))
+     (clobber (match_scratch:HI 6 "=q,q,q,q,q,q"))])]
   "TARGET_CMOVE"
   "#")
 
 (define_insn ""
-  [(set (match_operand:DF 0 "register_operand" "=f,f,f,f,f,f")
-	(if_then_else:DF (match_operator 1 "comparison_operator" 
+  [(parallel
+    [(set (match_operand:DF 0 "register_operand" "=f,f,f,f,f,f")
+	  (if_then_else:DF (match_operator 1 "comparison_operator" 
 	      [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
 		(match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
 	      (match_operand:DF 4 "register_operand" "f,f,0,0,f,f")
-	      (match_operand:DF 5 "register_operand" "0,0,f,f,f,f")))]
+	      (match_operand:DF 5 "register_operand" "0,0,f,f,f,f")))
+     (clobber (match_scratch:HI 6 "=q,q,q,q,q,q"))])]
   "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
   "#")
 
 (define_split
-  [(set (match_operand:DF 0 "register_operand" "=f,f,f")
-	(if_then_else:DF (match_operator 1 "comparison_operator" 
+  [(parallel
+    [(set (match_operand:DF 0 "register_operand" "=f,f,f")
+	  (if_then_else:DF (match_operator 1 "comparison_operator" 
 				[(match_operand 2 "nonimmediate_operand" "")
 				 (const_int 0)])
 		      (match_operand:DF 3 "register_operand" "f,0,f")
-		      (match_operand:DF 4 "register_operand" "0,f,f")))]
+		      (match_operand:DF 4 "register_operand" "0,f,f")))
+     (clobber (match_scratch:HI 5 "=q,q,q"))])]
   "TARGET_CMOVE && reload_completed"
-  [(set (cc0)
-	(match_dup 2))
+  [(parallel [(set (cc0) (match_dup 2))
+	      (clobber (match_dup 6))])
    (set (match_dup 0)
 	(if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
 		      (match_dup 3) (match_dup 4)))]
   "")
 
 (define_split
-  [(set (match_operand:DF 0 "register_operand" "=f,f,f")
-	(if_then_else:DF (match_operator 1 "comparison_operator" 
+  [(parallel
+    [(set (match_operand:DF 0 "register_operand" "=f,f,f")
+	  (if_then_else:DF (match_operator 1 "comparison_operator" 
 				[(match_operand 2 "nonimmediate_operand" "")
 				 (match_operand 3 "general_operand" "")])
 		      (match_operand:DF 4 "register_operand" "f,0,f")
-		      (match_operand:DF 5 "register_operand" "0,f,f")))]
+		      (match_operand:DF 5 "register_operand" "0,f,f")))
+     (clobber (match_scratch:HI 6 "=q,q,q"))])]
   "TARGET_CMOVE && reload_completed"
-  [(set (cc0) (compare (match_dup 2) (match_dup 3)))
+  [(parallel [(set (cc0) (compare (match_dup 2) (match_dup 3)))
+	      (clobber (match_dup 6))])
    (set (match_dup 0)
 	(if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
 		      (match_dup 4) (match_dup 5)))]
@@ -7533,10 +7601,12 @@ byte_xor_operation:
   "* return output_fp_conditional_move (which_alternative, operands);")
 
 (define_expand "movxfcc"
-  [(set (match_operand:XF 0 "register_operand" "")
-	(if_then_else:XF (match_operand 1 "comparison_operator" "")
-			 (match_operand:XF 2 "register_operand" "")
-			 (match_operand:XF 3 "register_operand" "")))]
+  [(parallel
+    [(set (match_operand:XF 0 "register_operand" "")
+	  (if_then_else:XF (match_operand 1 "comparison_operator" "")
+			   (match_operand:XF 2 "register_operand" "")
+			   (match_operand:XF 3 "register_operand" "")))
+     (clobber (match_scratch:HI 4 ""))])]
   "TARGET_CMOVE"
   "
 {
@@ -7549,49 +7619,58 @@ byte_xor_operation:
 }")
 
 (define_insn ""
-  [(set (match_operand:XF 0 "register_operand" "=f,f,f,f,f,f")
-	(if_then_else:XF (match_operator 1 "comparison_operator" 
+  [(parallel
+    [(set (match_operand:XF 0 "register_operand" "=f,f,f,f,f,f")
+	  (if_then_else:XF (match_operator 1 "comparison_operator" 
 	      [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
 		(match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
 	      (match_operand:XF 4 "register_operand" "f,f,0,0,f,f")
-	      (match_operand:XF 5 "register_operand" "0,0,f,f,f,f")))]
+	      (match_operand:XF 5 "register_operand" "0,0,f,f,f,f")))
+     (clobber (match_scratch:HI 6 "=q,q,q,q,q,q"))])]
   "TARGET_CMOVE"
   "#")
 
 (define_insn ""
-  [(set (match_operand:XF 0 "register_operand" "=f,f,f,f,f,f")
-	(if_then_else:XF (match_operator 1 "comparison_operator" 
+  [(parallel
+    [(set (match_operand:XF 0 "register_operand" "=f,f,f,f,f,f")
+	  (if_then_else:XF (match_operator 1 "comparison_operator" 
 	      [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
 		(match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
 	      (match_operand:XF 4 "register_operand" "f,f,0,0,f,f")
-	      (match_operand:XF 5 "register_operand" "0,0,f,f,f,f")))]
+	      (match_operand:XF 5 "register_operand" "0,0,f,f,f,f")))
+     (clobber (match_scratch:HI 6 "=q,q,q,q,q,q"))])]
   "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
   "#")
 
 (define_split
-  [(set (match_operand:XF 0 "register_operand" "=f,f,f")
-	(if_then_else:XF (match_operator 1 "comparison_operator" 
+  [(parallel
+    [(set (match_operand:XF 0 "register_operand" "=f,f,f")
+	  (if_then_else:XF (match_operator 1 "comparison_operator" 
 				[(match_operand 2 "nonimmediate_operand" "")
 				 (const_int 0)])
 		      (match_operand:XF 3 "register_operand" "f,0,f")
-		      (match_operand:XF 4 "register_operand" "0,f,f")))]
+		      (match_operand:XF 4 "register_operand" "0,f,f")))
+     (clobber (match_scratch:HI 5 "=q,q,q"))])]
   "TARGET_CMOVE && reload_completed"
-  [(set (cc0)
-	(match_dup 2))
+  [(parallel [(set (cc0) (match_dup 2))
+	      (clobber (match_dup 6))])
    (set (match_dup 0)
 	(if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
 		      (match_dup 3) (match_dup 4)))]
   "")
 
 (define_split
-  [(set (match_operand:XF 0 "register_operand" "=f,f,f")
-	(if_then_else:XF (match_operator 1 "comparison_operator" 
+  [(parallel
+    [(set (match_operand:XF 0 "register_operand" "=f,f,f")
+	  (if_then_else:XF (match_operator 1 "comparison_operator" 
 				[(match_operand 2 "nonimmediate_operand" "")
 				 (match_operand 3 "general_operand" "")])
 		      (match_operand:XF 4 "register_operand" "f,0,f")
-		      (match_operand:XF 5 "register_operand" "0,f,f")))]
+		      (match_operand:XF 5 "register_operand" "0,f,f")))
+     (clobber (match_scratch:HI 6 "=q,q,q"))])]
   "TARGET_CMOVE && reload_completed"
-  [(set (cc0) (compare (match_dup 2) (match_dup 3)))
+  [(parallel [(set (cc0) (compare (match_dup 2) (match_dup 3)))
+	      (clobber (match_dup 6))])
    (set (match_dup 0)
 	(if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
 		      (match_dup 4) (match_dup 5)))]
Index: config/i386/i386.c
===================================================================
RCS file: /home/work/cvs/gnu/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.1.1.19
diff -u -p -r1.1.1.19 i386.c
--- i386.c	1998/06/08 14:15:22	1.1.1.19
+++ i386.c	1998/06/09 14:28:59
@@ -3074,7 +3083,8 @@ put_condition_code (code, reverse_cc, mo
      enum mode_class mode;
      FILE * file;
 {
-  int ieee = (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)
+  int fp = cc_prev_status.flags & CC_IN_80387;
+  int ieee = (TARGET_IEEE_FP && fp
 	      && ! (cc_prev_status.flags & CC_FCOMI));
   if (reverse_cc && ! ieee)
     code = reverse_condition (code);
@@ -3148,16 +3158,28 @@ put_condition_code (code, reverse_cc, mo
 	fputs (ieee ? (reverse_cc ? "ne" : "e") : "e", file);
 	return;
       case GE: 
-	fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
+	if (fp)
+	  fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
+	else
+	  fputs (reverse_cc ? "e" : "ne", file);
 	return;
       case GT: 
-	fputs (ieee ? (reverse_cc ? "ne" : "e") : "nbe", file);
+	if (fp)
+	  fputs (ieee ? (reverse_cc ? "ne" : "e") : "nbe", file);
+	else
+	  fputs (reverse_cc ? "e" : "ne", file);
 	return;
       case LE: 
-	fputs (ieee ? (reverse_cc ? "nb" : "b") : "be", file);
+	if (fp)
+	  fputs (ieee ? (reverse_cc ? "nb" : "b") : "be", file);
+	else
+	  fputs (reverse_cc ? "e" : "ne", file);
 	return;
       case LT: 
-	fputs (ieee ? (reverse_cc ? "ne" : "e") : "b", file);
+	if (fp)
+	  fputs (ieee ? (reverse_cc ? "ne" : "e") : "b", file);
+	else
+	  fputs (reverse_cc ? "e" : "ne", file);
 	return;
       case GEU: 
 	fputs (ieee ? (reverse_cc ? "ne" : "e") : "nb", file);
@@ -4012,6 +4034,150 @@ output_fix_trunc (insn, operands)
   return AS1 (fldc%W2,%2);
 }
 
+/* For floating point conditional move, output integer test/comparison
+   code for INSN to compare OPERANDS. If TEST is 1, output for test;
+   otherwise for comparison. */
+
+char *
+output_int_test_compare_for_fcmov (insn, operands, test)
+     rtx insn;
+     rtx *operands;
+     int test;
+{
+  enum machine_mode mode = GET_MODE (operands [0]);
+  rtx cc0_user;
+  enum {gen_test, reverse, normal} output;
+
+  if (test)
+    {
+      operands[2] = operands [1];
+      if (REG_P (operands[0]))
+	{
+	  output = gen_test;
+	}
+      else
+	{
+	  output = normal;
+	  operands[1] = const0_rtx;
+	}
+    }
+  else
+    {
+      if (CONSTANT_P (operands[0]) || GET_CODE (operands[1]) == MEM)
+	output = reverse;
+      else
+	output = normal;
+    }
+
+  switch (mode)
+    {
+    case SImode:
+      switch (output)
+	{
+	case gen_test:
+	  output_asm_insn (AS2 (test%L0,%0,%0), operands);
+	  break;
+	case normal:
+	  output_asm_insn (AS2 (cmp%L0,%1,%0), operands);
+	  break;
+	case reverse:
+	  output_asm_insn (AS2 (cmp%L0,%0,%1), operands);
+	  break;
+	}
+      break;
+
+    case HImode:
+      switch (output)
+	{
+	case gen_test:
+	  output_asm_insn (AS2 (test%W0,%0,%0), operands);
+	  break;
+	case normal:
+	  output_asm_insn (AS2 (cmp%W0,%1,%0), operands);
+	  break;
+	case reverse:
+	  output_asm_insn (AS2 (cmp%W0,%0,%1), operands);
+	  break;
+	}
+      break;
+
+    case QImode:
+      switch (output)
+	{
+	case gen_test:
+	  output_asm_insn (AS2 (test%B0,%0,%0), operands);
+	  break;
+	case normal:
+	  output_asm_insn (AS2 (cmp%B0,%1,%0), operands);
+	  break;
+	case reverse:
+	  output_asm_insn (AS2 (cmp%B0,%0,%1), operands);
+	  break;
+	}
+      break;
+
+    default:
+      abort ();
+  }
+
+  /* The next CC user has to be the floating point conditional move.
+     We have to be very careful since the the floating point
+     conditional move doesn't support signed integer comparison.
+     We have to fake it. */
+  cc0_user = next_cc0_user (insn);
+
+  if (cc0_user
+      && GET_CODE (PATTERN (cc0_user)) == SET
+      && SET_DEST (PATTERN (cc0_user)) != pc_rtx
+      && GET_CODE (SET_SRC (PATTERN (cc0_user))) == IF_THEN_ELSE
+      && (GET_MODE_CLASS (GET_MODE (SET_DEST (PATTERN (cc0_user))))
+	  == MODE_FLOAT))
+    {
+      /* We have to convert it to something fcmovxx can handle. */
+      switch (GET_CODE (XEXP (SET_SRC (PATTERN (cc0_user)), 0)))
+	{
+	case GE:
+	  if (output == reverse)
+	    output_asm_insn (AS1 (setl,%b2), operands);
+	  else
+	    output_asm_insn (AS1 (setge,%b2), operands);
+	  output_asm_insn (AS2 (test%B2,%b2,%b2), operands);
+	  break;
+
+	case GT:
+	  if (output == reverse)
+	    output_asm_insn (AS1 (setle,%b2), operands);
+	  else
+	    output_asm_insn (AS1 (setg,%b2), operands);
+	  output_asm_insn (AS2 (test%B2,%b2,%b2), operands);
+	  break;
+
+	case LE:
+	  if (output == reverse)
+	    output_asm_insn (AS1 (setg,%b2), operands);
+	  else
+	    output_asm_insn (AS1 (setle,%b2), operands);
+	  output_asm_insn (AS2 (test%B2,%b2,%b2), operands);
+	  break;
+
+	case LT:
+	  if (output == reverse)
+	    output_asm_insn (AS1 (setge,%b2), operands);
+	  else
+	    output_asm_insn (AS1 (setl,%b2), operands);
+	  output_asm_insn (AS2 (test%B2,%b2,%b2), operands);
+	  break;
+
+	default:
+	  break;
+	}
+    }
+  else
+    abort ();
+
+  return "";
+}
+
 /* Output code for INSN to compare OPERANDS.  The two operands might
    not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
    expression.  If the compare is in mode CCFPEQmode, use an opcode that
@@ -5158,10 +5347,10 @@ output_fp_conditional_move (which_altern
 
      final_scan_insn () may delete the insn which sets CC. We have to
      tell final_scan_insn () if it should be reinserted. When CODE is
-     GT or LE, we have to check the CC_NO_OVERFLOW bit and return
-     NULL_PTR to tell final to reinsert the test insn because the
-     conditional move cannot be handled properly without it. */
-  if ((code == GT || code == LE)
+     GT, LE, GE or LT, we have to check the CC_NO_OVERFLOW bit and
+     return NULL_PTR to tell final to reinsert the test insn because
+     the conditional move cannot be handled properly without it. */
+  if ((code == GT || code == LE || code == GE || code == LT)
       && (cc_prev_status.flags & CC_NO_OVERFLOW))
     return NULL_PTR;
 


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