diff mbox series

[v2,3/4] aarch64: specify fpm mode in function instances and groups

Message ID 20241108161020.921071-4-claudio.bantaloukas@arm.com
State New
Headers show
Series aarch64: Add fp8 sve foundation | expand

Commit Message

Claudio Bantaloukas Nov. 8, 2024, 4:10 p.m. UTC
Some intrinsics require setting the fpm register before calling the
specific asm opcode required.
In order to simplify review, this patch:
- adds the fpm_mode_index attribute to function_group_info and
  function_instance objects
- updates existing initialisations and call sites.
- updates equality and hash operations

gcc/
	* config/aarch64/aarch64-sve-builtins-base.cc
	(svdiv_impl): Specify FPM_unused when folding.
	(svmul_impl): Likewise.
	* config/aarch64/aarch64-sve-builtins-base.def
	(svreinterpret): Specify FPM_unused mode
	* config/aarch64/aarch64-sve-builtins-shapes.cc
	(build_one): Use the group fpm_mode when creating function instances.
	* config/aarch64/aarch64-sve-builtins-sme.def
	(DEF_SME_FUNCTION): specify FPM_unset mode
	(DEF_SME_ZA_FUNCTION_GS): Allow specifying fpm mode
	(DEF_SME_ZA_FUNCTION): specify FPM_unset mode
	(svadd,svadd_write,svdot, svdot_lane, svluti2_lane_zt, svluti4_lane_zt,
	svmla, svmla_lane, svmls, svmls_lane, svread, svread_hor, svread_ver,
	svsub, svsub_write, svsudot, svsudot_lane, svsuvdot_lane, svusdot,
	svusdot_lane, svusvdot_lane, svvdot_lane, svwrite, svwrite_hor,
	svwrite_ver): Likewise
	* config/aarch64/aarch64-sve-builtins-sve2.cc
	(svaba_impl, svqrshl_impl, svqshl_impl,svrshl_impl, svsra_impl):
	Specify FPM_unused when folding.
	* config/aarch64/aarch64-sve-builtins-sve2.def
	(svadd, svclamp, svcvt, svcvtn, svld1, svldnt1, svmax, svmaxnm, svmin,
	svminnm, svpext_lane, svqcvt, svqcvtn, svqdmulh, svqrshr, svqrshrn,
	svqrshru, svqrshrun, svrinta, svrintm, svrintn, svrintp, svrshl, svsel,
	svst1, svstnt1,	svunpk,	svuzp, svuzpq, svwhilege, svwhilegt, svwhilele,
	svwhilelt, svzip, svzipq): Likewise
	* config/aarch64/aarch64-sve-builtins.cc (function_groups): Set
	fpm_mode on all elements.
	(neon_sve_function_groups, sme_function_groups): Likewise.
	(function_instance::hash): Include fpm_mode in hash.
	(function_builder::add_overloaded_functions): Use the group fpm mode.
	(function_resolver::lookup_form): Use the function instance fpm_mode
	when looking up a function.
	* config/aarch64/aarch64-sve-builtins.def
	(DEF_SVE_FUNCTION_GS): add argument.
	(DEF_SVE_FUNCTION): specify FPM_unset mode.
	* config/aarch64/aarch64-sve-builtins.h (fpm_mode_index): New.
	(function_group_info): Add fpm_mode.
	(function_instance): Likewise.
	(function_instance::operator==): Handle fpm_mode.
---
 .../aarch64/aarch64-sve-builtins-base.cc      |  15 +-
 .../aarch64/aarch64-sve-builtins-base.def     |   3 +-
 .../aarch64/aarch64-sve-builtins-shapes.cc    |   3 +-
 .../aarch64/aarch64-sve-builtins-sme.def      | 130 ++++++++++--------
 .../aarch64/aarch64-sve-builtins-sve2.cc      |  20 ++-
 .../aarch64/aarch64-sve-builtins-sve2.def     |  96 +++++++------
 gcc/config/aarch64/aarch64-sve-builtins.cc    |  23 ++--
 gcc/config/aarch64/aarch64-sve-builtins.def   |   4 +-
 gcc/config/aarch64/aarch64-sve-builtins.h     |  25 +++-
 9 files changed, 188 insertions(+), 131 deletions(-)
diff mbox series

Patch

diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index 1c9f515a52c..893ecb5f080 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -774,7 +774,8 @@  public:
       {
 	function_instance instance ("svneg", functions::svneg,
 				    shapes::unary, MODE_none,
-				    f.type_suffix_ids, GROUP_none, f.pred);
+				    f.type_suffix_ids, GROUP_none, f.pred,
+				    FPM_unused);
 	gcall *call = f.redirect_call (instance);
 	unsigned offset_index = 0;
 	if (f.pred == PRED_m)
@@ -802,7 +803,8 @@  public:
       {
 	function_instance instance ("svlsr", functions::svlsr,
 				    shapes::binary_uint_opt_n, MODE_n,
-				    f.type_suffix_ids, GROUP_none, f.pred);
+				    f.type_suffix_ids, GROUP_none, f.pred,
+				    FPM_unused);
 	call = f.redirect_call (instance);
 	tree d = INTEGRAL_TYPE_P (TREE_TYPE (op2)) ? op2 : op2_cst;
 	new_divisor = wide_int_to_tree (TREE_TYPE (d), tree_log2 (d));
