diff options
author | Alex Velenko <Alex.Velenko@arm.com> | 2014-01-23 16:24:13 +0000 |
---|---|---|
committer | James Greenhalgh <jgreenhalgh@gcc.gnu.org> | 2014-01-23 16:24:13 +0000 |
commit | f9a4c9a61396acaea09951aa26b57375a14ac632 (patch) | |
tree | 5f4d182dd6b600e9ccbf121141493e44d1ac6be7 /gcc | |
parent | 949ad9715a88d9010f3e6470a97b02080d500396 (diff) | |
download | gcc-f9a4c9a61396acaea09951aa26b57375a14ac632.zip gcc-f9a4c9a61396acaea09951aa26b57375a14ac632.tar.gz gcc-f9a4c9a61396acaea09951aa26b57375a14ac632.tar.bz2 |
[PATCH][AArch64] Vector shift by 64 fix
gcc/
* config/aarch64/aarch64-simd-builtins.def (ashr): DI mode removed.
(ashr_simd): New builtin handling DI mode.
* config/aarch64/aarch64-simd.md (aarch64_ashr_simddi): New pattern.
(aarch64_sshr_simddi): New match pattern.
* config/aarch64/arm_neon.h (vshr_n_s32): Builtin call modified.
(vshrd_n_s64): Likewise.
* config/aarch64/predicates.md (aarch64_shift_imm64_di): New predicate.
gcc/testsuite/
* gcc.target/aarch64/sshr64_1.c: New testcase.
From-SVN: r206978
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-simd-builtins.def | 3 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-simd.md | 26 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 1 | ||||
-rw-r--r-- | gcc/config/aarch64/arm_neon.h | 4 | ||||
-rw-r--r-- | gcc/config/aarch64/predicates.md | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/sshr64_1.c | 115 |
8 files changed, 164 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 68bda3b..dde3673 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2014-01-23 Alex Velenko <Alex.Velenko@arm.com> + + * config/aarch64/aarch64-simd-builtins.def (ashr): DI mode removed. + (ashr_simd): New builtin handling DI mode. + * config/aarch64/aarch64-simd.md (aarch64_ashr_simddi): New pattern. + (aarch64_sshr_simddi): New match pattern. + * config/aarch64/arm_neon.h (vshr_n_s32): Builtin call modified. + (vshrd_n_s64): Likewise. + * config/aarch64/predicates.md (aarch64_shift_imm64_di): New predicate. + 2014-01-23 Nick Clifton <nickc@redhat.com> * config/msp430/msp430.h (ASM_SPEC): Pass the -mcpu as -mcpu. diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def index 185281a..e5f71b4 100644 --- a/gcc/config/aarch64/aarch64-simd-builtins.def +++ b/gcc/config/aarch64/aarch64-simd-builtins.def @@ -190,7 +190,8 @@ BUILTIN_VSDQ_I_DI (BINOP, srshl, 0) BUILTIN_VSDQ_I_DI (BINOP, urshl, 0) - BUILTIN_VSDQ_I_DI (SHIFTIMM, ashr, 3) + BUILTIN_VDQ_I (SHIFTIMM, ashr, 3) + VAR1 (SHIFTIMM, ashr_simd, 0, di) BUILTIN_VSDQ_I_DI (SHIFTIMM, lshr, 3) /* Implemented by aarch64_<sur>shr_n<mode>. */ BUILTIN_VSDQ_I_DI (SHIFTIMM, srshr_n, 0) diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 680b943..7378da9 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -685,6 +685,32 @@ DONE; }) +;; DI vector shift +(define_expand "aarch64_ashr_simddi" + [(match_operand:DI 0 "register_operand" "=w") + (match_operand:DI 1 "register_operand" "w") + (match_operand:QI 2 "aarch64_shift_imm64_di" "")] + "TARGET_SIMD" + { + if (INTVAL (operands[2]) == 64) + emit_insn (gen_aarch64_sshr_simddi (operands[0], operands[1])); + else + emit_insn (gen_ashrdi3 (operands[0], operands[1], operands[2])); + DONE; + } +) + +;; SIMD shift by 64. This pattern is a special case as standard pattern does +;; not handle NEON shifts by 64. +(define_insn "aarch64_sshr_simddi" + [(set (match_operand:DI 0 "register_operand" "=w") + (unspec:DI + [(match_operand:DI 1 "register_operand" "w")] UNSPEC_SSHR64))] + "TARGET_SIMD" + "sshr\t%d0, %d1, 64" + [(set_attr "type" "neon_shift_imm")] +) + (define_expand "vlshr<mode>3" [(match_operand:VQ_S 0 "register_operand" "") (match_operand:VQ_S 1 "register_operand" "") diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 8657b16..99a6ac8 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -93,6 +93,7 @@ UNSPEC_SISD_SSHL UNSPEC_SISD_USHL UNSPEC_SSHL_2S + UNSPEC_SSHR64 UNSPEC_ST1 UNSPEC_ST2 UNSPEC_ST3 diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h index b6aee7a..6af99361 100644 --- a/gcc/config/aarch64/arm_neon.h +++ b/gcc/config/aarch64/arm_neon.h @@ -23340,7 +23340,7 @@ vshr_n_s32 (int32x2_t __a, const int __b) __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) vshr_n_s64 (int64x1_t __a, const int __b) { - return (int64x1_t) __builtin_aarch64_ashrdi (__a, __b); + return (int64x1_t) __builtin_aarch64_ashr_simddi (__a, __b); } __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__)) @@ -23418,7 +23418,7 @@ vshrq_n_u64 (uint64x2_t __a, const int __b) __extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) vshrd_n_s64 (int64x1_t __a, const int __b) { - return (int64x1_t) __builtin_aarch64_ashrdi (__a, __b); + return (int64x1_t) __builtin_aarch64_ashr_simddi (__a, __b); } __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index 45fcdc9..c8e27d8 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -86,6 +86,10 @@ (and (match_code "const_int") (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 64"))) +(define_predicate "aarch64_shift_imm64_di" + (and (match_code "const_int") + (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) <= 64"))) + (define_predicate "aarch64_reg_or_shift_imm_si" (ior (match_operand 0 "register_operand") (match_operand 0 "aarch64_shift_imm_si"))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f10db47..43979c3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-01-23 Alex Velenko <Alex.Velenko@arm.com> + + * gcc.target/aarch64/sshr64_1.c: New testcase. + 2014-01-23 Balaji V. Iyer <balaji.v.iyer@intel.com> * g++.dg/cilk-plus/cilk-plus.exp: Called the C/C++ common tests for diff --git a/gcc/testsuite/gcc.target/aarch64/sshr64_1.c b/gcc/testsuite/gcc.target/aarch64/sshr64_1.c new file mode 100644 index 0000000..89c6096 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/sshr64_1.c @@ -0,0 +1,115 @@ +/* Test SIMD shift works correctly. */ +/* { dg-do run } */ +/* { dg-options "-O3 --save-temps" } */ + +#include "arm_neon.h" + +extern void abort (void); + +int __attribute__ ((noinline)) +test_sshr64 () +{ + int64x1_t arg; + int64x1_t result; + int64_t got; + int64_t exp; + arg = vcreate_s64 (0x0000000080000000); + result = vshr_n_s64 (arg, 64); + got = vget_lane_s64 (result, 0); + exp = 0; + /* Expect: "result" = 0000000000000000. */ + if (exp != got) + return 1; + return 0; +} + +int __attribute__ ((noinline)) +test_sshr64_neg () +{ + int64x1_t arg; + int64x1_t result; + int64_t got; + int64_t exp; + arg = vcreate_s64 (0xffffffff80000000); + result = vshr_n_s64 (arg, 64); + got = vget_lane_s64 (result, 0); + exp = 0xffffffffffffffff; + /* Expect: "result" = -1. */ + if (exp != got) + return 1; + return 0; +} + +int +__attribute__ ((noinline)) +test_other () +{ + int64x1_t arg; + int64x1_t result; + int64_t got; + int64_t exp; + arg = vcreate_s64 (0x0000000080000000); + result = vshr_n_s64 (arg, 4); + got = vget_lane_s64 (result, 0); + exp = 0x0000000008000000; + /* Expect: "result" = 0x0000000008000000. */ + if (exp != got) + return 1; + return 0; +} + +int __attribute__ ((noinline)) +test_other_neg () +{ + int64x1_t arg; + int64x1_t result; + int64_t got; + int64_t exp; + arg = vcreate_s64 (0xffffffff80000000); + result = vshr_n_s64 (arg, 4); + got = vget_lane_s64 (result, 0); + exp = 0xfffffffff8000000; + /* Expect: "result" = 0xfffffffff8000000. */ + if (exp != got) + return 1; + return 0; +} + +int __attribute__ ((noinline)) +test_no_sshr0 () +{ + int64x1_t arg; + int64x1_t result; + int64_t got; + int64_t exp; + arg = vcreate_s64 (0x0000000080000000); + result = vshr_n_s64 (arg, 0); + got = vget_lane_s64 (result, 0); + exp = 0x0000000080000000; + /* Expect: "result" = 0x0000000080000000. */ + if (exp != got) + return 1; + return 0; +} + +/* { dg-final { scan-assembler-not "sshr\\td\[0-9\]+, d\[0-9\]+, 0" } } */ +int +main () +{ + if (test_sshr64 ()) + abort (); + if (test_other ()) + abort (); + + if (test_sshr64_neg ()) + abort (); + if (test_other_neg ()) + abort (); + + if (test_no_sshr0 ()) + abort (); + + return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ |