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]

[PATCH] post-cond-optab i386 cleanup


This patch removes all the machine-dependent i386 code for cbranch
and cstore tricks, which have been moved to the generic middle-end
with the three patches I posted.

The decisions on how to implement branches are consolidated into an
"enum ix86_fpcmp_strategy" and into ix86_fp_comparison_{cost,strategy}
functions.  All branches are generated when the strategy of performing
arithmetic on AH is used; otherwise those that need to be splitted are
separated from the beginning.

ix86_fp_jump_nontrivial_p is changed to just !TARGET_CMOVE, because cmov
targets never generate complex branches; this means that several patterns
for SSE jump optimizations can go.  Similarly, ix86_use_fcomi_compare is
the same as TARGET_CMOVE since fcomi is always a win for both speed and
size.

Another nice simplification is in ix86_expand_branch, where the sequence
ix86_prepare_fp_compare_args+ix86_split_fp_branch boils down to
ix86_expand_fp_compare -- so that it is possible to treat floating-point
branches as "simple".

Bootstrapped/regtested i686-pc-linux-gnu with -march=i486 (arith),
-march=pentium2 (cmov) and default (sahf).  Ok?

Paolo

2009-05-15  Paolo Bonzini  <bonzini@gnu.org>

	* config/i386/i386.h (enum ix86_fpcmp_strategy): New.
	* config/i386/i386.md (cbranchxf4, cstorexf4, cbranch<MODEF>4,
	cstore<MODEF>4, mov<X87MODEF>cc): Change predicate to
	ix86_fp_comparison_operator.
	(*fp_jcc_1_mixed, *fp_jcc_1_sse, *fp_jcc_1_387, *fp_jcc_2_mixed,
	*fp_jcc_2_sse, *fp_jcc_2_387): Delete
	(*fp_jcc_3_387, *fp_jcc_4_387, *fp_jcc_5_387, *fp_jcc_6_387,
	*fp_jcc_7_387, *fp_jcc_8<MODEF>_387): Eliminate call to
	!ix86_use_fcomi_compare, change ix86_fp_jump_nontrivial_p call
	to !TARGET_CMOVE, change predicate to ix86_fp_comparison_operator.
	(related splits): Change predicate to ix86_fp_comparison_operator.
	* config/i386/predicates.md: Use ix86_trivial_fp_comparison_operator
	instead of ix86_fp_comparison_codes.
	(ix86_trivial_fp_comparison_operator,
	ix86_fp_comparison_operator): New.
	* config/i386/i386-protos.h (ix86_fp_comparison_strategy): New.
	(ix86_expand_compare): Eliminate last two parameters.
	(ix86_fp_jump_nontrivial_p): Kill.
	* config/i386/i386.c (put_condition_code): Eliminate call to
	ix86_fp_comparison_codes and subsequent assertion.
	(ix86_fp_comparison_codes): Eliminate.
	(ix86_fp_swap_condition): New.
	(ix86_fp_comparison_arithmetics_cost, ix86_fp_comparison_fcomi_cost,
	ix86_fp_comparison_sahf_cost, ix86_use_fcomi_compare): Consolidate
	into ix86_fp_comparison_cost and ix86_fp_comparison_strategy.
	(ix86_prepare_fp_compare_args): Use ix86_fp_comparison_strategy
	and ix86_fp_swap_condition.
	(ix86_expand_fp_compare): Eliminate code for second jump/bypass jump.
	Use ix86_fp_comparison_strategy.
	(ix86_expand_compare): Likewise.  Eliminate last two arguments.
	(ix86_fp_jump_nontrivial_p): Eliminate.
	(ix86_expand_branch): Treat SFmode/DFmode/XFmode as simple.  Adjust
	call to ix86_expand_compare.
	(ix86_split_fp_branch, ix86_expand_setcc,
	ix86_expand_carry_flag_compare, ix86_expand_int_movcc,
	ix86_expand_fp_movcc): Eliminate code for second jump/bypass jump.

Index: gcc/config/i386/i386.h
===================================================================
--- gcc/config/i386/i386.h	(branch cond-optab2)
+++ gcc/config/i386/i386.h	(working copy)
@@ -2303,6 +2303,12 @@ extern enum reg_class const regclass_map
 
 extern rtx ix86_compare_op0;	/* operand 0 for comparisons */
 extern rtx ix86_compare_op1;	/* operand 1 for comparisons */