@@ -815,7 +817,8 @@  public:
 
 	function_instance instance ("svasrd", functions::svasrd,
 				    shapes::shift_right_imm, MODE_n,
-				    f.type_suffix_ids, GROUP_none, f.pred);
+				    f.type_suffix_ids, GROUP_none, f.pred,
+				    FPM_unused);
 	call = f.redirect_call (instance);
 	new_divisor = wide_int_to_tree (scalar_types[VECTOR_TYPE_svuint64_t],
 					tree_log2 (op2_cst));
@@ -2092,7 +2095,8 @@  public:
       {
 	function_instance instance ("svneg", functions::svneg,
 				    shapes::unary, MODE_none,
-				    f.type_suffix_ids, GROUP_none, f.pred);
+				    f.type_suffix_ids, GROUP_none, f.pred,
+				    FPM_unused);
 	gcall *call = f.redirect_call (instance);
 	unsigned offset_index = 0;
 	if (f.pred == PRED_m)
@@ -2133,7 +2137,8 @@  public:
 				      tree_log2 (shift_op2));
 	function_instance instance ("svlsl", functions::svlsl,
 				    shapes::binary_uint_opt_n, MODE_n,
-				    f.type_suffix_ids, GROUP_none, f.pred);
+				    f.type_suffix_ids, GROUP_none, f.pred,
+				    FPM_unused);
 	gcall *call = f.redirect_call (instance);
 	gimple_call_set_arg (call, 1, shift_op1);
 	gimple_call_set_arg (call, 2, shift_op2);
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.def b/gcc/config/aarch64/aarch64-sve-builtins-base.def
index da2a0e41aa5..1230ad78d09 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.def
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.def
@@ -200,7 +200,8 @@  DEF_SVE_FUNCTION (svrbit, unary, all_integer, mxz)
 DEF_SVE_FUNCTION (svrecpe, unary, all_float, none)
 DEF_SVE_FUNCTION (svrecps, binary, all_float, none)
 DEF_SVE_FUNCTION (svrecpx, unary, all_float, mxz)
-DEF_SVE_FUNCTION_GS (svreinterpret, reinterpret, reinterpret, x1234, none)
+DEF_SVE_FUNCTION_GS (svreinterpret, reinterpret, reinterpret, x1234, none,
+		     unused)
 DEF_SVE_FUNCTION (svreinterpret, reinterpret, reinterpret_b, none)
 DEF_SVE_FUNCTION (svrev, unary, all_data, none)
 DEF_SVE_FUNCTION (svrev, unary_pred, all_pred, none)
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
index f190770250f..51f7cfdf96f 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
@@ -350,7 +350,8 @@  build_one (function_builder &b, const char *signature,
   auto_vec<tree, 16> argument_types;
   function_instance instance (group.base_name, *group.base, *group.shape,
 			      mode_suffix_id, group.types[ti],
-			      group.groups[gi], group.preds[pi]);
+			      group.groups[gi], group.preds[pi],
+			      group.fpm_mode);
   tree return_type = parse_signature (instance, signature, argument_types);
   apply_predication (instance, return_type, argument_types);
   b.add_unique_function (instance, return_type, argument_types,
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sme.def b/gcc/config/aarch64/aarch64-sve-builtins-sme.def
index bc2c3323636..55d04900ec2 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-sme.def
+++ b/gcc/config/aarch64/aarch64-sve-builtins-sme.def
@@ -19,17 +19,17 @@ 
 
 #ifndef DEF_SME_FUNCTION
 #define DEF_SME_FUNCTION(NAME, SHAPE, TYPES, PREDS) \
-  DEF_SME_FUNCTION_GS (NAME, SHAPE, TYPES, none, PREDS)
+  DEF_SME_FUNCTION_GS (NAME, SHAPE, TYPES, none, PREDS, unused)
 #endif
 
 #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)
+#define DEF_SME_ZA_FUNCTION_GS(NAME, SHAPE, TYPES, GROUP, PREDS, FPM_MODE) \
+  DEF_SME_FUNCTION_GS (NAME, SHAPE, TYPES, GROUP, PREDS, FPM_MODE)
 #endif
 
 #ifndef DEF_SME_ZA_FUNCTION
 #define DEF_SME_ZA_FUNCTION(NAME, SHAPE, TYPES, PREDS) \
-  DEF_SME_ZA_FUNCTION_GS (NAME, SHAPE, TYPES, none, PREDS)
+  DEF_SME_ZA_FUNCTION_GS (NAME, SHAPE, TYPES, none, PREDS, unused)
 #endif
 
 #define REQUIRED_EXTENSIONS streaming_compatible (0)
@@ -97,113 +97,123 @@  DEF_SME_FUNCTION (svzero_zt, inherent_zt, none, none)
    floating-point function.  They are needed because the integer and
    floating-point functions have different architecture requirements.  */
 #define REQUIRED_EXTENSIONS streaming_only (AARCH64_FL_SME2)
-DEF_SME_ZA_FUNCTION_GS (svadd, unary_za_slice, za_s_data, vg1x24, none)
-DEF_SME_ZA_FUNCTION_GS (svadd, unary_za_slice, d_za, vg1x24, none)
+DEF_SME_ZA_FUNCTION_GS (svadd, unary_za_slice, za_s_data, vg1x24, none, unused)
+DEF_SME_ZA_FUNCTION_GS (svadd, unary_za_slice, d_za, vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svadd_write, binary_za_slice_opt_single, za_s_integer,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION (svbmopa, binary_za_m, za_s_unsigned, za_m)
 DEF_SME_ZA_FUNCTION (svbmops, binary_za_m, za_s_unsigned, za_m)
 DEF_SME_ZA_FUNCTION_GS (svdot, binary_za_slice_opt_single, za_s_h_data,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svdot, binary_za_slice_opt_single, za_s_b_integer,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svdot_lane, dot_za_slice_lane, za_s_h_data,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svdot_lane, dot_za_slice_lane, za_s_b_integer,
-			vg1x24, none)
-DEF_SME_FUNCTION_GS (svluti2_lane_zt, luti2_lane_zt, bhs_data, x124, none)
-DEF_SME_FUNCTION_GS (svluti4_lane_zt, luti4_lane_zt, bhs_data, x12, none)
-DEF_SME_FUNCTION_GS (svluti4_lane_zt, luti4_lane_zt, hs_data, x4, none)
+			vg1x24, none, unused)
+DEF_SME_FUNCTION_GS (svluti2_lane_zt, luti2_lane_zt, bhs_data, x124, none,
+			unused)
+DEF_SME_FUNCTION_GS (svluti4_lane_zt, luti4_lane_zt, bhs_data, x12, none,
+			unused)
+DEF_SME_FUNCTION_GS (svluti4_lane_zt, luti4_lane_zt, hs_data, x4, none,
+			unused)
 DEF_SME_ZA_FUNCTION_GS (svmla, binary_za_slice_opt_single, za_s_float,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmla, binary_za_slice_opt_single, za_s_h_data,
-			vg2, none)
+			vg2, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmla, binary_za_slice_opt_single, za_s_b_integer,
-			vg4, none)
+			vg4, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmla_lane, binary_za_slice_lane, za_s_float,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmla_lane, binary_za_slice_lane, za_s_h_data,
-			vg2, none)
+			vg2, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmla_lane, binary_za_slice_lane, za_s_b_integer,
-			vg4, none)
+			vg4, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmls, binary_za_slice_opt_single, za_s_float,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmls, binary_za_slice_opt_single, za_s_h_data,
-			vg2, none)
+			vg2, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmls, binary_za_slice_opt_single, za_s_b_integer,
-			vg4, none)
+			vg4, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmls_lane, binary_za_slice_lane, za_s_float,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmls_lane, binary_za_slice_lane, za_s_h_data,
-			vg2, none)
+			vg2, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmls_lane, binary_za_slice_lane, za_s_b_integer,
-			vg4, none)
+			vg4, none, unused)
 DEF_SME_ZA_FUNCTION (svmopa, binary_za_m, za_s_h_integer, za_m)
 DEF_SME_ZA_FUNCTION (svmops, binary_za_m, za_s_h_integer, za_m)
