rs6000.c (output_vec_const_move): Find all cases of EASY_VECTOR_15_ADD_SELF.
authorHartmut Penner <hpenner@de.ibm.com>
Tue, 30 Mar 2004 08:25:30 +0000 (08:25 +0000)
committerHartmut Penner <hpenner@gcc.gnu.org>
Tue, 30 Mar 2004 08:25:30 +0000 (08:25 +0000)
        * config/rs6000/rs6000.c (output_vec_const_move):
        Find all cases of EASY_VECTOR_15_ADD_SELF.
        (easy_vector_constant_add_self): Accept
        all vector constant loadable by vsplt* and vadd*.
        (easy_vector_same): Use easy_vector_splat_const.
        (easy_vector_const): Use easy_vector_splat_const.
        (easy_vector_splat_const): New function.
        (gen_easy_vector_constant_add_self): New function.

        * config/rs6000/rs6000-protos.c (gen_easy_vector_constant_add_self):
        New prototype.

        * config/rs6000/altivec.md (movv4si splitter): Change to
        emit move insn with halfed vector constant.
        (*movv8hi splitter): Likewise.
        (*movv16qi splitter): Likewise.

From-SVN: r80077

gcc/ChangeLog
gcc/config/rs6000/altivec.md
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c

index e0b5a3526c861295c43c42a8813e926b37709986..5b197fc1a449427c964cba0aa8df61644aabf8da 100644 (file)
@@ -1,3 +1,22 @@
+2004-03-30  Hartmut Penner  <hpenner@de.ibm.com>
+
+        * config/rs6000/rs6000.c (output_vec_const_move):
+        Find all cases of EASY_VECTOR_15_ADD_SELF.
+        (easy_vector_constant_add_self): Accept
+        all vector constant loadable by vsplt* and vadd*.
+       (easy_vector_same): Use easy_vector_splat_const.
+       (easy_vector_const): Use easy_vector_splat_const.
+        (easy_vector_splat_const): New function.
+       (gen_easy_vector_constant_add_self): New function.
+       
+       * config/rs6000/rs6000-protos.c (gen_easy_vector_constant_add_self):
+       New prototype.
+
+        * config/rs6000/altivec.md (movv4si splitter): Change to
+       emit move insn with halfed vector constant.
+       (*movv8hi splitter): Likewise.
+       (*movv16qi splitter): Likewise.
+       
 2004-03-30  Hartmut Penner  <hpenner@de.ibm.com>
 
        PR 11591        
index 684a5d4c4b97cf24dda742aeda3fa65085b61973..3e27a1b86c21617f360f4bc6761a1df4770a0e0b 100644 (file)
   [(set (match_operand:V4SI 0 "altivec_register_operand" "")
        (match_operand:V4SI 1 "easy_vector_constant_add_self" ""))]
   "TARGET_ALTIVEC && reload_completed"