+
+enum ix86_fpcmp_strategy {
+  IX86_FPCMP_SAHF,
+  IX86_FPCMP_COMI,
+  IX86_FPCMP_ARITH
+};
 
 /* To properly truncate FP values into integers, we need to set i387 control
    word.  We can't emit proper mode switching code before reload, as spills
Index: gcc/config/i386/i386.md
===================================================================
--- gcc/config/i386/i386.md	(branch cond-optab2)
+++ gcc/config/i386/i386.md	(working copy)
@@ -1189,7 +1189,7 @@
 	(compare:CC (match_operand:XF 1 "nonmemory_operand" "")
 		    (match_operand:XF 2 "nonmemory_operand" "")))
    (set (pc) (if_then_else
-              (match_operator 0 "comparison_operator"
+              (match_operator 0 "ix86_fp_comparison_operator"
                [(reg:CC FLAGS_REG)
                 (const_int 0)])
               (label_ref (match_operand 3 "" ""))
@@ -1207,7 +1207,7 @@
 	(compare:CC (match_operand:XF 2 "nonmemory_operand" "")
 		    (match_operand:XF 3 "nonmemory_operand" "")))
    (set (match_operand:QI 0 "register_operand" "")
-              (match_operator 1 "comparison_operator"
+              (match_operator 1 "ix86_fp_comparison_operator"
                [(reg:CC FLAGS_REG)
                 (const_int 0)]))]
   "TARGET_80387"
@@ -1223,7 +1223,7 @@
 	(compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
 		    (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
    (set (pc) (if_then_else
-              (match_operator 0 "comparison_operator"
+              (match_operator 0 "ix86_fp_comparison_operator"
                [(reg:CC FLAGS_REG)
                 (const_int 0)])
               (label_ref (match_operand 3 "" ""))
@@ -1241,7 +1241,7 @@
 	(compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
 		    (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
    (set (match_operand:QI 0 "register_operand" "")
-              (match_operator 1 "comparison_operator"
+              (match_operator 1 "ix86_fp_comparison_operator"
                [(reg:CC FLAGS_REG)
                 (const_int 0)]))]
   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
@@ -14764,103 +14764,12 @@
 		      (pc)))]
   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
 
-;; Define combination compare-and-branch fp compare instructions to use
-;; during early optimization.  Splitting the operation apart early makes
-;; for bad code when we want to reverse the operation.
-
-(define_insn "*fp_jcc_1_mixed"
-  [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
-			[(match_operand 1 "register_operand" "f,x")
-			 (match_operand 2 "nonimmediate_operand" "f,xm")])
-	  (label_ref (match_operand 3 "" ""))
-	  (pc)))
-   (clobber (reg:CCFP FPSR_REG))
-   (clobber (reg:CCFP FLAGS_REG))]
-  "TARGET_MIX_SSE_I387
-   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
-  "#")
-
-(define_insn "*fp_jcc_1_sse"
-  [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
-			[(match_operand 1 "register_operand" "x")
-			 (match_operand 2 "nonimmediate_operand" "xm")])
-	  (label_ref (match_operand 3 "" ""))
-	  (pc)))
-   (clobber (reg:CCFP FPSR_REG))
-   (clobber (reg:CCFP FLAGS_REG))]
-  "TARGET_SSE_MATH
-   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
-  "#")
-
-(define_insn "*fp_jcc_1_387"
-  [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
-			[(match_operand 1 "register_operand" "f")
-			 (match_operand 2 "register_operand" "f")])
-	  (label_ref (match_operand 3 "" ""))
-	  (pc)))
-   (clobber (reg:CCFP FPSR_REG))
-   (clobber (reg:CCFP FLAGS_REG))]
-  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && TARGET_CMOVE
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
-  "#")
-
-(define_insn "*fp_jcc_2_mixed"
-  [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
-			[(match_operand 1 "register_operand" "f,x")
-			 (match_operand 2 "nonimmediate_operand" "f,xm")])
-	  (pc)
-	  (label_ref (match_operand 3 "" ""))))
-   (clobber (reg:CCFP FPSR_REG))
-   (clobber (reg:CCFP FLAGS_REG))]
-  "TARGET_MIX_SSE_I387
-   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
-  "#")
-
-(define_insn "*fp_jcc_2_sse"
-  [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
-			[(match_operand 1 "register_operand" "x")
-			 (match_operand 2 "nonimmediate_operand" "xm")])
-	  (pc)
-	  (label_ref (match_operand 3 "" ""))))
-   (clobber (reg:CCFP FPSR_REG))
-   (clobber (reg:CCFP FLAGS_REG))]
-  "TARGET_SSE_MATH
-   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
-  "#")
-
-(define_insn "*fp_jcc_2_387"
-  [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
-			[(match_operand 1 "register_operand" "f")
-			 (match_operand 2 "register_operand" "f")])
-	  (pc)
-	  (label_ref (match_operand 3 "" ""))))
-   (clobber (reg:CCFP FPSR_REG))
-   (clobber (reg:CCFP FLAGS_REG))]
-  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
-   && TARGET_CMOVE
-   && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
-  "#")
+;; Define combination compare-and-branch fp compare instructions to help
+;; combine.
 
 (define_insn "*fp_jcc_3_387"
   [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
+	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
 			[(match_operand 1 "register_operand" "f")
 			 (match_operand 2 "nonimmediate_operand" "fm")])
 	  (label_ref (match_operand 3 "" ""))
@@ -14871,15 +14780,14 @@
   "TARGET_80387
    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
    && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
    && SELECT_CC_MODE (GET_CODE (operands[0]),
 		      operands[1], operands[2]) == CCFPmode
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
+   && !TARGET_CMOVE"
   "#")
 
 (define_insn "*fp_jcc_4_387"
   [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
+	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
 			[(match_operand 1 "register_operand" "f")
 			 (match_operand 2 "nonimmediate_operand" "fm")])
 	  (pc)
@@ -14890,15 +14798,14 @@
   "TARGET_80387
    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
    && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
    && SELECT_CC_MODE (GET_CODE (operands[0]),
 		      operands[1], operands[2]) == CCFPmode
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
+   && !TARGET_CMOVE"
   "#")
 
 (define_insn "*fp_jcc_5_387"
   [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
+	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
 			[(match_operand 1 "register_operand" "f")
 			 (match_operand 2 "register_operand" "f")])
 	  (label_ref (match_operand 3 "" ""))
@@ -14908,12 +14815,12 @@
    (clobber (match_scratch:HI 4 "=a"))]
   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
    && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
+   && !TARGET_CMOVE"
   "#")
 
 (define_insn "*fp_jcc_6_387"
   [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
+	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
 			[(match_operand 1 "register_operand" "f")
 			 (match_operand 2 "register_operand" "f")])
 	  (pc)
@@ -14923,12 +14830,12 @@
    (clobber (match_scratch:HI 4 "=a"))]
   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
    && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
+   && !TARGET_CMOVE"
   "#")
 
 (define_insn "*fp_jcc_7_387"
   [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
+	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
 			[(match_operand 1 "register_operand" "f")
 			 (match_operand 2 "const0_operand" "")])
 	  (label_ref (match_operand 3 "" ""))
@@ -14938,10 +14845,9 @@
    (clobber (match_scratch:HI 4 "=a"))]
   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
    && GET_MODE (operands[1]) == GET_MODE (operands[2])
-   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
    && SELECT_CC_MODE (GET_CODE (operands[0]),
 		      operands[1], operands[2]) == CCFPmode
-   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
+   && !TARGET_CMOVE"
   "#")
 
 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
@@ -14951,7 +14857,7 @@
 
 (define_insn "*fp_jcc_8<mode>_387"
   [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
+	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
 			[(match_operator 1 "float_operator"
 			   [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
 			   (match_operand 3 "register_operand" "f,f")])
@@ -14963,14 +14869,13 @@
   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
    && GET_MODE (operands[1]) == GET_MODE (operands[3])
-   && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
-   && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
+   && !TARGET_CMOVE"
   "#")
 
 (define_split
   [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
+	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
 			[(match_operand 1 "register_operand" "")
 			 (match_operand 2 "nonimmediate_operand" "")])
 	  (match_operand 3 "" "")
@@ -14987,7 +14892,7 @@
 
 (define_split
   [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
+	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
 			[(match_operand 1 "register_operand" "")
 			 (match_operand 2 "general_operand" "")])
 	  (match_operand 3 "" "")
@@ -15005,7 +14910,7 @@
 
 (define_split
   [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
+	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
 			[(match_operator 1 "float_operator"
 			   [(match_operand:X87MODEI12 2 "memory_operand" "")])
 			   (match_operand 3 "register_operand" "")])
@@ -15027,7 +14932,7 @@
 ;; %%% Kill this when reload knows how to do it.
 (define_split
   [(set (pc)
-	(if_then_else (match_operator 0 "comparison_operator"
+	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
 			[(match_operator 1 "float_operator"
 			   [(match_operand:X87MODEI12 2 "register_operand" "")])
 			   (match_operand 3 "register_operand" "")])
@@ -20208,7 +20113,7 @@
 (define_expand "mov<mode>cc"
   [(set (match_operand:X87MODEF 0 "register_operand" "")
 	(if_then_else:X87MODEF
-	  (match_operand 1 "comparison_operator" "")
+	  (match_operand 1 "ix86_fp_comparison_operator" "")
 	  (match_operand:X87MODEF 2 "register_operand" "")
 	  (match_operand:X87MODEF 3 "register_operand" "")))]
   "(TARGET_80387 && TARGET_CMOVE)
Index: gcc/config/i386/predicates.md
===================================================================
--- gcc/config/i386/predicates.md	(branch cond-optab2)
+++ gcc/config/i386/predicates.md	(working copy)
@@ -930,9 +930,7 @@
 
   if (inmode == CCFPmode || inmode == CCFPUmode)
     {
-      enum rtx_code second_code, bypass_code;
-      ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
-      if (bypass_code != UNKNOWN || second_code != UNKNOWN)
+      if (!ix86_trivial_fp_comparison_operator (op, mode))
 	return 0;
       code = ix86_fp_compare_code_to_integer (code);
     }
@@ -992,11 +990,8 @@
   enum rtx_code code = GET_CODE (op);
 
   if (inmode == CCFPmode || inmode == CCFPUmode)
-    {
-      enum rtx_code second_code, bypass_code;
-      ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
-      return (bypass_code == UNKNOWN && second_code == UNKNOWN);
-    }
+    return ix86_trivial_fp_comparison_operator (op, mode);
+
   switch (code)
     {
     case EQ: case NE:
@@ -1037,9 +1032,7 @@
 
   if (inmode == CCFPmode || inmode == CCFPUmode)
     {
-      enum rtx_code second_code, bypass_code;
-      ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
-      if (bypass_code != UNKNOWN || second_code != UNKNOWN)
+      if (!ix86_trivial_fp_comparison_operator (op, mode))
 	return 0;
       code = ix86_fp_compare_code_to_integer (code);
     }
@@ -1051,6 +1044,19 @@
   return code == LTU;
 })
 
+;; Return 1 if this comparison only requires testing one flag bit.
+(define_predicate "ix86_trivial_fp_comparison_operator"
+  (match_code "gt,ge,unlt,unle,uneq,ltgt,ordered,unordered"))
+
+;; Return 1 if we know how to do this comparison.  Others require
+;; testing more than one flag bit, and we let the generic middle-end
+;; code do that.
+(define_predicate "ix86_fp_comparison_operator"
+  (if_then_else (match_test "ix86_fp_comparison_strategy (GET_CODE (op))
+                             == IX86_FPCMP_ARITH")
+               (match_operand 0 "comparison_operator")
+               (match_operand 0 "ix86_trivial_fp_comparison_operator")))
+
 ;; Nearly general operand, but accept any const_double, since we wish
 ;; to be able to drop them into memory rather than have them get pulled
 ;; into registers.
Index: gcc/config/i386/i386-protos.h
===================================================================
--- gcc/config/i386/i386-protos.h	(branch cond-optab2)
+++ gcc/config/i386/i386-protos.h	(working copy)
@@ -96,6 +96,7 @@ extern void ix86_expand_convert_uns_sixf
 extern void ix86_expand_convert_uns_sidf_sse (rtx, rtx);
 extern void ix86_expand_convert_uns_sisf_sse (rtx, rtx);
 extern void ix86_expand_convert_sign_didf_sse (rtx, rtx);
+extern enum ix86_fpcmp_strategy ix86_fp_comparison_strategy (enum rtx_code);
 extern void ix86_expand_fp_absneg_operator (enum rtx_code, enum machine_mode,
 					    rtx[]);
 extern void ix86_expand_copysign (rtx []);
@@ -103,7 +104,7 @@ extern void ix86_split_copysign_const (r
 extern void ix86_split_copysign_var (rtx []);
 extern int ix86_unary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
 extern int ix86_match_ccmode (rtx, enum machine_mode);
-extern rtx ix86_expand_compare (enum rtx_code, rtx *, rtx *);
+extern rtx ix86_expand_compare (enum rtx_code);
 extern int ix86_use_fcomi_compare (enum rtx_code);
 extern void ix86_expand_branch (enum rtx_code, rtx);
 extern void ix86_expand_setcc (enum rtx_code, rtx);
@@ -163,7 +164,6 @@ extern enum reg_class ix86_preferred_out
 extern int ix86_memory_move_cost (enum machine_mode, enum reg_class, int);
 extern int ix86_mode_needed (int, rtx);
 extern void emit_i387_cw_initialization (int);
-extern bool ix86_fp_jump_nontrivial_p (enum rtx_code);
 extern void x86_order_regs_for_local_alloc (void);
 extern void x86_function_profiler (FILE *, int);
 extern void x86_emit_floatuns (rtx [2]);
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(branch cond-optab2)
+++ gcc/config/i386/i386.c	(working copy)
@@ -10530,9 +10530,6 @@ put_condition_code (enum rtx_code code, 
 
   if (mode == CCFPmode || mode == CCFPUmode)
     {
-      enum rtx_code second_code, bypass_code;
-      ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
-      gcc_assert (bypass_code == UNKNOWN && second_code == UNKNOWN);
       code = ix86_fp_compare_code_to_integer (code);
       mode = CCmode;
     }
@@ -14157,84 +14154,41 @@ ix86_cc_modes_compatible (enum machine_m
     }
 }
 
-/* Split comparison code CODE into comparisons we can do using branch
-   instructions.  BYPASS_CODE is comparison code for branch that will
-   branch around FIRST_CODE and SECOND_CODE.  If some of branches
-   is not required, set value to UNKNOWN.
-   We never require more than two branches.  */
 