-DEF_SME_ZA_FUNCTION_GS (svread, read_za_slice, za_bhsd_data, vg1x24, none)
-DEF_SME_ZA_FUNCTION_GS (svread_hor, read_za, za_bhsd_data, vg24, none)
-DEF_SME_ZA_FUNCTION_GS (svread_ver, read_za, za_bhsd_data, vg24, none)
-DEF_SME_ZA_FUNCTION_GS (svsub, unary_za_slice, za_s_data, vg1x24, none)
-DEF_SME_ZA_FUNCTION_GS (svsub, unary_za_slice, d_za, vg1x24, none)
+DEF_SME_ZA_FUNCTION_GS (svread, read_za_slice, za_bhsd_data, vg1x24, none, unused)
+DEF_SME_ZA_FUNCTION_GS (svread_hor, read_za, za_bhsd_data, vg24, none, unused)
+DEF_SME_ZA_FUNCTION_GS (svread_ver, read_za, za_bhsd_data, vg24, none, unused)
+DEF_SME_ZA_FUNCTION_GS (svsub, unary_za_slice, za_s_data, vg1x24, none, unused)
+DEF_SME_ZA_FUNCTION_GS (svsub, unary_za_slice, d_za, vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svsub_write, binary_za_slice_opt_single, za_s_integer,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svsudot, binary_za_slice_uint_opt_single,
-		        za_s_b_signed, vg1x24, none)
+		        za_s_b_signed, vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svsudot_lane, dot_za_slice_uint_lane,
-			za_s_b_signed, vg1x24, none)
+			za_s_b_signed, vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svsuvdot_lane, dot_za_slice_uint_lane,
-			za_s_b_signed, vg1x4, none)
+			za_s_b_signed, vg1x4, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svusdot, binary_za_slice_int_opt_single,
-		        za_s_b_unsigned, vg1x24, none)
+		        za_s_b_unsigned, vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svusdot_lane, dot_za_slice_int_lane,
-			za_s_b_unsigned, vg1x24, none)
+			za_s_b_unsigned, vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svusvdot_lane, dot_za_slice_int_lane,
-			za_s_b_unsigned, vg1x4, none)
+			za_s_b_unsigned, vg1x4, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svvdot_lane, dot_za_slice_lane, za_s_h_data,
-			vg1x2, none)
+			vg1x2, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svvdot_lane, dot_za_slice_lane, za_s_b_integer,
-			vg1x4, none)
-DEF_SME_ZA_FUNCTION_GS (svwrite, write_za_slice, za_bhsd_data, vg1x24, none)
-DEF_SME_ZA_FUNCTION_GS (svwrite_hor, write_za, za_bhsd_data, vg24, none)
-DEF_SME_ZA_FUNCTION_GS (svwrite_ver, write_za, za_bhsd_data, vg24, none)
+			vg1x4, none, unused)
+DEF_SME_ZA_FUNCTION_GS (svwrite, write_za_slice, za_bhsd_data, vg1x24, none,
+			unused)
+DEF_SME_ZA_FUNCTION_GS (svwrite_hor, write_za, za_bhsd_data, vg24, none,
+			unused)
+DEF_SME_ZA_FUNCTION_GS (svwrite_ver, write_za, za_bhsd_data, vg24, none,
+			unused)
 #undef REQUIRED_EXTENSIONS
 
 #define REQUIRED_EXTENSIONS streaming_only (AARCH64_FL_SME2 \
 					    | AARCH64_FL_SME_I16I64)
