No need to special-case this in several places anymore.

Cc: David Edelsohn <dje....@gmail.com>
---
        * config/rs6000/rs6000.c (num_insns_constant): Remove test
        for rs6000_is_valid_and_mask.
        (genimm_ppc::exam_mask): New.
        (genimm_ppc::exam_search): Use it.
        (genimm_ppc::generate): Handle AND.
        * config/rs6000/rs6000.md (rs6000_is_valid_and_mask splitter): Remove.
---
 gcc/config/rs6000/rs6000.c  | 27 ++++++++++++++++++++++-----
 gcc/config/rs6000/rs6000.md | 15 ---------------
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index a864a7e..6af5cf3 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -5246,11 +5246,7 @@ num_insns_constant (rtx op, machine_mode mode)
   switch (GET_CODE (op))
     {
     case CONST_INT:
-      if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
-         && rs6000_is_valid_and_mask (op, mode))
-       return 2;
-      else
-       return num_insns_constant_wide (INTVAL (op));
+      return num_insns_constant_wide (INTVAL (op));
 
     case CONST_WIDE_INT:
       {
@@ -8062,6 +8058,7 @@ struct genimm_ppc : genimm_base <rtx_code, 5>
 
   bool exam_simple (HOST_WIDE_INT c, machine_mode, int budget);
   bool exam_sub (HOST_WIDE_INT c, int budget);
+  bool exam_mask (HOST_WIDE_INT c, HOST_WIDE_INT mask, int sub_budget);
   bool exam_search (HOST_WIDE_INT c, int budget);
   void exam_full (HOST_WIDE_INT c);
   void generate (rtx dest, machine_mode mode) const;
@@ -8125,6 +8122,21 @@ genimm_ppc::exam_sub (HOST_WIDE_INT c, int budget)
          || (budget > 1 && exam_search (c, budget)));
 }
 
+/* If we are able to construct C within SUB_BUDGET + 1,
+   return true and fill in the recipe.  */
+
+bool
+genimm_ppc::exam_mask (HOST_WIDE_INT c, HOST_WIDE_INT mask, int sub_budget)
+{
+  if (rs6000_is_valid_and_mask_wide (mask, DImode)
+      && exam_sub (c, sub_budget))
+    {
+      opN (AND, mask); /* RLDICL, et al */
+      return true;
+    }
+  return false;
+}
+
 /* The body of the recursive search for C within BUDGET.
    We've already failed exam_simple.  */
 
@@ -8157,6 +8169,10 @@ genimm_ppc::exam_search (HOST_WIDE_INT c, int budget)
        }
     }
 
+  /* If C is a mask itself, apply it to all ones.  */
+  if (exam_mask (-1, c, sub_budget))
+    return true;
+
   /* Shift the constant left.  */
   test = HOST_WIDE_INT_UC (0xffffffff00000000);
   if ((c & test) == c && exam_sub (c >> 32, sub_budget))
@@ -8209,6 +8225,7 @@ genimm_ppc::generate (rtx dest, machine_mode mode) const
          x = op2;
          break;
        case PLUS:
+       case AND:
        case IOR:
        case ASHIFT:
          x = gen_rtx_fmt_ee (r, mode, op1, op2);
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 527ad98..9161931 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -7106,21 +7106,6 @@
   [(set_attr "type" 
"store,load,*,*,*,*,fpstore,fpload,fp,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,vecsimple")
    (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")])
 
-; Some DImode loads are best done as a load of -1 followed by a mask
-; instruction.
-(define_split
-  [(set (match_operand:DI 0 "gpc_reg_operand")
-       (match_operand:DI 1 "const_int_operand"))]
-  "TARGET_POWERPC64
-   && num_insns_constant (operands[1], DImode) > 1
-   && rs6000_is_valid_and_mask (operands[1], DImode)"
-  [(set (match_dup 0)
-       (const_int -1))
-   (set (match_dup 0)
-       (and:DI (match_dup 0)
-               (match_dup 1)))]
-  "")
-
 ;; Split a load of a large constant into the appropriate five-instruction
 ;; sequence.  Handle anything in a constant number of insns.
 ;; When non-easy constants can go in the TOC, this should use
-- 
2.4.3

Reply via email to