-void
-ix86_fp_comparison_codes (enum rtx_code code, enum rtx_code *bypass_code,
-			  enum rtx_code *first_code,
-			  enum rtx_code *second_code)
-{
-  *first_code = code;
-  *bypass_code = UNKNOWN;
-  *second_code = UNKNOWN;
-
-  /* The fcomi comparison sets flags as follows:
-
-     cmp    ZF PF CF
-     >      0  0  0
-     <      0  0  1
-     =      1  0  0
-     un     1  1  1 */
+/* Return a comparison we can do and that it is equivalent to 
+   swap_condition (code) apart possibly from orderedness.
+   But, never change orderedness if TARGET_IEEE_FP, returning
+   UNKNOWN in that case if necessary.  */
 
+static enum rtx_code
+ix86_fp_swap_condition (enum rtx_code code)
+{
   switch (code)
     {
-    case GT:			/* GTU - CF=0 & ZF=0 */
-    case GE:			/* GEU - CF=0 */
-    case ORDERED:		/* PF=0 */
-    case UNORDERED:		/* PF=1 */
-    case UNEQ:			/* EQ - ZF=1 */
-    case UNLT:			/* LTU - CF=1 */
-    case UNLE:			/* LEU - CF=1 | ZF=1 */
-    case LTGT:			/* EQ - ZF=0 */
-      break;
-    case LT:			/* LTU - CF=1 - fails on unordered */
-      *first_code = UNLT;
-      *bypass_code = UNORDERED;
-      break;
-    case LE:			/* LEU - CF=1 | ZF=1 - fails on unordered */
-      *first_code = UNLE;
-      *bypass_code = UNORDERED;
-      break;
-    case EQ:			/* EQ - ZF=1 - fails on unordered */
-      *first_code = UNEQ;
-      *bypass_code = UNORDERED;
-      break;
-    case NE:			/* NE - ZF=0 - fails on unordered */
-      *first_code = LTGT;
-      *second_code = UNORDERED;
-      break;
-    case UNGE:			/* GEU - CF=0 - fails on unordered */
-      *first_code = GE;
-      *second_code = UNORDERED;
-      break;
-    case UNGT:			/* GTU - CF=0 & ZF=0 - fails on unordered */
-      *first_code = GT;
-      *second_code = UNORDERED;
-      break;
+    case GT:                   /* GTU - CF=0 & ZF=0 */
+      return TARGET_IEEE_FP ? UNKNOWN : UNLT;
+    case GE:                   /* GEU - CF=0 */
+      return TARGET_IEEE_FP ? UNKNOWN : UNLE;
+    case UNLT:                 /* LTU - CF=1 */
+      return TARGET_IEEE_FP ? UNKNOWN : GT;
+    case UNLE:                 /* LEU - CF=1 | ZF=1 */
+      return TARGET_IEEE_FP ? UNKNOWN : GE;
     default:
-      gcc_unreachable ();
-    }
-  if (!TARGET_IEEE_FP)
-    {
-      *second_code = UNKNOWN;
-      *bypass_code = UNKNOWN;
+      return swap_condition (code);
     }
 }
 
-/* Return cost of comparison done fcom + arithmetics operations on AX.
+/* Return cost of comparison CODE using the best strategy for performance.
    All following functions do use number of instructions as a cost metrics.
    In future this should be tweaked to compute bytes for optimize_size and
    take into account performance of various instructions on various CPUs.  */
+
 static int
-ix86_fp_comparison_arithmetics_cost (enum rtx_code code)
+ix86_fp_comparison_cost (enum rtx_code code)
 {
-  if (!TARGET_IEEE_FP)
-    return 4;
-  /* The cost of code output by ix86_expand_fp_compare.  */
+  int arith_cost;
+
+  /* The cost of code using bit-twiddling on %ah.  */
   switch (code)
     {
     case UNLE:
@@ -14245,82 +14199,49 @@ ix86_fp_comparison_arithmetics_cost (enu
     case UNORDERED:
     case ORDERED:
     case UNEQ:
-      return 4;
+      arith_cost = 4;
       break;
     case LT:
     case NE:
     case EQ:
     case UNGE:
-      return 5;
+      arith_cost = TARGET_IEEE_FP ? 5 : 4;
       break;
     case LE:
     case UNGT:
-      return 6;
+      arith_cost = TARGET_IEEE_FP ? 6 : 4;
       break;
     default:
       gcc_unreachable ();
     }
-}
 
-/* Return cost of comparison done using fcomi operation.
-   See ix86_fp_comparison_arithmetics_cost for the metrics.  */
-static int
-ix86_fp_comparison_fcomi_cost (enum rtx_code code)
-{
-  enum rtx_code bypass_code, first_code, second_code;
-  /* Return arbitrarily high cost when instruction is not supported - this
-     prevents gcc from using it.  */
-  if (!TARGET_CMOVE)
-    return 1024;
-  ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
-  return (bypass_code != UNKNOWN || second_code != UNKNOWN) + 2;
+  switch (ix86_fp_comparison_strategy (code))
+    {
+    case IX86_FPCMP_COMI:
+      return arith_cost > 4 ? 3 : 2;
+    case IX86_FPCMP_SAHF:
+      return arith_cost > 4 ? 4 : 3;
+    default:
+      return arith_cost;
+    }
 }
 
-/* Return cost of comparison done using sahf operation.
-   See ix86_fp_comparison_arithmetics_cost for the metrics.  */
-static int
-ix86_fp_comparison_sahf_cost (enum rtx_code code)
-{
-  enum rtx_code bypass_code, first_code, second_code;
-  /* Return arbitrarily high cost when instruction is not preferred - this
-     avoids gcc from using it.  */
-  if (!(TARGET_SAHF && (TARGET_USE_SAHF || optimize_insn_for_size_p ())))
-    return 1024;
-  ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
-  return (bypass_code != UNKNOWN || second_code != UNKNOWN) + 3;
-}
+/* Return strategy to use for floating-point.  We assume that fcomi is always
+   preferrable where available, since that is also true when looking at size
+   (2 bytes, vs. 3 for fnstsw+sahf and at least 5 for fnstsw+test).  */
 
-/* Compute cost of the comparison done using any method.
-   See ix86_fp_comparison_arithmetics_cost for the metrics.  */
-static int
-ix86_fp_comparison_cost (enum rtx_code code)
+enum ix86_fpcmp_strategy
+ix86_fp_comparison_strategy (enum rtx_code code ATTRIBUTE_UNUSED)
 {
-  int fcomi_cost, sahf_cost, arithmetics_cost = 1024;
-  int min;
-
-  fcomi_cost = ix86_fp_comparison_fcomi_cost (code);
-  sahf_cost = ix86_fp_comparison_sahf_cost (code);
-
-  min = arithmetics_cost = ix86_fp_comparison_arithmetics_cost (code);
-  if (min > sahf_cost)
-    min = sahf_cost;
-  if (min > fcomi_cost)
-    min = fcomi_cost;
-  return min;
-}
+  /* Do fcomi/sahf based test when profitable.  */
 
-/* Return true if we should use an FCOMI instruction for this
-   fp comparison.  */
+  if (TARGET_CMOVE)
+    return IX86_FPCMP_COMI;
 
-int
-ix86_use_fcomi_compare (enum rtx_code code ATTRIBUTE_UNUSED)
-{
-  enum rtx_code swapped_code = swap_condition (code);
+  if (TARGET_SAHF && (TARGET_USE_SAHF || optimize_insn_for_size_p ()))
+    return IX86_FPCMP_SAHF;
 
-  return ((ix86_fp_comparison_cost (code)
-	   == ix86_fp_comparison_fcomi_cost (code))
-	  || (ix86_fp_comparison_cost (swapped_code)
-	      == ix86_fp_comparison_fcomi_cost (swapped_code)));
+  return IX86_FPCMP_ARITH;
 }
 
 /* Swap, force into registers, or otherwise massage the two operands
@@ -14347,7 +14268,7 @@ ix86_prepare_fp_compare_args (enum rtx_c
 	      && ! (standard_80387_constant_p (op0) == 1
 		    || standard_80387_constant_p (op1) == 1)
 	      && GET_CODE (op1) != FLOAT)
-	  || ix86_use_fcomi_compare (code)))
+	  || ix86_fp_comparison_strategy (code) == IX86_FPCMP_COMI))
     {
       op0 = force_reg (op_mode, op0);
       op1 = force_reg (op_mode, op1);
@@ -14363,9 +14284,13 @@ ix86_prepare_fp_compare_args (enum rtx_c
 	      && ! (standard_80387_constant_p (op1) == 0
 		    || MEM_P (op1))))
 	{
-	  rtx tmp;
-	  tmp = op0, op0 = op1, op1 = tmp;
-	  code = swap_condition (code);
+	  enum rtx_code new_code = ix86_fp_swap_condition (code);
+	  if (new_code != UNKNOWN)
+	    {
+	      rtx tmp;
+	      tmp = op0, op0 = op1, op1 = tmp;
+	      code = new_code;
+	    }
 	}
 
       if (!REG_P (op0))
@@ -14440,59 +14365,38 @@ ix86_fp_compare_code_to_integer (enum rt
 /* Generate insn patterns to do a floating point compare of OPERANDS.  */
 
 static rtx
-ix86_expand_fp_compare (enum rtx_code code, rtx op0, rtx op1, rtx scratch,
-			rtx *second_test, rtx *bypass_test)
+ix86_expand_fp_compare (enum rtx_code code, rtx op0, rtx op1, rtx scratch)
 {
   enum machine_mode fpcmp_mode, intcmp_mode;
   rtx tmp, tmp2;
-  int cost = ix86_fp_comparison_cost (code);
-  enum rtx_code bypass_code, first_code, second_code;
 
   fpcmp_mode = ix86_fp_compare_mode (code);
   code = ix86_prepare_fp_compare_args (code, &op0, &op1);
 
-  if (second_test)
-    *second_test = NULL_RTX;
-  if (bypass_test)
-    *bypass_test = NULL_RTX;
-
-  ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
-
   /* Do fcomi/sahf based test when profitable.  */
-  if (ix86_fp_comparison_arithmetics_cost (code) > cost
-      && (bypass_code == UNKNOWN || bypass_test)
-      && (second_code == UNKNOWN || second_test))
+  switch (ix86_fp_comparison_strategy (code))
     {
+    case IX86_FPCMP_COMI:
+      intcmp_mode = fpcmp_mode;
       tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
       tmp = gen_rtx_SET (VOIDmode, gen_rtx_REG (fpcmp_mode, FLAGS_REG),
 			 tmp);
-      if (TARGET_CMOVE)
-	emit_insn (tmp);
-      else
-	{
-	  gcc_assert (TARGET_SAHF);
+      emit_insn (tmp);
+      break;
 
-	  if (!scratch)
-	    scratch = gen_reg_rtx (HImode);
-	  tmp2 = gen_rtx_CLOBBER (VOIDmode, scratch);
+    case IX86_FPCMP_SAHF:
+      intcmp_mode = fpcmp_mode;
+      tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
+      tmp = gen_rtx_SET (VOIDmode, gen_rtx_REG (fpcmp_mode, FLAGS_REG),
+			 tmp);
 
-	  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, tmp2)));
-	}
+      if (!scratch)
+	scratch = gen_reg_rtx (HImode);
+      tmp2 = gen_rtx_CLOBBER (VOIDmode, scratch);
+      emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, tmp2)));
+      break;
 
