On 15/06/2026 07:37, Artemiy Volkov wrote:
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 ();?
No. If the user passes in tuples with > 2 vectors, or non-tuple vectors, we should keep going and let `r.resolve_to` return an error, instead of ICEing
+
+    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


Reply via email to