-DEF_SME_ZA_FUNCTION_GS (svadd, unary_za_slice, za_d_integer, vg1x24, none)
+DEF_SME_ZA_FUNCTION_GS (svadd, unary_za_slice, za_d_integer, vg1x24, none,
+			unused)
 DEF_SME_ZA_FUNCTION_GS (svadd_write, binary_za_slice_opt_single, za_d_integer,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svdot, binary_za_slice_opt_single, za_d_h_integer,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svdot_lane, dot_za_slice_lane, za_d_h_integer,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmla, binary_za_slice_opt_single, za_d_h_integer,
-			vg4, none)
+			vg4, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmla_lane, binary_za_slice_lane, za_d_h_integer,
-			vg4, none)
+			vg4, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmls, binary_za_slice_opt_single, za_d_h_integer,
-			vg4, none)
+			vg4, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmls_lane, binary_za_slice_lane, za_d_h_integer,
-			vg4, none)
-DEF_SME_ZA_FUNCTION_GS (svsub, unary_za_slice, za_d_integer, vg1x24, none)
+			vg4, none, unused)
+DEF_SME_ZA_FUNCTION_GS (svsub, unary_za_slice, za_d_integer, vg1x24, none,
+			unused)
 DEF_SME_ZA_FUNCTION_GS (svsub_write, binary_za_slice_opt_single, za_d_integer,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svvdot_lane, dot_za_slice_lane, za_d_h_integer,
-			vg1x4, none)
+			vg1x4, none, unused)
 #undef REQUIRED_EXTENSIONS
 
 #define REQUIRED_EXTENSIONS streaming_only (AARCH64_FL_SME2 \
 					    | AARCH64_FL_SME_F64F64)
-DEF_SME_ZA_FUNCTION_GS (svadd, unary_za_slice, za_d_float, vg1x24, none)
+DEF_SME_ZA_FUNCTION_GS (svadd, unary_za_slice, za_d_float, vg1x24, none,
+			unused)
 DEF_SME_ZA_FUNCTION_GS (svmla, binary_za_slice_opt_single, za_d_float,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmla_lane, binary_za_slice_lane, za_d_float,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmls, binary_za_slice_opt_single, za_d_float,
-			vg1x24, none)
+			vg1x24, none, unused)
 DEF_SME_ZA_FUNCTION_GS (svmls_lane, binary_za_slice_lane, za_d_float,
-			vg1x24, none)
-DEF_SME_ZA_FUNCTION_GS (svsub, unary_za_slice, za_d_float, vg1x24, none)
+			vg1x24, none, unused)
+DEF_SME_ZA_FUNCTION_GS (svsub, unary_za_slice, za_d_float, vg1x24, none,
+			unused)
 #undef REQUIRED_EXTENSIONS
 
 #undef DEF_SME_ZA_FUNCTION
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc b/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc
index f0ab7400ef5..d09b75b60c2 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.cc
@@ -90,7 +90,8 @@  public:
       return NULL;
     function_instance instance ("svabd", functions::svabd,
 				shapes::binary_opt_n, f.mode_suffix_id,
-				f.type_suffix_ids, GROUP_none, PRED_x);
+				f.type_suffix_ids, GROUP_none, PRED_x,
+				FPM_unused);
     gcall *call = f.redirect_call (instance);
     /* Add a ptrue as predicate, because unlike svaba, svabd is
        predicated.  */
@@ -338,7 +339,8 @@  public:
 	       that we can use for sensible shift amounts.  */
 	    function_instance instance ("svqshl", functions::svqshl,
 					shapes::binary_int_opt_n, MODE_n,
-					f.type_suffix_ids, GROUP_none, f.pred);
+					f.type_suffix_ids, GROUP_none, f.pred,
+					FPM_unused);
 	    return f.redirect_call (instance);
 	  }
 	else
@@ -348,7 +350,7 @@  public:
 	    function_instance instance ("svrshl", functions::svrshl,
 					shapes::binary_int_opt_single_n,
 					MODE_n, f.type_suffix_ids, GROUP_none,
-					f.pred);
+					f.pred, FPM_unused);
 	    return f.redirect_call (instance);
 	  }
       }
@@ -377,7 +379,8 @@  public:
 				       -wi::to_wide (amount));
 	    function_instance instance ("svasr", functions::svasr,
 					shapes::binary_uint_opt_n, MODE_n,
-					f.type_suffix_ids, GROUP_none, f.pred);
+					f.type_suffix_ids, GROUP_none, f.pred,
+					FPM_unused);
 	    if (f.type_suffix (0).unsigned_p)
 	      {
 		instance.base_name = "svlsr";
@@ -412,7 +415,8 @@  public:
 	       that we can use for sensible shift amounts.  */
 	    function_instance instance ("svlsl", functions::svlsl,
 					shapes::binary_uint_opt_n, MODE_n,
-					f.type_suffix_ids, GROUP_none, f.pred);
+					f.type_suffix_ids, GROUP_none, f.pred,
+					FPM_unused);
 	    gcall *call = f.redirect_call (instance);
 	    gimple_call_set_arg (call, 2, amount);
 	    return call;