-      /* The FP codes work out to act like unsigned.  */
-      intcmp_mode = fpcmp_mode;
-      code = first_code;
-      if (bypass_code != UNKNOWN)
-	*bypass_test = gen_rtx_fmt_ee (bypass_code, VOIDmode,
-				       gen_rtx_REG (intcmp_mode, FLAGS_REG),
-				       const0_rtx);
-      if (second_code != UNKNOWN)
-	*second_test = gen_rtx_fmt_ee (second_code, VOIDmode,
-				       gen_rtx_REG (intcmp_mode, FLAGS_REG),
-				       const0_rtx);
-    }
-  else
-    {
+    case IX86_FPCMP_ARITH:
       /* Sadness wrt reg-stack pops killing fpsr -- gotta get fnstsw first.  */
       tmp = gen_rtx_COMPARE (fpcmp_mode, op0, op1);
       tmp2 = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), UNSPEC_FNSTSW);
@@ -14614,6 +14518,10 @@ ix86_expand_fp_compare (enum rtx_code co
 	default:
 	  gcc_unreachable ();
 	}
+	break;
+
+    default:
+      gcc_unreachable();
     }
 
   /* Return the test that should be put into the flags user, i.e.
@@ -14624,25 +14532,19 @@ ix86_expand_fp_compare (enum rtx_code co
 }
 
 rtx
-ix86_expand_compare (enum rtx_code code, rtx *second_test, rtx *bypass_test)
+ix86_expand_compare (enum rtx_code code)
 {
   rtx op0, op1, ret;
   op0 = ix86_compare_op0;
   op1 = ix86_compare_op1;
 
-  if (second_test)
-    *second_test = NULL_RTX;
-  if (bypass_test)
-    *bypass_test = NULL_RTX;
-
   if (GET_MODE_CLASS (GET_MODE (ix86_compare_op0)) == MODE_CC)
     ret = gen_rtx_fmt_ee (code, VOIDmode, ix86_compare_op0, ix86_compare_op1);
 
   else if (SCALAR_FLOAT_MODE_P (GET_MODE (op0)))
     {
       gcc_assert (!DECIMAL_FLOAT_MODE_P (GET_MODE (op0)));
-      ret = ix86_expand_fp_compare (code, op0, op1, NULL_RTX,
-				    second_test, bypass_test);
+      ret = ix86_expand_fp_compare (code, op0, op1, NULL_RTX);
     }
   else
     ret = ix86_expand_int_compare (code, op0, op1);
@@ -14650,17 +14552,6 @@ ix86_expand_compare (enum rtx_code code,
   return ret;
 }
 
-/* Return true if the CODE will result in nontrivial jump sequence.  */
-bool
-ix86_fp_jump_nontrivial_p (enum rtx_code code)
-{
-  enum rtx_code bypass_code, first_code, second_code;
-  if (!TARGET_CMOVE)
-    return true;
-  ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
-  return bypass_code != UNKNOWN || second_code != UNKNOWN;
-}
-
 void
 ix86_expand_branch (enum rtx_code code, rtx label)
 {
@@ -14668,64 +14559,20 @@ ix86_expand_branch (enum rtx_code code, 
 
   switch (GET_MODE (ix86_compare_op0))
     {
+    case SFmode:
+    case DFmode:
+    case XFmode:
     case QImode:
     case HImode:
     case SImode:
       simple:
-      tmp = ix86_expand_compare (code, NULL, NULL);
+      tmp = ix86_expand_compare (code);
       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
 				  gen_rtx_LABEL_REF (VOIDmode, label),
 				  pc_rtx);
       emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
       return;
 
-    case SFmode:
-    case DFmode:
-    case XFmode:
-      {
-	rtvec vec;
-	int use_fcomi;
-	enum rtx_code bypass_code, first_code, second_code;
-
-	code = ix86_prepare_fp_compare_args (code, &ix86_compare_op0,
-					     &ix86_compare_op1);
-
-	ix86_fp_comparison_codes (code, &bypass_code, &first_code, &second_code);
-
-	/* Check whether we will use the natural sequence with one jump.  If
-	   so, we can expand jump early.  Otherwise delay expansion by
-	   creating compound insn to not confuse optimizers.  */
-	if (bypass_code == UNKNOWN && second_code == UNKNOWN)
-	  {
-	    ix86_split_fp_branch (code, ix86_compare_op0, ix86_compare_op1,
-				  gen_rtx_LABEL_REF (VOIDmode, label),
-				  pc_rtx, NULL_RTX, NULL_RTX);
-	  }
-	else
-	  {
-	    tmp = gen_rtx_fmt_ee (code, VOIDmode,
-				  ix86_compare_op0, ix86_compare_op1);
-	    tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
-					gen_rtx_LABEL_REF (VOIDmode, label),
-					pc_rtx);
-	    tmp = gen_rtx_SET (VOIDmode, pc_rtx, tmp);
-
-	    use_fcomi = ix86_use_fcomi_compare (code);
-	    vec = rtvec_alloc (3 + !use_fcomi);
-	    RTVEC_ELT (vec, 0) = tmp;
-	    RTVEC_ELT (vec, 1)
-	      = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, FPSR_REG));
-	    RTVEC_ELT (vec, 2)
-	      = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCFPmode, FLAGS_REG));
-	    if (! use_fcomi)
-	      RTVEC_ELT (vec, 3)
-		= gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (HImode));
-
-	    emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, vec));
-	  }
-	return;
-      }
-
     case DImode:
       if (TARGET_64BIT)
 	goto simple;
