2014-08-10 Yvan Roux <yvan.roux@linaro.org>
authoryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 10 Aug 2014 15:28:41 +0000 (15:28 +0000)
committeryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 10 Aug 2014 15:28:41 +0000 (15:28 +0000)
Backport from trunk r212142, r212225.
2014-07-02  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

* config/aarch64/aarch64.c (aarch64_expand_vec_perm): Delete unused
variable i.

2014-06-30  Alan Lawrence  <alan.lawrence@arm.com>

* config/aarch64/aarch64-simd.md (vec_perm): Enable for bigendian.
* config/aarch64/aarch64.c (aarch64_expand_vec_perm): Remove assert
against bigendian and adjust indices.

git-svn-id: svn://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@213793 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog.linaro
gcc/config/aarch64/aarch64-simd.md
gcc/config/aarch64/aarch64.c

index 4f8fbe0..0c03cc8 100644 (file)
@@ -1,5 +1,19 @@
 2014-08-10 Yvan Roux  <yvan.roux@linaro.org>
 
+       Backport from trunk r212142, r212225.
+       2014-07-02  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/aarch64/aarch64.c (aarch64_expand_vec_perm): Delete unused
+       variable i.
+
+       2014-06-30  Alan Lawrence  <alan.lawrence@arm.com>
+
+       * config/aarch64/aarch64-simd.md (vec_perm): Enable for bigendian.
+       * config/aarch64/aarch64.c (aarch64_expand_vec_perm): Remove assert
+       against bigendian and adjust indices.
+
+2014-08-10 Yvan Roux  <yvan.roux@linaro.org>
+
        Backport from trunk r211779.
        2014-06-18  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
index 372b260..643861e 100644 (file)
    (match_operand:VB 1 "register_operand")
    (match_operand:VB 2 "register_operand")
    (match_operand:VB 3 "register_operand")]
-  "TARGET_SIMD && !BYTES_BIG_ENDIAN"
+  "TARGET_SIMD"
 {
   aarch64_expand_vec_perm (operands[0], operands[1],
                           operands[2], operands[3]);
index be8da5f..37979fb 100644 (file)
@@ -8736,20 +8736,26 @@ void
 aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel)
 {
   enum machine_mode vmode = GET_MODE (target);
-  unsigned int i, nelt = GET_MODE_NUNITS (vmode);
+  unsigned int nelt = GET_MODE_NUNITS (vmode);
   bool one_vector_p = rtx_equal_p (op0, op1);
-  rtx rmask[MAX_VECT_LEN], mask;
-
-  gcc_checking_assert (!BYTES_BIG_ENDIAN);
+  rtx mask;
 
   /* The TBL instruction does not use a modulo index, so we must take care
      of that ourselves.  */
-  mask = GEN_INT (one_vector_p ? nelt - 1 : 2 * nelt - 1);
-  for (i = 0; i < nelt; ++i)
-    rmask[i] = mask;
-  mask = gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (nelt, rmask));
+  mask = aarch64_simd_gen_const_vector_dup (vmode,
+      one_vector_p ? nelt - 1 : 2 * nelt - 1);
   sel = expand_simple_binop (vmode, AND, sel, mask, NULL, 0, OPTAB_LIB_WIDEN);
 
+  /* For big-endian, we also need to reverse the index within the vector
+     (but not which vector).  */
+  if (BYTES_BIG_ENDIAN)
+    {
+      /* If one_vector_p, mask is a vector of (nelt - 1)'s already.  */
+      if (!one_vector_p)
+        mask = aarch64_simd_gen_const_vector_dup (vmode, nelt - 1);
+      sel = expand_simple_binop (vmode, XOR, sel, mask,
+                                NULL, 0, OPTAB_LIB_WIDEN);
+    }
   aarch64_expand_vec_perm_1 (target, op0, op1, sel);
 }