diff mbox

[03/14] rx: Cleanup conditional branches.

Message ID 4D39C2BB.6000706@redhat.com
State New
Headers show

Commit Message

Richard Henderson Jan. 21, 2011, 5:30 p.m. UTC
On 01/19/2011 08:43 AM, Paolo Bonzini wrote:
> On 01/19/2011 05:22 PM, Richard Henderson wrote:
>> Consider all of this deleted, and rx_fp_compare_operator reduced to
>> the bare essentials -- un/ordered + the non-swapping normal ops.
> 
> I think you're getting everything else for free anyway (especially if you leave the non-swapping, native unordered ops in).
> 
> Paolo

This does in fact seem to work.  Ok, Nick?


r~
commit 9db9d735c88d95d5a414bfb382628cb7150e6cb2
Author: Richard Henderson <rth@twiddle.net>
Date:   Thu Jan 20 07:24:13 2011 -0800

    rx: Uncomplicate fp comparisons.
    
    It turns out that the middle-end will happily take care of
    doing the swapping and splitting of compound fp comparisons.
    No need for us to replicate that here.

Comments

Nick Clifton Jan. 24, 2011, 3:56 p.m. UTC | #1
Hi Richard, Hi Paolo,

> This does in fact seem to work.  Ok, Nick?

OK.

Cheers
   Nick
diff mbox

Patch

diff --git a/gcc/config/rx/predicates.md b/gcc/config/rx/predicates.md
index 608fca5..77b3353 100644
--- a/gcc/config/rx/predicates.md
+++ b/gcc/config/rx/predicates.md
@@ -287,9 +287,9 @@ 
   (match_code "eq,ne,lt,ge")
 )
 
-;; GT, LE, UNLE, UNGT omitted due to operand swap required.
+;; GT and LE omitted due to operand swap required.
 (define_predicate "rx_fp_comparison_operator"
-  (match_code "eq,ne,lt,ge,ordered,unordered,uneq,unlt,unge,ltgt")
+  (match_code "eq,ne,lt,ge,ordered,unordered")
 )
 
 (define_predicate "rshift_operator"
diff --git a/gcc/config/rx/rx-protos.h b/gcc/config/rx/rx-protos.h
index 3c3f2d4..ad97c59 100644
--- a/gcc/config/rx/rx-protos.h
+++ b/gcc/config/rx/rx-protos.h
@@ -39,7 +39,6 @@  extern bool 		rx_is_mode_dependent_addr (rtx);
 extern bool		rx_is_restricted_memory_address (rtx, Mmode);
 extern void		rx_notice_update_cc (rtx body, rtx insn);
 extern void		rx_split_cbranch (Mmode, Rcode, rtx, rtx, rtx);
-extern bool		rx_split_fp_compare (Rcode, Rcode *, Rcode *);
 extern Mmode		rx_select_cc_mode (Rcode, rtx, rtx);
 extern bool		rx_match_ccmode (rtx, Mmode);
 #endif
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index c37ddcc..4474f70 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -2627,68 +2627,6 @@  rx_select_cc_mode (enum rtx_code cmp_code, rtx x, rtx y ATTRIBUTE_UNUSED)
   return mode_from_flags (flags_from_code (cmp_code));
 }
 
-/* Split the floating-point comparison IN into individual comparisons
-   O1 and O2.  O2 may be UNKNOWN if there is no second comparison.
-   Return true iff the comparison operands must be swapped.  */
-
-bool
-rx_split_fp_compare (enum rtx_code in, enum rtx_code *o1, enum rtx_code *o2)
-{
-  enum rtx_code cmp1 = in, cmp2 = UNKNOWN;
-  bool swap = false;
-
-  switch (in)
-    {
-    case ORDERED:
-    case UNORDERED:
-    case LT:
-    case GE:
-    case EQ:
-    case NE:
-      break;
-
-    case GT:
-    case LE:
-      cmp1 = swap_condition (cmp1);
-      swap = true;
-      break;
-
-    case UNEQ:
-      cmp1 = UNORDERED;
-      cmp2 = EQ;
-      break;
-    case UNLT:
-      cmp1 = UNORDERED;
-      cmp2 = LT;
-      break;
-    case UNGE:
-      cmp1 = UNORDERED;
-      cmp2 = GE;
-      break;
-    case UNLE:
-      cmp1 = UNORDERED;
-      cmp2 = GT;
-      swap = true;
-      break;
-    case UNGT:
-      cmp1 = UNORDERED;
-      cmp2 = LE;
-      swap = true;
-      break;
-    case LTGT:
-      cmp1 = ORDERED;
-      cmp2 = NE;
-      break;
-
-    default:
-      gcc_unreachable ();
-    }
-
-  *o1 = cmp1;
-  *o2 = cmp2;
-  return swap;
-}
-
 /* Split the conditional branch.  Emit (COMPARE C1 C2) into CC_REG with
    CC_MODE, and use that in branches based on that compare.  */
 
diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md
index d8cd66d..0df92d6 100644
--- a/gcc/config/rx/rx.md
+++ b/gcc/config/rx/rx.md
@@ -29,16 +29,6 @@ 
 (define_mode_iterator register_modes
   [(SF "ALLOW_RX_FPU_INSNS") (SI "") (HI "") (QI "")])
 
-
-;; Used to map RX condition names to GCC
-;; condition names for builtin instructions.
-(define_code_iterator gcc_conds [eq ne gt ge lt le gtu geu ltu leu
-				unge unlt uneq ltgt])
-(define_code_attr rx_conds [(eq "eq") (ne "ne") (gt "gt") (ge "ge") (lt "lt")
-			    (le "le") (gtu "gtu") (geu "geu") (ltu "ltu")
-			    (leu "leu") (unge "pz") (unlt "n") (uneq "o")
-			    (ltgt "no")])
-
 (define_constants
   [
    (SP_REG 0)
@@ -258,46 +248,20 @@ 
 (define_expand "cbranchsf4"
   [(set (pc)
 	(if_then_else
-	  (match_operator 0 "comparison_operator"
+	  (match_operator 0 "rx_fp_comparison_operator"
 	    [(match_operand:SF 1 "register_operand")
-	     (match_operand:SF 2 "register_operand")])
-          (label_ref (match_operand 3 ""))
+	     (match_operand:SF 2 "rx_source_operand")])
+	  (label_ref (match_operand 3 ""))
 	  (pc)))]
   "ALLOW_RX_FPU_INSNS"
-{
-  enum rtx_code cmp1, cmp2;
-
-  /* If the comparison needs swapping of operands, do that now.
-     Do not split the comparison in two yet.  */
-  if (rx_split_fp_compare (GET_CODE (operands[0]), &cmp1, &cmp2))
-    {
-      rtx op1, op2;
-
-      if (cmp2 != UNKNOWN)
-	{
-	  gcc_assert (cmp1 == UNORDERED);
-	  if (cmp2 == GT)
-	    cmp1 = UNGT;
-	  else if (cmp2 == LE)
-	    cmp1 = UNLE;
-	  else
-	    gcc_unreachable ();
-	}
-
-      op1 = operands[2];
-      op2 = operands[1];
-      operands[0] = gen_rtx_fmt_ee (cmp1, VOIDmode, op1, op2);
-      operands[1] = op1;
-      operands[2] = op2;
-    }
-})
+)
 
 (define_insn_and_split "*cbranchsf4"
   [(set (pc)
 	(if_then_else
 	  (match_operator 3 "rx_fp_comparison_operator"
 	    [(match_operand:SF  0 "register_operand"  "r")
-	     (match_operand:SF  1 "rx_source_operand" "rFiQ")])
+	     (match_operand:SF  1 "rx_source_operand" "rFQ")])
 	  (match_operand        2 "label_ref_operand" "")
 	  (pc)))]
   "ALLOW_RX_FPU_INSNS"
@@ -305,46 +269,8 @@ 
   "&& reload_completed"
   [(const_int 0)]
 {
-  enum rtx_code cmp0, cmp1, cmp2;
-  rtx flags, lab1, lab2, over, x;
-  bool swap;
-
-  cmp0 = GET_CODE (operands[3]);
-  swap = rx_split_fp_compare (cmp0, &cmp1, &cmp2);
-  gcc_assert (!swap);
-
-  flags = gen_rtx_REG (CC_Fmode, CC_REG);
-  x = gen_rtx_COMPARE (CC_Fmode, operands[0], operands[1]);
-  x = gen_rtx_SET (VOIDmode, flags, x);
-  emit_insn (x);
-
-  over = NULL;
-  lab1 = lab2 = operands[2];
-
-  /* The one case of LTGT needs to be split into cmp1 && cmp2.  */
-  if (cmp0 == LTGT)
-    {
-      over = gen_label_rtx ();
-      lab1 = gen_rtx_LABEL_REF (VOIDmode, over);
-      cmp1 = reverse_condition_maybe_unordered (cmp1);
-    }
-
-  /* Otherwise we split into cmp1 || cmp2.  */
-  x = gen_rtx_fmt_ee (cmp1, VOIDmode, flags, const0_rtx);
-  x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, lab1, pc_rtx);
-  x = gen_rtx_SET (VOIDmode, pc_rtx, x);
-  emit_jump_insn (x);
-
-  if (cmp2 != UNKNOWN)
-    {
-      x = gen_rtx_fmt_ee (cmp2, VOIDmode, flags, const0_rtx);
-      x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, lab2, pc_rtx);
-      x = gen_rtx_SET (VOIDmode, pc_rtx, x);
-      emit_jump_insn (x);
-    }
-
-  if (over)
-    emit_label (over);
+  rx_split_cbranch (CC_Fmode, GET_CODE (operands[3]),
+		    operands[0], operands[1], operands[2]);
   DONE;
 })
 