@@ -14879,10 +14726,7 @@ void
 ix86_split_fp_branch (enum rtx_code code, rtx op1, rtx op2,
 		      rtx target1, rtx target2, rtx tmp, rtx pushed)
 {
-  rtx second, bypass;
-  rtx label = NULL_RTX;
   rtx condition;
-  int bypass_probability = -1, second_probability = -1, probability = -1;
   rtx i;
 
   if (target2 != pc_rtx)
@@ -14894,103 +14738,30 @@ ix86_split_fp_branch (enum rtx_code code
     }
 
   condition = ix86_expand_fp_compare (code, op1, op2,
-				      tmp, &second, &bypass);
+				      tmp);
 
   /* Remove pushed operand from stack.  */
   if (pushed)
     ix86_free_from_memory (GET_MODE (pushed));
 
-  if (split_branch_probability >= 0)
-    {
-      /* Distribute the probabilities across the jumps.
-	 Assume the BYPASS and SECOND to be always test
-	 for UNORDERED.  */
-      probability = split_branch_probability;
-
-      /* Value of 1 is low enough to make no need for probability
-	 to be updated.  Later we may run some experiments and see
-	 if unordered values are more frequent in practice.  */
-      if (bypass)
-	bypass_probability = 1;
-      if (second)
-	second_probability = 1;
-    }
-  if (bypass != NULL_RTX)
-    {
-      label = gen_label_rtx ();
-      i = emit_jump_insn (gen_rtx_SET
-			  (VOIDmode, pc_rtx,
-			   gen_rtx_IF_THEN_ELSE (VOIDmode,
-						 bypass,
-						 gen_rtx_LABEL_REF (VOIDmode,
-								    label),
-						 pc_rtx)));
-      if (bypass_probability >= 0)
-	add_reg_note (i, REG_BR_PROB, GEN_INT (bypass_probability));
-    }
   i = emit_jump_insn (gen_rtx_SET
 		      (VOIDmode, pc_rtx,
 		       gen_rtx_IF_THEN_ELSE (VOIDmode,
 					     condition, target1, target2)));
