[1/6] aarch64: Port NEON saturating add/sub intrinsics to pragma-based framework
Commit Message
From: Dhruv Chawla <dhruvc@nvidia.com>
Port the following intrinsics to the pragma-based framework:
* vqadd
* vqsub
Plus their scalar variants: vq{add,sub}{b,h,s,d}.
The following are not ported in this patch as they cannot be directly
lowered from an IFN through an existing instruction pattern:
* vqadd_s64
* vqadd_u64
* vqsub_s64
* vqsub_u64
This is because the pattern does not iterate through the modes (V1DI) required
to lower them (it uses the VSDQ_I_QI_HI iterator).
Bootstrapped and regtested on aarch64-linux-gnu.
Signed-off-by: Dhruv Chawla <dhruvc@nvidia.com>
gcc/ChangeLog:
* config/aarch64/aarch64-neon-builtins-base.cc (vqaddb, vqaddh,
vqadds, vqaddd, vqadd, vqaddq, vqsubb, vqsubh, vqsubs, vqsubd, vqsub,
vqsubq): New function bases.
* config/aarch64/aarch64-neon-builtins-base.def (vqaddb, vqaddh,
vqadds, vqaddd, vqadd, vqaddq, vqsubb, vqsubh, vqsubs, vqsubd, vqsub,
vqsubq): New function groups.
* config/aarch64/arm_neon.h (vqadd_s8, vqadd_s16, vqadd_s32,
vqadd_u8, vqadd_u16, vqadd_u32, vqaddq_s8, vqaddq_s16, vqaddq_s32,
vqaddq_s64, vqaddq_u8, vqaddq_u16, vqaddq_u32, vqaddq_u64, vqsub_s8,
vqsub_s16, vqsub_s32, vqsub_u8, vqsub_u16, vqsub_u32, vqsubq_s8,
vqsubq_s16, vqsubq_s32, vqsubq_s64, vqsubq_u8, vqsubq_u16, vqsubq_u32,
vqsubq_u64, vqaddb_s8, vqaddh_s16, vqadds_s32, vqaddd_s64, vqaddb_u8,
vqaddh_u16, vqadds_u32, vqaddd_u64, vqsubb_s8, vqsubh_s16, vqsubs_s32,
vqsubd_s64, vqsubb_u8, vqsubh_u16, vqsubs_u32, vqsubd_u64): Delete
functions.
(vqadd_s64): Relocate to be grouped with the other {s,u}64
functions.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/neon/vqadd.c: New test.
* gcc.target/aarch64/neon/vqsub.c: Likewise.
---
.../aarch64/aarch64-neon-builtins-base.cc | 14 +
.../aarch64/aarch64-neon-builtins-base.def | 16 +
gcc/config/aarch64/arm_neon.h | 318 +-----------------
gcc/testsuite/gcc.target/aarch64/neon/vqadd.c | 192 +++++++++++
gcc/testsuite/gcc.target/aarch64/neon/vqsub.c | 192 +++++++++++
5 files changed, 417 insertions(+), 315 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vqadd.c
create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vqsub.c
Comments
Hi Dhruv,
> On 2 Sep 2026, at 10:38, Dhruv Chawla <dhruvc@nvidia.com> wrote:
>
> From: Dhruv Chawla <dhruvc@nvidia.com>
>
> Port the following intrinsics to the pragma-based framework:
> * vqadd
> * vqsub
>
> Plus their scalar variants: vq{add,sub}{b,h,s,d}.
>
> The following are not ported in this patch as they cannot be directly
> lowered from an IFN through an existing instruction pattern:
> * vqadd_s64
> * vqadd_u64
> * vqsub_s64
> * vqsub_u64
>
> This is because the pattern does not iterate through the modes (V1DI) required
> to lower them (it uses the VSDQ_I_QI_HI iterator).
>
I see this is an issue with many intrinsics groups. We’ll need to figure out a way to handle this, but in another patch.
This patch is ok.
Thanks,
Kyrill
> Bootstrapped and regtested on aarch64-linux-gnu.
>
> Signed-off-by: Dhruv Chawla <dhruvc@nvidia.com>
>
> gcc/ChangeLog:
>
> * config/aarch64/aarch64-neon-builtins-base.cc (vqaddb, vqaddh,
> vqadds, vqaddd, vqadd, vqaddq, vqsubb, vqsubh, vqsubs, vqsubd, vqsub,
> vqsubq): New function bases.
> * config/aarch64/aarch64-neon-builtins-base.def (vqaddb, vqaddh,
> vqadds, vqaddd, vqadd, vqaddq, vqsubb, vqsubh, vqsubs, vqsubd, vqsub,
> vqsubq): New function groups.
> * config/aarch64/arm_neon.h (vqadd_s8, vqadd_s16, vqadd_s32,
> vqadd_u8, vqadd_u16, vqadd_u32, vqaddq_s8, vqaddq_s16, vqaddq_s32,
> vqaddq_s64, vqaddq_u8, vqaddq_u16, vqaddq_u32, vqaddq_u64, vqsub_s8,
> vqsub_s16, vqsub_s32, vqsub_u8, vqsub_u16, vqsub_u32, vqsubq_s8,
> vqsubq_s16, vqsubq_s32, vqsubq_s64, vqsubq_u8, vqsubq_u16, vqsubq_u32,
> vqsubq_u64, vqaddb_s8, vqaddh_s16, vqadds_s32, vqaddd_s64, vqaddb_u8,
> vqaddh_u16, vqadds_u32, vqaddd_u64, vqsubb_s8, vqsubh_s16, vqsubs_s32,
> vqsubd_s64, vqsubb_u8, vqsubh_u16, vqsubs_u32, vqsubd_u64): Delete
> functions.
> (vqadd_s64): Relocate to be grouped with the other {s,u}64
> functions.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/aarch64/neon/vqadd.c: New test.
> * gcc.target/aarch64/neon/vqsub.c: Likewise.
> ---
> .../aarch64/aarch64-neon-builtins-base.cc | 14 +
> .../aarch64/aarch64-neon-builtins-base.def | 16 +
> gcc/config/aarch64/arm_neon.h | 318 +-----------------
> gcc/testsuite/gcc.target/aarch64/neon/vqadd.c | 192 +++++++++++
> gcc/testsuite/gcc.target/aarch64/neon/vqsub.c | 192 +++++++++++
> 5 files changed, 417 insertions(+), 315 deletions(-)
> create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vqadd.c
> create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vqsub.c
>
> diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.cc b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
> index d8fae81388e..5c886d32f42 100644
> --- a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
> +++ b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
> @@ -753,6 +753,20 @@ NEON_FUNCTION (vaddd, gimple_expr, (PLUS_EXPR))
> NEON_FUNCTION (vadd, gimple_expr, (PLUS_EXPR, PLUS_EXPR, BIT_XOR_EXPR))
> NEON_FUNCTION (vaddq, gimple_expr, (PLUS_EXPR, PLUS_EXPR, BIT_XOR_EXPR))
>
> +// Saturating arithmetic
> +NEON_FUNCTION (vqaddb, gimple_ifn, (IFN_SAT_ADD))
> +NEON_FUNCTION (vqaddh, gimple_ifn, (IFN_SAT_ADD))
> +NEON_FUNCTION (vqadds, gimple_ifn, (IFN_SAT_ADD))
> +NEON_FUNCTION (vqaddd, gimple_ifn, (IFN_SAT_ADD))
> +NEON_FUNCTION (vqadd, gimple_ifn, (IFN_SAT_ADD))
> +NEON_FUNCTION (vqaddq, gimple_ifn, (IFN_SAT_ADD))
> +NEON_FUNCTION (vqsubb, gimple_ifn, (IFN_SAT_SUB))
> +NEON_FUNCTION (vqsubh, gimple_ifn, (IFN_SAT_SUB))
> +NEON_FUNCTION (vqsubs, gimple_ifn, (IFN_SAT_SUB))
> +NEON_FUNCTION (vqsubd, gimple_ifn, (IFN_SAT_SUB))
> +NEON_FUNCTION (vqsub, gimple_ifn, (IFN_SAT_SUB))
> +NEON_FUNCTION (vqsubq, gimple_ifn, (IFN_SAT_SUB))
> +
> // Bitwise operations
> NEON_FUNCTION (vand, gimple_expr, (BIT_AND_EXPR))
> NEON_FUNCTION (vandq, gimple_expr, (BIT_AND_EXPR))
> diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.def b/gcc/config/aarch64/aarch64-neon-builtins-base.def
> index 7257f59bbc5..52e4746453b 100644
> --- a/gcc/config/aarch64/aarch64-neon-builtins-base.def
> +++ b/gcc/config/aarch64/aarch64-neon-builtins-base.def
> @@ -76,6 +76,22 @@ DEF_NEON_FUNCTION (vadd, h_float, ("D0,D0,D0"))
> DEF_NEON_FUNCTION (vaddq, h_float, ("Q0,Q0,Q0"))
> #undef REQUIRED_EXTENSIONS
>
> +// Saturating arithmetic
> +#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD)
> +DEF_NEON_FUNCTION (vqaddb, b_integer, ("s0,s0,s0"))
> +DEF_NEON_FUNCTION (vqaddh, h_integer, ("s0,s0,s0"))
> +DEF_NEON_FUNCTION (vqadds, s_integer, ("s0,s0,s0"))
> +DEF_NEON_FUNCTION (vqaddd, d_integer, ("s0,s0,s0"))
> +DEF_NEON_FUNCTION (vqadd, bhs_integer, ("D0,D0,D0"))
> +DEF_NEON_FUNCTION (vqaddq, all_integer, ("Q0,Q0,Q0"))
> +DEF_NEON_FUNCTION (vqsubb, b_integer, ("s0,s0,s0"))
> +DEF_NEON_FUNCTION (vqsubh, h_integer, ("s0,s0,s0"))
> +DEF_NEON_FUNCTION (vqsubs, s_integer, ("s0,s0,s0"))
> +DEF_NEON_FUNCTION (vqsubd, d_integer, ("s0,s0,s0"))
> +DEF_NEON_FUNCTION (vqsub, bhs_integer, ("D0,D0,D0"))
> +DEF_NEON_FUNCTION (vqsubq, all_integer, ("Q0,Q0,Q0"))
> +#undef REQUIRED_EXTENSIONS
> +
> // Bitwise operations
> #define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD)
> DEF_NEON_FUNCTION (vand, all_integer, ("D0,D0,D0"))
> diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
> index 873a1195d3e..985b4bdb6cc 100644
> --- a/gcc/config/aarch64/arm_neon.h
> +++ b/gcc/config/aarch64/arm_neon.h
> @@ -1071,41 +1071,6 @@ vsubw_high_u32 (uint64x2_t __a, uint32x4_t __b)
> return __builtin_aarch64_usubw2v4si_uuu (__a, __b);
> }
>
> -__extension__ extern __inline int8x8_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqadd_s8 (int8x8_t __a, int8x8_t __b)
> -{
> - return (int8x8_t) __builtin_aarch64_ssaddv8qi (__a, __b);
> -}
> -
> -__extension__ extern __inline int16x4_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqadd_s16 (int16x4_t __a, int16x4_t __b)
> -{
> - return (int16x4_t) __builtin_aarch64_ssaddv4hi (__a, __b);
> -}
> -
> -__extension__ extern __inline int32x2_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqadd_s32 (int32x2_t __a, int32x2_t __b)
> -{
> - return (int32x2_t) __builtin_aarch64_ssaddv2si (__a, __b);
> -}
> -
> -__extension__ extern __inline int64x1_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqadd_s64 (int64x1_t __a, int64x1_t __b)
> -{
> - return (int64x1_t) {__builtin_aarch64_ssadddi (__a[0], __b[0])};
> -}
> -
> -__extension__ extern __inline uint8x8_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqadd_u8 (uint8x8_t __a, uint8x8_t __b)
> -{
> - return __builtin_aarch64_usaddv8qi_uuu (__a, __b);
> -}
> -
> __extension__ extern __inline int8x8_t
> __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> vhsub_s8 (int8x8_t __a, int8x8_t __b)
> @@ -1358,18 +1323,11 @@ vsubhn_high_u64 (uint32x2_t __a, uint64x2_t __b, uint64x2_t __c)
> return __builtin_aarch64_subhn2v2di_uuuu (__a, __b, __c);
> }
>
> -__extension__ extern __inline uint16x4_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqadd_u16 (uint16x4_t __a, uint16x4_t __b)
> -{
> - return __builtin_aarch64_usaddv4hi_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint32x2_t
> +__extension__ extern __inline int64x1_t
> __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqadd_u32 (uint32x2_t __a, uint32x2_t __b)
> +vqadd_s64 (int64x1_t __a, int64x1_t __b)
> {
> - return __builtin_aarch64_usaddv2si_uuu (__a, __b);
> + return (int64x1_t) {__builtin_aarch64_ssadddi (__a[0], __b[0])};
> }
>
> __extension__ extern __inline uint64x1_t
> @@ -1379,83 +1337,6 @@ vqadd_u64 (uint64x1_t __a, uint64x1_t __b)
> return (uint64x1_t) {__builtin_aarch64_usadddi_uuu (__a[0], __b[0])};
> }
>
> -__extension__ extern __inline int8x16_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqaddq_s8 (int8x16_t __a, int8x16_t __b)
> -{
> - return (int8x16_t) __builtin_aarch64_ssaddv16qi (__a, __b);
> -}
> -
> -__extension__ extern __inline int16x8_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqaddq_s16 (int16x8_t __a, int16x8_t __b)
> -{
> - return (int16x8_t) __builtin_aarch64_ssaddv8hi (__a, __b);
> -}
> -
> -__extension__ extern __inline int32x4_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqaddq_s32 (int32x4_t __a, int32x4_t __b)
> -{
> - return (int32x4_t) __builtin_aarch64_ssaddv4si (__a, __b);
> -}
> -
> -__extension__ extern __inline int64x2_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqaddq_s64 (int64x2_t __a, int64x2_t __b)
> -{
> - return (int64x2_t) __builtin_aarch64_ssaddv2di (__a, __b);
> -}
> -
> -__extension__ extern __inline uint8x16_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqaddq_u8 (uint8x16_t __a, uint8x16_t __b)
> -{
> - return __builtin_aarch64_usaddv16qi_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint16x8_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqaddq_u16 (uint16x8_t __a, uint16x8_t __b)
> -{
> - return __builtin_aarch64_usaddv8hi_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint32x4_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqaddq_u32 (uint32x4_t __a, uint32x4_t __b)
> -{
> - return __builtin_aarch64_usaddv4si_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint64x2_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqaddq_u64 (uint64x2_t __a, uint64x2_t __b)
> -{
> - return __builtin_aarch64_usaddv2di_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline int8x8_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsub_s8 (int8x8_t __a, int8x8_t __b)
> -{
> - return (int8x8_t) __builtin_aarch64_sssubv8qi (__a, __b);
> -}
> -
> -__extension__ extern __inline int16x4_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsub_s16 (int16x4_t __a, int16x4_t __b)
> -{
> - return (int16x4_t) __builtin_aarch64_sssubv4hi (__a, __b);
> -}
> -
> -__extension__ extern __inline int32x2_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsub_s32 (int32x2_t __a, int32x2_t __b)
> -{
> - return (int32x2_t) __builtin_aarch64_sssubv2si (__a, __b);
> -}
> -
> __extension__ extern __inline int64x1_t
> __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> vqsub_s64 (int64x1_t __a, int64x1_t __b)
> @@ -1463,27 +1344,6 @@ vqsub_s64 (int64x1_t __a, int64x1_t __b)
> return (int64x1_t) {__builtin_aarch64_sssubdi (__a[0], __b[0])};
> }
>
> -__extension__ extern __inline uint8x8_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsub_u8 (uint8x8_t __a, uint8x8_t __b)
> -{
> - return __builtin_aarch64_ussubv8qi_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint16x4_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsub_u16 (uint16x4_t __a, uint16x4_t __b)
> -{
> - return __builtin_aarch64_ussubv4hi_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint32x2_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsub_u32 (uint32x2_t __a, uint32x2_t __b)
> -{
> - return __builtin_aarch64_ussubv2si_uuu (__a, __b);
> -}
> -
> __extension__ extern __inline uint64x1_t
> __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> vqsub_u64 (uint64x1_t __a, uint64x1_t __b)
> @@ -1491,62 +1351,6 @@ vqsub_u64 (uint64x1_t __a, uint64x1_t __b)
> return (uint64x1_t) {__builtin_aarch64_ussubdi_uuu (__a[0], __b[0])};
> }
>
> -__extension__ extern __inline int8x16_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubq_s8 (int8x16_t __a, int8x16_t __b)
> -{
> - return (int8x16_t) __builtin_aarch64_sssubv16qi (__a, __b);
> -}
> -
> -__extension__ extern __inline int16x8_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubq_s16 (int16x8_t __a, int16x8_t __b)
> -{
> - return (int16x8_t) __builtin_aarch64_sssubv8hi (__a, __b);
> -}
> -
> -__extension__ extern __inline int32x4_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubq_s32 (int32x4_t __a, int32x4_t __b)
> -{
> - return (int32x4_t) __builtin_aarch64_sssubv4si (__a, __b);
> -}
> -
> -__extension__ extern __inline int64x2_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubq_s64 (int64x2_t __a, int64x2_t __b)
> -{
> - return (int64x2_t) __builtin_aarch64_sssubv2di (__a, __b);
> -}
> -
> -__extension__ extern __inline uint8x16_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubq_u8 (uint8x16_t __a, uint8x16_t __b)
> -{
> - return __builtin_aarch64_ussubv16qi_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint16x8_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubq_u16 (uint16x8_t __a, uint16x8_t __b)
> -{
> - return __builtin_aarch64_ussubv8hi_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint32x4_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubq_u32 (uint32x4_t __a, uint32x4_t __b)
> -{
> - return __builtin_aarch64_ussubv4si_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint64x2_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubq_u64 (uint64x2_t __a, uint64x2_t __b)
> -{
> - return __builtin_aarch64_ussubv2di_uuu (__a, __b);
> -}
> -
> __extension__ extern __inline int8x8_t
> __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> vqneg_s8 (int8x8_t __a)
> @@ -13921,64 +13725,6 @@ vqabsd_s64 (int64_t __a)
> return __builtin_aarch64_sqabsdi (__a);
> }
>
> -/* vqadd */
> -
> -__extension__ extern __inline int8_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqaddb_s8 (int8_t __a, int8_t __b)
> -{
> - return (int8_t) __builtin_aarch64_ssaddqi (__a, __b);
> -}
> -
> -__extension__ extern __inline int16_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqaddh_s16 (int16_t __a, int16_t __b)
> -{
> - return (int16_t) __builtin_aarch64_ssaddhi (__a, __b);
> -}
> -
> -__extension__ extern __inline int32_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqadds_s32 (int32_t __a, int32_t __b)
> -{
> - return (int32_t) __builtin_aarch64_ssaddsi (__a, __b);
> -}
> -
> -__extension__ extern __inline int64_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqaddd_s64 (int64_t __a, int64_t __b)
> -{
> - return __builtin_aarch64_ssadddi (__a, __b);
> -}
> -
> -__extension__ extern __inline uint8_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqaddb_u8 (uint8_t __a, uint8_t __b)
> -{
> - return (uint8_t) __builtin_aarch64_usaddqi_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint16_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqaddh_u16 (uint16_t __a, uint16_t __b)
> -{
> - return (uint16_t) __builtin_aarch64_usaddhi_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint32_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqadds_u32 (uint32_t __a, uint32_t __b)
> -{
> - return (uint32_t) __builtin_aarch64_usaddsi_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint64_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqaddd_u64 (uint64_t __a, uint64_t __b)
> -{
> - return __builtin_aarch64_usadddi_uuu (__a, __b);
> -}
> -
> /* vqdmlal */
>
> __extension__ extern __inline int32x4_t
> @@ -15620,64 +15366,6 @@ vqshrund_n_s64 (int64_t __a, const int __b)
> return (int32_t) __builtin_aarch64_sqshrun_ndi (__a, __b);
> }
>
> -/* vqsub */
> -
> -__extension__ extern __inline int8_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubb_s8 (int8_t __a, int8_t __b)
> -{
> - return (int8_t) __builtin_aarch64_sssubqi (__a, __b);
> -}
> -
> -__extension__ extern __inline int16_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubh_s16 (int16_t __a, int16_t __b)
> -{
> - return (int16_t) __builtin_aarch64_sssubhi (__a, __b);
> -}
> -
> -__extension__ extern __inline int32_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubs_s32 (int32_t __a, int32_t __b)
> -{
> - return (int32_t) __builtin_aarch64_sssubsi (__a, __b);
> -}
> -
> -__extension__ extern __inline int64_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubd_s64 (int64_t __a, int64_t __b)
> -{
> - return __builtin_aarch64_sssubdi (__a, __b);
> -}
> -
> -__extension__ extern __inline uint8_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubb_u8 (uint8_t __a, uint8_t __b)
> -{
> - return (uint8_t) __builtin_aarch64_ussubqi_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint16_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubh_u16 (uint16_t __a, uint16_t __b)
> -{
> - return (uint16_t) __builtin_aarch64_ussubhi_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint32_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubs_u32 (uint32_t __a, uint32_t __b)
> -{
> - return (uint32_t) __builtin_aarch64_ussubsi_uuu (__a, __b);
> -}
> -
> -__extension__ extern __inline uint64_t
> -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
> -vqsubd_u64 (uint64_t __a, uint64_t __b)
> -{
> - return __builtin_aarch64_ussubdi_uuu (__a, __b);
> -}
> -
> /* vqtbl2 */
>
> __extension__ extern __inline int8x8_t
> diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vqadd.c b/gcc/testsuite/gcc.target/aarch64/neon/vqadd.c
> new file mode 100644
> index 00000000000..322f54c5a42
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/neon/vqadd.c
> @@ -0,0 +1,192 @@
> +/* { dg-do compile } */
> +/* { dg-final { check-function-bodies "**" "" } } */
> +
> +#include "arm_neon_test.h"
> +
> +/*
> +** test_vqadd_u8:
> +** uqadd v0\.8b, (v0\.8b, v1\.8b|v1\.8b, v0\.8b)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqadd_u8, uint8x8_t)
> +
> +/*
> +** test_vqadd_s8:
> +** sqadd v0\.8b, (v0\.8b, v1\.8b|v1\.8b, v0\.8b)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqadd_s8, int8x8_t)
> +
> +/*
> +** test_vqadd_u16:
> +** uqadd v0\.4h, (v0\.4h, v1\.4h|v1\.4h, v0\.4h)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqadd_u16, uint16x4_t)
> +
> +/*
> +** test_vqadd_s16:
> +** sqadd v0\.4h, (v0\.4h, v1\.4h|v1\.4h, v0\.4h)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqadd_s16, int16x4_t)
> +
> +/*
> +** test_vqadd_u32:
> +** uqadd v0\.2s, (v0\.2s, v1\.2s|v1\.2s, v0\.2s)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqadd_u32, uint32x2_t)
> +
> +/*
> +** test_vqadd_s32:
> +** sqadd v0\.2s, (v0\.2s, v1\.2s|v1\.2s, v0\.2s)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqadd_s32, int32x2_t)
> +
> +/*
> +** test_vqadd_u64:
> +** uqadd d0, (d0, d1|d1, d0)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqadd_u64, uint64x1_t)
> +
> +/*
> +** test_vqadd_s64:
> +** sqadd d0, (d0, d1|d1, d0)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqadd_s64, int64x1_t)
> +
> +/*
> +** test_vqaddq_u8:
> +** uqadd v0\.16b, (v0\.16b, v1\.16b|v1\.16b, v0\.16b)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqaddq_u8, uint8x16_t)
> +
> +/*
> +** test_vqaddq_s8:
> +** sqadd v0\.16b, (v0\.16b, v1\.16b|v1\.16b, v0\.16b)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqaddq_s8, int8x16_t)
> +
> +/*
> +** test_vqaddq_u16:
> +** uqadd v0\.8h, (v0\.8h, v1\.8h|v1\.8h, v0\.8h)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqaddq_u16, uint16x8_t)
> +
> +/*
> +** test_vqaddq_s16:
> +** sqadd v0\.8h, (v0\.8h, v1\.8h|v1\.8h, v0\.8h)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqaddq_s16, int16x8_t)
> +
> +/*
> +** test_vqaddq_u32:
> +** uqadd v0\.4s, (v0\.4s, v1\.4s|v1\.4s, v0\.4s)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqaddq_u32, uint32x4_t)
> +
> +/*
> +** test_vqaddq_s32:
> +** sqadd v0\.4s, (v0\.4s, v1\.4s|v1\.4s, v0\.4s)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqaddq_s32, int32x4_t)
> +
> +/*
> +** test_vqaddq_u64:
> +** uqadd v0\.2d, (v0\.2d, v1\.2d|v1\.2d, v0\.2d)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqaddq_u64, uint64x2_t)
> +
> +/*
> +** test_vqaddq_s64:
> +** sqadd v0\.2d, (v0\.2d, v1\.2d|v1\.2d, v0\.2d)
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqaddq_s64, int64x2_t)
> +
> +/*
> +** test_vqaddb_u8:
> +** dup v([0-9]+)\.8b, w[0-9]+
> +** dup v([0-9]+)\.8b, w[0-9]+
> +** uqadd b([0-9]+), (b\2, b\1|b\1, b\2)
> +** umov w0, v\3\.b\[0\]
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqaddb_u8, uint8_t)
> +
> +/*
> +** test_vqaddb_s8:
> +** dup v([0-9]+)\.8b, w[0-9]+
> +** dup v([0-9]+)\.8b, w[0-9]+
> +** sqadd b([0-9]+), (b\2, b\1|b\1, b\2)
> +** umov w0, v\3\.b\[0\]
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqaddb_s8, int8_t)
> +
> +/*
> +** test_vqaddh_u16:
> +** dup v([0-9]+)\.4h, w[0-9]+
> +** dup v([0-9]+)\.4h, w[0-9]+
> +** uqadd h([0-9]+), (h\2, h\1|h\1, h\2)
> +** umov w0, v\3\.h\[0\]
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqaddh_u16, uint16_t)
> +
> +/*
> +** test_vqaddh_s16:
> +** dup v([0-9]+)\.4h, w[0-9]+
> +** dup v([0-9]+)\.4h, w[0-9]+
> +** sqadd h([0-9]+), (h\2, h\1|h\1, h\2)
> +** umov w0, v\3\.h\[0\]
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqaddh_s16, int16_t)
> +
> +/*
> +** test_vqadds_u32:
> +** adds (w[0-9]+), (w0, w1|w1, w0)
> +** csinv w0, \1, wzr, cc
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqadds_u32, uint32_t)
> +
> +/*
> +** test_vqadds_s32:
> +** fmov (s[0-9]+), w[0-9]+
> +** fmov (s[0-9]+), w[0-9]+
> +** sqadd s([0-9]+), (\2, \1|\1, \2)
> +** fmov w0, s\3
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqadds_s32, int32_t)
> +
> +/*
> +** test_vqaddd_u64:
> +** adds (x[0-9]+), (x0, x1|x1, x0)
> +** csinv x0, \1, xzr, cc
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqaddd_u64, uint64_t)
> +
> +/*
> +** test_vqaddd_s64:
> +** fmov (d[0-9]+), x[0-9]+
> +** fmov (d[0-9]+), x[0-9]+
> +** sqadd d([0-9]+), (\2, \1|\1, \2)
> +** fmov x0, d\3
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqaddd_s64, int64_t)
> diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vqsub.c b/gcc/testsuite/gcc.target/aarch64/neon/vqsub.c
> new file mode 100644
> index 00000000000..52ac2f102eb
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/neon/vqsub.c
> @@ -0,0 +1,192 @@
> +/* { dg-do compile } */
> +/* { dg-final { check-function-bodies "**" "" } } */
> +
> +#include "arm_neon_test.h"
> +
> +/*
> +** test_vqsub_u8:
> +** uqsub v0\.8b, v0\.8b, v1\.8b
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsub_u8, uint8x8_t)
> +
> +/*
> +** test_vqsub_s8:
> +** sqsub v0\.8b, v0\.8b, v1\.8b
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsub_s8, int8x8_t)
> +
> +/*
> +** test_vqsub_u16:
> +** uqsub v0\.4h, v0\.4h, v1\.4h
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsub_u16, uint16x4_t)
> +
> +/*
> +** test_vqsub_s16:
> +** sqsub v0\.4h, v0\.4h, v1\.4h
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsub_s16, int16x4_t)
> +
> +/*
> +** test_vqsub_u32:
> +** uqsub v0\.2s, v0\.2s, v1\.2s
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsub_u32, uint32x2_t)
> +
> +/*
> +** test_vqsub_s32:
> +** sqsub v0\.2s, v0\.2s, v1\.2s
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsub_s32, int32x2_t)
> +
> +/*
> +** test_vqsub_u64:
> +** uqsub d0, d0, d1
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsub_u64, uint64x1_t)
> +
> +/*
> +** test_vqsub_s64:
> +** sqsub d0, d0, d1
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsub_s64, int64x1_t)
> +
> +/*
> +** test_vqsubq_u8:
> +** uqsub v0\.16b, v0\.16b, v1\.16b
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubq_u8, uint8x16_t)
> +
> +/*
> +** test_vqsubq_s8:
> +** sqsub v0\.16b, v0\.16b, v1\.16b
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubq_s8, int8x16_t)
> +
> +/*
> +** test_vqsubq_u16:
> +** uqsub v0\.8h, v0\.8h, v1\.8h
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubq_u16, uint16x8_t)
> +
> +/*
> +** test_vqsubq_s16:
> +** sqsub v0\.8h, v0\.8h, v1\.8h
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubq_s16, int16x8_t)
> +
> +/*
> +** test_vqsubq_u32:
> +** uqsub v0\.4s, v0\.4s, v1\.4s
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubq_u32, uint32x4_t)
> +
> +/*
> +** test_vqsubq_s32:
> +** sqsub v0\.4s, v0\.4s, v1\.4s
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubq_s32, int32x4_t)
> +
> +/*
> +** test_vqsubq_u64:
> +** uqsub v0\.2d, v0\.2d, v1\.2d
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubq_u64, uint64x2_t)
> +
> +/*
> +** test_vqsubq_s64:
> +** sqsub v0\.2d, v0\.2d, v1\.2d
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubq_s64, int64x2_t)
> +
> +/*
> +** test_vqsubb_u8:
> +** dup v([0-9]+)\.8b, w0
> +** dup v([0-9]+)\.8b, w1
> +** uqsub b([0-9]+), b\1, b\2
> +** umov w0, v\3\.b\[0\]
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubb_u8, uint8_t)
> +
> +/*
> +** test_vqsubb_s8:
> +** dup v([0-9]+)\.8b, w0
> +** dup v([0-9]+)\.8b, w1
> +** sqsub b([0-9]+), b\1, b\2
> +** umov w0, v\3\.b\[0\]
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubb_s8, int8_t)
> +
> +/*
> +** test_vqsubh_u16:
> +** dup v([0-9]+)\.4h, w0
> +** dup v([0-9]+)\.4h, w1
> +** uqsub h([0-9]+), h\1, h\2
> +** umov w0, v\3\.h\[0\]
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubh_u16, uint16_t)
> +
> +/*
> +** test_vqsubh_s16:
> +** dup v([0-9]+)\.4h, w0
> +** dup v([0-9]+)\.4h, w1
> +** sqsub h([0-9]+), h\1, h\2
> +** umov w0, v\3\.h\[0\]
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubh_s16, int16_t)
> +
> +/*
> +** test_vqsubs_u32:
> +** subs (w[0-9]+), w0, w1
> +** csel w0, \1, wzr, cs
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubs_u32, uint32_t)
> +
> +/*
> +** test_vqsubs_s32:
> +** fmov (s[0-9]+), w0
> +** fmov (s[0-9]+), w1
> +** sqsub s([0-9]+), \1, \2
> +** fmov w0, s\3
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubs_s32, int32_t)
> +
> +/*
> +** test_vqsubd_u64:
> +** subs (x[0-9]+), x0, x1
> +** csel x0, \1, xzr, cs
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubd_u64, uint64_t)
> +
> +/*
> +** test_vqsubd_s64:
> +** fmov (d[0-9]+), x0
> +** fmov (d[0-9]+), x1
> +** sqsub d([0-9]+), \1, \2
> +** fmov x0, d\3
> +** ret
> +*/
> +TEST_UNIFORM_BINARY (vqsubd_s64, int64_t)
> --
> 2.43.0
>
@@ -753,6 +753,20 @@ NEON_FUNCTION (vaddd, gimple_expr, (PLUS_EXPR))
NEON_FUNCTION (vadd, gimple_expr, (PLUS_EXPR, PLUS_EXPR, BIT_XOR_EXPR))
NEON_FUNCTION (vaddq, gimple_expr, (PLUS_EXPR, PLUS_EXPR, BIT_XOR_EXPR))
+// Saturating arithmetic
+NEON_FUNCTION (vqaddb, gimple_ifn, (IFN_SAT_ADD))
+NEON_FUNCTION (vqaddh, gimple_ifn, (IFN_SAT_ADD))
+NEON_FUNCTION (vqadds, gimple_ifn, (IFN_SAT_ADD))
+NEON_FUNCTION (vqaddd, gimple_ifn, (IFN_SAT_ADD))
+NEON_FUNCTION (vqadd, gimple_ifn, (IFN_SAT_ADD))
+NEON_FUNCTION (vqaddq, gimple_ifn, (IFN_SAT_ADD))
+NEON_FUNCTION (vqsubb, gimple_ifn, (IFN_SAT_SUB))
+NEON_FUNCTION (vqsubh, gimple_ifn, (IFN_SAT_SUB))
+NEON_FUNCTION (vqsubs, gimple_ifn, (IFN_SAT_SUB))
+NEON_FUNCTION (vqsubd, gimple_ifn, (IFN_SAT_SUB))
+NEON_FUNCTION (vqsub, gimple_ifn, (IFN_SAT_SUB))
+NEON_FUNCTION (vqsubq, gimple_ifn, (IFN_SAT_SUB))
+
// Bitwise operations
NEON_FUNCTION (vand, gimple_expr, (BIT_AND_EXPR))
NEON_FUNCTION (vandq, gimple_expr, (BIT_AND_EXPR))
@@ -76,6 +76,22 @@ DEF_NEON_FUNCTION (vadd, h_float, ("D0,D0,D0"))
DEF_NEON_FUNCTION (vaddq, h_float, ("Q0,Q0,Q0"))
#undef REQUIRED_EXTENSIONS
+// Saturating arithmetic
+#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD)
+DEF_NEON_FUNCTION (vqaddb, b_integer, ("s0,s0,s0"))
+DEF_NEON_FUNCTION (vqaddh, h_integer, ("s0,s0,s0"))
+DEF_NEON_FUNCTION (vqadds, s_integer, ("s0,s0,s0"))
+DEF_NEON_FUNCTION (vqaddd, d_integer, ("s0,s0,s0"))
+DEF_NEON_FUNCTION (vqadd, bhs_integer, ("D0,D0,D0"))
+DEF_NEON_FUNCTION (vqaddq, all_integer, ("Q0,Q0,Q0"))
+DEF_NEON_FUNCTION (vqsubb, b_integer, ("s0,s0,s0"))
+DEF_NEON_FUNCTION (vqsubh, h_integer, ("s0,s0,s0"))
+DEF_NEON_FUNCTION (vqsubs, s_integer, ("s0,s0,s0"))
+DEF_NEON_FUNCTION (vqsubd, d_integer, ("s0,s0,s0"))
+DEF_NEON_FUNCTION (vqsub, bhs_integer, ("D0,D0,D0"))
+DEF_NEON_FUNCTION (vqsubq, all_integer, ("Q0,Q0,Q0"))
+#undef REQUIRED_EXTENSIONS
+
// Bitwise operations
#define REQUIRED_EXTENSIONS nonstreaming_only (AARCH64_FL_SIMD)
DEF_NEON_FUNCTION (vand, all_integer, ("D0,D0,D0"))
@@ -1071,41 +1071,6 @@ vsubw_high_u32 (uint64x2_t __a, uint32x4_t __b)
return __builtin_aarch64_usubw2v4si_uuu (__a, __b);
}
-__extension__ extern __inline int8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqadd_s8 (int8x8_t __a, int8x8_t __b)
-{
- return (int8x8_t) __builtin_aarch64_ssaddv8qi (__a, __b);
-}
-
-__extension__ extern __inline int16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqadd_s16 (int16x4_t __a, int16x4_t __b)
-{
- return (int16x4_t) __builtin_aarch64_ssaddv4hi (__a, __b);
-}
-
-__extension__ extern __inline int32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqadd_s32 (int32x2_t __a, int32x2_t __b)
-{
- return (int32x2_t) __builtin_aarch64_ssaddv2si (__a, __b);
-}
-
-__extension__ extern __inline int64x1_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqadd_s64 (int64x1_t __a, int64x1_t __b)
-{
- return (int64x1_t) {__builtin_aarch64_ssadddi (__a[0], __b[0])};
-}
-
-__extension__ extern __inline uint8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqadd_u8 (uint8x8_t __a, uint8x8_t __b)
-{
- return __builtin_aarch64_usaddv8qi_uuu (__a, __b);
-}
-
__extension__ extern __inline int8x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vhsub_s8 (int8x8_t __a, int8x8_t __b)
@@ -1358,18 +1323,11 @@ vsubhn_high_u64 (uint32x2_t __a, uint64x2_t __b, uint64x2_t __c)
return __builtin_aarch64_subhn2v2di_uuuu (__a, __b, __c);
}
-__extension__ extern __inline uint16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqadd_u16 (uint16x4_t __a, uint16x4_t __b)
-{
- return __builtin_aarch64_usaddv4hi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint32x2_t
+__extension__ extern __inline int64x1_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqadd_u32 (uint32x2_t __a, uint32x2_t __b)
+vqadd_s64 (int64x1_t __a, int64x1_t __b)
{
- return __builtin_aarch64_usaddv2si_uuu (__a, __b);
+ return (int64x1_t) {__builtin_aarch64_ssadddi (__a[0], __b[0])};
}
__extension__ extern __inline uint64x1_t
@@ -1379,83 +1337,6 @@ vqadd_u64 (uint64x1_t __a, uint64x1_t __b)
return (uint64x1_t) {__builtin_aarch64_usadddi_uuu (__a[0], __b[0])};
}
-__extension__ extern __inline int8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqaddq_s8 (int8x16_t __a, int8x16_t __b)
-{
- return (int8x16_t) __builtin_aarch64_ssaddv16qi (__a, __b);
-}
-
-__extension__ extern __inline int16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqaddq_s16 (int16x8_t __a, int16x8_t __b)
-{
- return (int16x8_t) __builtin_aarch64_ssaddv8hi (__a, __b);
-}
-
-__extension__ extern __inline int32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqaddq_s32 (int32x4_t __a, int32x4_t __b)
-{
- return (int32x4_t) __builtin_aarch64_ssaddv4si (__a, __b);
-}
-
-__extension__ extern __inline int64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqaddq_s64 (int64x2_t __a, int64x2_t __b)
-{
- return (int64x2_t) __builtin_aarch64_ssaddv2di (__a, __b);
-}
-
-__extension__ extern __inline uint8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqaddq_u8 (uint8x16_t __a, uint8x16_t __b)
-{
- return __builtin_aarch64_usaddv16qi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqaddq_u16 (uint16x8_t __a, uint16x8_t __b)
-{
- return __builtin_aarch64_usaddv8hi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqaddq_u32 (uint32x4_t __a, uint32x4_t __b)
-{
- return __builtin_aarch64_usaddv4si_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqaddq_u64 (uint64x2_t __a, uint64x2_t __b)
-{
- return __builtin_aarch64_usaddv2di_uuu (__a, __b);
-}
-
-__extension__ extern __inline int8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsub_s8 (int8x8_t __a, int8x8_t __b)
-{
- return (int8x8_t) __builtin_aarch64_sssubv8qi (__a, __b);
-}
-
-__extension__ extern __inline int16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsub_s16 (int16x4_t __a, int16x4_t __b)
-{
- return (int16x4_t) __builtin_aarch64_sssubv4hi (__a, __b);
-}
-
-__extension__ extern __inline int32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsub_s32 (int32x2_t __a, int32x2_t __b)
-{
- return (int32x2_t) __builtin_aarch64_sssubv2si (__a, __b);
-}
-
__extension__ extern __inline int64x1_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vqsub_s64 (int64x1_t __a, int64x1_t __b)
@@ -1463,27 +1344,6 @@ vqsub_s64 (int64x1_t __a, int64x1_t __b)
return (int64x1_t) {__builtin_aarch64_sssubdi (__a[0], __b[0])};
}
-__extension__ extern __inline uint8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsub_u8 (uint8x8_t __a, uint8x8_t __b)
-{
- return __builtin_aarch64_ussubv8qi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsub_u16 (uint16x4_t __a, uint16x4_t __b)
-{
- return __builtin_aarch64_ussubv4hi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsub_u32 (uint32x2_t __a, uint32x2_t __b)
-{
- return __builtin_aarch64_ussubv2si_uuu (__a, __b);
-}
-
__extension__ extern __inline uint64x1_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vqsub_u64 (uint64x1_t __a, uint64x1_t __b)
@@ -1491,62 +1351,6 @@ vqsub_u64 (uint64x1_t __a, uint64x1_t __b)
return (uint64x1_t) {__builtin_aarch64_ussubdi_uuu (__a[0], __b[0])};
}
-__extension__ extern __inline int8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubq_s8 (int8x16_t __a, int8x16_t __b)
-{
- return (int8x16_t) __builtin_aarch64_sssubv16qi (__a, __b);
-}
-
-__extension__ extern __inline int16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubq_s16 (int16x8_t __a, int16x8_t __b)
-{
- return (int16x8_t) __builtin_aarch64_sssubv8hi (__a, __b);
-}
-
-__extension__ extern __inline int32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubq_s32 (int32x4_t __a, int32x4_t __b)
-{
- return (int32x4_t) __builtin_aarch64_sssubv4si (__a, __b);
-}
-
-__extension__ extern __inline int64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubq_s64 (int64x2_t __a, int64x2_t __b)
-{
- return (int64x2_t) __builtin_aarch64_sssubv2di (__a, __b);
-}
-
-__extension__ extern __inline uint8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubq_u8 (uint8x16_t __a, uint8x16_t __b)
-{
- return __builtin_aarch64_ussubv16qi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubq_u16 (uint16x8_t __a, uint16x8_t __b)
-{
- return __builtin_aarch64_ussubv8hi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubq_u32 (uint32x4_t __a, uint32x4_t __b)
-{
- return __builtin_aarch64_ussubv4si_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubq_u64 (uint64x2_t __a, uint64x2_t __b)
-{
- return __builtin_aarch64_ussubv2di_uuu (__a, __b);
-}
-
__extension__ extern __inline int8x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vqneg_s8 (int8x8_t __a)
@@ -13921,64 +13725,6 @@ vqabsd_s64 (int64_t __a)
return __builtin_aarch64_sqabsdi (__a);
}
-/* vqadd */
-
-__extension__ extern __inline int8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqaddb_s8 (int8_t __a, int8_t __b)
-{
- return (int8_t) __builtin_aarch64_ssaddqi (__a, __b);
-}
-
-__extension__ extern __inline int16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqaddh_s16 (int16_t __a, int16_t __b)
-{
- return (int16_t) __builtin_aarch64_ssaddhi (__a, __b);
-}
-
-__extension__ extern __inline int32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqadds_s32 (int32_t __a, int32_t __b)
-{
- return (int32_t) __builtin_aarch64_ssaddsi (__a, __b);
-}
-
-__extension__ extern __inline int64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqaddd_s64 (int64_t __a, int64_t __b)
-{
- return __builtin_aarch64_ssadddi (__a, __b);
-}
-
-__extension__ extern __inline uint8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqaddb_u8 (uint8_t __a, uint8_t __b)
-{
- return (uint8_t) __builtin_aarch64_usaddqi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqaddh_u16 (uint16_t __a, uint16_t __b)
-{
- return (uint16_t) __builtin_aarch64_usaddhi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqadds_u32 (uint32_t __a, uint32_t __b)
-{
- return (uint32_t) __builtin_aarch64_usaddsi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqaddd_u64 (uint64_t __a, uint64_t __b)
-{
- return __builtin_aarch64_usadddi_uuu (__a, __b);
-}
-
/* vqdmlal */
__extension__ extern __inline int32x4_t
@@ -15620,64 +15366,6 @@ vqshrund_n_s64 (int64_t __a, const int __b)
return (int32_t) __builtin_aarch64_sqshrun_ndi (__a, __b);
}
-/* vqsub */
-
-__extension__ extern __inline int8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubb_s8 (int8_t __a, int8_t __b)
-{
- return (int8_t) __builtin_aarch64_sssubqi (__a, __b);
-}
-
-__extension__ extern __inline int16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubh_s16 (int16_t __a, int16_t __b)
-{
- return (int16_t) __builtin_aarch64_sssubhi (__a, __b);
-}
-
-__extension__ extern __inline int32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubs_s32 (int32_t __a, int32_t __b)
-{
- return (int32_t) __builtin_aarch64_sssubsi (__a, __b);
-}
-
-__extension__ extern __inline int64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubd_s64 (int64_t __a, int64_t __b)
-{
- return __builtin_aarch64_sssubdi (__a, __b);
-}
-
-__extension__ extern __inline uint8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubb_u8 (uint8_t __a, uint8_t __b)
-{
- return (uint8_t) __builtin_aarch64_ussubqi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubh_u16 (uint16_t __a, uint16_t __b)
-{
- return (uint16_t) __builtin_aarch64_ussubhi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubs_u32 (uint32_t __a, uint32_t __b)
-{
- return (uint32_t) __builtin_aarch64_ussubsi_uuu (__a, __b);
-}
-
-__extension__ extern __inline uint64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vqsubd_u64 (uint64_t __a, uint64_t __b)
-{
- return __builtin_aarch64_ussubdi_uuu (__a, __b);
-}
-
/* vqtbl2 */
__extension__ extern __inline int8x8_t
new file mode 100644
@@ -0,0 +1,192 @@
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_neon_test.h"
+
+/*
+** test_vqadd_u8:
+** uqadd v0\.8b, (v0\.8b, v1\.8b|v1\.8b, v0\.8b)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqadd_u8, uint8x8_t)
+
+/*
+** test_vqadd_s8:
+** sqadd v0\.8b, (v0\.8b, v1\.8b|v1\.8b, v0\.8b)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqadd_s8, int8x8_t)
+
+/*
+** test_vqadd_u16:
+** uqadd v0\.4h, (v0\.4h, v1\.4h|v1\.4h, v0\.4h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqadd_u16, uint16x4_t)
+
+/*
+** test_vqadd_s16:
+** sqadd v0\.4h, (v0\.4h, v1\.4h|v1\.4h, v0\.4h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqadd_s16, int16x4_t)
+
+/*
+** test_vqadd_u32:
+** uqadd v0\.2s, (v0\.2s, v1\.2s|v1\.2s, v0\.2s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqadd_u32, uint32x2_t)
+
+/*
+** test_vqadd_s32:
+** sqadd v0\.2s, (v0\.2s, v1\.2s|v1\.2s, v0\.2s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqadd_s32, int32x2_t)
+
+/*
+** test_vqadd_u64:
+** uqadd d0, (d0, d1|d1, d0)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqadd_u64, uint64x1_t)
+
+/*
+** test_vqadd_s64:
+** sqadd d0, (d0, d1|d1, d0)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqadd_s64, int64x1_t)
+
+/*
+** test_vqaddq_u8:
+** uqadd v0\.16b, (v0\.16b, v1\.16b|v1\.16b, v0\.16b)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqaddq_u8, uint8x16_t)
+
+/*
+** test_vqaddq_s8:
+** sqadd v0\.16b, (v0\.16b, v1\.16b|v1\.16b, v0\.16b)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqaddq_s8, int8x16_t)
+
+/*
+** test_vqaddq_u16:
+** uqadd v0\.8h, (v0\.8h, v1\.8h|v1\.8h, v0\.8h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqaddq_u16, uint16x8_t)
+
+/*
+** test_vqaddq_s16:
+** sqadd v0\.8h, (v0\.8h, v1\.8h|v1\.8h, v0\.8h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqaddq_s16, int16x8_t)
+
+/*
+** test_vqaddq_u32:
+** uqadd v0\.4s, (v0\.4s, v1\.4s|v1\.4s, v0\.4s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqaddq_u32, uint32x4_t)
+
+/*
+** test_vqaddq_s32:
+** sqadd v0\.4s, (v0\.4s, v1\.4s|v1\.4s, v0\.4s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqaddq_s32, int32x4_t)
+
+/*
+** test_vqaddq_u64:
+** uqadd v0\.2d, (v0\.2d, v1\.2d|v1\.2d, v0\.2d)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqaddq_u64, uint64x2_t)
+
+/*
+** test_vqaddq_s64:
+** sqadd v0\.2d, (v0\.2d, v1\.2d|v1\.2d, v0\.2d)
+** ret
+*/
+TEST_UNIFORM_BINARY (vqaddq_s64, int64x2_t)
+
+/*
+** test_vqaddb_u8:
+** dup v([0-9]+)\.8b, w[0-9]+
+** dup v([0-9]+)\.8b, w[0-9]+
+** uqadd b([0-9]+), (b\2, b\1|b\1, b\2)
+** umov w0, v\3\.b\[0\]
+** ret
+*/
+TEST_UNIFORM_BINARY (vqaddb_u8, uint8_t)
+
+/*
+** test_vqaddb_s8:
+** dup v([0-9]+)\.8b, w[0-9]+
+** dup v([0-9]+)\.8b, w[0-9]+
+** sqadd b([0-9]+), (b\2, b\1|b\1, b\2)
+** umov w0, v\3\.b\[0\]
+** ret
+*/
+TEST_UNIFORM_BINARY (vqaddb_s8, int8_t)
+
+/*
+** test_vqaddh_u16:
+** dup v([0-9]+)\.4h, w[0-9]+
+** dup v([0-9]+)\.4h, w[0-9]+
+** uqadd h([0-9]+), (h\2, h\1|h\1, h\2)
+** umov w0, v\3\.h\[0\]
+** ret
+*/
+TEST_UNIFORM_BINARY (vqaddh_u16, uint16_t)
+
+/*
+** test_vqaddh_s16:
+** dup v([0-9]+)\.4h, w[0-9]+
+** dup v([0-9]+)\.4h, w[0-9]+
+** sqadd h([0-9]+), (h\2, h\1|h\1, h\2)
+** umov w0, v\3\.h\[0\]
+** ret
+*/
+TEST_UNIFORM_BINARY (vqaddh_s16, int16_t)
+
+/*
+** test_vqadds_u32:
+** adds (w[0-9]+), (w0, w1|w1, w0)
+** csinv w0, \1, wzr, cc
+** ret
+*/
+TEST_UNIFORM_BINARY (vqadds_u32, uint32_t)
+
+/*
+** test_vqadds_s32:
+** fmov (s[0-9]+), w[0-9]+
+** fmov (s[0-9]+), w[0-9]+
+** sqadd s([0-9]+), (\2, \1|\1, \2)
+** fmov w0, s\3
+** ret
+*/
+TEST_UNIFORM_BINARY (vqadds_s32, int32_t)
+
+/*
+** test_vqaddd_u64:
+** adds (x[0-9]+), (x0, x1|x1, x0)
+** csinv x0, \1, xzr, cc
+** ret
+*/
+TEST_UNIFORM_BINARY (vqaddd_u64, uint64_t)
+
+/*
+** test_vqaddd_s64:
+** fmov (d[0-9]+), x[0-9]+
+** fmov (d[0-9]+), x[0-9]+
+** sqadd d([0-9]+), (\2, \1|\1, \2)
+** fmov x0, d\3
+** ret
+*/
+TEST_UNIFORM_BINARY (vqaddd_s64, int64_t)
new file mode 100644
@@ -0,0 +1,192 @@
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_neon_test.h"
+
+/*
+** test_vqsub_u8:
+** uqsub v0\.8b, v0\.8b, v1\.8b
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsub_u8, uint8x8_t)
+
+/*
+** test_vqsub_s8:
+** sqsub v0\.8b, v0\.8b, v1\.8b
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsub_s8, int8x8_t)
+
+/*
+** test_vqsub_u16:
+** uqsub v0\.4h, v0\.4h, v1\.4h
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsub_u16, uint16x4_t)
+
+/*
+** test_vqsub_s16:
+** sqsub v0\.4h, v0\.4h, v1\.4h
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsub_s16, int16x4_t)
+
+/*
+** test_vqsub_u32:
+** uqsub v0\.2s, v0\.2s, v1\.2s
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsub_u32, uint32x2_t)
+
+/*
+** test_vqsub_s32:
+** sqsub v0\.2s, v0\.2s, v1\.2s
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsub_s32, int32x2_t)
+
+/*
+** test_vqsub_u64:
+** uqsub d0, d0, d1
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsub_u64, uint64x1_t)
+
+/*
+** test_vqsub_s64:
+** sqsub d0, d0, d1
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsub_s64, int64x1_t)
+
+/*
+** test_vqsubq_u8:
+** uqsub v0\.16b, v0\.16b, v1\.16b
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubq_u8, uint8x16_t)
+
+/*
+** test_vqsubq_s8:
+** sqsub v0\.16b, v0\.16b, v1\.16b
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubq_s8, int8x16_t)
+
+/*
+** test_vqsubq_u16:
+** uqsub v0\.8h, v0\.8h, v1\.8h
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubq_u16, uint16x8_t)
+
+/*
+** test_vqsubq_s16:
+** sqsub v0\.8h, v0\.8h, v1\.8h
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubq_s16, int16x8_t)
+
+/*
+** test_vqsubq_u32:
+** uqsub v0\.4s, v0\.4s, v1\.4s
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubq_u32, uint32x4_t)
+
+/*
+** test_vqsubq_s32:
+** sqsub v0\.4s, v0\.4s, v1\.4s
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubq_s32, int32x4_t)
+
+/*
+** test_vqsubq_u64:
+** uqsub v0\.2d, v0\.2d, v1\.2d
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubq_u64, uint64x2_t)
+
+/*
+** test_vqsubq_s64:
+** sqsub v0\.2d, v0\.2d, v1\.2d
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubq_s64, int64x2_t)
+
+/*
+** test_vqsubb_u8:
+** dup v([0-9]+)\.8b, w0
+** dup v([0-9]+)\.8b, w1
+** uqsub b([0-9]+), b\1, b\2
+** umov w0, v\3\.b\[0\]
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubb_u8, uint8_t)
+
+/*
+** test_vqsubb_s8:
+** dup v([0-9]+)\.8b, w0
+** dup v([0-9]+)\.8b, w1
+** sqsub b([0-9]+), b\1, b\2
+** umov w0, v\3\.b\[0\]
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubb_s8, int8_t)
+
+/*
+** test_vqsubh_u16:
+** dup v([0-9]+)\.4h, w0
+** dup v([0-9]+)\.4h, w1
+** uqsub h([0-9]+), h\1, h\2
+** umov w0, v\3\.h\[0\]
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubh_u16, uint16_t)
+
+/*
+** test_vqsubh_s16:
+** dup v([0-9]+)\.4h, w0
+** dup v([0-9]+)\.4h, w1
+** sqsub h([0-9]+), h\1, h\2
+** umov w0, v\3\.h\[0\]
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubh_s16, int16_t)
+
+/*
+** test_vqsubs_u32:
+** subs (w[0-9]+), w0, w1
+** csel w0, \1, wzr, cs
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubs_u32, uint32_t)
+
+/*
+** test_vqsubs_s32:
+** fmov (s[0-9]+), w0
+** fmov (s[0-9]+), w1
+** sqsub s([0-9]+), \1, \2
+** fmov w0, s\3
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubs_s32, int32_t)
+
+/*
+** test_vqsubd_u64:
+** subs (x[0-9]+), x0, x1
+** csel x0, \1, xzr, cs
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubd_u64, uint64_t)
+
+/*
+** test_vqsubd_s64:
+** fmov (d[0-9]+), x0
+** fmov (d[0-9]+), x1
+** sqsub d([0-9]+), \1, \2
+** fmov x0, d\3
+** ret
+*/
+TEST_UNIFORM_BINARY (vqsubd_s64, int64_t)