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]

[cond-optab] Convert rs6000


The rs6000 code needed a lot of search-and-replace, but otherwise it is
quite plain.  It is also different in that it sometimes prefers the
standard portable sequences for sCC.

Paolo

2009-03-26  Paolo Bonzini  <bonzini@gnu.org>

	* config/rs6000/predicates.md (rs6000_cbranch_operator): New.
	(trap_comparison_operator): Delete.
	* config/rs6000/rs6000-protos.h (rs6000_emit_sCOND,
	rs6000_emit_cbranch): Accept mode and operands.
	* config/rs6000/rs6000.c (rs6000_compare_op0, rs6000_compare_op1,
	rs6000_compare_fp_p): Delete.
	(rs6000_generate_compare): Accept mode and comparison.  Extract code
	and op0/op1 from there.  Replace references to rs6000_compare_op0
	and rs6000_compare_op1.
	(rs6000_emit_sCOND): Adjust call to rs6000_generate_compare and
	extract result from passed operands.
	(rs6000_emit_cbranch): Adjust call to rs6000_generate_compare and
	extract loc from passed operands.
	(rs6000_emit_cmove): Likewise.
	* config/rs6000/rs6000.h (rs6000_compare_op0, rs6000_compare_op1,
        rs6000_compare_fp_p): Delete.
	* config/rs6000/rs6000.md (cmp<GPR>, cmp<FP>, bCC, sCC): Delete.
	(cbranch<GPR>4, cbranch<FP>4): New.
	(cstore<mode>4): New.  Consolidate here all choices about when to use
	portable or specialized sCC sequences.
	(stack_protect_test): Use cbranchsi4.
	(conditional_trap): Replace with ctrap<GPR>4.
	(conditional trap insn): Replace trap_comparison_operator with
	ordered_comparison_operator.
Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md	(branch cond-optab)
+++ gcc/config/rs6000/predicates.md	(working copy)
@@ -830,6 +830,11 @@
 						   GET_MODE (XEXP (op, 0))),
 			  1"))))
 
+(define_predicate "rs6000_cbranch_operator"
+  (if_then_else (match_test "TARGET_HARD_FLOAT && !TARGET_FPRS")
+		(match_operand 0 "ordered_comparison_operator")
+		(match_operand 0 "comparison_operator")))
+
 ;; Return 1 if OP is a comparison operation that is valid for an SCC insn --
 ;; it must be a positive comparison.
 (define_predicate "scc_comparison_operator"
@@ -842,11 +847,6 @@
   (and (match_operand 0 "branch_comparison_operator")
        (match_code "eq,lt,gt,ltu,gtu,unordered")))
 