-  if (probability >= 0)
-    add_reg_note (i, REG_BR_PROB, GEN_INT (probability));
-  if (second != NULL_RTX)
-    {
-      i = emit_jump_insn (gen_rtx_SET
-			  (VOIDmode, pc_rtx,
-			   gen_rtx_IF_THEN_ELSE (VOIDmode, second, target1,
-						 target2)));
-      if (second_probability >= 0)
-	add_reg_note (i, REG_BR_PROB, GEN_INT (second_probability));
-    }
-  if (label != NULL_RTX)
-    emit_label (label);
+  if (split_branch_probability >= 0)
+    add_reg_note (i, REG_BR_PROB, GEN_INT (split_branch_probability));
 }
 
 void
 ix86_expand_setcc (enum rtx_code code, rtx dest)
 {
-  rtx ret, tmp, tmpreg, equiv;
-  rtx second_test, bypass_test;
+  rtx ret;
 
   gcc_assert (GET_MODE (dest) == QImode);
 
-  ret = ix86_expand_compare (code, &second_test, &bypass_test);
+  ret = ix86_expand_compare (code);
   PUT_MODE (ret, QImode);
-
-  tmp = dest;
-  tmpreg = dest;
-
-  emit_insn (gen_rtx_SET (VOIDmode, tmp, ret));
-  if (bypass_test || second_test)
-    {
-      rtx test = second_test;
-      int bypass = 0;
-      rtx tmp2 = gen_reg_rtx (QImode);
-      if (bypass_test)
-	{
-	  gcc_assert (!second_test);
-	  test = bypass_test;
-	  bypass = 1;
-	  PUT_CODE (test, reverse_condition_maybe_unordered (GET_CODE (test)));
-	}
-      PUT_MODE (test, QImode);
-      emit_insn (gen_rtx_SET (VOIDmode, tmp2, test));
-
-      if (bypass)
-	emit_insn (gen_andqi3 (tmp, tmpreg, tmp2));
-      else
-	emit_insn (gen_iorqi3 (tmp, tmpreg, tmp2));
-    }
-
-  /* Attach a REG_EQUAL note describing the comparison result.  */
-  if (ix86_compare_op0 && ix86_compare_op1)
-    {
-      equiv = simplify_gen_relational (code, QImode,
-				       GET_MODE (ix86_compare_op0),
-				       ix86_compare_op0, ix86_compare_op1);
-      set_unique_reg_note (get_last_insn (), REG_EQUAL, equiv);
-    }
+  emit_insn (gen_rtx_SET (VOIDmode, dest, ret));
 }
 
 /* Expand comparison setting or clearing carry flag.  Return true when
@@ -15007,7 +14778,6 @@ ix86_expand_carry_flag_compare (enum rtx
 
   if (SCALAR_FLOAT_MODE_P (mode))
     {
-      rtx second_test = NULL, bypass_test = NULL;
       rtx compare_op, compare_seq;
 
       gcc_assert (!DECIMAL_FLOAT_MODE_P (mode));
@@ -15033,14 +14803,10 @@ ix86_expand_carry_flag_compare (enum rtx
 	 we decide to expand comparison using arithmetic that is not
 	 too common scenario.  */
       start_sequence ();