-  [(set (match_dup 0)
-       (unspec:V4SI [(match_dup 3)] UNSPEC_VSPLTISW))
+  [(set (match_dup 0) (match_dup 3))
    (set (match_dup 0)
        (plus:V4SI (match_dup 0)
                   (match_dup 0)))]
   "
-{ operands[3] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 0)) >> 1); }")
+{ 
+  operands[3] = gen_easy_vector_constant_add_self (operands[1]);
+}")    
 
 (define_expand "movv8hi"
   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
   [(set (match_operand:V8HI 0 "altivec_register_operand" "")
        (match_operand:V8HI 1 "easy_vector_constant_add_self" ""))]
   "TARGET_ALTIVEC && reload_completed"
-  [(set (match_dup 0)
-       (unspec:V8HI [(match_dup 3)] UNSPEC_VSPLTISH))
+  [(set (match_dup 0) (match_dup 3))
    (set (match_dup 0)
        (plus:V8HI (match_dup 0)
                   (match_dup 0)))]
   "
-{ operands[3] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 0)) >> 1); }")
+{
+  operands[3] = gen_easy_vector_constant_add_self (operands[1]);
+}")
 
 (define_expand "movv16qi"
   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
   [(set (match_operand:V16QI 0 "altivec_register_operand" "")
        (match_operand:V16QI 1 "easy_vector_constant_add_self" ""))]
   "TARGET_ALTIVEC && reload_completed"
-  [(set (match_dup 0)
-       (unspec:V16QI [(match_dup 3)] UNSPEC_VSPLTISB))
+  [(set (match_dup 0) (match_dup 3))
    (set (match_dup 0)
        (plus:V16QI (match_dup 0)
                   (match_dup 0)))]
   "
-{ operands[3] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 0)) >> 1); }")
+{
+  operands[3] = gen_easy_vector_constant_add_self (operands[1]);
+}")
 
 (define_expand "movv4sf"
   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
index 5c778e15f05bd5fc042db019388297291925eee1..95a506b4fcc4b371ea08e3b67993b1ea928f5f26 100644 (file)
@@ -57,6 +57,7 @@ extern int got_no_const_operand (rtx, enum machine_mode);
 extern int num_insns_constant (rtx, enum machine_mode);
 extern int easy_fp_constant (rtx, enum machine_mode);
 extern int easy_vector_constant (rtx, enum machine_mode);
+extern rtx gen_easy_vector_constant_add_self (rtx);
 extern const char *output_vec_const_move (rtx *);
 extern int zero_fp_constant (rtx, enum machine_mode);
 extern int zero_constant (rtx, enum machine_mode);
index c8854b093281c40c24454a67aaa5aa8e244951f9..bd649fa5695b3498d1a141be129d40abe76f0311 100644 (file)
 #define TARGET_NO_PROTOTYPE 0
 #endif
 
-#define EASY_VECTOR_15(n, x, y) ((n) >= -16 && (n) <= 15 \
-                                && easy_vector_same (x, y))
-
-#define EASY_VECTOR_15_ADD_SELF(n, x, y) ((n) >= 0x10 && (n) <= 0x1e \
-                                          && !((n) & 1)              \
-                                         && easy_vector_same (x, y))
+#define EASY_VECTOR_15(n) ((n) >= -16 && (n) <= 15)
+#define EASY_VECTOR_15_ADD_SELF(n) ((n) >= 0x10 && (n) <= 0x1e \
+                                          && !((n) & 1))
 
 #define min(A,B)       ((A) < (B) ? (A) : (B))
 #define max(A,B)       ((A) > (B) ? (A) : (B))
@@ -411,6 +408,7 @@ static void is_altivec_return_reg (rtx, void *);
 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
 int easy_vector_constant (rtx, enum machine_mode);
 static int easy_vector_same (rtx, enum machine_mode);
+static int easy_vector_splat_const (int, enum machine_mode);
 static bool is_ev64_opaque_type (tree);
 static rtx rs6000_dwarf_register_span (rtx);
 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
@@ -1677,6 +1675,38 @@ easy_fp_constant (rtx op, enum machine_mode mode)
     abort ();
 }
 
+/* Returns the constant for the splat instrunction, if exists.  */
+
+static int
+easy_vector_splat_const (int cst, enum machine_mode mode)
+{
+  switch (mode) 
+    {
+    case V4SImode:
+      if (EASY_VECTOR_15 (cst) 
+         || EASY_VECTOR_15_ADD_SELF (cst)) 
+       return cst;
+      if ((cst & 0xffff) != ((cst >> 16) & 0xffff))
+       break;
+      cst = cst >> 16;
+    case V8HImode:
+      if (EASY_VECTOR_15 (cst) 
+         || EASY_VECTOR_15_ADD_SELF (cst)) 
+       return cst;
+      if ((cst & 0xff) != ((cst >> 8) & 0xff))
+       break;
+      cst = cst >> 8;
+    case V16QImode:
+         if (EASY_VECTOR_15 (cst) 
+             || EASY_VECTOR_15_ADD_SELF (cst)) 
+           return cst;
+    default: 
+      break;
+    }
+  return 0;
+}
+
+
 /* Return nonzero if all elements of a vector have the same value.  */
 
 static int
@@ -1690,7 +1720,7 @@ easy_vector_same (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
   for (i = 1; i < units; ++i)
     if (INTVAL (CONST_VECTOR_ELT (op, i)) != cst)
       break;
-  if (i == units)
+  if (i == units && easy_vector_splat_const (cst, mode))
     return 1;
   return 0;
 }
