Hi Karl,
On Thu, Dec 11, 2025 at 01:31:21PM +0000, Karl Meakin wrote:
> gcc/ChangeLog:
>
> * config/aarch64/aarch64-sve-builtins-shapes.cc (struct mop4_def): New
> function shape.
> * config/aarch64/aarch64-sve-builtins-shapes.h: New function shape.
> * config/aarch64/aarch64-sve-builtins-sme.def (DEF_SME_FUNCTION):
> Unconditionally define in terms of `DEF_SME_FUNCTION_GS`.
> (DEF_SME_ZA_FUNCTION_GS): Unconditionally define in terms of
> `DEF_SME_ZA_FUNCTION_GS_FPM`.
> (DEF_SME_ZA_FUNCTION): Unconditionally define in terms of
> `DEF_SME_ZA_FUNCTION_GS`.
> (svmop4a): New function groups.
> (svmop4s): Likewise.
> * config/aarch64/aarch64-sve-builtins.cc (TYPES_za_s_mf8): New type
> array.
> (TYPES_mop4_f16f16): Likewise.
> (TYPES_mop4_b16b16): Likewise.
> (TYPES_mop4_base): Likewise.
> (TYPES_mop4_f64f64): Likewise.
> (TYPES_mop4_i16i64): Likewise.
> (TYPES_mop4_f8f16): Likewise.
> (TYPES_mop4_f8f32): Likewise.
> (mop4_f16f16): Likewise.
> (mop4_b16b16): Likewise.
> (mop4_base): Likewise.
> (mop4_f64f64): Likewise.
> (mop4_i16i64): Likewise.
> (mop4_f8f16): Likewise.
> (mop4_f8f32): Likewise.
> (DEF_SME_ZA_FUNCTION_GS): New macro.
> (DEF_SME_ZA_FUNCTION_GS_FPM): Likewise.
> * config/aarch64/aarch64-sve-builtins.def (1x1): New SVE function mode.
> (1x2): Likewise.
> (2x1): Likewise.
> (2x2): Likewise.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/aarch64/sve/acle/general-c/mop4_b16b16.c: New test.
> * gcc.target/aarch64/sve/acle/general-c/mop4_base.c: Likewise.
> * gcc.target/aarch64/sve/acle/general-c/mop4_f16f16.c: Likewise.
> * gcc.target/aarch64/sve/acle/general-c/mop4_f64f64.c: Likewise.
> * gcc.target/aarch64/sve/acle/general-c/mop4_f8f16.c: Likewise.
> * gcc.target/aarch64/sve/acle/general-c/mop4_f8f32.c: Likewise.
> * gcc.target/aarch64/sve/acle/general-c/mop4_i16i64.c: Likewise.
> ---
> .../aarch64/aarch64-sve-builtins-shapes.cc | 41 +++++++
> .../aarch64/aarch64-sve-builtins-shapes.h | 1 +
> .../aarch64/aarch64-sve-builtins-sme.def | 79 +++++++++++--
> gcc/config/aarch64/aarch64-sve-builtins.cc | 65 ++++++++++-
> gcc/config/aarch64/aarch64-sve-builtins.def | 4 +
> .../aarch64/sve/acle/general-c/mop4_b16b16.c | 79 +++++++++++++
> .../aarch64/sve/acle/general-c/mop4_base.c | 106 ++++++++++++++++++
> .../aarch64/sve/acle/general-c/mop4_f16f16.c | 79 +++++++++++++
> .../aarch64/sve/acle/general-c/mop4_f64f64.c | 79 +++++++++++++
> .../aarch64/sve/acle/general-c/mop4_f8f16.c | 84 ++++++++++++++
> .../aarch64/sve/acle/general-c/mop4_f8f32.c | 84 ++++++++++++++
> .../aarch64/sve/acle/general-c/mop4_i16i64.c | 88 +++++++++++++++
> 12 files changed, 774 insertions(+), 15 deletions(-)
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_b16b16.c
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_base.c
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f16f16.c
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f64f64.c
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f8f16.c
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f8f32.c
> create mode 100644
> gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_i16i64.c
>
> diff --git a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
> b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
> index 3663a9d416b..3d2db1e74aa 100644
> --- a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
> +++ b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
> @@ -5412,4 +5412,45 @@ struct write_lane_zt_def : public overloaded_base<0>
> }
> };
> SHAPE (write_lane_zt);
> +
> +struct mop4_def : public overloaded_base<1>
Please keep these structs in alphabetical order.
> +{
> + void build (function_builder &b,
> + const function_group_info &group) const override
> + {
> + b.add_overloaded_functions (group, MODE_none);
> + build_all (b, "_,su64,v1,v2", group, MODE_1x1);
> + build_all (b, "_,su64,v1,u2", group, MODE_1x2);
> + build_all (b, "_,su64,u1,v2", group, MODE_2x1);
> + build_all (b, "_,su64,u1,u2", group, MODE_2x2);
> + }
> +
> + tree resolve (function_resolver &r) const override
> + {
> + mode_suffix_index mode = MODE_1x1;
> + sve_type type1;
> + sve_type type2;
> +
> + if (!r.check_num_arguments (3 + (r.fpm_mode == FPM_set))
> + || !r.require_scalar_type (0, "uint64_t")
> + || !r.require_integer_immediate (0)
> + || !(type1 = r.infer_sve_type (1))
> + || !(type2 = r.infer_sve_type (2)))
> + return error_mark_node;
> +
> + if (type1.num_vectors == 1 && type2.num_vectors == 1) mode =
> MODE_1x1;
> + else if (type1.num_vectors == 1 && type2.num_vectors == 2) mode =
> MODE_1x2;
> + else if (type1.num_vectors == 2 && type2.num_vectors == 1) mode =
> MODE_2x1;
> + else if (type1.num_vectors == 2 && type2.num_vectors == 2) mode =
> MODE_2x2;
else gcc_unreachable ();?
> +
> + return r.resolve_to (mode, r.type_suffix_ids[0],
> + type1.type, type2.type, GROUP_none);
> + }
> +
> + bool check (function_checker &c) const override
> + {
> + return c.require_immediate_range (0, 0, c.num_za_tiles () - 1);
> + }
> +};
> +SHAPE (mop4);
> }
> diff --git a/gcc/config/aarch64/aarch64-sve-builtins-shapes.h
> b/gcc/config/aarch64/aarch64-sve-builtins-shapes.h
> index 421cb1e8b85..b3d7e046437 100644
> --- a/gcc/config/aarch64/aarch64-sve-builtins-shapes.h
> +++ b/gcc/config/aarch64/aarch64-sve-builtins-shapes.h
> @@ -263,6 +263,7 @@ namespace aarch64_sve
> extern const function_shape *const write_za_slice;
> extern const function_shape *const write_zt;
> extern const function_shape *const write_lane_zt;
> + extern const function_shape *const mop4;
This list should be alphabetized as well.
> }
> }
>
> diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sme.def
> b/gcc/config/aarch64/aarch64-sve-builtins-sme.def
> index 978a74f438d..08046eb3610 100644
> --- a/gcc/config/aarch64/aarch64-sve-builtins-sme.def
> +++ b/gcc/config/aarch64/aarch64-sve-builtins-sme.def
> @@ -17,20 +17,14 @@
> along with GCC; see the file COPYING3. If not see
> <http://www.gnu.org/licenses/>. */
>
> -#ifndef DEF_SME_FUNCTION
> #define DEF_SME_FUNCTION(NAME, SHAPE, TYPES, PREDS) \
> - DEF_SME_FUNCTION_GS (NAME, SHAPE, TYPES, none, PREDS)
> -#endif
> + DEF_SME_FUNCTION_GS (NAME, SHAPE, TYPES, none, PREDS)
>
> -#ifndef DEF_SME_ZA_FUNCTION_GS
> #define DEF_SME_ZA_FUNCTION_GS(NAME, SHAPE, TYPES, GROUP, PREDS) \
> - DEF_SME_FUNCTION_GS (NAME, SHAPE, TYPES, GROUP, PREDS)
> -#endif
> + DEF_SME_ZA_FUNCTION_GS_FPM (NAME, SHAPE, TYPES, GROUP, PREDS, unused)
>
> -#ifndef DEF_SME_ZA_FUNCTION
> #define DEF_SME_ZA_FUNCTION(NAME, SHAPE, TYPES, PREDS) \
> - DEF_SME_ZA_FUNCTION_GS (NAME, SHAPE, TYPES, none, PREDS)
> -#endif
> + DEF_SME_ZA_FUNCTION_GS (NAME, SHAPE, TYPES, none, PREDS)
>
> #define REQUIRED_EXTENSIONS streaming_compatible (0)
> DEF_SME_FUNCTION (arm_has_sme, bool_inherent, none, none)
> @@ -259,6 +253,73 @@ DEF_SME_FUNCTION_GS (svwrite_lane_zt, write_lane_zt,
> all_data, none, none)
> DEF_SME_FUNCTION_GS (svluti4_zt, luti4_zt, b_integer, x4, none)
> #undef REQUIRED_EXTENSIONS
>
> +// All svmop4a functions also have `_1x2`, `2x1` and `2x2` variants, and all
> +// functions except `mf8_mf8` have `svmop4s` variants.
> +
> +// svmop4a[_1x1]_za16[_f16_f16] (only if __ARM_FEATURE_SME_F16F16 != 0)
> +#define REQUIRED_EXTENSIONS streaming_only (AARCH64_FL_SME2 \
> + | AARCH64_FL_SME_MOP4 \
> + | AARCH64_FL_SME_F16F16)
> +DEF_SME_ZA_FUNCTION_GS (svmop4a, mop4, mop4_f16f16, none, none)
> +DEF_SME_ZA_FUNCTION_GS (svmop4s, mop4, mop4_f16f16, none, none)
> +#undef REQUIRED_EXTENSIONS
> +
> +// svmop4a[_1x1]_za16[_bf16_bf16] (only if __ARM_FEATURE_SME_B16B16 != 0)
> +#define REQUIRED_EXTENSIONS streaming_only (AARCH64_FL_SME2 \
> + | AARCH64_FL_SME_MOP4 \
> + | AARCH64_FL_SME_B16B16)
> +DEF_SME_ZA_FUNCTION_GS (svmop4a, mop4, mop4_b16b16, none, none)
> +DEF_SME_ZA_FUNCTION_GS (svmop4s, mop4, mop4_b16b16, none, none)
> +#undef REQUIRED_EXTENSIONS
> +
> +// svmop4a[_1x1]_za32[_f32_f32]
> +// svmop4a[_1x1]_za32[_f16_f16]
> +// svmop4a[_1x1]_za32[_bf16_bf16]
> +// svmop4a[_1x1]_za32[_s16_s16]
> +// svmop4a[_1x1]_za32[_u16_u16]
> +// svmop4a[_1x1]_za32[_s8_s8]
> +// svmop4a[_1x1]_za32[_u8_u8]
> +// svmop4a[_1x1]_za32[_s8_u8]
> +// svmop4a[_1x1]_za32[_u8_s8]
> +#define REQUIRED_EXTENSIONS streaming_only (AARCH64_FL_SME2 \
> + | AARCH64_FL_SME_MOP4)
> +DEF_SME_ZA_FUNCTION_GS (svmop4a, mop4, mop4_base, none, none)
> +DEF_SME_ZA_FUNCTION_GS (svmop4s, mop4, mop4_base, none, none)
> +#undef REQUIRED_EXTENSIONS
I see that (up until this point) you've ordered these by width of ZA, but
ISTM it would be better to have the base variant of the feature first, and
the rest in some sort of topological order wrt additional extensions.
> +
> +// svmop4a[_1x1]_za64[_f64_f64] (only if __ARM_FEATURE_SME_F64F64 != 0)
> +#define REQUIRED_EXTENSIONS streaming_only (AARCH64_FL_SME2 \
> + | AARCH64_FL_SME_MOP4 \
> + | AARCH64_FL_SME_F64F64)
> +DEF_SME_ZA_FUNCTION_GS (svmop4a, mop4, mop4_f64f64, none, none)
> +DEF_SME_ZA_FUNCTION_GS (svmop4s, mop4, mop4_f64f64, none, none)
> +#undef REQUIRED_EXTENSIONS
> +
> +// svmop4a[_1x1]_za64[_s16_s16] (only if __ARM_FEATURE_SME_I16I64 != 0)
> +// svmop4a[_1x1]_za64[_u16_u16] (only if __ARM_FEATURE_SME_I16I64 != 0)
> +// svmop4a[_1x1]_za64[_s16_u16] (only if __ARM_FEATURE_SME_I16I64 != 0)
> +// svmop4a[_1x1]_za64[_u16_s16] (only if __ARM_FEATURE_SME_I16I64 != 0)
> +#define REQUIRED_EXTENSIONS streaming_only (AARCH64_FL_SME2 \
> + | AARCH64_FL_SME_MOP4 \
> + | AARCH64_FL_SME_I16I64)
> +DEF_SME_ZA_FUNCTION_GS (svmop4a, mop4, mop4_i16i64, none, none)
> +DEF_SME_ZA_FUNCTION_GS (svmop4s, mop4, mop4_i16i64, none, none)
> +#undef REQUIRED_EXTENSIONS
> +
> +// svmop4a[_1x1]_za16[_mf8_mf8]_fpm (only if __ARM_FEATURE_SME_F8F16 != 0)
> +#define REQUIRED_EXTENSIONS streaming_only (AARCH64_FL_SME2 \
> + | AARCH64_FL_SME_MOP4 \
> + | AARCH64_FL_SME_F8F16)
> +DEF_SME_ZA_FUNCTION_GS_FPM (svmop4a, mop4, mop4_f8f16, none, none, set)
> +#undef REQUIRED_EXTENSIONS
> +
> +// svmop4a[_1x1]_za32[_mf8_mf8]_fpm (only if __ARM_FEATURE_SME_F8F32 != 0)
> +#define REQUIRED_EXTENSIONS streaming_only (AARCH64_FL_SME2 \
> + | AARCH64_FL_SME_MOP4 \
> + | AARCH64_FL_SME_F8F32)
> +DEF_SME_ZA_FUNCTION_GS_FPM (svmop4a, mop4, mop4_f8f32, none, none, set)
> +#undef REQUIRED_EXTENSIONS
> +
> #undef DEF_SME_ZA_FUNCTION
> #undef DEF_SME_ZA_FUNCTION_GS
> #undef DEF_SME_FUNCTION
> diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc
> b/gcc/config/aarch64/aarch64-sve-builtins.cc
> index 89452578e25..11dc822ab55 100644
> --- a/gcc/config/aarch64/aarch64-sve-builtins.cc
> +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
> @@ -708,10 +708,6 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
> #define TYPES_za_s_integer(S, D, T) \
> D (za32, s32), D (za32, u32)
>
> -/* _za32_mf8. */
> -#define TYPES_za_s_mf8(S, D, T) \
> - D (za32, mf8)
> -
Are you sure this needs to be removed?
> /* _za32_f32. */
> #define TYPES_za_s_float(S, D, T) \
> D (za32, f32)
> @@ -756,6 +752,56 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
> #define TYPES_mop_i16i64_unsigned(S, D, T) \
> D (za64, u16)
>
> +// svmop4a[_1x1]_za16[_f16_f16] (only if __ARM_FEATURE_SME_F16F16 != 0)
> +#define TYPES_mop4_f16f16(S, D, T) \
> + T (za16, f16, f16)
> +
> +// svmop4a[_1x1]_za16[_bf16_bf16] (only if __ARM_FEATURE_SME_B16B16 != 0)
> +#define TYPES_mop4_b16b16(S, D, T) \
> + T (za16, bf16, bf16)
> +
> +// svmop4a[_1x1]_za32[_f32]
> +// svmop4a[_1x1]_za32[_f16_f16]
> +// svmop4a[_1x1]_za32[_bf16_bf16]
> +// svmop4a[_1x1]_za32[_s16_s16]
> +// svmop4a[_1x1]_za32[_u16_u16]
> +// svmop4a[_1x1]_za32[_s8_s8]
> +// svmop4a[_1x1]_za32[_u8_u8]
> +// svmop4a[_1x1]_za32[_s8_u8]
> +// svmop4a[_1x1]_za32[_u8_s8]
> +#define TYPES_mop4_base(S, D, T) \
> + T (za32, f32, f32), \
> + T (za32, f16, f16), \
> + T (za32, bf16, bf16), \
> + T (za32, s16, s16), \
> + T (za32, u16, u16), \
> + T (za32, s8, s8), \
> + T (za32, u8, u8), \
> + T (za32, s8, u8), \
> + T (za32, u8, s8)
> +
> +// svmop4a[_1x1]_za64[_f64_f64] (only if __ARM_FEATURE_SME_F64F64 != 0)
> +#define TYPES_mop4_f64f64(S, D, T) \
> + T (za64, f64, f64)
> +
> +// svmop4a[_1x1]_za64[_s16_s16] (only if __ARM_FEATURE_SME_I16I64 != 0)
> +// svmop4a[_1x1]_za64[_u16_u16] (only if __ARM_FEATURE_SME_I16I64 != 0)
> +// svmop4a[_1x1]_za64[_s16_u16] (only if __ARM_FEATURE_SME_I16I64 != 0)
> +// svmop4a[_1x1]_za64[_u16_s16] (only if __ARM_FEATURE_SME_I16I64 != 0)
> +#define TYPES_mop4_i16i64(S, D, T) \
> + T (za64, s16, s16), \
> + T (za64, u16, u16), \
> + T (za64, s16, u16), \
> + T (za64, u16, s16)
> +
> +// svmop4a[_1x1]_za16[_mf8_mf8]_fpm (only if __ARM_FEATURE_SME_F8F16 != 0)
> +#define TYPES_mop4_f8f16(S, D, T) \
> + T (za16, mf8, mf8)
> +
> +// svmop4a[_1x1]_za32[_mf8_mf8]_fpm (only if __ARM_FEATURE_SME_F8F32 != 0)
> +#define TYPES_mop4_f8f32(S, D, T) \
> + T (za32, mf8, mf8)
> +
> /* _za. */
> #define TYPES_za(S, D, T) \
> S (za)
> @@ -887,6 +933,13 @@ DEF_SVE_TYPES_ARRAY (mop_base_unsigned);
> DEF_SVE_TYPES_ARRAY (mop_i16i64);
> DEF_SVE_TYPES_ARRAY (mop_i16i64_signed);
> DEF_SVE_TYPES_ARRAY (mop_i16i64_unsigned);
> +DEF_SVE_TYPES_ARRAY (mop4_f16f16);
> +DEF_SVE_TYPES_ARRAY (mop4_b16b16);
> +DEF_SVE_TYPES_ARRAY (mop4_base);
> +DEF_SVE_TYPES_ARRAY (mop4_f64f64);
> +DEF_SVE_TYPES_ARRAY (mop4_i16i64);
> +DEF_SVE_TYPES_ARRAY (mop4_f8f16);
> +DEF_SVE_TYPES_ARRAY (mop4_f8f32);
These are also better alphabetized, except perhaps "base" should come
first.
Thanks,
Artemiy
> DEF_SVE_TYPES_ARRAY (za);
>
> static const group_suffix_index groups_none[] = {
> @@ -1009,11 +1062,11 @@ static CONSTEXPR const function_group_info
> sme_function_groups[] = {
> { #NAME, &functions::NAME, &shapes::SHAPE, types_##TYPES, groups_##GROUPS,
> \
> preds_##PREDS, aarch64_required_extensions::REQUIRED_EXTENSIONS, \
> FPM_unused },
> -#define DEF_SME_ZA_FUNCTION_GS(NAME, SHAPE, TYPES, GROUPS, PREDS) \
> +#define DEF_SME_ZA_FUNCTION_GS_FPM(NAME, SHAPE, TYPES, GROUPS, PREDS, FPM) \
> { #NAME, &functions::NAME##_za, &shapes::SHAPE, types_##TYPES, \
> groups_##GROUPS, preds_##PREDS, \
> aarch64_required_extensions::REQUIRED_EXTENSIONS \
> - .and_also (AARCH64_FL_ZA_ON), FPM_unused },
> + .and_also (AARCH64_FL_ZA_ON), FPM_##FPM },
> #include "aarch64-sve-builtins-sme.def"
> };
>
> diff --git a/gcc/config/aarch64/aarch64-sve-builtins.def
> b/gcc/config/aarch64/aarch64-sve-builtins.def
> index df77497abae..023e823473f 100644
> --- a/gcc/config/aarch64/aarch64-sve-builtins.def
> +++ b/gcc/config/aarch64/aarch64-sve-builtins.def
> @@ -83,6 +83,10 @@ DEF_SVE_MODE (u64base_u64offset, svuint64_t, svuint64_t,
> bytes)
> DEF_SVE_MODE (u64index, none, svuint64_t, elements)
> DEF_SVE_MODE (u64offset, none, svuint64_t, bytes)
> DEF_SVE_MODE (vnum, none, none, vectors)
> +DEF_SVE_MODE (1x1, none, none, none)
> +DEF_SVE_MODE (1x2, none, none, none)
> +DEF_SVE_MODE (2x1, none, none, none)
> +DEF_SVE_MODE (2x2, none, none, none)
>
> DEF_SVE_TYPE (svbool_t, 10, __SVBool_t, boolean_type_node)
> DEF_SVE_TYPE (svcount_t, 11, __SVCount_t, boolean_type_node)
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_b16b16.c
> b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_b16b16.c
> new file mode 100644
> index 00000000000..d9a535ba7a7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_b16b16.c
> @@ -0,0 +1,79 @@
> +// { dg-options "-std=c23 -fsyntax-only" }
> +// { dg-do compile }
> +
> +// svmop4a[_1x1]_za16[_bbf16_bbf16] (only if __ARM_FEATURE_SME_B16B16 != 0)
> +
> +#pragma GCC target "+sve2,+sme-mop4,+sme-b16b16"
> +static_assert (__ARM_FEATURE_SME_MOP4 == 1);
> +static_assert (__ARM_FEATURE_SME_B16B16 == 1);
> +#include <arm_sme.h>
> +
> +void
> +explicit_ok (svbfloat16_t bf16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_bf16_bf16 (0, bf16, bf16);
> +}
> +
> +void
> +implicit_ok (svbfloat16_t bf16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_za16 (0, bf16, bf16);
> +}
> +
> +void
> +error_not_streaming (svbfloat16_t bf16)
> +{
> + svmop4a_1x1_za16_bf16_bf16 (0, bf16, bf16); // { dg-error {ACLE function
> 'svmop4a_1x1_za16_bf16_bf16' can only be called when SME streaming mode is
> enabled} }
> + svmop4a_za16 (0, bf16, bf16); // { dg-error {ACLE function
> 'svmop4a_1x1_za16_bf16_bf16' can only be called when SME streaming mode is
> enabled} }
> +}
> +
> +void
> +error_streaming_compatible (svbfloat16_t bf16) __arm_streaming_compatible
> +{
> + svmop4a_1x1_za16_bf16_bf16 (0, bf16, bf16); // { dg-error {ACLE function
> 'svmop4a_1x1_za16_bf16_bf16' can only be called when SME streaming mode is
> enabled} }
> + svmop4a_za16 (0, bf16, bf16); // { dg-error {ACLE function
> 'svmop4a_1x1_za16_bf16_bf16' can only be called when SME streaming mode is
> enabled} }
> +}
> +
> +void
> +error_arg_count_mismatch (svbfloat16_t bf16) __arm_streaming __arm_inout
> ("za")
> +{
> + svmop4a_1x1_za16_bf16_bf16 (); // { dg-error {too few arguments to
> function 'svmop4a_1x1_za16_bf16_bf16'; expected 3, have 0} }
> + svmop4a_za16 (); // { dg-error {too few arguments to function
> 'svmop4a_za16'} }
> +
> + svmop4a_1x1_za16_bf16_bf16 (0, bf16, bf16, 0); // { dg-error {too many
> arguments to function 'svmop4a_1x1_za16_bf16_bf16'; expected 3, have 4} }
> + svmop4a_za16 (0, bf16, bf16, 0); // { dg-error {too many arguments to
> function 'svmop4a_za16'} }
> +}
> +
> +void
> +error_arg_type_mismatch (svbfloat16_t bf16, svbfloat16x2_t bf16x2,
> + svbfloat16x4_t bf16x4) __arm_streaming __arm_inout
> ("za")
> +{
> + svmop4a_1x1_za16_bf16_bf16 (0, bf16x2, bf16); // { dg-error {incompatible
> type for argument 2 of 'svmop4a_1x1_za16_bf16_bf16'} }
> + svmop4a_za16 (0, bf16x4, bf16); // { dg-error {incompatible type for
> argument 2 of 'svmop4a_1x1_za16_bf16_bf16'} }
> +}
> +
> +void
> +error_zt0_not_immediate (uint64_t zt0,
> + svbfloat16_t bf16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_bf16_bf16 (zt0, bf16, bf16); // { dg-error {argument 1 of
> 'svmop4a_1x1_za16_bf16_bf16' must be an integer constant expression} }
> + svmop4a_za16 (zt0, bf16, bf16); // { dg-error {argument 1 of
> 'svmop4a_za16' must be an integer constant expression} }
> +}
> +
> +void
> +error_zt0_not_in_range (svbfloat16_t bf16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_bf16_bf16 (-1, bf16, bf16); // { dg-error {passing -1 to
> argument 1 of 'svmop4a_1x1_za16_bf16_bf16', which expects a value in the
> range \[0, 1\]} }
> + svmop4a_za16 (-1, bf16, bf16); // { dg-error {passing -1 to argument 1 of
> 'svmop4a_za16', which expects a value in the range \[0, 1\]} }
> +
> + svmop4a_1x1_za16_bf16_bf16 (2, bf16, bf16); // { dg-error {passing 2 to
> argument 1 of 'svmop4a_1x1_za16_bf16_bf16', which expects a value in the
> range \[0, 1\]} }
> + svmop4a_za16 (2, bf16, bf16); // { dg-error {passing 2 to argument 1 of
> 'svmop4a_za16', which expects a value in the range \[0, 1\]} }
> +}
> +
> +#pragma GCC target "+nothing,+sve2,+sme2,+sme-mop4"
> +
> +void
> +error_missing_feature (svbfloat16_t bf16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_bf16_bf16 (0, bf16, bf16); // { dg-error {ACLE function
> 'svmop4a_1x1_za16_bf16_bf16' requires ISA extension 'sme-b16b16'} }
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_base.c
> b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_base.c
> new file mode 100644
> index 00000000000..5e062914705
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_base.c
> @@ -0,0 +1,106 @@
> +// { dg-options "-std=c23 -fsyntax-only" }
> +// { dg-do compile }
> +
> +// svmop4a[_1x1]_za32[_f32_f32]
> +// svmop4a[_1x1]_za32[_f16_f16]
> +// svmop4a[_1x1]_za32[_bf16_bf16]
> +// svmop4a[_1x1]_za32[_s16_s16]
> +// svmop4a[_1x1]_za32[_u16_u16]
> +// svmop4a[_1x1]_za32[_s8_s8]
> +// svmop4a[_1x1]_za32[_u8_u8]
> +// svmop4a[_1x1]_za32[_s8_u8]
> +// svmop4a[_1x1]_za32[_u8_s8]
> +
> +#pragma GCC target "+sve2,+sme-mop4"
> +static_assert (__ARM_FEATURE_SME_MOP4 == 1);
> +#include <arm_sme.h>
> +
> +void
> +explicit_ok (svfloat32_t f32, svfloat16_t f16, svbfloat16_t bf16, svint16_t
> s16,
> + svuint16_t u16, svint8_t s8,
> + svuint8_t u8) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za32_f32_f32 (0, f32, f32);
> + svmop4a_1x1_za32_f16_f16 (0, f16, f16);
> + svmop4a_1x1_za32_bf16_bf16 (0, bf16, bf16);
> + svmop4a_1x1_za32_s16_s16 (0, s16, s16);
> + svmop4a_1x1_za32_u16_u16 (0, u16, u16);
> + svmop4a_1x1_za32_s8_s8 (0, s8, s8);
> + svmop4a_1x1_za32_u8_u8 (0, u8, u8);
> + svmop4a_1x1_za32_s8_u8 (0, s8, u8);
> + svmop4a_1x1_za32_u8_s8 (0, u8, s8);
> +}
> +
> +void
> +implicit_ok (svfloat32_t f32, svfloat16_t f16, svbfloat16_t bf16, svint16_t
> s16,
> + svuint16_t u16, svint8_t s8,
> + svuint8_t u8) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_za32 (0, f32, f32);
> + svmop4a_za32 (0, f16, f16);
> + svmop4a_za32 (0, bf16, bf16);
> + svmop4a_za32 (0, s16, s16);
> + svmop4a_za32 (0, u16, u16);
> + svmop4a_za32 (0, s8, s8);
> + svmop4a_za32 (0, u8, u8);
> + svmop4a_za32 (0, s8, u8);
> + svmop4a_za32 (0, u8, s8);
> +}
> +
> +void
> +error_not_streaming (svfloat16_t f16)
> +{
> + svmop4a_1x1_za32_f16_f16 (0, f16, f16); // { dg-error {ACLE function
> 'svmop4a_1x1_za32_f16_f16' can only be called when SME streaming mode is
> enabled} }
> + svmop4a_za32 (0, f16, f16); // { dg-error {ACLE function
> 'svmop4a_1x1_za32_f16_f16' can only be called when SME streaming mode is
> enabled} }
> +}
> +
> +void
> +error_streaming_compatible (svfloat16_t f16) __arm_streaming_compatible
> +{
> + svmop4a_1x1_za32_f16_f16 (0, f16, f16); // { dg-error {ACLE function
> 'svmop4a_1x1_za32_f16_f16' can only be called when SME streaming mode is
> enabled} }
> + svmop4a_za32 (0, f16, f16); // { dg-error {ACLE function
> 'svmop4a_1x1_za32_f16_f16' can only be called when SME streaming mode is
> enabled} }
> +}
> +
> +void
> +error_arg_count_mismatch (svfloat16_t f16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za32_f16_f16 (); // { dg-error {too few arguments to function
> 'svmop4a_1x1_za32_f16_f16'; expected 3, have 0} }
> + svmop4a_za32 (); // { dg-error {too few arguments to function
> 'svmop4a_za32'} }
> +
> + svmop4a_1x1_za32_f16_f16 (0, f16, f16, 0); // { dg-error {too many
> arguments to function 'svmop4a_1x1_za32_f16_f16'; expected 3, have 4} }
> + svmop4a_za32 (0, f16, f16, 0); // { dg-error {too many arguments to
> function 'svmop4a_za32'} }
> +}
> +
> +void
> +error_arg_type_mismatch (svfloat16_t f16, svfloat16x2_t f16x2,
> + svfloat16x4_t f16x4) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za32_f16_f16 (0, f16x2, f16); // { dg-error {incompatible type
> for argument 2 of 'svmop4a_1x1_za32_f16_f16'} }
> + svmop4a_za32 (0, f16x4, f16); // { dg-error {incompatible type for
> argument 2 of 'svmop4a_1x1_za32_f16_f16'} }
> +}
> +
> +void
> +error_zt0_not_immediate (uint64_t zt0,
> + svfloat16_t f16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za32_f16_f16 (zt0, f16, f16); // { dg-error {argument 1 of
> 'svmop4a_1x1_za32_f16_f16' must be an integer constant expression} }
> + svmop4a_za32 (zt0, f16, f16); // { dg-error {argument 1 of 'svmop4a_za32'
> must be an integer constant expression} }
> +}
> +
> +void
> +error_zt0_not_in_range (svfloat16_t f16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za32_f16_f16 (-1, f16, f16); // { dg-error {passing -1 to
> argument 1 of 'svmop4a_1x1_za32_f16_f16', which expects a value in the range
> \[0, 3\]} }
> + svmop4a_za32 (-1, f16, f16); // { dg-error {passing -1 to argument 1 of
> 'svmop4a_za32', which expects a value in the range \[0, 3\]} }
> +
> + svmop4a_1x1_za32_f16_f16 (4, f16, f16); // { dg-error {passing 4 to
> argument 1 of 'svmop4a_1x1_za32_f16_f16', which expects a value in the range
> \[0, 3\]} }
> + svmop4a_za32 (4, f16, f16); // { dg-error {passing 4 to argument 1 of
> 'svmop4a_za32', which expects a value in the range \[0, 3\]} }
> +}
> +
> +#pragma GCC target "+nothing,+sve2,+sme2"
> +
> +void
> +error_missing_feature (svfloat16_t f16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za32_f16_f16 (0, f16, f16); // { dg-error {ACLE function
> 'svmop4a_1x1_za32_f16_f16' requires ISA extension 'sme-mop4'} }
> +}
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f16f16.c
> b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f16f16.c
> new file mode 100644
> index 00000000000..dd5fc855b47
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f16f16.c
> @@ -0,0 +1,79 @@
> +// { dg-options "-std=c23 -fsyntax-only" }
> +// { dg-do compile }
> +
> +// svmop4a[_1x1]_za16[_f16_f16] (only if __ARM_FEATURE_SME_F16F16 != 0)
> +
> +#pragma GCC target "+sve2,+sme-mop4,+sme-f16f16"
> +static_assert (__ARM_FEATURE_SME_MOP4 == 1);
> +static_assert (__ARM_FEATURE_SME_F16F16 == 1);
> +#include <arm_sme.h>
> +
> +void
> +explicit_ok (svfloat16_t f16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_f16_f16 (0, f16, f16);
> +}
> +
> +void
> +implicit_ok (svfloat16_t f16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_za16 (0, f16, f16);
> +}
> +
> +void
> +error_not_streaming (svfloat16_t f16)
> +{
> + svmop4a_1x1_za16_f16_f16 (0, f16, f16); // { dg-error {ACLE function
> 'svmop4a_1x1_za16_f16_f16' can only be called when SME streaming mode is
> enabled} }
> + svmop4a_za16 (0, f16, f16); // { dg-error {ACLE function
> 'svmop4a_1x1_za16_f16_f16' can only be called when SME streaming mode is
> enabled} }
> +}
> +
> +void
> +error_streaming_compatible (svfloat16_t f16) __arm_streaming_compatible
> +{
> + svmop4a_1x1_za16_f16_f16 (0, f16, f16); // { dg-error {ACLE function
> 'svmop4a_1x1_za16_f16_f16' can only be called when SME streaming mode is
> enabled} }
> + svmop4a_za16 (0, f16, f16); // { dg-error {ACLE function
> 'svmop4a_1x1_za16_f16_f16' can only be called when SME streaming mode is
> enabled} }
> +}
> +
> +void
> +error_arg_count_mismatch (svfloat16_t f16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_f16_f16 (); // { dg-error {too few arguments to function
> 'svmop4a_1x1_za16_f16_f16'; expected 3, have 0} }
> + svmop4a_za16 (); // { dg-error {too few arguments to function
> 'svmop4a_za16'} }
> +
> + svmop4a_1x1_za16_f16_f16 (0, f16, f16, 0); // { dg-error {too many
> arguments to function 'svmop4a_1x1_za16_f16_f16'; expected 3, have 4} }
> + svmop4a_za16 (0, f16, f16, 0); // { dg-error {too many arguments to
> function 'svmop4a_za16'} }
> +}
> +
> +void
> +error_arg_type_mismatch (svfloat16_t f16, svfloat16x2_t f16x2,
> + svfloat16x4_t f16x4) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_f16_f16 (0, f16x2, f16); // { dg-error {incompatible type
> for argument 2 of 'svmop4a_1x1_za16_f16_f16'} }
> + svmop4a_za16 (0, f16x4, f16); // { dg-error {incompatible type for
> argument 2 of 'svmop4a_1x1_za16_f16_f16'} }
> +}
> +
> +void
> +error_zt0_not_immediate (uint64_t zt0,
> + svfloat16_t f16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_f16_f16 (zt0, f16, f16); // { dg-error {argument 1 of
> 'svmop4a_1x1_za16_f16_f16' must be an integer constant expression} }
> + svmop4a_za16 (zt0, f16, f16); // { dg-error {argument 1 of 'svmop4a_za16'
> must be an integer constant expression} }
> +}
> +
> +void
> +error_zt0_not_in_range (svfloat16_t f16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_f16_f16 (-1, f16, f16); // { dg-error {passing -1 to
> argument 1 of 'svmop4a_1x1_za16_f16_f16', which expects a value in the range
> \[0, 1\]} }
> + svmop4a_za16 (-1, f16, f16); // { dg-error {passing -1 to argument 1 of
> 'svmop4a_za16', which expects a value in the range \[0, 1\]} }
> +
> + svmop4a_1x1_za16_f16_f16 (2, f16, f16); // { dg-error {passing 2 to
> argument 1 of 'svmop4a_1x1_za16_f16_f16', which expects a value in the range
> \[0, 1\]} }
> + svmop4a_za16 (2, f16, f16); // { dg-error {passing 2 to argument 1 of
> 'svmop4a_za16', which expects a value in the range \[0, 1\]} }
> +}
> +
> +#pragma GCC target "+nothing,+sve2,+sme2,+sme-mop4"
> +
> +void
> +error_missing_feature (svfloat16_t f16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_f16_f16 (0, f16, f16); // { dg-error {ACLE function
> 'svmop4a_1x1_za16_f16_f16' requires ISA extension 'sme-f16f16'} }
> +}
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f64f64.c
> b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f64f64.c
> new file mode 100644
> index 00000000000..9a899f5eaa7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f64f64.c
> @@ -0,0 +1,79 @@
> +// { dg-options "-std=c23 -fsyntax-only" }
> +// { dg-do compile }
> +
> +// svmop4a[_1x1]_za64[_f64_f64] (only if __ARM_FEATURE_SME_F64F64 != 0)
> +
> +#pragma GCC target "+sve2,+sme-mop4,+sme-f64f64"
> +static_assert (__ARM_FEATURE_SME_MOP4 == 1);
> +static_assert (__ARM_FEATURE_SME_F64F64 == 1);
> +#include <arm_sme.h>
> +
> +void
> +explicit_ok (svfloat64_t f64) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za64_f64_f64 (0, f64, f64);
> +}
> +
> +void
> +implicit_ok (svfloat64_t f64) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_za64 (0, f64, f64);
> +}
> +
> +void
> +error_not_streaming (svfloat64_t f64)
> +{
> + svmop4a_1x1_za64_f64_f64 (0, f64, f64); // { dg-error {ACLE function
> 'svmop4a_1x1_za64_f64_f64' can only be called when SME streaming mode is
> enabled} }
> + svmop4a_za64 (0, f64, f64); // { dg-error {ACLE function
> 'svmop4a_1x1_za64_f64_f64' can only be called when SME streaming mode is
> enabled} }
> +}
> +
> +void
> +error_streaming_compatible (svfloat64_t f64) __arm_streaming_compatible
> +{
> + svmop4a_1x1_za64_f64_f64 (0, f64, f64); // { dg-error {ACLE function
> 'svmop4a_1x1_za64_f64_f64' can only be called when SME streaming mode is
> enabled} }
> + svmop4a_za64 (0, f64, f64); // { dg-error {ACLE function
> 'svmop4a_1x1_za64_f64_f64' can only be called when SME streaming mode is
> enabled} }
> +}
> +
> +void
> +error_arg_count_mismatch (svfloat64_t f64) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za64_f64_f64 (); // { dg-error {too few arguments to function
> 'svmop4a_1x1_za64_f64_f64'; expected 3, have 0} }
> + svmop4a_za64 (); // { dg-error {too few arguments to function
> 'svmop4a_za64'} }
> +
> + svmop4a_1x1_za64_f64_f64 (0, f64, f64, 0); // { dg-error {too many
> arguments to function 'svmop4a_1x1_za64_f64_f64'; expected 3, have 4} }
> + svmop4a_za64 (0, f64, f64, 0); // { dg-error {too many arguments to
> function 'svmop4a_za64'} }
> +}
> +
> +void
> +error_arg_type_mismatch (svfloat64_t f64, svfloat64x2_t f64x2,
> + svfloat64x4_t f64x4) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za64_f64_f64 (0, f64x2, f64); // { dg-error {incompatible type
> for argument 2 of 'svmop4a_1x1_za64_f64_f64'} }
> + svmop4a_za64 (0, f64x4, f64); // { dg-error {incompatible type for
> argument 2 of 'svmop4a_1x1_za64_f64_f64'} }
> +}
> +
> +void
> +error_zt0_not_immediate (uint64_t zt0,
> + svfloat64_t f64) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za64_f64_f64 (zt0, f64, f64); // { dg-error {argument 1 of
> 'svmop4a_1x1_za64_f64_f64' must be an integer constant expression} }
> + svmop4a_za64 (zt0, f64, f64); // { dg-error {argument 1 of 'svmop4a_za64'
> must be an integer constant expression} }
> +}
> +
> +void
> +error_zt0_not_in_range (svfloat64_t f64) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za64_f64_f64 (-1, f64, f64); // { dg-error {passing -1 to
> argument 1 of 'svmop4a_1x1_za64_f64_f64', which expects a value in the range
> \[0, 7\]} }
> + svmop4a_za64 (-1, f64, f64); // { dg-error {passing -1 to argument 1 of
> 'svmop4a_za64', which expects a value in the range \[0, 7\]} }
> +
> + svmop4a_1x1_za64_f64_f64 (8, f64, f64); // { dg-error {passing 8 to
> argument 1 of 'svmop4a_1x1_za64_f64_f64', which expects a value in the range
> \[0, 7\]} }
> + svmop4a_za64 (8, f64, f64); // { dg-error {passing 8 to argument 1 of
> 'svmop4a_za64', which expects a value in the range \[0, 7\]} }
> +}
> +
> +#pragma GCC target "+nothing,+sve2,+sme2,+sme-mop4"
> +
> +void
> +error_missing_feature (svfloat64_t f64) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za64_f64_f64 (0, f64, f64); // { dg-error {ACLE function
> 'svmop4a_1x1_za64_f64_f64' requires ISA extension 'sme-f64f64'} }
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f8f16.c
> b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f8f16.c
> new file mode 100644
> index 00000000000..56021dc8cd9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f8f16.c
> @@ -0,0 +1,84 @@
> +// { dg-options "-std=c23 -fsyntax-only" }
> +// { dg-do compile }
> +
> +// svmop4a[_1x1]_za16[_mf8_mf8]_fpm (only if __ARM_FEATURE_SME_F8F16 != 0)
> +
> +#pragma GCC target "+sve2,+sme-mop4,+sme-f8f16"
> +static_assert (__ARM_FEATURE_SME_MOP4 == 1);
> +static_assert (__ARM_FEATURE_SME_F8F16 == 1);
> +#include <arm_sme.h>
> +
> +void
> +explicit_ok (svmfloat8_t mf8, fpm_t fpm) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_mf8_mf8_fpm (0, mf8, mf8, fpm);
> +}
> +
> +void
> +implicit_ok (svmfloat8_t mf8, fpm_t fpm) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_za16_fpm (0, mf8, mf8, fpm);
> +}
> +
> +void
> +error_not_streaming (svmfloat8_t mf8, fpm_t fpm)
> +{
> + svmop4a_1x1_za16_mf8_mf8_fpm (0, mf8, mf8, fpm); // { dg-error {ACLE
> function 'svmop4a_1x1_za16_mf8_mf8_fpm' can only be called when SME streaming
> mode is enabled} }
> + svmop4a_za16_fpm (0, mf8, mf8, fpm); // { dg-error {ACLE function
> 'svmop4a_1x1_za16_mf8_mf8_fpm' can only be called when SME streaming mode is
> enabled} }
> +}
> +
> +void
> +error_streaming_compatible (svmfloat8_t mf8,
> + fpm_t fpm) __arm_streaming_compatible
> +{
> + svmop4a_1x1_za16_mf8_mf8_fpm (0, mf8, mf8, fpm); // { dg-error {ACLE
> function 'svmop4a_1x1_za16_mf8_mf8_fpm' can only be called when SME streaming
> mode is enabled} }
> + svmop4a_za16_fpm (0, mf8, mf8, fpm); // { dg-error {ACLE function
> 'svmop4a_1x1_za16_mf8_mf8_fpm' can only be called when SME streaming mode is
> enabled} }
> +}
> +
> +void
> +error_arg_count_mismatch (svmfloat8_t mf8,
> + fpm_t fpm) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_mf8_mf8_fpm (); // { dg-error {too few arguments to
> function 'svmop4a_1x1_za16_mf8_mf8_fpm'; expected 4, have 0} }
> + svmop4a_za16_fpm (); // { dg-error {too few arguments to function
> 'svmop4a_za16_fpm'} }
> +
> + svmop4a_1x1_za16_mf8_mf8_fpm (0, mf8, mf8, fpm, 0); // { dg-error {too
> many arguments to function 'svmop4a_1x1_za16_mf8_mf8_fpm'; expected 4, have
> 5} }
> + svmop4a_za16_fpm (0, mf8, mf8, fpm, 0); // { dg-error {too many arguments
> to function 'svmop4a_za16_fpm'} }
> +}
> +
> +void
> +error_arg_type_mismatch (svmfloat8_t mf8, svmfloat8x2_t mf8x2,
> + svmfloat8x4_t mf8x4,
> + fpm_t fpm) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_mf8_mf8_fpm (0, mf8x2, mf8, fpm); // { dg-error
> {incompatible type for argument 2 of 'svmop4a_1x1_za16_mf8_mf8_fpm'} }
> + svmop4a_za16_fpm (0, mf8x4, mf8, fpm); // { dg-error {incompatible type
> for argument 2 of 'svmop4a_1x1_za16_mf8_mf8_fpm'} }
> +}
> +
> +void
> +error_zt0_not_immediate (uint64_t zt0, svmfloat8_t mf8,
> + fpm_t fpm) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_mf8_mf8_fpm (zt0, mf8, mf8, fpm); // { dg-error {argument
> 1 of 'svmop4a_1x1_za16_mf8_mf8_fpm' must be an integer constant expression} }
> + svmop4a_za16_fpm (zt0, mf8, mf8, fpm); // { dg-error {argument 1 of
> 'svmop4a_za16_fpm' must be an integer constant expression} }
> +}
> +
> +void
> +error_zt0_not_in_range (svmfloat8_t mf8,
> + fpm_t fpm) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_mf8_mf8_fpm (-1, mf8, mf8, fpm); // { dg-error {passing
> -1 to argument 1 of 'svmop4a_1x1_za16_mf8_mf8_fpm', which expects a value in
> the range \[0, 1\]} }
> + svmop4a_za16_fpm (-1, mf8, mf8, fpm); // { dg-error {passing -1 to
> argument 1 of 'svmop4a_za16_fpm', which expects a value in the range \[0,
> 1\]} }
> +
> + svmop4a_1x1_za16_mf8_mf8_fpm (2, mf8, mf8, fpm); // { dg-error {passing 2
> to argument 1 of 'svmop4a_1x1_za16_mf8_mf8_fpm', which expects a value in the
> range \[0, 1\]} }
> + svmop4a_za16_fpm (2, mf8, mf8, fpm); // { dg-error {passing 2 to argument
> 1 of 'svmop4a_za16_fpm', which expects a value in the range \[0, 1\]} }
> +}
> +
> +#pragma GCC target "+nothing,+sve2,+sme2,+sme-mop4"
> +
> +void
> +error_missing_feature (svmfloat8_t mf8,
> + fpm_t fpm) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za16_mf8_mf8_fpm (0, mf8, mf8, fpm); // { dg-error {ACLE
> function 'svmop4a_1x1_za16_mf8_mf8_fpm' requires ISA extension 'sme-f8f16'} }
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f8f32.c
> b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f8f32.c
> new file mode 100644
> index 00000000000..21c159a61e6
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_f8f32.c
> @@ -0,0 +1,84 @@
> +// { dg-options "-std=c23 -fsyntax-only" }
> +// { dg-do compile }
> +
> +// svmop4a[_1x1]_za32[_mf8_mf8]_fpm (only if __ARM_FEATURE_SME_F8F32 != 0)
> +
> +#pragma GCC target "+sve2,+sme-mop4,+sme-f8f32"
> +static_assert (__ARM_FEATURE_SME_MOP4 == 1);
> +static_assert (__ARM_FEATURE_SME_F8F32 == 1);
> +#include <arm_sme.h>
> +
> +void
> +explicit_ok (svmfloat8_t mf8, fpm_t fpm) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za32_mf8_mf8_fpm (0, mf8, mf8, fpm);
> +}
> +
> +void
> +implicit_ok (svmfloat8_t mf8, fpm_t fpm) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_za32_fpm (0, mf8, mf8, fpm);
> +}
> +
> +void
> +error_not_streaming (svmfloat8_t mf8, fpm_t fpm)
> +{
> + svmop4a_1x1_za32_mf8_mf8_fpm (0, mf8, mf8, fpm); // { dg-error {ACLE
> function 'svmop4a_1x1_za32_mf8_mf8_fpm' can only be called when SME streaming
> mode is enabled} }
> + svmop4a_za32_fpm (0, mf8, mf8, fpm); // { dg-error {ACLE function
> 'svmop4a_1x1_za32_mf8_mf8_fpm' can only be called when SME streaming mode is
> enabled} }
> +}
> +
> +void
> +error_streaming_compatible (svmfloat8_t mf8,
> + fpm_t fpm) __arm_streaming_compatible
> +{
> + svmop4a_1x1_za32_mf8_mf8_fpm (0, mf8, mf8, fpm); // { dg-error {ACLE
> function 'svmop4a_1x1_za32_mf8_mf8_fpm' can only be called when SME streaming
> mode is enabled} }
> + svmop4a_za32_fpm (0, mf8, mf8, fpm); // { dg-error {ACLE function
> 'svmop4a_1x1_za32_mf8_mf8_fpm' can only be called when SME streaming mode is
> enabled} }
> +}
> +
> +void
> +error_arg_count_mismatch (svmfloat8_t mf8,
> + fpm_t fpm) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za32_mf8_mf8_fpm (); // { dg-error {too few arguments to
> function 'svmop4a_1x1_za32_mf8_mf8_fpm'; expected 4, have 0} }
> + svmop4a_za32_fpm (); // { dg-error {too few arguments to function
> 'svmop4a_za32_fpm'} }
> +
> + svmop4a_1x1_za32_mf8_mf8_fpm (0, mf8, mf8, fpm, 0); // { dg-error {too
> many arguments to function 'svmop4a_1x1_za32_mf8_mf8_fpm'; expected 4, have
> 5} }
> + svmop4a_za32_fpm (0, mf8, mf8, fpm, 0); // { dg-error {too many arguments
> to function 'svmop4a_za32_fpm'} }
> +}
> +
> +void
> +error_arg_type_mismatch (svmfloat8_t mf8, svmfloat8x2_t mf8x2,
> + svmfloat8x4_t mf8x4,
> + fpm_t fpm) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za32_mf8_mf8_fpm (0, mf8x2, mf8, fpm); // { dg-error
> {incompatible type for argument 2 of 'svmop4a_1x1_za32_mf8_mf8_fpm'} }
> + svmop4a_za32_fpm (0, mf8x4, mf8, fpm); // { dg-error {incompatible type
> for argument 2 of 'svmop4a_1x1_za32_mf8_mf8_fpm'} }
> +}
> +
> +void
> +error_zt0_not_immediate (uint64_t zt0, svmfloat8_t mf8,
> + fpm_t fpm) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za32_mf8_mf8_fpm (zt0, mf8, mf8, fpm); // { dg-error {argument
> 1 of 'svmop4a_1x1_za32_mf8_mf8_fpm' must be an integer constant expression} }
> + svmop4a_za32_fpm (zt0, mf8, mf8, fpm); // { dg-error {argument 1 of
> 'svmop4a_za32_fpm' must be an integer constant expression} }
> +}
> +
> +void
> +error_zt0_not_in_range (svmfloat8_t mf8,
> + fpm_t fpm) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za32_mf8_mf8_fpm (-1, mf8, mf8, fpm); // { dg-error {passing
> -1 to argument 1 of 'svmop4a_1x1_za32_mf8_mf8_fpm', which expects a value in
> the range \[0, 3\]} }
> + svmop4a_za32_fpm (-1, mf8, mf8, fpm); // { dg-error {passing -1 to
> argument 1 of 'svmop4a_za32_fpm', which expects a value in the range \[0,
> 3\]} }
> +
> + svmop4a_1x1_za32_mf8_mf8_fpm (4, mf8, mf8, fpm); // { dg-error {passing 4
> to argument 1 of 'svmop4a_1x1_za32_mf8_mf8_fpm', which expects a value in the
> range \[0, 3\]} }
> + svmop4a_za32_fpm (4, mf8, mf8, fpm); // { dg-error {passing 4 to argument
> 1 of 'svmop4a_za32_fpm', which expects a value in the range \[0, 3\]} }
> +}
> +
> +#pragma GCC target "+nothing,+sve2,+sme2,+sme-mop4"
> +
> +void
> +error_missing_feature (svmfloat8_t mf8,
> + fpm_t fpm) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za32_mf8_mf8_fpm (0, mf8, mf8, fpm); // { dg-error {ACLE
> function 'svmop4a_1x1_za32_mf8_mf8_fpm' requires ISA extension 'sme-f8f32'} }
> +}
> diff --git
> a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_i16i64.c
> b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_i16i64.c
> new file mode 100644
> index 00000000000..ace25ff9a7b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/mop4_i16i64.c
> @@ -0,0 +1,88 @@
> +// { dg-options "-std=c23 -fsyntax-only" }
> +// { dg-do compile }
> +
> +// svmop4a[_1x1]_za64[_s16_s16] (only if __ARM_FEATURE_SME_I16I64 != 0)
> +// svmop4a[_1x1]_za64[_u16_u16] (only if __ARM_FEATURE_SME_I16I64 != 0)
> +// svmop4a[_1x1]_za64[_s16_u16] (only if __ARM_FEATURE_SME_I16I64 != 0)
> +// svmop4a[_1x1]_za64[_u16_s16] (only if __ARM_FEATURE_SME_I16I64 != 0)
> +
> +#pragma GCC target "+sve2,+sme-mop4,+sme-i16i64"
> +static_assert (__ARM_FEATURE_SME_MOP4 == 1);
> +static_assert (__ARM_FEATURE_SME_I16I64 == 1);
> +#include <arm_sme.h>
> +
> +void
> +explicit_ok (svint16_t s16, svuint16_t u16) __arm_streaming __arm_inout
> ("za")
> +{
> + svmop4a_1x1_za64_s16_s16 (0, s16, s16);
> + svmop4a_1x1_za64_u16_u16 (0, u16, u16);
> + svmop4a_1x1_za64_s16_u16 (0, s16, u16);
> + svmop4a_1x1_za64_u16_s16 (0, u16, s16);
> +}
> +
> +void
> +implicit_ok (svint16_t s16, svuint16_t u16) __arm_streaming __arm_inout
> ("za")
> +{
> + svmop4a_za64 (0, s16, s16);
> + svmop4a_za64 (0, u16, u16);
> + svmop4a_za64 (0, s16, u16);
> + svmop4a_za64 (0, u16, s16);
> +}
> +
> +void
> +error_not_streaming (svint16_t s16)
> +{
> + svmop4a_1x1_za64_s16_s16 (0, s16, s16); // { dg-error {ACLE function
> 'svmop4a_1x1_za64_s16_s16' can only be called when SME streaming mode is
> enabled} }
> + svmop4a_za64 (0, s16, s16); // { dg-error {ACLE function
> 'svmop4a_1x1_za64_s16_s16' can only be called when SME streaming mode is
> enabled} }
> +}
> +
> +void
> +error_streaming_compatible (svint16_t s16) __arm_streaming_compatible
> +{
> + svmop4a_1x1_za64_s16_s16 (0, s16, s16); // { dg-error {ACLE function
> 'svmop4a_1x1_za64_s16_s16' can only be called when SME streaming mode is
> enabled} }
> + svmop4a_za64 (0, s16, s16); // { dg-error {ACLE function
> 'svmop4a_1x1_za64_s16_s16' can only be called when SME streaming mode is
> enabled} }
> +}
> +
> +void
> +error_arg_count_mismatch (svint16_t s16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za64_s16_s16 (); // { dg-error {too few arguments to function
> 'svmop4a_1x1_za64_s16_s16'; expected 3, have 0} }
> + svmop4a_za64 (); // { dg-error {too few arguments to function
> 'svmop4a_za64'} }
> +
> + svmop4a_1x1_za64_s16_s16 (0, s16, s16, 0); // { dg-error {too many
> arguments to function 'svmop4a_1x1_za64_s16_s16'; expected 3, have 4} }
> + svmop4a_za64 (0, s16, s16, 0); // { dg-error {too many arguments to
> function 'svmop4a_za64'} }
> +}
> +
> +void
> +error_arg_type_mismatch (svint16_t s16, svint16x2_t s16x2,
> + svint16x4_t s16x4) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za64_s16_s16 (0, s16x2, s16); // { dg-error {incompatible type
> for argument 2 of 'svmop4a_1x1_za64_s16_s16'} }
> + svmop4a_za64 (0, s16x4, s16); // { dg-error {incompatible type for
> argument 2 of 'svmop4a_1x1_za64_s16_s16'} }
> +}
> +
> +void
> +error_zt0_not_immediate (uint64_t zt0,
> + svint16_t s16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za64_s16_s16 (zt0, s16, s16); // { dg-error {argument 1 of
> 'svmop4a_1x1_za64_s16_s16' must be an integer constant expression} }
> + svmop4a_za64 (zt0, s16, s16); // { dg-error {argument 1 of 'svmop4a_za64'
> must be an integer constant expression} }
> +}
> +
> +void
> +error_zt0_not_in_range (svint16_t s16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za64_s16_s16 (-1, s16, s16); // { dg-error {passing -1 to
> argument 1 of 'svmop4a_1x1_za64_s16_s16', which expects a value in the range
> \[0, 7\]} }
> + svmop4a_za64 (-1, s16, s16); // { dg-error {passing -1 to argument 1 of
> 'svmop4a_za64', which expects a value in the range \[0, 7\]} }
> +
> + svmop4a_1x1_za64_s16_s16 (8, s16, s16); // { dg-error {passing 8 to
> argument 1 of 'svmop4a_1x1_za64_s16_s16', which expects a value in the range
> \[0, 7\]} }
> + svmop4a_za64 (8, s16, s16); // { dg-error {passing 8 to argument 1 of
> 'svmop4a_za64', which expects a value in the range \[0, 7\]} }
> +}
> +
> +#pragma GCC target "+nothing,+sve2,+sme2,+sme-mop4"
> +
> +void
> +error_missing_feature (svint16_t s16) __arm_streaming __arm_inout ("za")
> +{
> + svmop4a_1x1_za64_s16_s16 (0, s16, s16); // { dg-error {ACLE function
> 'svmop4a_1x1_za64_s16_s16' requires ISA extension 'sme-i16i64'} }
> +}
> --
> 2.43.0
>