-      compare_op = ix86_expand_fp_compare (code, op0, op1, NULL_RTX,
-					   &second_test, &bypass_test);
+      compare_op = ix86_expand_fp_compare (code, op0, op1, NULL_RTX);
       compare_seq = get_insns ();
       end_sequence ();
 
-      if (second_test || bypass_test)
-	return false;
-
       if (GET_MODE (XEXP (compare_op, 0)) == CCFPmode
 	  || GET_MODE (XEXP (compare_op, 0)) == CCFPUmode)
         code = ix86_fp_compare_code_to_integer (GET_CODE (compare_op));
@@ -15123,7 +14889,7 @@ ix86_expand_carry_flag_compare (enum rtx
     }
   ix86_compare_op0 = op0;
   ix86_compare_op1 = op1;
-  *pop = ix86_expand_compare (code, NULL, NULL);
+  *pop = ix86_expand_compare (code);
   gcc_assert (GET_CODE (*pop) == LTU || GET_CODE (*pop) == GEU);
   return true;
 }
@@ -15133,14 +14899,13 @@ ix86_expand_int_movcc (rtx operands[])
 {
   enum rtx_code code = GET_CODE (operands[1]), compare_code;
   rtx compare_seq, compare_op;
-  rtx second_test, bypass_test;
   enum machine_mode mode = GET_MODE (operands[0]);
   bool sign_bit_compare_p = false;;
 
   start_sequence ();
   ix86_compare_op0 = XEXP (operands[1], 0);
   ix86_compare_op1 = XEXP (operands[1], 1);
-  compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
+  compare_op = ix86_expand_compare (code);
   compare_seq = get_insns ();
   end_sequence ();
 
@@ -15612,19 +15377,6 @@ ix86_expand_int_movcc (rtx operands[])
   if (! nonimmediate_operand (operands[3], mode))
     operands[3] = force_reg (mode, operands[3]);
 
-  if (bypass_test && reg_overlap_mentioned_p (operands[0], operands[3]))
-    {
-      rtx tmp = gen_reg_rtx (mode);
-      emit_move_insn (tmp, operands[3]);
-      operands[3] = tmp;
-    }
-  if (second_test && reg_overlap_mentioned_p (operands[0], operands[2]))
-    {
-      rtx tmp = gen_reg_rtx (mode);
-      emit_move_insn (tmp, operands[2]);
-      operands[2] = tmp;
-    }
-
   if (! register_operand (operands[2], VOIDmode)
       && (mode == QImode
           || ! register_operand (operands[3], VOIDmode)))
@@ -15639,18 +15391,6 @@ ix86_expand_int_movcc (rtx operands[])
 			  gen_rtx_IF_THEN_ELSE (mode,
 						compare_op, operands[2],
 						operands[3])));