@@ -1736,31 +1766,14 @@ easy_vector_constant (rtx op, enum machine_mode mode)
       && cst2 >= -0x7fff && cst2 <= 0x7fff)
     return 1;
 
-  if (TARGET_ALTIVEC)
-    switch (mode) 
-      {
-      case V4SImode:
-       if (EASY_VECTOR_15 (cst, op, mode))
-         return 1;
-       if ((cst & 0xffff) != ((cst >> 16) & 0xffff))
-         break;
-       cst = cst >> 16;
-      case V8HImode:
-       if (EASY_VECTOR_15 (cst, op, mode))
-         return 1;
-       if ((cst & 0xff) != ((cst >> 8) & 0xff))
-         break;
-       cst = cst >> 8;
-      case V16QImode:
-       if (EASY_VECTOR_15 (cst, op, mode))
-         return 1;
-      default: 
-       break;
-      }
-
-  if (TARGET_ALTIVEC && EASY_VECTOR_15_ADD_SELF (cst, op, mode))
-    return 1;
-
+  if (TARGET_ALTIVEC 
+      && easy_vector_same (op, mode))
+    {
+      cst = easy_vector_splat_const (cst, mode);
+      if (EASY_VECTOR_15_ADD_SELF (cst) 
+         || EASY_VECTOR_15 (cst))
+       return 1;
+    }  
   return 0;
 }
 
@@ -1770,13 +1783,31 @@ int
 easy_vector_constant_add_self (rtx op, enum machine_mode mode)
 {
   int cst;
+  if (TARGET_ALTIVEC
+      && GET_CODE (op) == CONST_VECTOR
+      && easy_vector_same (op, mode))
+    {
+      cst = easy_vector_splat_const (INTVAL (CONST_VECTOR_ELT (op, 0)), mode);
+      if (EASY_VECTOR_15_ADD_SELF (cst))
+       return 1;  
+    }
+  return 0;
+}
 
-  if (!easy_vector_constant (op, mode))
-    return 0;
+/* Generate easy_vector_constant out of a easy_vector_constant_add_self.  */
 
-  cst = INTVAL (CONST_VECTOR_ELT (op, 0));
+rtx 
+gen_easy_vector_constant_add_self (rtx op)
+{
+  int i, units;
+  rtvec v;
+  units = GET_MODE_NUNITS (GET_MODE (op));
+  v = rtvec_alloc (units);
 
-  return TARGET_ALTIVEC && EASY_VECTOR_15_ADD_SELF (cst, op, mode);
+  for (i = 0; i < units; i++)
+    RTVEC_ELT (v, i) = 
+      GEN_INT (INTVAL (CONST_VECTOR_ELT (op, i)) >> 1);
+  return gen_rtx_raw_CONST_VECTOR (GET_MODE (op), v);
 }
 
 const char *
@@ -1797,33 +1828,37 @@ output_vec_const_move (rtx *operands)
     {
       if (zero_constant (vec, mode))
        return "vxor %0,%0,%0";
-      else if (EASY_VECTOR_15_ADD_SELF (cst, vec, mode))
-       return "#";
       else if (easy_vector_constant (vec, mode))
        {
          operands[1] = GEN_INT (cst);
          switch (mode)
            {
            case V4SImode:
-             if (EASY_VECTOR_15 (cst, vec, mode))
+             if (EASY_VECTOR_15 (cst))
                {
                  operands[1] = GEN_INT (cst);
                  return "vspltisw %0,%1";
                }
+             else if (EASY_VECTOR_15_ADD_SELF (cst))
+               return "#";
              cst = cst >> 16;
            case V8HImode:
-             if (EASY_VECTOR_15 (cst, vec, mode))
+             if (EASY_VECTOR_15 (cst))
                {
                  operands[1] = GEN_INT (cst);
                  return "vspltish %0,%1";
                }
+             else if (EASY_VECTOR_15_ADD_SELF (cst))
+               return "#";
              cst = cst >> 8;
            case V16QImode:
-             if (EASY_VECTOR_15 (cst, vec, mode))
+             if (EASY_VECTOR_15 (cst))
                {
                  operands[1] = GEN_INT (cst);
                  return "vspltisb %0,%1";
                }
+             else if (EASY_VECTOR_15_ADD_SELF (cst))
+               return "#";
            default:
              abort ();
            }