@@ -352,7 +278,7 @@ 
   [(set (reg:CC_F CC_REG)
 	(compare:CC_F
 	  (match_operand:SF 0 "register_operand"  "r,r,r")
-	  (match_operand:SF 1 "rx_source_operand" "r,iF,Q")))]
+	  (match_operand:SF 1 "rx_source_operand" "r,F,Q")))]
   "ALLOW_RX_FPU_INSNS && reload_completed"
   "fcmp\t%1, %0"
   [(set_attr "timings" "11,11,33")
@@ -368,7 +294,7 @@ 
 	    [(reg CC_REG) (const_int 0)])
 	  (label_ref (match_operand 0 "" ""))
 	  (pc)))]
-  ""
+  "reload_completed"
   "b%B1\t%0"
   [(set_attr "length" "8")    ;; This length is wrong, but it is
                               ;; too hard to compute statically.
@@ -739,95 +665,26 @@ 
   [(set_attr "length" "3")]
 )
 
-(define_expand "cstoresf4"
-  [(parallel [(set (match_operand:SI 0 "register_operand" "")
-		   (match_operator:SI 1 "comparison_operator"
-		    [(match_operand:SF 2 "register_operand" "")
-		     (match_operand:SF 3 "register_operand" "")]))
-	     (clobber (match_scratch:SI 4))])]
-  "ALLOW_RX_FPU_INSNS"
-{
-  enum rtx_code cmp1, cmp2;
-
-  /* If the comparison needs swapping of operands, do that now.
-     Do not split the comparison in two yet.  */
-  if (rx_split_fp_compare (GET_CODE (operands[0]), &cmp1, &cmp2))
-    {
-      rtx op2, op3;
-
-      if (cmp2 != UNKNOWN)
-	{
-	  gcc_assert (cmp1 == UNORDERED);
-	  if (cmp2 == GT)
-	    cmp1 = UNGT;
-	  else if (cmp2 == LE)
-	    cmp1 = UNLE;
-	  else
-	    gcc_unreachable ();
-	}
-
-      op2 = operands[3];
-      op3 = operands[2];
-      operands[0] = gen_rtx_fmt_ee (cmp1, VOIDmode, op2, op3);
-      operands[2] = op2;
-      operands[3] = op3;
-    }
-})
-
-(define_insn_and_split "*cstoresf4"
+(define_insn_and_split "cstoresf4"
   [(set (match_operand:SI 0 "register_operand" "=r")
-	(match_operator:SI 4 "rx_fp_comparison_operator"
+	(match_operator:SI 1 "rx_fp_comparison_operator"
 	 [(match_operand:SF 2 "register_operand" "r")
-	  (match_operand:SF 3 "rx_source_operand" "rFiQ")]))
-   (clobber (match_scratch:SI 1 "=r"))]
+	  (match_operand:SF 3 "rx_source_operand" "rFQ")]))]
   "ALLOW_RX_FPU_INSNS"
   "#"
   "reload_completed"
   [(const_int 0)]
 {
-  enum rtx_code cmp0, cmp1, cmp2;
   rtx flags, x;
-  bool swap;
-
-  cmp0 = GET_CODE (operands[4]);
-  swap = rx_split_fp_compare (cmp0, &cmp1, &cmp2);
-  gcc_assert (!swap);
 
   flags = gen_rtx_REG (CC_Fmode, CC_REG);
   x = gen_rtx_COMPARE (CC_Fmode, operands[2], operands[3]);
   x = gen_rtx_SET (VOIDmode, flags, x);
   emit_insn (x);
 
-  x = gen_rtx_fmt_ee (cmp1, SImode, flags, const0_rtx);
+  x = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, flags, const0_rtx);
   x = gen_rtx_SET (VOIDmode, operands[0], x);
   emit_insn (x);
-
-  if (cmp0 == LTGT)
-    {
-      /* The one case of LTGT needs to be split into ORDERED && NE.  */
-      x = gen_rtx_fmt_ee (EQ, VOIDmode, flags, const0_rtx);
-      x = gen_rtx_IF_THEN_ELSE (SImode, x, const0_rtx, operands[0]);
-      x = gen_rtx_SET (VOIDmode, operands[0], x);
-      emit_insn (x);
-    }
-  else if (cmp2 == EQ || cmp2 == NE)
-    {
-      /* Oring the two flags can be performed with a movcc operation.  */
-      x = gen_rtx_fmt_ee (cmp2, VOIDmode, flags, const0_rtx);
-      x = gen_rtx_IF_THEN_ELSE (SImode, x, const1_rtx, operands[0]);
-      x = gen_rtx_SET (VOIDmode, operands[0], x);
-      emit_insn (x);
-    }
-  else if (cmp2 != UNKNOWN)
-    {
-      /* We can't use movcc, but need to or in another compare.
-	 Do this by storing the second operation into the scratch.  */
-      x = gen_rtx_fmt_ee (cmp2, SImode, flags, const0_rtx);
-      x = gen_rtx_SET (VOIDmode, operands[1], x);
-      emit_insn (x);
-
-      emit_insn (gen_iorsi3 (operands[0], operands[0], operands[1]));
-    }
   DONE;
 })