Port the `vmul` family of NEON intrinsics to pragma-based framework, and
add assembly tests for every variant.
gcc/ChangeLog:
* config/aarch64/aarch64-neon-builtins-base.cc (vmulh, vmul,
vmulq): New function bases.
* config/aarch64/aarch64-acle-builtins.h (neon_mul): New type
array.
* config/aarch64/aarch64-neon-builtins-base.def (vmul, vmulq,
vmulh): New function declarations.
* config/aarch64/arm_neon.h (vmul_s8, vmul_s16, vmul_s32,
vmul_f32, vmul_f64, vmul_u8, vmul_u16, vmul_u32, vmulq_s8,
vmulq_s16, vmulq_s32, vmulq_f32, vmulq_f64, vmulq_u8,
vmulq_u16, vmulq_u32, vmul_f16, vmulq_f16): Delete function
definitions.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/neon/arm_neon_test.h (TEST_BINARY_LANE):
New macro.
* gcc.target/aarch64/neon/vmul.c: New test.
---
gcc/config/aarch64/aarch64-acle-builtins.h | 5 +
.../aarch64/aarch64-neon-builtins-base.cc | 44 +-
.../aarch64/aarch64-neon-builtins-base.def | 26 +
gcc/config/aarch64/arm_neon.h | 479 ------------------
.../gcc.target/aarch64/neon/arm_neon_test.h | 6 +
gcc/testsuite/gcc.target/aarch64/neon/vmul.c | 479 ++++++++++++++++++
6 files changed, 552 insertions(+), 487 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/neon/vmul.c
diff --git a/gcc/config/aarch64/aarch64-acle-builtins.h
b/gcc/config/aarch64/aarch64-acle-builtins.h
index 1572594872b..d685d44e80e 100644
--- a/gcc/config/aarch64/aarch64-acle-builtins.h
+++ b/gcc/config/aarch64/aarch64-acle-builtins.h
@@ -1951,6 +1951,10 @@ function_expander::result_mode () const
TYPES_bhs_integer (S, D, T), \
TYPES_hs_float (S, D, T)
+#define TYPES_neon_mul(S,D,T) \
+ TYPES_bhs_integer (S,D,T), \
+ TYPES_sd_float (S,D,T)
+
/* _p8 _s8 _u8 _mf8
_p16 _s16 _u16 _f16
_s32 _u32 _f32
@@ -2228,6 +2232,7 @@ DEF_SVE_TYPES_ARRAY (neon_rev32);
DEF_SVE_TYPES_ARRAY (neon_rev64);
DEF_SVE_TYPES_ARRAY (neon_reinterpret);
DEF_SVE_TYPES_ARRAY (neon_reinterpretq);
+DEF_SVE_TYPES_ARRAY (neon_mul);
static const group_suffix_index groups_none[] = {
GROUP_none, NUM_GROUP_SUFFIXES
diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
index be5db38a8d6..fe6d569171f 100644
--- a/gcc/config/aarch64/aarch64-neon-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-neon-builtins-base.cc
@@ -238,21 +238,29 @@ public:
}
};
+enum class arith_kind
+{
+ normal,
+ dup,
+ lane
+};
+
/* Like gimple_expr above, but converts signed inputs to unsigned first, to
avoid undefined behaviour on overflow. */
-class gimple_arith : public gimple_function_base
+template <arith_kind kind>
+class gimple_arith_base : public gimple_function_base
{
tree_code m_int_code;
tree_code m_float_code;
tree_code m_poly_code;
public:
- constexpr gimple_arith (tree_code code)
+ constexpr gimple_arith_base (tree_code code)
: m_int_code (code), m_float_code (code), m_poly_code (code)
{}
- constexpr gimple_arith (tree_code int_code, tree_code float_code,
- tree_code poly_code)
+ constexpr gimple_arith_base (tree_code int_code, tree_code float_code,
+ tree_code poly_code)
: m_int_code (int_code), m_float_code (float_code), m_poly_code (poly_code)
{}
@@ -268,11 +276,21 @@ public:
auto nargs = gimple_call_num_args (f.call);
auto arg0 = nargs >= 1 ? gimple_call_arg (f.call, 0) : nullptr;
auto arg1 = nargs >= 2 ? gimple_call_arg (f.call, 1) : nullptr;
- auto arg2 = nargs >= 3 ? gimple_call_arg (f.call, 2) : nullptr;
+
+ if (kind == arith_kind::dup)
+ arg1 = f.force_val (build_vec_dup (TREE_TYPE (arg0), arg1));
+
+ if (kind == arith_kind::lane)
+ {
+ auto lane_idx = gimple_call_arg (f.call, 2);
+ arg1 = f.force_val (build_lane_get (arg1, lane_idx));
+ if (VECTOR_TYPE_P (TREE_TYPE (arg0)))
+ arg1 = f.force_val (build_vec_dup (TREE_TYPE (arg0), arg1));
+ }
+
auto build = [&] (auto code, auto type) {
auto ret = nargs == 1 ? fold_build1 (code, type, arg0)
- : nargs == 2 ? fold_build2 (code, type, arg0, arg1)
- : fold_build3 (code, type, arg0, arg1, arg2);
+ : fold_build2 (code, type, arg0, arg1);
return f.force_val (ret);
};
@@ -290,7 +308,6 @@ public:
};
arg0 = to_unsigned (arg0);
arg1 = to_unsigned (arg1);
- arg2 = to_unsigned (arg2);
ret = build (m_int_code, unsigned_type);
ret = fold_build1 (VIEW_CONVERT_EXPR, signed_type, f.force_val (ret));
break;
@@ -321,6 +338,9 @@ public:
return gimple_build_assign (f.lhs, ret);
}
};
+using gimple_arith = gimple_arith_base<arith_kind::normal>;
+using gimple_arith_dup = gimple_arith_base<arith_kind::dup>;
+using gimple_arith_lane = gimple_arith_base<arith_kind::lane>;
struct gimple_create : public gimple_function_base
{
@@ -882,6 +902,14 @@ NEON_FUNCTION (vdupb_lane, vdupb_laneq, vduph_lane,
vduph_laneq,
NEON_FUNCTION (vadd, vaddq, vaddd, gimple_arith, (PLUS_EXPR, PLUS_EXPR,
BIT_XOR_EXPR))
NEON_FUNCTION (vsub, vsubq, vsubd, gimple_arith, (MINUS_EXPR))
+NEON_FUNCTION (vmul, vmulq, gimple_arith, (MULT_EXPR))
+NEON_FUNCTION (vmul_n, vmulq_n, gimple_arith_dup, (MULT_EXPR))
+NEON_FUNCTION (vmul_lane, vmul_laneq,
+ vmulq_lane, vmulq_laneq,
+ vmulh_lane, vmulh_laneq,
+ vmuls_lane, vmuls_laneq,
+ vmuld_lane, vmuld_laneq, gimple_arith_lane, (MULT_EXPR))
+
// Saturating arithmetic
NEON_FUNCTION (vqaddb, vqaddh, vqadds, vqaddd, vqadd, vqaddq, gimple_ifn,
(IFN_SAT_ADD))
NEON_FUNCTION (vqsubb, vqsubh, vqsubs, vqsubd, vqsub, vqsubq, gimple_ifn,
(IFN_SAT_SUB))
diff --git a/gcc/config/aarch64/aarch64-neon-builtins-base.def
b/gcc/config/aarch64/aarch64-neon-builtins-base.def
index 2034416634a..e96bd77be92 100644
--- a/gcc/config/aarch64/aarch64-neon-builtins-base.def
+++ b/gcc/config/aarch64/aarch64-neon-builtins-base.def
@@ -76,6 +76,20 @@ DEF_NEON_FUNCTION (vaddq, bhdq_poly, ("Q0,Q0,Q0"))
DEF_NEON_FUNCTION (vsubd, d_integer, ("s0,s0,s0"))
DEF_NEON_FUNCTION (vsub, all_arith_no_fp16, ("D0,D0,D0"))
DEF_NEON_FUNCTION (vsubq, all_arith_no_fp16, ("Q0,Q0,Q0"))
+
+// Multiplication
+DEF_NEON_FUNCTION (vmul, neon_mul, ("D0,D0,D0"))
+DEF_NEON_FUNCTION (vmulq, neon_mul, ("Q0,Q0,Q0"))
+DEF_NEON_FUNCTION (vmul_n, neon_mul, ("D0,D0,s0"))
+DEF_NEON_FUNCTION (vmulq_n, neon_mul, ("Q0,Q0,s0"))
+DEF_NEON_FUNCTION (vmul_lane, neon_mul, ("D0,D0,D0,ss32", lane<2>))
+DEF_NEON_FUNCTION (vmul_laneq, neon_mul, ("D0,D0,Q0,ss32", lane<2>))
+DEF_NEON_FUNCTION (vmulq_lane, neon_mul, ("Q0,Q0,D0,ss32", lane<2>))
+DEF_NEON_FUNCTION (vmulq_laneq, neon_mul, ("Q0,Q0,Q0,ss32", lane<2>))
+DEF_NEON_FUNCTION (vmuls_lane, neon_mul, ("s0,s0,D0,ss32", lane<2>))
+DEF_NEON_FUNCTION (vmuls_laneq, neon_mul, ("s0,s0,Q0,ss32", lane<2>))
+DEF_NEON_FUNCTION (vmuld_lane, neon_mul, ("s0,s0,D0,ss32", lane<2>))
+DEF_NEON_FUNCTION (vmuld_laneq, neon_mul, ("s0,s0,Q0,ss32", lane<2>))
#undef REQUIRED_EXTENSIONS
// Lanewise arithmetic (FP16)
@@ -87,6 +101,18 @@ DEF_NEON_FUNCTION (vaddq, h_float, ("Q0,Q0,Q0"))
// Subtraction
DEF_NEON_FUNCTION (vsub, h_float, ("D0,D0,D0"))
DEF_NEON_FUNCTION (vsubq, h_float, ("Q0,Q0,Q0"))
+
+// Multiplication
+DEF_NEON_FUNCTION (vmul, h_float, ("D0,D0,D0"))
+DEF_NEON_FUNCTION (vmulq, h_float, ("Q0,Q0,Q0"))
+DEF_NEON_FUNCTION (vmul_n, h_float, ("D0,D0,s0"))
+DEF_NEON_FUNCTION (vmulq_n, h_float, ("Q0,Q0,s0"))
+DEF_NEON_FUNCTION (vmul_lane, h_float, ("D0,D0,D0,ss32", lane<2>))
+DEF_NEON_FUNCTION (vmul_laneq, h_float, ("D0,D0,Q0,ss32", lane<2>))
+DEF_NEON_FUNCTION (vmulq_lane, h_float, ("Q0,Q0,D0,ss32", lane<2>))
+DEF_NEON_FUNCTION (vmulq_laneq, h_float, ("Q0,Q0,Q0,ss32", lane<2>))
+DEF_NEON_FUNCTION (vmulh_lane, h_float, ("s0,s0,D0,ss32", lane<2>))
+DEF_NEON_FUNCTION (vmulh_laneq, h_float, ("s0,s0,Q0,ss32", lane<2>))
#undef REQUIRED_EXTENSIONS
// Saturating arithmetic
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index b0072059ccd..201e8de2621 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -469,62 +469,6 @@ vdivq_f64 (float64x2_t __a, float64x2_t __b)
return __a / __b;
}
-__extension__ extern __inline int8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_s8 (int8x8_t __a, int8x8_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline int16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_s16 (int16x4_t __a, int16x4_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline int32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_s32 (int32x2_t __a, int32x2_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline float32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_f32 (float32x2_t __a, float32x2_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline float64x1_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_f64 (float64x1_t __a, float64x1_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint8x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_u8 (uint8x8_t __a, uint8x8_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_u16 (uint16x4_t __a, uint16x4_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_u32 (uint32x2_t __a, uint32x2_t __b)
-{
- return __a * __b;
-}
-
__extension__ extern __inline poly8x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vmul_p8 (poly8x8_t __a, poly8x8_t __b)
@@ -532,62 +476,6 @@ vmul_p8 (poly8x8_t __a, poly8x8_t __b)
return __builtin_aarch64_pmulv8qi_ppp (__a, __b);
}
-__extension__ extern __inline int8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_s8 (int8x16_t __a, int8x16_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline int16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_s16 (int16x8_t __a, int16x8_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline int32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_s32 (int32x4_t __a, int32x4_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline float32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_f32 (float32x4_t __a, float32x4_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline float64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_f64 (float64x2_t __a, float64x2_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint8x16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_u8 (uint8x16_t __a, uint8x16_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_u16 (uint16x8_t __a, uint16x8_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_u32 (uint32x4_t __a, uint32x4_t __b)
-{
- return __a * __b;
-}
-
__extension__ extern __inline poly8x16_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vmulq_p8 (poly8x16_t __a, poly8x16_t __b)
@@ -12251,303 +12139,6 @@ vmlsq_laneq_u32 (uint32x4_t __a, uint32x4_t __b,
return (__a - (__b * __aarch64_vget_lane_any (__c, __lane)));
}
-/* vmul_lane */
-
-__extension__ extern __inline float32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_lane_f32 (float32x2_t __a, float32x2_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline float64x1_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_lane_f64 (float64x1_t __a, float64x1_t __b, const int __lane)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline int16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_lane_s16 (int16x4_t __a, int16x4_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline int32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_lane_s32 (int32x2_t __a, int32x2_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline uint16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_lane_u16 (uint16x4_t __a, uint16x4_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline uint32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_lane_u32 (uint32x2_t __a, uint32x2_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-/* vmuld_lane */
-
-__extension__ extern __inline float64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmuld_lane_f64 (float64_t __a, float64x1_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline float64_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmuld_laneq_f64 (float64_t __a, float64x2_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-/* vmuls_lane */
-
-__extension__ extern __inline float32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmuls_lane_f32 (float32_t __a, float32x2_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline float32_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmuls_laneq_f32 (float32_t __a, float32x4_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-/* vmul_laneq */
-
-__extension__ extern __inline float32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_laneq_f32 (float32x2_t __a, float32x4_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline float64x1_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_laneq_f64 (float64x1_t __a, float64x2_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline int16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_laneq_s16 (int16x4_t __a, int16x8_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline int32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_laneq_s32 (int32x2_t __a, int32x4_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline uint16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_laneq_u16 (uint16x4_t __a, uint16x8_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline uint32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_laneq_u32 (uint32x2_t __a, uint32x4_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-/* vmul_n */
-
-__extension__ extern __inline float64x1_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_n_f64 (float64x1_t __a, float64_t __b)
-{
- return (float64x1_t) { vget_lane_f64 (__a, 0) * __b };
-}
-
-/* vmulq_lane */
-
-__extension__ extern __inline float32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_lane_f32 (float32x4_t __a, float32x2_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline float64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_lane_f64 (float64x2_t __a, float64x1_t __b, const int __lane)
-{
- __AARCH64_LANE_CHECK (__a, __lane);
- return __a * __b[0];
-}
-
-__extension__ extern __inline int16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_lane_s16 (int16x8_t __a, int16x4_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline int32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_lane_s32 (int32x4_t __a, int32x2_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline uint16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_lane_u16 (uint16x8_t __a, uint16x4_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline uint32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_lane_u32 (uint32x4_t __a, uint32x2_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-/* vmulq_laneq */
-
-__extension__ extern __inline float32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_laneq_f32 (float32x4_t __a, float32x4_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline float64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_laneq_f64 (float64x2_t __a, float64x2_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline int16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_laneq_s16 (int16x8_t __a, int16x8_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline int32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_laneq_s32 (int32x4_t __a, int32x4_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline uint16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_laneq_u16 (uint16x8_t __a, uint16x8_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline uint32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_laneq_u32 (uint32x4_t __a, uint32x4_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-/* vmul_n. */
-
-__extension__ extern __inline float32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_n_f32 (float32x2_t __a, float32_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline float32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_n_f32 (float32x4_t __a, float32_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline float64x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_n_f64 (float64x2_t __a, float64_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline int16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_n_s16 (int16x4_t __a, int16_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline int16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_n_s16 (int16x8_t __a, int16_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline int32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_n_s32 (int32x2_t __a, int32_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline int32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_n_s32 (int32x4_t __a, int32_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_n_u16 (uint16x4_t __a, uint16_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_n_u16 (uint16x8_t __a, uint16_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint32x2_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_n_u32 (uint32x2_t __a, uint32_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline uint32x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_n_u32 (uint32x4_t __a, uint32_t __b)
-{
- return __a * __b;
-}
-
/* vneg */
__extension__ extern __inline float32x2_t
@@ -18695,20 +18286,6 @@ vminq_f16 (float16x8_t __a, float16x8_t __b)
return __builtin_aarch64_fmin_nanv8hf (__a, __b);
}
-__extension__ extern __inline float16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_f16 (float16x4_t __a, float16x4_t __b)
-{
- return __a * __b;
-}
-
-__extension__ extern __inline float16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_f16 (float16x8_t __a, float16x8_t __b)
-{
- return __a * __b;
-}
-
__extension__ extern __inline float16x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vmulx_f16 (float16x4_t __a, float16x4_t __b)
@@ -18977,62 +18554,6 @@ vfmsq_n_f16 (float16x8_t __a, float16x8_t __b,
float16_t __c)
return vfmsq_f16 (__a, __b, vdupq_n_f16 (__c));
}
-__extension__ extern __inline float16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulh_lane_f16 (float16_t __a, float16x4_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline float16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_lane_f16 (float16x4_t __a, float16x4_t __b, const int __lane)
-{
- return vmul_f16 (__a, vdup_n_f16 (__aarch64_vget_lane_any (__b, __lane)));
-}
-
-__extension__ extern __inline float16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_lane_f16 (float16x8_t __a, float16x4_t __b, const int __lane)
-{
- return vmulq_f16 (__a, vdupq_n_f16 (__aarch64_vget_lane_any (__b, __lane)));
-}
-
-__extension__ extern __inline float16_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulh_laneq_f16 (float16_t __a, float16x8_t __b, const int __lane)
-{
- return __a * __aarch64_vget_lane_any (__b, __lane);
-}
-
-__extension__ extern __inline float16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_laneq_f16 (float16x4_t __a, float16x8_t __b, const int __lane)
-{
- return vmul_f16 (__a, vdup_n_f16 (__aarch64_vget_lane_any (__b, __lane)));
-}
-
-__extension__ extern __inline float16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_laneq_f16 (float16x8_t __a, float16x8_t __b, const int __lane)
-{
- return vmulq_f16 (__a, vdupq_n_f16 (__aarch64_vget_lane_any (__b, __lane)));
-}
-
-__extension__ extern __inline float16x4_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmul_n_f16 (float16x4_t __a, float16_t __b)
-{
- return vmul_lane_f16 (__a, vdup_n_f16 (__b), 0);
-}
-
-__extension__ extern __inline float16x8_t
-__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-vmulq_n_f16 (float16x8_t __a, float16_t __b)
-{
- return vmulq_laneq_f16 (__a, vdupq_n_f16 (__b), 0);
-}
-
__extension__ extern __inline float16_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vmulxh_lane_f16 (float16_t __a, float16x4_t __b, const int __lane)
diff --git a/gcc/testsuite/gcc.target/aarch64/neon/arm_neon_test.h
b/gcc/testsuite/gcc.target/aarch64/neon/arm_neon_test.h
index fe90b124cc7..5a9d02decd6 100644
--- a/gcc/testsuite/gcc.target/aarch64/neon/arm_neon_test.h
+++ b/gcc/testsuite/gcc.target/aarch64/neon/arm_neon_test.h
@@ -12,6 +12,12 @@
#define TEST_BINARY(NAME, RET_TYPE, ARG_1_TYPE, ARG_2_TYPE)
\
RET_TYPE test_##NAME (ARG_1_TYPE a, ARG_2_TYPE b) { return NAME (a, b); }
+#define TEST_BINARY_LANE(NAME, RET_TYPE, ARG_1_TYPE, ARG_2_TYPE)
\
+ RET_TYPE test_##NAME (ARG_1_TYPE a, ARG_2_TYPE b)
\
+ {
\
+ return NAME (a, b, VEC_LEN (b) - 1);
\
+ }
+
#define TEST_UNIFORM_BINARY(NAME, TYPE) TEST_BINARY (NAME, TYPE, TYPE, TYPE)
#define TEST_TERNARY(NAME, RET_TYPE, ARG_1_TYPE, ARG_2_TYPE, ARG_3_TYPE)
\
diff --git a/gcc/testsuite/gcc.target/aarch64/neon/vmul.c
b/gcc/testsuite/gcc.target/aarch64/neon/vmul.c
new file mode 100644
index 00000000000..688aa56c733
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/neon/vmul.c
@@ -0,0 +1,479 @@
+/* { dg-do compile } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include "arm_neon_test.h"
+
+/*
+** test_vmul_s8:
+** mul v0\.8b, (v0\.8b, v1\.8b|v1\.8b, v0\.8b)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_s8, int8x8_t)
+
+/*
+** test_vmulq_s8:
+** mul v0\.16b, (v0\.16b, v1\.16b|v1\.16b, v0\.16b)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_s8, int8x16_t)
+
+/*
+** test_vmul_s16:
+** mul v0\.4h, (v0\.4h, v1\.4h|v1\.4h, v0\.4h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_s16, int16x4_t)
+
+/*
+** test_vmulq_s16:
+** mul v0\.8h, (v0\.8h, v1\.8h|v1\.8h, v0\.8h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_s16, int16x8_t)
+
+/*
+** test_vmul_s32:
+** mul v0\.2s, (v0\.2s, v1\.2s|v1\.2s, v0\.2s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_s32, int32x2_t)
+
+/*
+** test_vmulq_s32:
+** mul v0\.4s, (v0\.4s, v1\.4s|v1\.4s, v0\.4s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_s32, int32x4_t)
+
+/*
+** test_vmul_u8:
+** mul v0\.8b, (v0\.8b, v1\.8b|v1\.8b, v0\.8b)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_u8, uint8x8_t)
+
+/*
+** test_vmulq_u8:
+** mul v0\.16b, (v0\.16b, v1\.16b|v1\.16b, v0\.16b)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_u8, uint8x16_t)
+
+/*
+** test_vmul_u16:
+** mul v0\.4h, (v0\.4h, v1\.4h|v1\.4h, v0\.4h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_u16, uint16x4_t)
+
+/*
+** test_vmulq_u16:
+** mul v0\.8h, (v0\.8h, v1\.8h|v1\.8h, v0\.8h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_u16, uint16x8_t)
+
+/*
+** test_vmul_u32:
+** mul v0\.2s, (v0\.2s, v1\.2s|v1\.2s, v0\.2s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_u32, uint32x2_t)
+
+/*
+** test_vmulq_u32:
+** mul v0\.4s, (v0\.4s, v1\.4s|v1\.4s, v0\.4s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_u32, uint32x4_t)
+
+/*
+** test_vmul_f32:
+** fmul v0\.2s, (v0\.2s, v1\.2s|v1\.2s, v0\.2s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_f32, float32x2_t)
+
+/*
+** test_vmulq_f32:
+** fmul v0\.4s, (v0\.4s, v1\.4s|v1\.4s, v0\.4s)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_f32, float32x4_t)
+
+/*
+** test_vmul_f64:
+** fmul d0, (d0, d1|d1, d0)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_f64, float64x1_t)
+
+/*
+** test_vmulq_f64:
+** fmul v0\.2d, (v0\.2d, v1\.2d|v1\.2d, v0\.2d)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_f64, float64x2_t)
+
+/*
+** test_vmul_f16:
+** fmul v0\.4h, (v0\.4h, v1\.4h|v1\.4h, v0\.4h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmul_f16, float16x4_t)
+
+/*
+** test_vmulq_f16:
+** fmul v0\.8h, (v0\.8h, v1\.8h|v1\.8h, v0\.8h)
+** ret
+*/
+TEST_UNIFORM_BINARY (vmulq_f16, float16x8_t)
+
+/*
+** test_vmul_n_f16:
+** fmul v0\.4h, v0\.4h, v1\.h\[0\]
+** ret
+*/
+TEST_BINARY (vmul_n_f16, float16x4_t, float16x4_t, float16_t)
+
+/*
+** test_vmulq_n_f16:
+** fmul v0\.8h, v0\.8h, v1\.h\[0\]
+** ret
+*/
+TEST_BINARY (vmulq_n_f16, float16x8_t, float16x8_t, float16_t)
+
+/*
+** test_vmul_n_f32:
+** fmul v0\.2s, v0\.2s, v1\.s\[0\]
+** ret
+*/
+TEST_BINARY (vmul_n_f32, float32x2_t, float32x2_t, float32_t)
+
+/*
+** test_vmulq_n_f32:
+** fmul v0\.4s, v0\.4s, v1\.s\[0\]
+** ret
+*/
+TEST_BINARY (vmulq_n_f32, float32x4_t, float32x4_t, float32_t)
+
+/*
+** test_vmul_n_f64:
+** fmul d0, (d0, d1|d1, d0)
+** ret
+*/
+TEST_BINARY (vmul_n_f64, float64x1_t, float64x1_t, float64_t)
+
+/*
+** test_vmulq_n_f64:
+** fmul v0\.2d, v0\.2d, v1\.d\[0\]
+** ret
+*/
+TEST_BINARY (vmulq_n_f64, float64x2_t, float64x2_t, float64_t)
+
+/*
+** test_vmul_n_s16:
+** dup v([0-9]+)\.4h, w0
+** mul v0\.4h, v0\.4h, v\1\.h\[0\]
+** ret
+*/
+TEST_BINARY (vmul_n_s16, int16x4_t, int16x4_t, int16_t)
+
+/*
+** test_vmulq_n_s16:
+** dup v([0-9]+)\.4h, w0
+** mul v0\.8h, v0\.8h, v\1\.h\[0\]
+** ret
+*/
+TEST_BINARY (vmulq_n_s16, int16x8_t, int16x8_t, int16_t)
+
+/*
+** test_vmul_n_s32:
+** fmov s([0-9]+), w0
+** mul v0\.2s, v0\.2s, v\1\.s\[0\]
+** ret
+*/
+TEST_BINARY (vmul_n_s32, int32x2_t, int32x2_t, int32_t)
+
+/*
+** test_vmulq_n_s32:
+** fmov s([0-9]+), w0
+** mul v0\.4s, v0\.4s, v\1\.s\[0\]
+** ret
+*/
+TEST_BINARY (vmulq_n_s32, int32x4_t, int32x4_t, int32_t)
+
+/*
+** test_vmul_n_u16:
+** dup v([0-9]+)\.4h, w0
+** mul v0\.4h, v0\.4h, v\1\.h\[0\]
+** ret
+*/
+TEST_BINARY (vmul_n_u16, uint16x4_t, uint16x4_t, uint16_t)
+
+/*
+** test_vmulq_n_u16:
+** dup v([0-9]+)\.4h, w0
+** mul v0\.8h, v0\.8h, v\1\.h\[0\]
+** ret
+*/
+TEST_BINARY (vmulq_n_u16, uint16x8_t, uint16x8_t, uint16_t)
+
+/*
+** test_vmul_n_u32:
+** fmov s([0-9]+), w0
+** mul v0\.2s, v0\.2s, v\1\.s\[0\]
+** ret
+*/
+TEST_BINARY (vmul_n_u32, uint32x2_t, uint32x2_t, uint32_t)
+
+/*
+** test_vmulq_n_u32:
+** fmov s([0-9]+), w0
+** mul v0\.4s, v0\.4s, v\1\.s\[0\]
+** ret
+*/
+TEST_BINARY (vmulq_n_u32, uint32x4_t, uint32x4_t, uint32_t)
+
+/*
+** test_vmul_lane_f16:
+** fmul v0\.4h, v0\.4h, v1\.h\[3\]
+** ret
+*/
+TEST_BINARY_LANE (vmul_lane_f16, float16x4_t, float16x4_t, float16x4_t)
+
+/*
+** test_vmul_laneq_f16:
+** fmul v0\.4h, v0\.4h, v1\.h\[7\]
+** ret
+*/
+TEST_BINARY_LANE (vmul_laneq_f16, float16x4_t, float16x4_t, float16x8_t)
+
+/*
+** test_vmulq_lane_f16:
+** fmul v0\.8h, v0\.8h, v1\.h\[3\]
+** ret
+*/
+TEST_BINARY_LANE (vmulq_lane_f16, float16x8_t, float16x8_t, float16x4_t)
+
+/*
+** test_vmulq_laneq_f16:
+** fmul v0\.8h, v0\.8h, v1\.h\[7\]
+** ret
+*/
+TEST_BINARY_LANE (vmulq_laneq_f16, float16x8_t, float16x8_t, float16x8_t)
+
+/*
+** test_vmul_lane_f32:
+** fmul v0\.2s, v0\.2s, v1\.s\[1\]
+** ret
+*/
+TEST_BINARY_LANE (vmul_lane_f32, float32x2_t, float32x2_t, float32x2_t)
+
+/*
+** test_vmul_laneq_f32:
+** fmul v0\.2s, v0\.2s, v1\.s\[3\]
+** ret
+*/
+TEST_BINARY_LANE (vmul_laneq_f32, float32x2_t, float32x2_t, float32x4_t)
+
+/*
+** test_vmulq_lane_f32:
+** fmul v0\.4s, v0\.4s, v1\.s\[1\]
+** ret
+*/
+TEST_BINARY_LANE (vmulq_lane_f32, float32x4_t, float32x4_t, float32x2_t)
+
+/*
+** test_vmulq_laneq_f32:
+** fmul v0\.4s, v0\.4s, v1\.s\[3\]
+** ret
+*/
+TEST_BINARY_LANE (vmulq_laneq_f32, float32x4_t, float32x4_t, float32x4_t)
+
+/*
+** test_vmul_lane_f64:
+** fmul d0, (d0, d1|d1, d0)
+** ret
+*/
+TEST_BINARY_LANE (vmul_lane_f64, float64x1_t, float64x1_t, float64x1_t)
+
+/*
+** test_vmul_laneq_f64:
+** fmul v0\.2d, v0\.2d, v1\.d\[1\]
+** ret
+*/
+TEST_BINARY_LANE (vmul_laneq_f64, float64x1_t, float64x1_t, float64x2_t)
+
+/*
+** test_vmulq_lane_f64:
+** fmul v0\.2d, v0\.2d, v1\.d\[0\]
+** ret
+*/
+TEST_BINARY_LANE (vmulq_lane_f64, float64x2_t, float64x2_t, float64x1_t)
+
+/*
+** test_vmulq_laneq_f64:
+** fmul v0\.2d, v0\.2d, v1\.d\[1\]
+** ret
+*/
+TEST_BINARY_LANE (vmulq_laneq_f64, float64x2_t, float64x2_t, float64x2_t)
+
+/*
+** test_vmul_lane_s16:
+** mul v0\.4h, v0\.4h, v1\.h\[3\]
+** ret
+*/
+TEST_BINARY_LANE (vmul_lane_s16, int16x4_t, int16x4_t, int16x4_t)
+
+/*
+** test_vmul_laneq_s16:
+** mul v0\.4h, v0\.4h, v1\.h\[7\]
+** ret
+*/
+TEST_BINARY_LANE (vmul_laneq_s16, int16x4_t, int16x4_t, int16x8_t)
+
+/*
+** test_vmulq_lane_s16:
+** mul v0\.8h, v0\.8h, v1\.h\[3\]
+** ret
+*/
+TEST_BINARY_LANE (vmulq_lane_s16, int16x8_t, int16x8_t, int16x4_t)
+
+/*
+** test_vmulq_laneq_s16:
+** mul v0\.8h, v0\.8h, v1\.h\[7\]
+** ret
+*/
+TEST_BINARY_LANE (vmulq_laneq_s16, int16x8_t, int16x8_t, int16x8_t)
+
+/*
+** test_vmul_lane_s32:
+** mul v0\.2s, v0\.2s, v1\.s\[1\]
+** ret
+*/
+TEST_BINARY_LANE (vmul_lane_s32, int32x2_t, int32x2_t, int32x2_t)
+
+/*
+** test_vmul_laneq_s32:
+** mul v0\.2s, v0\.2s, v1\.s\[3\]
+** ret
+*/
+TEST_BINARY_LANE (vmul_laneq_s32, int32x2_t, int32x2_t, int32x4_t)
+
+/*
+** test_vmulq_lane_s32:
+** mul v0\.4s, v0\.4s, v1\.s\[1\]
+** ret
+*/
+TEST_BINARY_LANE (vmulq_lane_s32, int32x4_t, int32x4_t, int32x2_t)
+
+/*
+** test_vmulq_laneq_s32:
+** mul v0\.4s, v0\.4s, v1\.s\[3\]
+** ret
+*/
+TEST_BINARY_LANE (vmulq_laneq_s32, int32x4_t, int32x4_t, int32x4_t)
+
+/*
+** test_vmul_lane_u16:
+
+** mul v0\.4h, v0\.4h, v1\.h\[3\]
+** ret
+*/
+TEST_BINARY_LANE (vmul_lane_u16, uint16x4_t, uint16x4_t, uint16x4_t)
+
+/*
+** test_vmul_laneq_u16:
+** mul v0\.4h, v0\.4h, v1\.h\[7\]
+** ret
+*/
+TEST_BINARY_LANE (vmul_laneq_u16, uint16x4_t, uint16x4_t, uint16x8_t)
+
+/*
+** test_vmulq_lane_u16:
+** mul v0\.8h, v0\.8h, v1\.h\[3\]
+** ret
+*/
+TEST_BINARY_LANE (vmulq_lane_u16, uint16x8_t, uint16x8_t, uint16x4_t)
+
+/*
+** test_vmulq_laneq_u16:
+** mul v0\.8h, v0\.8h, v1\.h\[7\]
+** ret
+*/
+TEST_BINARY_LANE (vmulq_laneq_u16, uint16x8_t, uint16x8_t, uint16x8_t)
+
+/*
+** test_vmul_lane_u32:
+** mul v0\.2s, v0\.2s, v1\.s\[1\]
+** ret
+*/
+TEST_BINARY_LANE (vmul_lane_u32, uint32x2_t, uint32x2_t, uint32x2_t)
+
+/*
+** test_vmul_laneq_u32:
+** mul v0\.2s, v0\.2s, v1\.s\[3\]
+** ret
+*/
+TEST_BINARY_LANE (vmul_laneq_u32, uint32x2_t, uint32x2_t, uint32x4_t)
+
+/*
+** test_vmulq_lane_u32:
+** mul v0\.4s, v0\.4s, v1\.s\[1\]
+** ret
+*/
+TEST_BINARY_LANE (vmulq_lane_u32, uint32x4_t, uint32x4_t, uint32x2_t)
+
+/*
+** test_vmulq_laneq_u32:
+** mul v0\.4s, v0\.4s, v1\.s\[3\]
+** ret
+*/
+TEST_BINARY_LANE (vmulq_laneq_u32, uint32x4_t, uint32x4_t, uint32x4_t)
+
+/*
+** test_vmulh_lane_f16:
+** dup h([0-9]+), v1\.h\[3\]
+** fmul h0, (h0, h\1|h\1, h0)
+** ret
+*/
+TEST_BINARY_LANE (vmulh_lane_f16, float16_t, float16_t, float16x4_t)
+
+/*
+** test_vmulh_laneq_f16:
+** dup h([0-9]+), v1\.h\[7\]
+** fmul h0, (h0, h\1|h\1, h0)
+** ret
+*/
+TEST_BINARY_LANE (vmulh_laneq_f16, float16_t, float16_t, float16x8_t)
+
+/*
+** test_vmuls_lane_f32:
+** dup s([0-9]+), v1\.s\[1\]
+** fmul s0, (s0, s\1|s\1, s0)
+** ret
+*/
+TEST_BINARY_LANE (vmuls_lane_f32, float32_t, float32_t, float32x2_t)
+
+/*
+** test_vmuls_laneq_f32:
+** dup s([0-9]+), v1\.s\[3\]
+** fmul s0, (s0, s\1|s\1, s0)
+** ret
+*/
+TEST_BINARY_LANE (vmuls_laneq_f32, float32_t, float32_t, float32x4_t)
+
+/*
+** test_vmuld_lane_f64:
+** fmul d0, (d0, d1|d1, d0)
+** ret
+*/
+TEST_BINARY_LANE (vmuld_lane_f64, float64_t, float64_t, float64x1_t)
+
+/*
+** test_vmuld_laneq_f64:
+** fmul v0\.2d, v0\.2d, v1\.d\[1\]
+** ret
+*/
+TEST_BINARY_LANE (vmuld_laneq_f64, float64_t, float64_t, float64x2_t)
--
2.56.0