From bed34e8314ab4f7439bcda61eb221ae13833200d Mon Sep 17 00:00:00 2001 From: jgreenhalgh Date: Mon, 24 Mar 2014 12:05:38 +0000 Subject: [PATCH] [AArch64] Logical vector shift right conformance gcc/ * config/aarch64/aarch64-simd-builtins.def (lshr): DI mode excluded. (lshr_simd): DI mode added. * config/aarch64/aarch64-simd.md (aarch64_lshr_simddi): New pattern. (aarch64_ushr_simddi): Likewise. * config/aarch64/aarch64.md (UNSPEC_USHR64): New unspec. * config/aarch64/arm_neon.h (vshr_n_u64): Intrinsic fixed. (vshrd_n_u64): Likewise. gcc/testsuite/ * gcc.target/aarch64/ushr64_1.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@208789 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 ++++ gcc/config/aarch64/aarch64-builtins.c | 4 ++ gcc/config/aarch64/aarch64-simd-builtins.def | 3 +- gcc/config/aarch64/aarch64-simd.md | 25 +++++++++ gcc/config/aarch64/aarch64.md | 1 + gcc/config/aarch64/arm_neon.h | 8 +-- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.target/aarch64/ushr64_1.c | 84 ++++++++++++++++++++++++++++ 8 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/ushr64_1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fd8cd6c486a..a0e21f28616 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2014-03-24 Alex Velenko + + * config/aarch64/aarch64-simd-builtins.def (lshr): DI mode excluded. + (lshr_simd): DI mode added. + * config/aarch64/aarch64-simd.md (aarch64_lshr_simddi): New pattern. + (aarch64_ushr_simddi): Likewise. + * config/aarch64/aarch64.md (UNSPEC_USHR64): New unspec. + * config/aarch64/arm_neon.h (vshr_n_u64): Intrinsic fixed. + (vshrd_n_u64): Likewise. + 2014-03-24 Rainer Orth * Makefile.in (s-macro_list): Depend on cc1. diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c index 9dfe0b6e1a5..55cfe0ab225 100644 --- a/gcc/config/aarch64/aarch64-builtins.c +++ b/gcc/config/aarch64/aarch64-builtins.c @@ -183,6 +183,10 @@ aarch64_types_getlane_qualifiers[SIMD_MAX_BUILTIN_ARGS] #define TYPES_GETLANE (aarch64_types_getlane_qualifiers) #define TYPES_SHIFTIMM (aarch64_types_getlane_qualifiers) static enum aarch64_type_qualifiers +aarch64_types_unsigned_shift_qualifiers[SIMD_MAX_BUILTIN_ARGS] + = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate }; +#define TYPES_USHIFTIMM (aarch64_types_unsigned_shift_qualifiers) +static enum aarch64_type_qualifiers aarch64_types_setlane_qualifiers[SIMD_MAX_BUILTIN_ARGS] = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate }; #define TYPES_SETLANE (aarch64_types_setlane_qualifiers) diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def index e5f71b479cc..c9b7570e565 100644 --- a/gcc/config/aarch64/aarch64-simd-builtins.def +++ b/gcc/config/aarch64/aarch64-simd-builtins.def @@ -192,7 +192,8 @@ BUILTIN_VDQ_I (SHIFTIMM, ashr, 3) VAR1 (SHIFTIMM, ashr_simd, 0, di) - BUILTIN_VSDQ_I_DI (SHIFTIMM, lshr, 3) + BUILTIN_VDQ_I (SHIFTIMM, lshr, 3) + VAR1 (USHIFTIMM, lshr_simd, 0, di) /* Implemented by aarch64_shr_n. */ BUILTIN_VSDQ_I_DI (SHIFTIMM, srshr_n, 0) BUILTIN_VSDQ_I_DI (SHIFTIMM, urshr_n, 0) diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md index 4dffb59e856..6048d605c72 100644 --- a/gcc/config/aarch64/aarch64-simd.md +++ b/gcc/config/aarch64/aarch64-simd.md @@ -724,6 +724,31 @@ DONE; }) +(define_expand "aarch64_lshr_simddi" + [(match_operand:DI 0 "register_operand" "=w") + (match_operand:DI 1 "register_operand" "w") + (match_operand:SI 2 "aarch64_shift_imm64_di" "")] + "TARGET_SIMD" + { + if (INTVAL (operands[2]) == 64) + emit_insn (gen_aarch64_ushr_simddi (operands[0], operands[1])); + else + emit_insn (gen_lshrdi3 (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_ushr_simddi" + [(set (match_operand:DI 0 "register_operand" "=w") + (unspec:DI + [(match_operand:DI 1 "register_operand" "w")] UNSPEC_USHR64))] + "TARGET_SIMD" + "ushr\t%d0, %d1, 64" + [(set_attr "type" "neon_shift_imm")] +) + (define_expand "vec_set" [(match_operand:VQ_S 0 "register_operand") (match_operand: 1 "register_operand") diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 99a6ac8fcbd..c86a29d8e7f 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -101,6 +101,7 @@ UNSPEC_TLS UNSPEC_TLSDESC UNSPEC_USHL_2S + UNSPEC_USHR64 UNSPEC_VSTRUCTDUMMY ]) diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h index 8272a843c41..747a292ba9b 100644 --- a/gcc/config/aarch64/arm_neon.h +++ b/gcc/config/aarch64/arm_neon.h @@ -23364,7 +23364,7 @@ vshr_n_u32 (uint32x2_t __a, const int __b) __extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) vshr_n_u64 (uint64x1_t __a, const int __b) { - return (uint64x1_t) __builtin_aarch64_lshrdi ((int64x1_t) __a, __b); + return __builtin_aarch64_lshr_simddi_uus ( __a, __b); } __extension__ static __inline int8x16_t __attribute__ ((__always_inline__)) @@ -23421,10 +23421,10 @@ vshrd_n_s64 (int64x1_t __a, const int __b) return (int64x1_t) __builtin_aarch64_ashr_simddi (__a, __b); } -__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__)) -vshrd_n_u64 (uint64x1_t __a, const int __b) +__extension__ static __inline uint64_t __attribute__ ((__always_inline__)) +vshrd_n_u64 (uint64_t __a, const int __b) { - return (uint64x1_t) __builtin_aarch64_lshrdi (__a, __b); + return __builtin_aarch64_lshr_simddi_uus (__a, __b); } /* vsli */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 99801b51438..a07de067040 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-03-24 Alex Velenko + + * gcc.target/aarch64/ushr64_1.c: New. + 2014-03-24 James Greenhalgh * gcc.target/aarch64/vect-abs.c (dg-options): Add -std=c99. diff --git a/gcc/testsuite/gcc.target/aarch64/ushr64_1.c b/gcc/testsuite/gcc.target/aarch64/ushr64_1.c new file mode 100644 index 00000000000..b1c741dac31 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/ushr64_1.c @@ -0,0 +1,84 @@ +/* Test logical SIMD shift works correctly. */ +/* { dg-do run } */ +/* { dg-options "--save-temps" } */ + +#include "arm_neon.h" + +extern void abort (void); + +int __attribute__ ((noinline)) +test_vshr_n_u64_64 (uint64x1_t passed, uint64_t expected) +{ + return vget_lane_u64 (vshr_n_u64 (passed, 64), 0) != expected; +} + +int __attribute__ ((noinline)) +test_vshr_n_u64_4 (uint64x1_t passed, uint64_t expected) +{ + return vget_lane_u64 (vshr_n_u64 (passed, 4), 0) != expected; +} + +int __attribute__ ((noinline)) +test_vshr_n_u64_0 (uint64x1_t passed, uint64_t expected) +{ + return vget_lane_u64 (vshr_n_u64 (passed, 0), 0) != expected; +} + +int __attribute__ ((noinline)) +test_vshrd_n_u64_64 (uint64_t passed, uint64_t expected) +{ + return vshrd_n_u64 (passed, 64) != expected; +} + +int __attribute__ ((noinline)) +test_vshrd_n_u64_4 (uint64_t passed, uint64_t expected) +{ + return vshrd_n_u64 (passed, 4) != expected; +} + +int __attribute__ ((noinline)) +test_vshrd_n_u64_0 (uint64_t passed, uint64_t expected) +{ + return vshrd_n_u64 (passed, 0) != expected; +} + +/* { dg-final { scan-assembler-times "ushr\\td\[0-9\]+, d\[0-9\]+, 64" 2 } } */ +/* { dg-final { (scan-assembler-times "ushr\\td\[0-9\]+, d\[0-9\]+, 4" 2) || \ + (scan-assembler-times "lsr\\tx\[0-9\]+, x\[0-9\]+, 4" 2) } } */ +/* { dg-final { scan-assembler-not "ushr\\td\[0-9\]+, d\[0-9\]+, 0" } } */ + +int +main (int argc, char *argv[]) +{ + /* Testing vshr_n_u64. */ + if (test_vshr_n_u64_64 (vcreate_u64 (0x0000000080000000), 0)) + abort (); + if (test_vshr_n_u64_64 (vcreate_u64 (0xffffffff80000000), 0)) + abort (); + + if (test_vshr_n_u64_4 (vcreate_u64 (0x0000000080000000), 0x0000000008000000)) + abort (); + if (test_vshr_n_u64_4 (vcreate_u64 (0xffffffff80000000), 0x0ffffffff8000000)) + abort (); + + if (test_vshr_n_u64_0 (vcreate_u64 (0x0000000080000000), 0x0000000080000000)) + abort (); + + /* Testing vshrd_n_u64. */ + if (test_vshrd_n_u64_64 (0x0000000080000000, 0)) + abort (); + if (test_vshrd_n_u64_64 (0xffffffff80000000, 0)) + abort (); + + if (test_vshrd_n_u64_4 (0x0000000080000000, 0x0000000008000000)) + abort (); + if (test_vshrd_n_u64_4 (0xffffffff80000000, 0x0ffffffff8000000)) + abort (); + + if (test_vshrd_n_u64_0 (0x0000000080000000, 0x0000000080000000)) + abort (); + + return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ -- 2.11.4.GIT