From 9551c7ec222937e23a96c415de1ca5b55dc4d922 Mon Sep 17 00:00:00 2001 From: Alex Velenko Date: Tue, 22 Apr 2014 15:55:53 +0000 Subject: [PATCH] [AArch64] vqneg and vqabs intrinsics implementation. This patch implements vqneg_s64, vqnegd_s64, vqabs_s64 and vqabsd_s64 AArch64 intrinsics. From-SVN: r209640 --- gcc/ChangeLog | 12 +++++ gcc/config/aarch64/aarch64-simd-builtins.def | 4 +- gcc/config/aarch64/aarch64-simd.md | 6 +-- gcc/config/aarch64/arm_neon.h | 24 +++++++++ gcc/testsuite/ChangeLog | 5 ++ .../gcc.target/aarch64/vqabs_s64_1.c | 54 +++++++++++++++++++ .../gcc.target/aarch64/vqneg_s64_1.c | 47 ++++++++++++++++ 7 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/vqabs_s64_1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/vqneg_s64_1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eeaa5e44146..23d05eeb8a3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2014-04-22 Alex Velenko + + * gcc/config/aarch64/aarch64-simd.md (aarch64_s): + Pattern extended. + * config/aarch64/aarch64-simd-builtins.def (sqneg): Iterator + extended. + (sqabs): Likewise. + * config/aarch64/arm_neon.h (vqneg_s64): New intrinsic. + (vqnegd_s64): Likewise. + (vqabs_s64): Likewise. + (vqabsd_s64): Likewise. + 2014-04-22 Richard Henderson * config/sparc/sparc.c (sparc_init_modes): Hoist GET_MODE_SIZE diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def index c5e3b3e9fb3..d4c7403748d 100644 --- a/gcc/config/aarch64/aarch64-simd-builtins.def +++ b/gcc/config/aarch64/aarch64-simd-builtins.def @@ -142,8 +142,8 @@ BUILTIN_VSQN_HSDI (UNOP, sqmovn, 0) BUILTIN_VSQN_HSDI (UNOP, uqmovn, 0) /* Implemented by aarch64_s. */ - BUILTIN_VSDQ_I_BHSI (UNOP, sqabs, 0) - BUILTIN_VSDQ_I_BHSI (UNOP, sqneg, 0) + BUILTIN_VSDQ_I (UNOP, sqabs, 0) + BUILTIN_VSDQ_I (UNOP, sqneg, 0) BUILTIN_VSD_HSI (QUADOP, sqdmlal_lane, 0) BUILTIN_VSD_HSI (QUADOP, sqdmlsl_lane, 0) diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 995b4a81acd..753ca1c9e9e 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -2610,9 +2610,9 @@ ;; q (define_insn "aarch64_s" - [(set (match_operand:VSDQ_I_BHSI 0 "register_operand" "=w") - (UNQOPS:VSDQ_I_BHSI - (match_operand:VSDQ_I_BHSI 1 "register_operand" "w")))] + [(set (match_operand:VSDQ_I 0 "register_operand" "=w") + (UNQOPS:VSDQ_I + (match_operand:VSDQ_I 1 "register_operand" "w")))] "TARGET_SIMD" "s\\t%0, %1" [(set_attr "type" "neon_")] diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h index a3c15ac3da2..75a62e522a0 100644 --- a/gcc/config/aarch64/arm_neon.h +++ b/gcc/config/aarch64/arm_neon.h @@ -2318,6 +2318,12 @@ vqneg_s32 (int32x2_t __a) return (int32x2_t) __builtin_aarch64_sqnegv2si (__a); } +__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) +vqneg_s64 (int64x1_t __a) +{ + return __builtin_aarch64_sqnegdi (__a); +} + __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) vqnegq_s8 (int8x16_t __a) { @@ -2354,6 +2360,12 @@ vqabs_s32 (int32x2_t __a) return (int32x2_t) __builtin_aarch64_sqabsv2si (__a); } +__extension__ static __inline int64x1_t __attribute__ ((__always_inline__)) +vqabs_s64 (int64x1_t __a) +{ + return __builtin_aarch64_sqabsdi (__a); +} + __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) vqabsq_s8 (int8x16_t __a) { @@ -20943,6 +20955,12 @@ vqabss_s32 (int32x1_t __a) return (int32x1_t) __builtin_aarch64_sqabssi (__a); } +__extension__ static __inline int64_t __attribute__ ((__always_inline__)) +vqabsd_s64 (int64_t __a) +{ + return __builtin_aarch64_sqabsdi (__a); +} + /* vqadd */ __extension__ static __inline int8x1_t __attribute__ ((__always_inline__)) @@ -21561,6 +21579,12 @@ vqnegs_s32 (int32x1_t __a) return (int32x1_t) __builtin_aarch64_sqnegsi (__a); } +__extension__ static __inline int64_t __attribute__ ((__always_inline__)) +vqnegd_s64 (int64_t __a) +{ + return __builtin_aarch64_sqnegdi (__a); +} + /* vqrdmulh */ __extension__ static __inline int16x4_t __attribute__ ((__always_inline__)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 53f5e27d946..908646d6823 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-04-22 Alex Velenko + + * gcc.target/aarch64/vqneg_s64_1.c: New testcase. + * gcc.target/aarch64/vqabs_s64_1.c: New testcase. + 2014-04-22 Richard Sandiford * gcc.dg/memcpy-5.c: New test. diff --git a/gcc/testsuite/gcc.target/aarch64/vqabs_s64_1.c b/gcc/testsuite/gcc.target/aarch64/vqabs_s64_1.c new file mode 100644 index 00000000000..3ea532278d6 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/vqabs_s64_1.c @@ -0,0 +1,54 @@ +/* Test vqabs_s64 intrinsics work correctly. */ +/* { dg-do run } */ +/* { dg-options "--save-temps" } */ + +#include + +extern void abort (void); + +int __attribute__ ((noinline)) +test_vqabs_s64 (int64x1_t passed, int64_t expected) +{ + return vget_lane_s64 (vqabs_s64 (passed), 0) != expected; +} + +int __attribute__ ((noinline)) +test_vqabsd_s64 (int64_t passed, int64_t expected) +{ + return vqabsd_s64 (passed) != expected; +} + +/* { dg-final { scan-assembler-times "sqabs\\td\[0-9\]+, d\[0-9\]+" 2 } } */ + +int +main (int argc, char **argv) +{ + /* Basic test. */ + if (test_vqabs_s64 (vcreate_s64 (-1), 1)) + abort (); + if (test_vqabsd_s64 (-1, 1)) + abort (); + + /* Getting absolute value of min int64_t. + Note, exact result cannot be represented in int64_t, + so max int64_t is expected. */ + if (test_vqabs_s64 (vcreate_s64 (0x8000000000000000), 0x7fffffffffffffff)) + abort (); + if (test_vqabsd_s64 (0x8000000000000000, 0x7fffffffffffffff)) + abort (); + + /* Another input that gets max int64_t. */ + if (test_vqabs_s64 (vcreate_s64 (0x8000000000000001), 0x7fffffffffffffff)) + abort (); + if (test_vqabsd_s64 (0x8000000000000001, 0x7fffffffffffffff)) + abort (); + + /* Checking that large positive numbers stay the same. */ + if (test_vqabs_s64 (vcreate_s64 (0x7fffffffffffffff), 0x7fffffffffffffff)) + abort (); + if (test_vqabsd_s64 (0x7fffffffffffffff, 0x7fffffffffffffff)) + abort (); + + return 0; +} +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/vqneg_s64_1.c b/gcc/testsuite/gcc.target/aarch64/vqneg_s64_1.c new file mode 100644 index 00000000000..a555b6529cb --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/vqneg_s64_1.c @@ -0,0 +1,47 @@ +/* Test vqneg_s64 intrinsics work correctly. */ +/* { dg-do run } */ +/* { dg-options "--save-temps" } */ + +#include + +extern void abort (void); + +int __attribute__ ((noinline)) +test_vqneg_s64 (int64x1_t passed, int64_t expected) +{ + return vget_lane_s64 (vqneg_s64 (passed), 0) != expected; +} + +int __attribute__ ((noinline)) +test_vqnegd_s64 (int64_t passed, int64_t expected) +{ + return vqnegd_s64 (passed) != expected; +} + +/* { dg-final { scan-assembler-times "sqneg\\td\[0-9\]+, d\[0-9\]+" 2 } } */ + +int +main (int argc, char **argv) +{ + /* Basic test. */ + if (test_vqneg_s64 (vcreate_s64 (-1), 1)) + abort (); + if (test_vqnegd_s64 (-1, 1)) + abort (); + + /* Negating max int64_t. */ + if (test_vqneg_s64 (vcreate_s64 (0x7fffffffffffffff), 0x8000000000000001)) + abort (); + if (test_vqnegd_s64 (0x7fffffffffffffff, 0x8000000000000001)) + abort (); + + /* Negating min int64_t. + Note, exact negation cannot be represented as int64_t. */ + if (test_vqneg_s64 (vcreate_s64 (0x8000000000000000), 0x7fffffffffffffff)) + abort (); + if (test_vqnegd_s64 (0x8000000000000000, 0x7fffffffffffffff)) + abort (); + + return 0; +} +/* { dg-final { cleanup-saved-temps } } */ -- 2.30.2