-;; Return 1 is OP is a comparison operation that is valid for a trap insn.
-(define_predicate "trap_comparison_operator"
-   (and (match_operand 0 "comparison_operator")
-	(match_code "eq,ne,le,lt,ge,gt,leu,ltu,geu,gtu")))
-
 ;; Return 1 if OP is a load multiple operation, known to be a PARALLEL.
 (define_predicate "load_multiple_operation"
   (match_code "parallel")
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
--- gcc/config/rs6000/rs6000-protos.h	(branch cond-optab)
+++ gcc/config/rs6000/rs6000-protos.h	(working copy)
@@ -81,8 +81,8 @@ extern void print_operand_address (FILE 
 extern bool rs6000_output_addr_const_extra (FILE *, rtx);
 extern enum rtx_code rs6000_reverse_condition (enum machine_mode,
 					       enum rtx_code);
-extern void rs6000_emit_sCOND (enum rtx_code, rtx);
-extern void rs6000_emit_cbranch (enum rtx_code, rtx);
+extern void rs6000_emit_sCOND (enum machine_mode, rtx[]);
+extern void rs6000_emit_cbranch (enum machine_mode, rtx[]);
 extern char * output_cbranch (rtx, const char *, int, rtx);
 extern char * output_e500_flip_gt_bit (rtx, rtx);
 extern rtx rs6000_emit_set_const (rtx, enum machine_mode, rtx, int);
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(branch cond-optab)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -190,11 +190,6 @@ int rs6000_darwin64_abi;
 /* Set to nonzero once AIX common-mode calls have been defined.  */
 static GTY(()) int common_mode_defined;
 
-/* Save information from a "cmpxx" operation until the branch or scc is
-   emitted.  */
-rtx rs6000_compare_op0, rs6000_compare_op1;
-int rs6000_compare_fp_p;
-
 /* Label number of label created for -mrelocatable, to call to so we can
    get the address of the GOT section */
 int rs6000_pic_labelno;
@@ -752,7 +747,7 @@ struct processor_costs power6_cost = {
 
 static bool rs6000_function_ok_for_sibcall (tree, tree);
 static const char *rs6000_invalid_within_doloop (const_rtx);
-static rtx rs6000_generate_compare (enum rtx_code);
+static rtx rs6000_generate_compare (rtx, enum machine_mode);
 static void rs6000_emit_stack_tie (void);
 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
 static bool spe_func_has_64bit_regs_p (void);
@@ -12774,21 +12769,24 @@ rs6000_reverse_condition (enum machine_m
    represents the result of the compare.  */
 
 static rtx
-rs6000_generate_compare (enum rtx_code code)
+rs6000_generate_compare (rtx cmp, enum machine_mode mode)
 {
   enum machine_mode comp_mode;
   rtx compare_result;
+  enum rtx_code code = GET_CODE (cmp);
+  rtx op0 = XEXP (cmp, 0);
+  rtx op1 = XEXP (cmp, 1);
 
-  if (rs6000_compare_fp_p)
+  if (FLOAT_MODE_P (mode))
     comp_mode = CCFPmode;
   else if (code == GTU || code == LTU
 	   || code == GEU || code == LEU)
     comp_mode = CCUNSmode;
   else if ((code == EQ || code == NE)
-	   && GET_CODE (rs6000_compare_op0) == SUBREG
-	   && GET_CODE (rs6000_compare_op1) == SUBREG
-	   && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0)
-	   && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1))
+	   && GET_CODE (op0) == SUBREG
+	   && GET_CODE (op1) == SUBREG
+	   && SUBREG_PROMOTED_UNSIGNED_P (op0)
+	   && SUBREG_PROMOTED_UNSIGNED_P (op1))
     /* These are unsigned values, perhaps there will be a later
        ordering compare that can be shared with this one.
        Unfortunately we cannot detect the signedness of the operands
@@ -12802,13 +12800,13 @@ rs6000_generate_compare (enum rtx_code c
 
   /* E500 FP compare instructions on the GPRs.  Yuck!  */
   if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
-      && rs6000_compare_fp_p)
+      && FLOAT_MODE_P (mode))
     {
       rtx cmp, or_result, compare_result2;
-      enum machine_mode op_mode = GET_MODE (rs6000_compare_op0);
+      enum machine_mode op_mode = GET_MODE (op0);
 
       if (op_mode == VOIDmode)
-	op_mode = GET_MODE (rs6000_compare_op1);
+	op_mode = GET_MODE (op1);
 
       /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
 	 This explains the following mess.  */
@@ -12820,26 +12818,20 @@ rs6000_generate_compare (enum rtx_code c
 	    {
 	    case SFmode:
 	      cmp = (flag_finite_math_only && !flag_trapping_math)
-		? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1)
-		: gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1);
+		? gen_tstsfeq_gpr (compare_result, op0, op1)
+		: gen_cmpsfeq_gpr (compare_result, op0, op1);
 	      break;
 
 	    case DFmode:
 	      cmp = (flag_finite_math_only && !flag_trapping_math)
-		? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1)
-		: gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1);
+		? gen_tstdfeq_gpr (compare_result, op0, op1)
+		: gen_cmpdfeq_gpr (compare_result, op0, op1);
 	      break;
 
 	    case TFmode:
 	      cmp = (flag_finite_math_only && !flag_trapping_math)
-		? gen_tsttfeq_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1)
-		: gen_cmptfeq_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1);
+		? gen_tsttfeq_gpr (compare_result, op0, op1)
+		: gen_cmptfeq_gpr (compare_result, op0, op1);
 	      break;
 
 	    default:
@@ -12852,26 +12844,20 @@ rs6000_generate_compare (enum rtx_code c
 	    {
 	    case SFmode:
 	      cmp = (flag_finite_math_only && !flag_trapping_math)
-		? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1)
-		: gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1);
+		? gen_tstsfgt_gpr (compare_result, op0, op1)
+		: gen_cmpsfgt_gpr (compare_result, op0, op1);
 	      break;
 
 	    case DFmode:
 	      cmp = (flag_finite_math_only && !flag_trapping_math)
-		? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1)
-		: gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1);
+		? gen_tstdfgt_gpr (compare_result, op0, op1)
+		: gen_cmpdfgt_gpr (compare_result, op0, op1);
 	      break;
 
 	    case TFmode:
 	      cmp = (flag_finite_math_only && !flag_trapping_math)
-		? gen_tsttfgt_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1)
-		: gen_cmptfgt_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1);
+		? gen_tsttfgt_gpr (compare_result, op0, op1)
+		: gen_cmptfgt_gpr (compare_result, op0, op1);
 	      break;
 
 	    default:
@@ -12884,26 +12870,20 @@ rs6000_generate_compare (enum rtx_code c
 	    {
 	    case SFmode:
 	      cmp = (flag_finite_math_only && !flag_trapping_math)
-		? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1)
-		: gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1);
+		? gen_tstsflt_gpr (compare_result, op0, op1)
+		: gen_cmpsflt_gpr (compare_result, op0, op1);
 	      break;
 
 	    case DFmode:
 	      cmp = (flag_finite_math_only && !flag_trapping_math)
-		? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1)
-		: gen_cmpdflt_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1);
+		? gen_tstdflt_gpr (compare_result, op0, op1)
+		: gen_cmpdflt_gpr (compare_result, op0, op1);
 	      break;
 
 	    case TFmode:
 	      cmp = (flag_finite_math_only && !flag_trapping_math)
-		? gen_tsttflt_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1)
-		: gen_cmptflt_gpr (compare_result, rs6000_compare_op0,
-				   rs6000_compare_op1);
+		? gen_tsttflt_gpr (compare_result, op0, op1)
+		: gen_cmptflt_gpr (compare_result, op0, op1);
 	      break;
 
 	    default:
@@ -12935,26 +12915,20 @@ rs6000_generate_compare (enum rtx_code c
 	    {
 	    case SFmode:
 	      cmp = (flag_finite_math_only && !flag_trapping_math)
-		? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
-				   rs6000_compare_op1)
-		: gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
-				   rs6000_compare_op1);
+		? gen_tstsfeq_gpr (compare_result2, op0, op1)
+		: gen_cmpsfeq_gpr (compare_result2, op0, op1);
 	      break;
 
 	    case DFmode:
 	      cmp = (flag_finite_math_only && !flag_trapping_math)
-		? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0,
-				   rs6000_compare_op1)
-		: gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0,
-				   rs6000_compare_op1);
+		? gen_tstdfeq_gpr (compare_result2, op0, op1)
+		: gen_cmpdfeq_gpr (compare_result2, op0, op1);
 	      break;
 
 	    case TFmode:
 	      cmp = (flag_finite_math_only && !flag_trapping_math)
-		? gen_tsttfeq_gpr (compare_result2, rs6000_compare_op0,
-				   rs6000_compare_op1)
-		: gen_cmptfeq_gpr (compare_result2, rs6000_compare_op0,
-				   rs6000_compare_op1);
+		? gen_tsttfeq_gpr (compare_result2, op0, op1)
+		: gen_cmptfeq_gpr (compare_result2, op0, op1);
 	      break;
 
 	    default:
@@ -12984,16 +12958,14 @@ rs6000_generate_compare (enum rtx_code c
       /* Generate XLC-compatible TFmode compare as PARALLEL with extra
 	 CLOBBERs to match cmptf_internal2 pattern.  */
       if (comp_mode == CCFPmode && TARGET_XL_COMPAT
-	  && GET_MODE (rs6000_compare_op0) == TFmode
+	  && GET_MODE (op0) == TFmode
 	  && !TARGET_IEEEQUAD
 	  && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
 	emit_insn (gen_rtx_PARALLEL (VOIDmode,
 	  gen_rtvec (9,
 		     gen_rtx_SET (VOIDmode,
 				  compare_result,
-				  gen_rtx_COMPARE (comp_mode,
-						   rs6000_compare_op0,
-						   rs6000_compare_op1)),
+				  gen_rtx_COMPARE (comp_mode, op0, op1)),
 		     gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
 		     gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
 		     gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
@@ -13002,29 +12974,25 @@ rs6000_generate_compare (enum rtx_code c
 		     gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
 		     gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
 		     gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
-      else if (GET_CODE (rs6000_compare_op1) == UNSPEC
-	       && XINT (rs6000_compare_op1, 1) == UNSPEC_SP_TEST)
+      else if (GET_CODE (op1) == UNSPEC
+	       && XINT (op1, 1) == UNSPEC_SP_TEST)
 	{
-	  rtx op1 = XVECEXP (rs6000_compare_op1, 0, 0);
+	  rtx op1 = XVECEXP (op1, 0, 0);
 	  comp_mode = CCEQmode;
 	  compare_result = gen_reg_rtx (CCEQmode);
 	  if (TARGET_64BIT)
-	    emit_insn (gen_stack_protect_testdi (compare_result,
-						 rs6000_compare_op0, op1));
+	    emit_insn (gen_stack_protect_testdi (compare_result, op0, op1));
 	  else
-	    emit_insn (gen_stack_protect_testsi (compare_result,
-						 rs6000_compare_op0, op1));
+	    emit_insn (gen_stack_protect_testsi (compare_result, op0, op1));
 	}
       else
 	emit_insn (gen_rtx_SET (VOIDmode, compare_result,
-				gen_rtx_COMPARE (comp_mode,
-						 rs6000_compare_op0,
-						 rs6000_compare_op1)));
+				gen_rtx_COMPARE (comp_mode, op0, op1)));
     }
 
   /* Some kinds of FP comparisons need an OR operation;
      under flag_finite_math_only we don't bother.  */
-  if (rs6000_compare_fp_p
+  if (FLOAT_MODE_P (mode)
       && !flag_finite_math_only
       && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
       && (code == LE || code == GE
@@ -13067,16 +13035,17 @@ rs6000_generate_compare (enum rtx_code c
 /* Emit the RTL for an sCOND pattern.  */
 
 void
-rs6000_emit_sCOND (enum rtx_code code, rtx result)
+rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
 {
   rtx condition_rtx;
   enum machine_mode op_mode;
   enum rtx_code cond_code;
+  rtx result = operands[0];
 
-  condition_rtx = rs6000_generate_compare (code);
+  condition_rtx = rs6000_generate_compare (operands[1], mode);
   cond_code = GET_CODE (condition_rtx);
 
-  if (rs6000_compare_fp_p
+  if (FLOAT_MODE_P (mode)
       && !TARGET_FPRS && TARGET_HARD_FLOAT)
     {
       rtx t;
@@ -13111,11 +13080,11 @@ rs6000_emit_sCOND (enum rtx_code code, r
       condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
     }
 
-  op_mode = GET_MODE (rs6000_compare_op0);
+  op_mode = GET_MODE (XEXP (operands[1], 0));
   if (op_mode == VOIDmode)
-    op_mode = GET_MODE (rs6000_compare_op1);
+    op_mode = GET_MODE (XEXP (operands[1], 1));
 
-  if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
+  if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
     {
       PUT_MODE (condition_rtx, DImode);
       convert_move (result, condition_rtx, 0);
@@ -13130,12 +13099,12 @@ rs6000_emit_sCOND (enum rtx_code code, r
 /* Emit a branch of kind CODE to location LOC.  */
 
 void
-rs6000_emit_cbranch (enum rtx_code code, rtx loc)
+rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
 {
   rtx condition_rtx, loc_ref;
 
-  condition_rtx = rs6000_generate_compare (code);
-  loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
+  condition_rtx = rs6000_generate_compare (operands[0], mode);
+  loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
 			       gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
 						     loc_ref, pc_rtx)));
@@ -13581,8 +13550,8 @@ int
 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
 {
   enum rtx_code code = GET_CODE (op);
-  rtx op0 = rs6000_compare_op0;
-  rtx op1 = rs6000_compare_op1;
+  rtx op0 = XEXP (op, 0);
+  rtx op1 = XEXP (op, 1);
   REAL_VALUE_TYPE c1;
   enum machine_mode compare_mode = GET_MODE (op0);
   enum machine_mode result_mode = GET_MODE (dest);
@@ -13602,7 +13571,7 @@ rs6000_emit_cmove (rtx dest, rtx op, rtx
 
   /* First, work out if the hardware can do this at all, or
      if it's too slow....  */
-  if (! rs6000_compare_fp_p)
+  if (!FLOAT_MODE_P (compare_mode))
     {
       if (TARGET_ISEL)
 	return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
@@ -13767,13 +13736,13 @@ rs6000_emit_int_cmove (rtx dest, rtx op,
   rtx condition_rtx, cr;
 
   /* All isel implementations thus far are 32-bits.  */
-  if (GET_MODE (rs6000_compare_op0) != SImode)
+  if (GET_MODE (XEXP (op, 0)) != SImode)
     return 0;
 
   /* We still have to do the compare, because isel doesn't do a
      compare, it just looks at the CRx bits set by a previous compare
      instruction.  */
-  condition_rtx = rs6000_generate_compare (GET_CODE (op));
+  condition_rtx = rs6000_generate_compare (op, SImode);
   cr = XEXP (condition_rtx, 0);
 
   if (GET_MODE (cr) == CCmode)
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(branch cond-optab)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -2020,12 +2020,6 @@ do {								\
 /* Given a condition code and a mode, return the inverse condition.  */
 #define REVERSE_CONDITION(CODE, MODE) rs6000_reverse_condition (MODE, CODE)
 
-/* Define the information needed to generate branch and scc insns.  This is
-   stored from the compare operation.  */
-
-extern GTY(()) rtx rs6000_compare_op0;
-extern GTY(()) rtx rs6000_compare_op1;
-extern int rs6000_compare_fp_p;
 
 /* Control the assembler format that we output.  */
 
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(branch cond-optab)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -11790,262 +11790,80 @@
 ;; signed & unsigned, and one type of branch.
 ;;
 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
-;; insns, and branches.  We store the operands of compares until we see
-;; how it is used.
-(define_expand "cmp<mode>"
-  [(set (cc0)
-        (compare (match_operand:GPR 0 "gpc_reg_operand" "")
-  		 (match_operand:GPR 1 "reg_or_short_operand" "")))]
-  ""
-  "
-{
-  /* Take care of the possibility that operands[1] might be negative but
-     this might be a logical operation.  That insn doesn't exist.  */
-  if (GET_CODE (operands[1]) == CONST_INT
-      && INTVAL (operands[1]) < 0)
-    operands[1] = force_reg (<MODE>mode, operands[1]);
-
-  rs6000_compare_op0 = operands[0];
-  rs6000_compare_op1 = operands[1];
-  rs6000_compare_fp_p = 0;
-  DONE;
-}")
+;; insns, and branches.
 
-(define_expand "cmp<mode>"
-  [(set (cc0) (compare (match_operand:FP 0 "gpc_reg_operand" "")
-		       (match_operand:FP 1 "gpc_reg_operand" "")))]
+(define_expand "cbranch<mode>4"
+  [(use (match_operator 0 "rs6000_cbranch_operator"
+         [(match_operand:GPR 1 "gpc_reg_operand" "")
+          (match_operand:GPR 2 "reg_or_short_operand" "")]))
+   (use (match_operand 3 ""))]
   ""
   "
 {
-  rs6000_compare_op0 = operands[0];
-  rs6000_compare_op1 = operands[1];
-  rs6000_compare_fp_p = 1;
-  DONE;
-}")
-
-(define_expand "beq"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (EQ, operands[0]); DONE; }")
-
-(define_expand "bne"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (NE, operands[0]); DONE; }")
-
-(define_expand "bge"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (GE, operands[0]); DONE; }")
-
-(define_expand "bgt"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (GT, operands[0]); DONE; }")
-
-(define_expand "ble"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (LE, operands[0]); DONE; }")
-
-(define_expand "blt"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (LT, operands[0]); DONE; }")
-
-(define_expand "bgeu"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (GEU, operands[0]); DONE; }")
-
-(define_expand "bgtu"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (GTU, operands[0]); DONE; }")
-
-(define_expand "bleu"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (LEU, operands[0]); DONE; }")
-
-(define_expand "bltu"
-  [(use (match_operand 0 "" ""))]
-  ""
-  "{ rs6000_emit_cbranch (LTU, operands[0]); DONE; }")
-
-(define_expand "bunordered"
-  [(use (match_operand 0 "" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_cbranch (UNORDERED, operands[0]); DONE; }")
-
-(define_expand "bordered"
-  [(use (match_operand 0 "" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_cbranch (ORDERED, operands[0]); DONE; }")
-
-(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"
-  [(use (match_operand 0 "" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_cbranch (LTGT, operands[0]); DONE; }")
-
-;; For SNE, we would prefer that the xor/abs sequence be used for integers.
-;; For SEQ, likewise, except that comparisons with zero should be done
-;; with an scc insns.  However, due to the order that combine see the
-;; resulting insns, we must, in fact, allow SEQ for integers.  Fail in
-;; the cases we don't want to handle.
-(define_expand "seq"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "{ rs6000_emit_sCOND (EQ, operands[0]); DONE; }")
-
-(define_expand "sne"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "
-{
-  if (! rs6000_compare_fp_p)
-    FAIL;
+  /* Take care of the possibility that operands[2] might be negative but
+     this might be a logical operation.  That insn doesn't exist.  */
+  if (GET_CODE (operands[2]) == CONST_INT
+      && INTVAL (operands[2]) < 0)
+    operands[2] = force_reg (<MODE>mode, operands[2]);
 
-  rs6000_emit_sCOND (NE, operands[0]);
+  rs6000_emit_cbranch (<MODE>mode, operands);
   DONE;
 }")
 
-;; A >= 0 is best done the portable way for A an integer.
-(define_expand "sge"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+(define_expand "cbranch<mode>4"
+  [(use (match_operator 0 "rs6000_cbranch_operator"
+         [(match_operand:FP 1 "gpc_reg_operand" "")
+          (match_operand:FP 2 "gpc_reg_operand" "")]))
+   (use (match_operand 3 ""))]
   ""
   "
 {
-  if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
-    FAIL;
-
-  rs6000_emit_sCOND (GE, operands[0]);
+  rs6000_emit_cbranch (<MODE>mode, operands);
   DONE;
 }")
 
-;; A > 0 is best done using the portable sequence, so fail in that case.
-(define_expand "sgt"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+(define_expand "cstore<mode>4"
+  [(use (match_operator 1 "rs6000_cbranch_operator"
+         [(match_operand:GPR 2 "gpc_reg_operand" "")
+          (match_operand:GPR 3 "reg_or_short_operand" "")]))
+   (clobber (match_operand:SI 0 "register_operand"))]
   ""
   "
 {
-  if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
+  /* Take care of the possibility that operands[3] might be negative but
+     this might be a logical operation.  That insn doesn't exist.  */
+  if (GET_CODE (operands[3]) == CONST_INT
+      && INTVAL (operands[3]) < 0)
+    operands[3] = force_reg (<MODE>mode, operands[3]);
+
+  /* For SNE, we would prefer that the xor/abs sequence be used for integers.
+     For SEQ, likewise, except that comparisons with zero should be done
+     with an scc insns.  However, due to the order that combine see the
+     resulting insns, we must, in fact, allow SEQ for integers.  Fail in
+     the cases we don't want to handle or are best handled by portable
+     code.  */
+  if (GET_CODE (operands[1]) == NE)
     FAIL;
-
-  rs6000_emit_sCOND (GT, operands[0]);
-  DONE;
-}")
-
-;; A <= 0 is best done the portable way for A an integer.
-(define_expand "sle"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "
-{
-  if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
+  if ((GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE
+       || GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
+      && operands[3] == const0_rtx)
     FAIL;
-
-  rs6000_emit_sCOND (LE, operands[0]);
+  rs6000_emit_sCOND (<MODE>mode, operands);
   DONE;
 }")
 
-;; A < 0 is best done in the portable way for A an integer.
-(define_expand "slt"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+(define_expand "cstore<mode>4"
+  [(use (match_operator 1 "rs6000_cbranch_operator"
+         [(match_operand:FP 2 "gpc_reg_operand" "")
+          (match_operand:FP 3 "gpc_reg_operand" "")]))
+   (clobber (match_operand:SI 0 "register_operand"))]
   ""
   "
 {
-  if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
-    FAIL;
-
-  rs6000_emit_sCOND (LT, operands[0]);
+  rs6000_emit_sCOND (<MODE>mode, operands);
   DONE;
 }")
 
-(define_expand "sgeu"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "{ rs6000_emit_sCOND (GEU, operands[0]); DONE; }")
-
-(define_expand "sgtu"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "{ rs6000_emit_sCOND (GTU, operands[0]); DONE; }")
-
-(define_expand "sleu"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "{ rs6000_emit_sCOND (LEU, operands[0]); DONE; }")
-
-(define_expand "sltu"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  ""
-  "{ rs6000_emit_sCOND (LTU, operands[0]); DONE; }")
-
-(define_expand "sunordered"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_sCOND (UNORDERED, operands[0]); DONE; }")
-
-(define_expand "sordered"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_sCOND (ORDERED, operands[0]); DONE; }")
-
-(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"
-  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
-  "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
-  "{ rs6000_emit_sCOND (LTGT, operands[0]); DONE; }")
 
 (define_expand "stack_protect_set"
   [(match_operand 0 "memory_operand" "")
@@ -12088,16 +11906,16 @@
    (match_operand 2 "" "")]
   ""
 {
+  rtx test, op0, op1;
 #ifdef TARGET_THREAD_SSP_OFFSET
   rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
   operands[1] = gen_rtx_MEM (Pmode, addr);
 #endif
-  rs6000_compare_op0 = operands[0];
-  rs6000_compare_op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]),
-				       UNSPEC_SP_TEST);
-  rs6000_compare_fp_p = 0;
-  emit_jump_insn (gen_beq (operands[2]));
+  op0 = operands[0];
+  op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
+  test = gen_rtx_EQ (VOIDmode, op0, op1);
+  emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
   DONE;
 })
 
@@ -14668,17 +14486,16 @@
   "{t 31,0,0|trap}"
   [(set_attr "type" "trap")])
 
-(define_expand "conditional_trap"
-  [(trap_if (match_operator 0 "trap_comparison_operator"
-			    [(match_dup 2) (match_dup 3)])
-	    (match_operand 1 "const_int_operand" ""))]
+(define_expand "ctrap<mode>4"
+  [(trap_if (match_operator 0 "ordered_comparison_operator"
+			    [(match_operand:GPR 1 "register_operand")
+			     (match_operand:GPR 2 "reg_or_short_operand")])
+	    (match_operand 3 "zero_constant" ""))]
   ""
-  "if (rs6000_compare_fp_p || operands[1] != const0_rtx) FAIL;
-   operands[2] = rs6000_compare_op0;
-   operands[3] = rs6000_compare_op1;")
+  "")
 
 (define_insn ""
-  [(trap_if (match_operator 0 "trap_comparison_operator"
+  [(trap_if (match_operator 0 "ordered_comparison_operator"
                             [(match_operand:GPR 1 "register_operand" "r")
                              (match_operand:GPR 2 "reg_or_short_operand" "rI")])
 	    (const_int 0))]


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