@@ -425,7 +429,8 @@  public:
 				       -wi::to_wide (amount));
 	    function_instance instance ("svrshr", functions::svrshr,
 					shapes::shift_right_imm, MODE_n,
-					f.type_suffix_ids, GROUP_none, f.pred);
+					f.type_suffix_ids, GROUP_none, f.pred,
+					FPM_unused);
 	    gcall *call = f.redirect_call (instance);
 	    gimple_call_set_arg (call, 2, amount);
 	    return call;
@@ -461,7 +466,8 @@  public:
       return NULL;
     function_instance instance ("svlsr", functions::svlsr,
 				shapes::binary_uint_opt_n, MODE_n,
-				f.type_suffix_ids, GROUP_none, PRED_x);
+				f.type_suffix_ids, GROUP_none, PRED_x,
+				FPM_unused);
     if (!f.type_suffix (0).unsigned_p)
       {
 	instance.base_name = "svasr";
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
index e4021559f36..8d25bb33dad 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
+++ b/gcc/config/aarch64/aarch64-sve-builtins-sve2.def
@@ -227,61 +227,73 @@  DEF_SVE_FUNCTION (svrevd, unary, all_data, mxz)
 #undef REQUIRED_EXTENSIONS
 
 #define REQUIRED_EXTENSIONS streaming_only (AARCH64_FL_SME2)
-DEF_SVE_FUNCTION_GS (svadd, binary_single, all_integer, x24, none)
+DEF_SVE_FUNCTION_GS (svadd, binary_single, all_integer, x24, none, unused)
 DEF_SVE_FUNCTION (svbfmlslb, ternary_bfloat_opt_n, s_float, none)
 DEF_SVE_FUNCTION (svbfmlslb_lane, ternary_bfloat_lane, s_float, none)
 DEF_SVE_FUNCTION (svbfmlslt, ternary_bfloat_opt_n, s_float, none)
 DEF_SVE_FUNCTION (svbfmlslt_lane, ternary_bfloat_lane, s_float, none)
 DEF_SVE_FUNCTION (svclamp, clamp, all_float, none)
-DEF_SVE_FUNCTION_GS (svclamp, clamp, all_arith, x24, none)
+DEF_SVE_FUNCTION_GS (svclamp, clamp, all_arith, x24, none, unused)
 DEF_SVE_FUNCTION (svcntp, count_pred_c, all_count, none)
-DEF_SVE_FUNCTION_GS (svcvt, unary_convertxn, cvt_h_s_float, x2, none)
-DEF_SVE_FUNCTION_GS (svcvt, unary_convertxn, cvt_s_s, x24, none)
-DEF_SVE_FUNCTION_GS (svcvtn, unary_convertxn, cvt_h_s_float, x2, none)
+DEF_SVE_FUNCTION_GS (svcvt, unary_convertxn, cvt_h_s_float, x2, none, unused)
+DEF_SVE_FUNCTION_GS (svcvt, unary_convertxn, cvt_s_s, x24, none, unused)
+DEF_SVE_FUNCTION_GS (svcvtn, unary_convertxn, cvt_h_s_float, x2, none, unused)
 DEF_SVE_FUNCTION (svdot, ternary_qq_opt_n_or_011, s_narrow_fsu, none)
 DEF_SVE_FUNCTION (svdot_lane, ternary_qq_or_011_lane, s_narrow_fsu, none)
-DEF_SVE_FUNCTION_GS (svld1, load, all_data, x24, implicit)
-DEF_SVE_FUNCTION_GS (svldnt1, load, all_data, x24, implicit)
-DEF_SVE_FUNCTION_GS (svmax, binary_opt_single_n, all_arith, x24, none)
-DEF_SVE_FUNCTION_GS (svmaxnm, binary_opt_single_n, all_float, x24, none)
-DEF_SVE_FUNCTION_GS (svmin, binary_opt_single_n, all_arith, x24, none)
-DEF_SVE_FUNCTION_GS (svminnm, binary_opt_single_n, all_float, x24, none)
-DEF_SVE_FUNCTION_GS (svpext_lane, extract_pred, all_count, x12, none)
+DEF_SVE_FUNCTION_GS (svld1, load, all_data, x24, implicit, unused)
+DEF_SVE_FUNCTION_GS (svldnt1, load, all_data, x24, implicit, unused)
+DEF_SVE_FUNCTION_GS (svmax, binary_opt_single_n, all_arith, x24, none, unused)
+DEF_SVE_FUNCTION_GS (svmaxnm, binary_opt_single_n, all_float, x24, none,
+			unused)
+DEF_SVE_FUNCTION_GS (svmin, binary_opt_single_n, all_arith, x24, none, unused)
+DEF_SVE_FUNCTION_GS (svminnm, binary_opt_single_n, all_float, x24, none,
+			unused)
+DEF_SVE_FUNCTION_GS (svpext_lane, extract_pred, all_count, x12, none, unused)
 DEF_SVE_FUNCTION (svptrue, inherent, all_count, none)
-DEF_SVE_FUNCTION_GS (svqcvt, unary_convertxn, qcvt_x2, x2, none)
-DEF_SVE_FUNCTION_GS (svqcvt, unary_convertxn, qcvt_x4, x4, none)
-DEF_SVE_FUNCTION_GS (svqcvtn, unary_convertxn, qcvt_x2, x2, none)
-DEF_SVE_FUNCTION_GS (svqcvtn, unary_convertxn, qcvt_x4, x4, none)
-DEF_SVE_FUNCTION_GS (svqdmulh, binary_opt_single_n, all_signed, x24, none)
-DEF_SVE_FUNCTION_GS (svqrshr, shift_right_imm_narrowxn, qrshr_x2, x2, none)
-DEF_SVE_FUNCTION_GS (svqrshr, shift_right_imm_narrowxn, qrshr_x4, x4, none)
-DEF_SVE_FUNCTION_GS (svqrshrn, shift_right_imm_narrowxn, qrshr_x2, x2, none)
-DEF_SVE_FUNCTION_GS (svqrshrn, shift_right_imm_narrowxn, qrshr_x4, x4, none)
-DEF_SVE_FUNCTION_GS (svqrshru, shift_right_imm_narrowxn, qrshru_x2, x2, none)
-DEF_SVE_FUNCTION_GS (svqrshru, shift_right_imm_narrowxn, qrshru_x4, x4, none)
-DEF_SVE_FUNCTION_GS (svqrshrun, shift_right_imm_narrowxn, qrshru_x2, x2, none)
-DEF_SVE_FUNCTION_GS (svqrshrun, shift_right_imm_narrowxn, qrshru_x4, x4, none)
-DEF_SVE_FUNCTION_GS (svrinta, unaryxn, s_float, x24, none)
-DEF_SVE_FUNCTION_GS (svrintm, unaryxn, s_float, x24, none)
-DEF_SVE_FUNCTION_GS (svrintn, unaryxn, s_float, x24, none)
-DEF_SVE_FUNCTION_GS (svrintp, unaryxn, s_float, x24, none)
-DEF_SVE_FUNCTION_GS (svrshl, binary_int_opt_single_n, all_integer, x24, none)
-DEF_SVE_FUNCTION_GS (svsel, binaryxn, all_data, x24, implicit)
-DEF_SVE_FUNCTION_GS (svst1, storexn, all_data, x24, implicit)
-DEF_SVE_FUNCTION_GS (svstnt1, storexn, all_data, x24, implicit)
-DEF_SVE_FUNCTION_GS (svunpk, unary_convertxn, bhs_widen, x24, none)
-DEF_SVE_FUNCTION_GS (svuzp, unaryxn, all_data, x24, none)
-DEF_SVE_FUNCTION_GS (svuzpq, unaryxn, all_data, x24, none)
-DEF_SVE_FUNCTION_GS (svwhilege, compare_scalar, while_x, x2, none)
+DEF_SVE_FUNCTION_GS (svqcvt, unary_convertxn, qcvt_x2, x2, none, unused)
+DEF_SVE_FUNCTION_GS (svqcvt, unary_convertxn, qcvt_x4, x4, none, unused)
+DEF_SVE_FUNCTION_GS (svqcvtn, unary_convertxn, qcvt_x2, x2, none, unused)
+DEF_SVE_FUNCTION_GS (svqcvtn, unary_convertxn, qcvt_x4, x4, none, unused)
+DEF_SVE_FUNCTION_GS (svqdmulh, binary_opt_single_n, all_signed, x24, none,
+			unused)
+DEF_SVE_FUNCTION_GS (svqrshr, shift_right_imm_narrowxn, qrshr_x2, x2, none,
+			unused)
+DEF_SVE_FUNCTION_GS (svqrshr, shift_right_imm_narrowxn, qrshr_x4, x4, none,
+			unused)
+DEF_SVE_FUNCTION_GS (svqrshrn, shift_right_imm_narrowxn, qrshr_x2, x2, none,
+			unused)
+DEF_SVE_FUNCTION_GS (svqrshrn, shift_right_imm_narrowxn, qrshr_x4, x4, none,
+			unused)
+DEF_SVE_FUNCTION_GS (svqrshru, shift_right_imm_narrowxn, qrshru_x2, x2, none,
+			unused)
+DEF_SVE_FUNCTION_GS (svqrshru, shift_right_imm_narrowxn, qrshru_x4, x4, none,
+			unused)
+DEF_SVE_FUNCTION_GS (svqrshrun, shift_right_imm_narrowxn, qrshru_x2, x2, none,
+			unused)
+DEF_SVE_FUNCTION_GS (svqrshrun, shift_right_imm_narrowxn, qrshru_x4, x4, none,
+			unused)
+DEF_SVE_FUNCTION_GS (svrinta, unaryxn, s_float, x24, none, unused)
+DEF_SVE_FUNCTION_GS (svrintm, unaryxn, s_float, x24, none, unused)
+DEF_SVE_FUNCTION_GS (svrintn, unaryxn, s_float, x24, none, unused)
+DEF_SVE_FUNCTION_GS (svrintp, unaryxn, s_float, x24, none, unused)
+DEF_SVE_FUNCTION_GS (svrshl, binary_int_opt_single_n, all_integer, x24, none,
+			unused)
+DEF_SVE_FUNCTION_GS (svsel, binaryxn, all_data, x24, implicit, unused)
+DEF_SVE_FUNCTION_GS (svst1, storexn, all_data, x24, implicit, unused)
+DEF_SVE_FUNCTION_GS (svstnt1, storexn, all_data, x24, implicit, unused)
+DEF_SVE_FUNCTION_GS (svunpk, unary_convertxn, bhs_widen, x24, none, unused)
+DEF_SVE_FUNCTION_GS (svuzp, unaryxn, all_data, x24, none, unused)
+DEF_SVE_FUNCTION_GS (svuzpq, unaryxn, all_data, x24, none, unused)
+DEF_SVE_FUNCTION_GS (svwhilege, compare_scalar, while_x, x2, none, unused)
 DEF_SVE_FUNCTION (svwhilege, compare_scalar_count, while_x_c, none)
-DEF_SVE_FUNCTION_GS (svwhilegt, compare_scalar, while_x, x2, none)
+DEF_SVE_FUNCTION_GS (svwhilegt, compare_scalar, while_x, x2, none, unused)
 DEF_SVE_FUNCTION (svwhilegt, compare_scalar_count, while_x_c, none)
-DEF_SVE_FUNCTION_GS (svwhilele, compare_scalar, while_x, x2, none)
+DEF_SVE_FUNCTION_GS (svwhilele, compare_scalar, while_x, x2, none, unused)
 DEF_SVE_FUNCTION (svwhilele, compare_scalar_count, while_x_c, none)
-DEF_SVE_FUNCTION_GS (svwhilelt, compare_scalar, while_x, x2, none)
+DEF_SVE_FUNCTION_GS (svwhilelt, compare_scalar, while_x, x2, none, unused)
 DEF_SVE_FUNCTION (svwhilelt, compare_scalar_count, while_x_c, none)
-DEF_SVE_FUNCTION_GS (svzip, unaryxn, all_data, x24, none)
-DEF_SVE_FUNCTION_GS (svzipq, unaryxn, all_data, x24, none)
+DEF_SVE_FUNCTION_GS (svzip, unaryxn, all_data, x24, none, unused)
+DEF_SVE_FUNCTION_GS (svzipq, unaryxn, all_data, x24, none, unused)
 #undef REQUIRED_EXTENSIONS
 
 #define REQUIRED_EXTENSIONS \
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc
index 34384c0f5d7..dfe6221e5c2 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
@@ -890,9 +890,10 @@  static const predication_index preds_za_m[] = { PRED_za_m, NUM_PREDS };
 
 /* A list of all arm_sve.h functions.  */
 static CONSTEXPR const function_group_info function_groups[] = {
-#define DEF_SVE_FUNCTION_GS(NAME, SHAPE, TYPES, GROUPS, PREDS) \
+#define DEF_SVE_FUNCTION_GS(NAME, SHAPE, TYPES, GROUPS, PREDS, FPM_MODE) \
   { #NAME, &functions::NAME, &shapes::SHAPE, types_##TYPES, groups_##GROUPS, \
-    preds_##PREDS, aarch64_required_extensions::REQUIRED_EXTENSIONS },
+    preds_##PREDS, aarch64_required_extensions::REQUIRED_EXTENSIONS, \
+    FPM_##FPM_MODE },
 #include "aarch64-sve-builtins.def"
 };
 
@@ -900,20 +901,22 @@  static CONSTEXPR const function_group_info function_groups[] = {
 static CONSTEXPR const function_group_info neon_sve_function_groups[] = {
 #define DEF_NEON_SVE_FUNCTION(NAME, SHAPE, TYPES, GROUPS, PREDS) \
   { #NAME, &neon_sve_bridge_functions::NAME, &shapes::SHAPE, types_##TYPES, \
-    groups_##GROUPS, preds_##PREDS, aarch64_required_extensions::ssve (0) },
+    groups_##GROUPS, preds_##PREDS, aarch64_required_extensions::ssve (0), \
+    FPM_unused },
 #include "aarch64-neon-sve-bridge-builtins.def"
 };
 
 /* A list of all arm_sme.h functions.  */
 static CONSTEXPR const function_group_info sme_function_groups[] = {
-#define DEF_SME_FUNCTION_GS(NAME, SHAPE, TYPES, GROUPS, PREDS) \
+#define DEF_SME_FUNCTION_GS(NAME, SHAPE, TYPES, GROUPS, PREDS, FPM_MODE1) \
   { #NAME, &functions::NAME, &shapes::SHAPE, types_##TYPES, groups_##GROUPS, \
-    preds_##PREDS, aarch64_required_extensions::REQUIRED_EXTENSIONS },
-#define DEF_SME_ZA_FUNCTION_GS(NAME, SHAPE, TYPES, GROUPS, PREDS) \
+    preds_##PREDS, aarch64_required_extensions::REQUIRED_EXTENSIONS, \
+    FPM_##FPM_MODE1 },
+#define DEF_SME_ZA_FUNCTION_GS(NAME, SHAPE, TYPES, GROUPS, PREDS, FPM_MODE2) \
   { #NAME, &functions::NAME##_za, &shapes::SHAPE, types_##TYPES, \
     groups_##GROUPS, preds_##PREDS, \
     aarch64_required_extensions::REQUIRED_EXTENSIONS \
-      .and_also (AARCH64_FL_ZA_ON) },
+      .and_also (AARCH64_FL_ZA_ON), FPM_##FPM_MODE2 },
 #include "aarch64-sve-builtins-sme.def"
 };
 
@@ -1180,6 +1183,7 @@  function_instance::hash () const
   h.add_int (type_suffix_ids[1]);
   h.add_int (group_suffix_id);
   h.add_int (pred);
+  h.add_int (fpm_mode);
   return h.end ();
 }
 
@@ -1606,7 +1610,8 @@  function_builder::add_overloaded_functions (const function_group_info &group,
     {
       function_instance instance (group.base_name, *group.base,
 				  *group.shape, mode, types,
-				  group_suffix_id, group.preds[pi]);
+				  group_suffix_id, group.preds[pi],
+				  group.fpm_mode);
       add_overloaded_function (instance, group.required_extensions);
     };
 
@@ -1784,7 +1789,7 @@  function_resolver::lookup_form (mode_suffix_index mode,
 {
   type_suffix_pair types = { type0, type1 };
   function_instance instance (base_name, base, shape, mode, types,
-			      group, pred);
+			      group, pred, fpm_mode);
   registered_function *rfn
     = function_table->find_with_hash (instance, instance.hash ());
   return rfn ? rfn->decl : NULL_TREE;
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.def b/gcc/config/aarch64/aarch64-sve-builtins.def
index 47c396b866d..982f9ed2312 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.def
+++ b/gcc/config/aarch64/aarch64-sve-builtins.def
@@ -38,7 +38,7 @@ 
 #endif
 
 #ifndef DEF_SVE_FUNCTION_GS
-#define DEF_SVE_FUNCTION_GS(A, B, C, D, E)
+#define DEF_SVE_FUNCTION_GS(A, B, C, D, E, F)
 #endif
 
 #ifndef DEF_SVE_NEON_TYPE_SUFFIX
@@ -48,7 +48,7 @@ 
 
 #ifndef DEF_SVE_FUNCTION
 #define DEF_SVE_FUNCTION(NAME, SHAPE, TYPES, PREDS) \
-  DEF_SVE_FUNCTION_GS (NAME, SHAPE, TYPES, none, PREDS)
+  DEF_SVE_FUNCTION_GS (NAME, SHAPE, TYPES, none, PREDS, unused)
 #endif
 
 DEF_SVE_MODE (n, none, none, none)
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h b/gcc/config/aarch64/aarch64-sve-builtins.h
index 28726875401..41a9dfc56e5 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.h
+++ b/gcc/config/aarch64/aarch64-sve-builtins.h
@@ -28,6 +28,7 @@ 
    - the "mode" suffix ("_n", "_index", etc.)
    - the type suffixes ("_s32", "_b8", etc.)
    - the predication suffix ("_x", "_z", etc.)
+   - the "_fpm" suffix when the floating point mode register is set
 
    Each piece of information is individually useful, so we retain this
    classification throughout:
@@ -42,6 +43,8 @@ 
    - prediction_index extends the predication suffix with an additional
      alternative: PRED_implicit for implicitly-predicated operations
 
+   - fpm_mode represents whether the fpm register is set or not
+
    In addition to its unique full name, a function may have a shorter
    overloaded alias.  This alias removes pieces of the suffixes that
    can be inferred from the arguments, such as by shortening the mode
@@ -164,6 +167,14 @@  enum predication_index
   NUM_PREDS
 };
 
+/* Classifies intrinsics on whether they set the FPM register */
+enum fpm_mode_index
+{
+  FPM_unused,
+  FPM_set,
+  NUM_FPM_MODES
+};
+
 /* Classifies element types, based on type suffixes with the bit count
    removed.  "count" isn't really an element type, but we pretend it is
    for consistency.  */
@@ -366,6 +377,9 @@  struct function_group_info
 
   /* The architecture extensions that the functions require.  */
   aarch64_required_extensions required_extensions;
+  
+  /* Whether the floating point register is set */
+  fpm_mode_index fpm_mode;
 };
 
 /* Describes a single fully-resolved function (i.e. one that has a
@@ -376,7 +390,7 @@  public:
   function_instance (const char *, const function_base *,
 		     const function_shape *, mode_suffix_index,
 		     const type_suffix_pair &, group_suffix_index,
-		     predication_index);
+		     predication_index, fpm_mode_index);
 
   bool operator== (const function_instance &) const;
   bool operator!= (const function_instance &) const;
@@ -420,6 +434,7 @@  public:
   type_suffix_pair type_suffix_ids;
   group_suffix_index group_suffix_id;
   predication_index pred;
+  fpm_mode_index fpm_mode;
 };
 
 class registered_function;
@@ -878,10 +893,11 @@  function_instance (const char *base_name_in,
 		   mode_suffix_index mode_suffix_id_in,
 		   const type_suffix_pair &type_suffix_ids_in,
 		   group_suffix_index group_suffix_id_in,
-		   predication_index pred_in)
+		   predication_index pred_in,
+		   fpm_mode_index fpm_mode_in)
   : base_name (base_name_in), base (base_in), shape (shape_in),
     mode_suffix_id (mode_suffix_id_in), group_suffix_id (group_suffix_id_in),
-    pred (pred_in)
+    pred (pred_in), fpm_mode(fpm_mode_in)
 {
   memcpy (type_suffix_ids, type_suffix_ids_in, sizeof (type_suffix_ids));
 }
@@ -895,7 +911,8 @@  function_instance::operator== (const function_instance &other) const
 	  && type_suffix_ids[0] == other.type_suffix_ids[0]
 	  && type_suffix_ids[1] == other.type_suffix_ids[1]
 	  && group_suffix_id == other.group_suffix_id
-	  && pred == other.pred);
+	  && pred == other.pred
+	  && fpm_mode == other.fpm_mode);
 }
 
 inline bool