diff options
author | Alan Lawrence <alan.lawrence@arm.com> | 2014-06-30 11:07:58 +0000 |
---|---|---|
committer | Alan Lawrence <alalaw01@gcc.gnu.org> | 2014-06-30 11:07:58 +0000 |
commit | f7c4e5b837b22f774cb765ea4f57cd7b06d2af75 (patch) | |
tree | 6406945af69eada3b6bc32edd5a6f06b915de25c /gcc | |
parent | 10e4b63297f2dab38e5867991762419ea7fb9daa (diff) | |
download | gcc-f7c4e5b837b22f774cb765ea4f57cd7b06d2af75.zip gcc-f7c4e5b837b22f774cb765ea4f57cd7b06d2af75.tar.gz gcc-f7c4e5b837b22f774cb765ea4f57cd7b06d2af75.tar.bz2 |
[AArch64] fix and enable non-const shuffle for bigendian using TBL instruction
* 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.
From-SVN: r212142
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-simd.md | 2 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 20 |
3 files changed, 20 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d1b5dc3..463035d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +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-06-30 Gerald Pfeifer <gerald@pfeifer.com> * doc/install.texi (Specific, aarch64*-*-*): Fix markup. Reword a bit. diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 1c32f0c..f03d647 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -4361,7 +4361,7 @@ (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]); diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index befdfbb..e9bbe0c 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -8733,18 +8733,24 @@ 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); 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); } |