-  if (bypass_test)
-    emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (operands[0]),
-			    gen_rtx_IF_THEN_ELSE (mode,
-				  bypass_test,
-				  copy_rtx (operands[3]),
-				  copy_rtx (operands[0]))));
-  if (second_test)
-    emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (operands[0]),
-			    gen_rtx_IF_THEN_ELSE (mode,
-				  second_test,
-				  copy_rtx (operands[2]),
-				  copy_rtx (operands[0]))));
 
   return 1; /* DONE */
 }
@@ -15855,7 +15595,7 @@ ix86_expand_fp_movcc (rtx operands[])
 {
   enum machine_mode mode = GET_MODE (operands[0]);
   enum rtx_code code = GET_CODE (operands[1]);
-  rtx tmp, compare_op, second_test, bypass_test;
+  rtx tmp, compare_op;
 
   ix86_compare_op0 = XEXP (operands[1], 0);
   ix86_compare_op1 = XEXP (operands[1], 1);
@@ -15892,45 +15632,20 @@ ix86_expand_fp_movcc (rtx operands[])
   /* The floating point conditional move instructions don't directly
      support conditions resulting from a signed integer comparison.  */
 
-  compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
-
-  /* The floating point conditional move instructions don't directly
-     support signed integer comparisons.  */
-
+  compare_op = ix86_expand_compare (code);
   if (!fcmov_comparison_operator (compare_op, VOIDmode))
     {
-      gcc_assert (!second_test && !bypass_test);
       tmp = gen_reg_rtx (QImode);
       ix86_expand_setcc (code, tmp);
       code = NE;
       ix86_compare_op0 = tmp;
       ix86_compare_op1 = const0_rtx;
-      compare_op = ix86_expand_compare (code,  &second_test, &bypass_test);
-    }
-  if (bypass_test && reg_overlap_mentioned_p (operands[0], operands[3]))
-    {
-      tmp = gen_reg_rtx (mode);
-      emit_move_insn (tmp, operands[3]);
-      operands[3] = tmp;
-    }
-  if (second_test && reg_overlap_mentioned_p (operands[0], operands[2]))
-    {
-      tmp = gen_reg_rtx (mode);
-      emit_move_insn (tmp, operands[2]);
-      operands[2] = tmp;
+      compare_op = ix86_expand_compare (code);
     }
 
   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
 			  gen_rtx_IF_THEN_ELSE (mode, compare_op,
 						operands[2], operands[3])));
-  if (bypass_test)
-    emit_insn (gen_rtx_SET (VOIDmode, operands[0],
-			    gen_rtx_IF_THEN_ELSE (mode, bypass_test,
-						  operands[3], operands[0])));
-  if (second_test)
-    emit_insn (gen_rtx_SET (VOIDmode, operands[0],
-			    gen_rtx_IF_THEN_ELSE (mode, second_test,
-						  operands[2], operands[0])));
 
   return 1;
 }


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