Hi, This patch implements vqneg_s64, vqnegd_s64, vqabs_s64 and vqabsd_s64 AArch64 intrinsics. Regression tests added. Run full regression with no regressions.
Is patch OK? Thanks, Alex gcc/ 2014-02-12 Alex Velenko <alex.vele...@arm.com> * gcc/config/aarch64/aarch64-simd.md (aarch64_s<optab><mode>): 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. gcc/testsuite/ 2014-02-12 Alex Velenko <alex.vele...@arm.com> *gcc.target/aarch64/vqneg_s64_1.c: New testcase. *gcc.target/aarch64/vqabs_s64_1.c: New testcase.
diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def index e5f71b479ccfd1a9cbf84aed0f96b49762053f59..b3d0989f1b3bce1cab301f5fdb522324ed758c87 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<optab><mode>. */ - 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 7378da9122d550f869c3e830e3e5a7681e7581f6..8a63dcdae8376b935c004fc84081e222d0a9a720 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -2585,9 +2585,9 @@ ;; <su>q<absneg> (define_insn "aarch64_s<optab><mode>" - [(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<optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>" [(set_attr "type" "neon_<optab><q>")] diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h index 6af99361b8e265f66026dc506cfc23f044d153b4..7347bc0b18968d69b1c66ec75d30facb59450936 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/gcc.target/aarch64/vqabs_s64_1.c b/gcc/testsuite/gcc.target/aarch64/vqabs_s64_1.c new file mode 100644 index 0000000000000000000000000000000000000000..3ea532278d6db7aedc0b6cc6c2498658ad80a72b --- /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 <arm_neon.h> + +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 0000000000000000000000000000000000000000..a555b6529cba1200c77a1d587ec2d34386e9df97 --- /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 <arm_neon.h> + +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 } } */