OSDN Git Service

rx: Uncomplicate fp comparisons.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 24 Jan 2011 16:59:15 +0000 (16:59 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 24 Jan 2011 16:59:15 +0000 (16:59 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@169169 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rx/predicates.md
gcc/config/rx/rx-protos.h
gcc/config/rx/rx.c
gcc/config/rx/rx.md

index d13b627..26edfae 100644 (file)
@@ -1,3 +1,16 @@
+2011-01-24  Richard Henderson  <rth@redhat.com>
+
+       * config/rx/predicates.md (rx_fp_comparison_operator): Don't accept
+       compound unordered comparisons.
+       * config/rx/rx.c (rx_split_fp_compare): Remove.
+       * config/rx/rx-protos.h: Update.
+       * config/rx/rx.md (gcc_conds, rx_conds): Remove.
+       (cbranchsf4): Don't call rx_split_fp_compare.
+       (*cbranchsf4): Use rx_split_cbranch.
+       (*cmpsf): Don't accept "i" constraint.
+       (*conditional_branch): Only valid after reload.
+       (cstoresf4): Merge expander with insn.  Don't call rx_split_fp_compare.
+
 2011-01-24  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        PR target/47385
index 608fca5..77b3353 100644 (file)
   (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"
index 3c3f2d4..ad97c59 100644 (file)
@@ -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
index 9855c62..f2429b7 100644 (file)
@@ -2665,68 +2665,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.  */
 
index 11dc1f3..9ab5f17 100644 (file)
 (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)
 (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"
   "&& 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;
 })
 
   [(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")
            [(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.
   [(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[1]), &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;
 })