The majority of sve/sme intrinsics have names which are defined by one type
(like svuint8_t svextq[_u8]) or two types (like svsub_za32[_f32]_vg1x2).
Some intrinsics now have three types (like svtmopa_lane_za32[_s8_u8]).
This change extends the number of type_suffix_indexes from two to three
to cover this case.
gcc/
* config/aarch64/aarch64-sve-builtins-base.cc: (svmul_impl::fold):
Replace use of type_suffix_pair with type_suffix_triple.
* config/aarch64/aarch64-sve-builtins-shapes.cc: (parse_element_type):
Handle third type suffix.
(parse_type): Handle c2 in function signature. Add the u signature with
the ability to pass a tuple with twice as many vectors as the base type.
Calculate number of vectors against the type with the maximum number of
bits rather than "the other one".
(load_contiguous_base::resolve): Add argument to resolve_to call.
(compare_scalar_def::resolve): Likewise.
(ternary_mfloat8_def::resolve): Likewise.
(ternary_mfloat8_lane_def::resolve): Likewise.
(ternary_mfloat8_opt_n_def::resolve): Likewise.
* config/aarch64/aarch64-sve-builtins.cc: (TYPES_all_pred,
TYPES_all_count, TYPES_all_pred_count, TYPES_all_float,
TYPES_all_signed, TYPES_all_float_and_signed, TYPES_all_unsigned,
TYPES_all_integer, TYPES_all_arith, TYPES_all_data, TYPES_b, TYPES_c,
TYPES_b_unsigned, TYPES_b_integer, TYPES_b_data, TYPES_bh_integer,
TYPES_bs_unsigned, TYPES_bhs_signed, TYPES_bhs_unsigned,
TYPES_bhs_integer, TYPES_bh_data, TYPES_bhs_data, TYPES_bhs_widen,
TYPES_h_bfloat, TYPES_h_float, TYPES_h_integer, TYPES_h_data,
TYPES_hs_signed, TYPES_hs_integer, TYPES_hs_float, TYPES_hs_data,
TYPES_hd_unsigned, TYPES_hsd_signed, TYPES_hsd_integer, TYPES_hsd_data,
TYPES_h_float_mf8, TYPES_s_float, TYPES_s_float_mf8,
TYPES_s_float_hsd_integer, TYPES_s_float_sd_integer, TYPES_s_signed,
TYPES_s_unsigned, TYPES_s_integer, TYPES_s_data, TYPES_sd_signed,
TYPES_sd_unsigned, TYPES_sd_integer, TYPES_sd_data,
TYPES_all_float_and_sd_integer, TYPES_d_float, TYPES_d_unsigned,
TYPES_d_integer, TYPES_d_data, TYPES_cvt, TYPES_cvt_bfloat,
TYPES_cvt_h_s_float, TYPES_cvt_f32_f16, TYPES_cvt_long,
TYPES_cvt_narrow_s, TYPES_cvt_narrow, TYPES_cvt_s_s, TYPES_cvt_mf8,
TYPES_cvtn_mf8, TYPES_cvtnx_mf8, TYPES_inc_dec_n, TYPES_qcvt_x2,
TYPES_qcvt_x4, TYPES_qrshr_x2,TYPES_qrshru_x2, TYPES_qrshr_x4,
TYPES_qrshru_x4, TYPES_reinterpret, TYPES_reinterpret_b,TYPES_while,
TYPES_while_x, TYPES_while_x_c, TYPES_s_narrow_fsu,TYPES_all_za,
TYPES_d_za, TYPES_za_bhsd_data,TYPES_za_all_data, TYPES_za_h_mf8,
TYPES_za_hs_mf8, TYPES_za_h_bfloat, TYPES_za_h_float,
TYPES_za_s_b_signed, TYPES_za_s_b_unsigned, TYPES_za_s_b_integer,
TYPES_za_s_h_integer,TYPES_za_s_h_data, TYPES_za_s_unsigned,
TYPES_za_s_integer, TYPES_za_s_mf8, TYPES_za_s_float, TYPES_za_s_data,
TYPES_za_d_h_integer, TYPES_za_d_float, TYPES_za_d_integer,
TYPES_mop_base, TYPES_mop_base_signed, TYPES_mop_base_unsigned,
TYPES_mop_i16i64, TYPES_mop_i16i64_signed, TYPES_mop_i16i64_unsigned,
ΤYPES_za): Extend defines to three arguments.
(DEF_VECTOR_TYPE, DEF_DOUBLE_TYPE): Likewise.
(DEF_TRIPLE_TYPE): Add new define.
(DEF_SVE_TYPES_ARRAY): Redefine all types_ arrays into arrays of
type_suffix_triple.
(types_none): Likewise.
(function_instance::hash): Add third type to hash calculation.
(function_builder::get_name): Add third type to function name.
(function_builder::add_overloaded_functions): Handle third type.
(function_resolver::lookup_form): Likewise.
(function_resolver::resolve_to): Likewise.
(function_resolver::resolve_unary): Likewise.
* config/aarch64/aarch64-sve-builtins.h: (type_suffix_triple): replace
type_suffix_pair.
(function_group_info::types): Likewise.
(function_instance::ctor): Likewise.
(function_instance::type_suffix_ids): Likewise.
(function_resolver::lookup_form): Add third type argument.
(function_resolver::resolve_to): Likewise.
(function_instance::operator==): Add third type to equality calculation.
---
.../aarch64/aarch64-sve-builtins-base.cc | 8 +-
.../aarch64/aarch64-sve-builtins-shapes.cc | 41 ++-
gcc/config/aarch64/aarch64-sve-builtins.cc | 327 +++++++++---------
gcc/config/aarch64/aarch64-sve-builtins.h | 19 +-
4 files changed, 215 insertions(+), 180 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index ecc06877cac..0378c8343a3 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -2335,9 +2335,11 @@ public:
tree negated_op = op1;
if (integer_minus_onep (op1))
negated_op = op2;
- type_suffix_pair signed_tsp =
- {find_type_suffix (TYPE_signed, f.type_suffix (0).element_bits),
- f.type_suffix_ids[1]};
+ type_suffix_triple signed_tsp = {
+ find_type_suffix (TYPE_signed, f.type_suffix (0).element_bits),
+ f.type_suffix_ids[1],
+ NUM_TYPE_SUFFIXES
+ };
function_instance instance ("svneg", functions::svneg,
shapes::unary, MODE_none, signed_tsp,
GROUP_none, f.pred, FPM_unused);
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
index b315dc91cc7..3663a9d416b 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-shapes.cc
@@ -178,7 +178,7 @@ parse_element_type (const function_instance &instance, const char *&format)
type_suffixes[suffix].element_bits / 2);
}
- if (ch == '0' || ch == '1')
+ if (ch == '0' || ch == '1' || ch == '2')
return instance.type_suffix_ids[ch - '0'];
gcc_unreachable ();
@@ -194,11 +194,13 @@ parse_element_type (const function_instance &instance, const char *&format)
b - base vector type (from a _<m0>base suffix)
c0 - the result of a conversion, based on type and group suffixes
c1 - the source of a conversion, based on type and group suffixes
+ c2 - the source of a conversion, based on type and group suffixes
d - displacement vector type (from a _<m1>index or _<m1>offset suffix)
e<name> - an enum with the given name
s<elt> - a scalar type with the given element suffix
t<elt> - a vector or tuple type with given element suffix [*1]
T<elt> - a vector or tuple type with given element suffix [*2]
+ u<elt> - a vector or tuple type with given element suffix [*3]
v<elt> - a vector with the given element suffix
D<elt> - a 64 bit neon vector
Q<elt> - a 128 bit neon vector
@@ -208,6 +210,7 @@ parse_element_type (const function_instance &instance, const char *&format)
[*1] the vectors_per_tuple function indicates whether the type should
be a tuple, and if so, how many vectors it should contain.
[*2] same as for [*1], but the tuple contains half as many vectors.
+ [*3] same as for [*1], but the tuple contains twice as many vectors.
*/
static tree
parse_type (const function_instance &instance, const char *&format)
@@ -235,16 +238,19 @@ parse_type (const function_instance &instance, const char *&format)
if (ch == 'c')
{
int ch = *format++;
- gcc_assert (ch == '0' || ch == '1');
- unsigned int id = (ch == '0' ? 0 : 1);
+ gcc_assert (ch == '0' || ch == '1' || ch == '2');
+ unsigned int id = ch - '0';
auto vector_type = instance.type_suffix (id).vector_type;
unsigned int num_vectors = instance.group_suffix ().vectors_per_tuple;
if (num_vectors != 1)
{
- unsigned int bits = instance.type_suffix (id).element_bits;
- unsigned int other_bits = instance.type_suffix (1 - id).element_bits;
- if (other_bits > bits)
- num_vectors /= other_bits / bits;
+ unsigned int type_bits = instance.type_suffix (id).element_bits;
+ unsigned int max_bits = std::max ( std:: max (
+ instance.type_suffix (0).element_bits,
+ instance.type_suffix (1).element_bits),
+ instance.type_suffix (2).element_bits);
+ if (max_bits > type_bits)
+ num_vectors /= max_bits / type_bits;
}
return acle_vector_types[num_vectors - 1][vector_type];
}
@@ -288,6 +294,14 @@ parse_type (const function_instance &instance, const char *&format)
return acle_vector_types[num_vectors - 1][vector_type];
}
+ if (ch == 'u')
+ {
+ type_suffix_index suffix = parse_element_type (instance, format);
+ vector_type_index vector_type = type_suffixes[suffix].vector_type;
+ unsigned int num_vectors = instance.vectors_per_tuple () * 2;
+ return acle_vector_types[num_vectors - 1][vector_type];
+ }
+
if (ch == 'v')
{
type_suffix_index suffix = parse_element_type (instance, format);
@@ -850,7 +864,7 @@ struct load_contiguous_base : public overloaded_base<0>
return error_mark_node;
return r.resolve_to (r.mode_suffix_id, type, NUM_TYPE_SUFFIXES,
- r.group_suffix_id);
+ NUM_TYPE_SUFFIXES, r.group_suffix_id);
}
};
@@ -2318,7 +2332,7 @@ struct compare_scalar_def : public overloaded_base<1>
return error_mark_node;
return r.resolve_to (r.mode_suffix_id, r.type_suffix_ids[0], type,
- r.group_suffix_id);
+ NUM_TYPE_SUFFIXES, r.group_suffix_id);
}
};
SHAPE (compare_scalar)
@@ -4130,7 +4144,8 @@ struct ternary_mfloat8_def
|| !r.require_scalar_type (3, "uint64_t"))
return error_mark_node;
- return r.resolve_to (r.mode_suffix_id, type, TYPE_SUFFIX_mf8, GROUP_none);
+ return r.resolve_to (r.mode_suffix_id, type, TYPE_SUFFIX_mf8,
+ NUM_TYPE_SUFFIXES, GROUP_none);
}
};
SHAPE (ternary_mfloat8)
@@ -4182,7 +4197,8 @@ struct ternary_mfloat8_lane_def
|| !r.require_scalar_type (4, "uint64_t"))
return error_mark_node;
- return r.resolve_to (r.mode_suffix_id, type, TYPE_SUFFIX_mf8, GROUP_none);
+ return r.resolve_to (r.mode_suffix_id, type, TYPE_SUFFIX_mf8,
+ NUM_TYPE_SUFFIXES, GROUP_none);
}
};
SHAPE (ternary_mfloat8_lane)
@@ -4253,7 +4269,8 @@ struct ternary_mfloat8_opt_n_def
else if (!r.require_vector_type (2, VECTOR_TYPE_svmfloat8_t))
return error_mark_node;
- return r.resolve_to (mode, type, TYPE_SUFFIX_mf8, GROUP_none);
+ return r.resolve_to (mode, type, TYPE_SUFFIX_mf8, NUM_TYPE_SUFFIXES,
+ GROUP_none);
}
};
SHAPE (ternary_mfloat8_opt_n)
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc
index dbd80cab627..8af558c9a05 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
@@ -192,255 +192,255 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
class ("b", "f", etc.) and a numerical bit count. */
/* _b8 _b16 _b32 _b64. */
-#define TYPES_all_pred(S, D) \
+#define TYPES_all_pred(S, D, T) \
S (b8), S (b16), S (b32), S (b64)
/* _c8 _c16 _c32 _c64. */
-#define TYPES_all_count(S, D) \
+#define TYPES_all_count(S, D, T) \
S (c8), S (c16), S (c32), S (c64)
/* _b8 _b16 _b32 _b64
_c8 _c16 _c32 _c64. */
-#define TYPES_all_pred_count(S, D) \
- TYPES_all_pred (S, D), \
- TYPES_all_count (S, D)
+#define TYPES_all_pred_count(S, D, T) \
+ TYPES_all_pred (S, D, T), \
+ TYPES_all_count (S, D, T)
/* _f16 _f32 _f64. */
-#define TYPES_all_float(S, D) \
+#define TYPES_all_float(S, D, T) \
S (f16), S (f32), S (f64)
/* _s8 _s16 _s32 _s64. */
-#define TYPES_all_signed(S, D) \
+#define TYPES_all_signed(S, D, T) \
S (s8), S (s16), S (s32), S (s64)
/* _f16 _f32 _f64
_s8 _s16 _s32 _s64. */
-#define TYPES_all_float_and_signed(S, D) \
- TYPES_all_float (S, D), TYPES_all_signed (S, D)
+#define TYPES_all_float_and_signed(S, D, T) \
+ TYPES_all_float (S, D, T), TYPES_all_signed (S, D, T)
/* _u8 _u16 _u32 _u64. */
-#define TYPES_all_unsigned(S, D) \
+#define TYPES_all_unsigned(S, D, T) \
S (u8), S (u16), S (u32), S (u64)
/* _s8 _s16 _s32 _s64
_u8 _u16 _u32 _u64. */
-#define TYPES_all_integer(S, D) \
- TYPES_all_signed (S, D), TYPES_all_unsigned (S, D)
+#define TYPES_all_integer(S, D, T) \
+ TYPES_all_signed (S, D, T), TYPES_all_unsigned (S, D, T)
/* _f16 _f32 _f64
_s8 _s16 _s32 _s64
_u8 _u16 _u32 _u64. */
-#define TYPES_all_arith(S, D) \
- TYPES_all_float (S, D), TYPES_all_integer (S, D)
+#define TYPES_all_arith(S, D, T) \
+ TYPES_all_float (S, D, T), TYPES_all_integer (S, D, T)
-#define TYPES_all_data(S, D) \
- TYPES_b_data (S, D), \
- TYPES_h_data (S, D), \
- TYPES_s_data (S, D), \
- TYPES_d_data (S, D)
+#define TYPES_all_data(S, D, T) \
+ TYPES_b_data (S, D, T), \
+ TYPES_h_data (S, D, T), \
+ TYPES_s_data (S, D, T), \
+ TYPES_d_data (S, D, T)
/* _b only. */
-#define TYPES_b(S, D) \
+#define TYPES_b(S, D, T) \
S (b)
/* _c only. */
-#define TYPES_c(S, D) \
+#define TYPES_c(S, D, T) \
S (c)
/* _u8. */
-#define TYPES_b_unsigned(S, D) \
+#define TYPES_b_unsigned(S, D, T) \
S (u8)
/* _s8
_u8. */
-#define TYPES_b_integer(S, D) \
- S (s8), TYPES_b_unsigned (S, D)
+#define TYPES_b_integer(S, D, T) \
+ S (s8), TYPES_b_unsigned (S, D, T)
/* _mf8
_s8
_u8. */
-#define TYPES_b_data(S, D) \
- S (mf8), TYPES_b_integer (S, D)
+#define TYPES_b_data(S, D, T) \
+ S (mf8), TYPES_b_integer (S, D, T)
/* _s8 _s16
_u8 _u16. */
-#define TYPES_bh_integer(S, D) \
+#define TYPES_bh_integer(S, D, T) \
S (s8), S (s16), S (u8), S (u16)
/* _u8 _u32. */
-#define TYPES_bs_unsigned(S, D) \
+#define TYPES_bs_unsigned(S, D, T) \
S (u8), S (u32)
/* _s8 _s16 _s32. */
-#define TYPES_bhs_signed(S, D) \
+#define TYPES_bhs_signed(S, D, T) \
S (s8), S (s16), S (s32)
/* _u8 _u16 _u32. */
-#define TYPES_bhs_unsigned(S, D) \
+#define TYPES_bhs_unsigned(S, D, T) \
S (u8), S (u16), S (u32)
/* _s8 _s16 _s32
_u8 _u16 _u32. */
-#define TYPES_bhs_integer(S, D) \
- TYPES_bhs_signed (S, D), TYPES_bhs_unsigned (S, D)
+#define TYPES_bhs_integer(S, D, T) \
+ TYPES_bhs_signed (S, D, T), TYPES_bhs_unsigned (S, D, T)
-#define TYPES_bh_data(S, D) \
- TYPES_b_data (S, D), \
- TYPES_h_data (S, D)
+#define TYPES_bh_data(S, D, T) \
+ TYPES_b_data (S, D, T), \
+ TYPES_h_data (S, D, T)
-#define TYPES_bhs_data(S, D) \
- TYPES_b_data (S, D), \
- TYPES_h_data (S, D), \
- TYPES_s_data (S, D)
+#define TYPES_bhs_data(S, D, T) \
+ TYPES_b_data (S, D, T), \
+ TYPES_h_data (S, D, T), \
+ TYPES_s_data (S, D, T)
/* _s16_s8 _s32_s16 _s64_s32
_u16_u8 _u32_u16 _u64_u32. */
-#define TYPES_bhs_widen(S, D) \
+#define TYPES_bhs_widen(S, D, T) \
D (s16, s8), D (s32, s16), D (s64, s32), \
D (u16, u8), D (u32, u16), D (u64, u32)
/* _bf16. */
-#define TYPES_h_bfloat(S, D) \
+#define TYPES_h_bfloat(S, D, T) \
S (bf16)
/* _f16. */
-#define TYPES_h_float(S, D) \
+#define TYPES_h_float(S, D, T) \
S (f16)
/* _s16
_u16. */
-#define TYPES_h_integer(S, D) \
+#define TYPES_h_integer(S, D, T) \
S (s16), S (u16)
/* _bf16
_f16
_s16
_u16. */
-#define TYPES_h_data(S, D) \
- S (bf16), S (f16), TYPES_h_integer (S, D)
+#define TYPES_h_data(S, D, T) \
+ S (bf16), S (f16), TYPES_h_integer (S, D, T)
/* _s16 _s32. */
-#define TYPES_hs_signed(S, D) \
+#define TYPES_hs_signed(S, D, T) \
S (s16), S (s32)
/* _s16 _s32
_u16 _u32. */
-#define TYPES_hs_integer(S, D) \
- TYPES_hs_signed (S, D), S (u16), S (u32)
+#define TYPES_hs_integer(S, D, T) \
+ TYPES_hs_signed (S, D, T), S (u16), S (u32)
/* _f16 _f32. */
-#define TYPES_hs_float(S, D) \
+#define TYPES_hs_float(S, D, T) \
S (f16), S (f32)
-#define TYPES_hs_data(S, D) \
- TYPES_h_data (S, D), \
- TYPES_s_data (S, D)
+#define TYPES_hs_data(S, D, T) \
+ TYPES_h_data (S, D, T), \
+ TYPES_s_data (S, D, T)
/* _u16 _u64. */
-#define TYPES_hd_unsigned(S, D) \
+#define TYPES_hd_unsigned(S, D, T) \
S (u16), S (u64)
/* _s16 _s32 _s64. */
-#define TYPES_hsd_signed(S, D) \
+#define TYPES_hsd_signed(S, D, T) \
S (s16), S (s32), S (s64)
/* _s16 _s32 _s64
_u16 _u32 _u64. */
-#define TYPES_hsd_integer(S, D) \
- TYPES_hsd_signed (S, D), S (u16), S (u32), S (u64)
+#define TYPES_hsd_integer(S, D, T) \
+ TYPES_hsd_signed (S, D, T), S (u16), S (u32), S (u64)
-#define TYPES_hsd_data(S, D) \
- TYPES_h_data (S, D), \
- TYPES_s_data (S, D), \
- TYPES_d_data (S, D)
+#define TYPES_hsd_data(S, D, T) \
+ TYPES_h_data (S, D, T), \
+ TYPES_s_data (S, D, T), \
+ TYPES_d_data (S, D, T)
/* _f16_mf8. */
-#define TYPES_h_float_mf8(S, D) \
+#define TYPES_h_float_mf8(S, D, T) \
D (f16, mf8)
/* _f32. */
-#define TYPES_s_float(S, D) \
+#define TYPES_s_float(S, D, T) \
S (f32)
/* _f32_mf8. */
-#define TYPES_s_float_mf8(S, D) \
+#define TYPES_s_float_mf8(S, D, T) \
D (f32, mf8)
/* _f32
_s16 _s32 _s64
_u16 _u32 _u64. */
-#define TYPES_s_float_hsd_integer(S, D) \
- TYPES_s_float (S, D), TYPES_hsd_integer (S, D)
+#define TYPES_s_float_hsd_integer(S, D, T) \
+ TYPES_s_float (S, D, T), TYPES_hsd_integer (S, D, T)
/* _f32
_s32 _s64
_u32 _u64. */
-#define TYPES_s_float_sd_integer(S, D) \
- TYPES_s_float (S, D), TYPES_sd_integer (S, D)
+#define TYPES_s_float_sd_integer(S, D, T) \
+ TYPES_s_float (S, D, T), TYPES_sd_integer (S, D, T)
/* _s32. */
-#define TYPES_s_signed(S, D) \
+#define TYPES_s_signed(S, D, T) \
S (s32)
/* _u32. */
-#define TYPES_s_unsigned(S, D) \
+#define TYPES_s_unsigned(S, D, T) \
S (u32)
/* _s32
_u32. */
-#define TYPES_s_integer(S, D) \
- TYPES_s_signed (S, D), TYPES_s_unsigned (S, D)
+#define TYPES_s_integer(S, D, T) \
+ TYPES_s_signed (S, D, T), TYPES_s_unsigned (S, D, T)
/* _f32
_s32
_u32. */
-#define TYPES_s_data(S, D) \
- TYPES_s_float (S, D), TYPES_s_integer (S, D)
+#define TYPES_s_data(S, D, T) \
+ TYPES_s_float (S, D, T), TYPES_s_integer (S, D, T)
/* _s32 _s64. */
-#define TYPES_sd_signed(S, D) \
+#define TYPES_sd_signed(S, D, T) \
S (s32), S (s64)
/* _u32 _u64. */
-#define TYPES_sd_unsigned(S, D) \
+#define TYPES_sd_unsigned(S, D, T) \
S (u32), S (u64)
/* _s32 _s64
_u32 _u64. */
-#define TYPES_sd_integer(S, D) \
- TYPES_sd_signed (S, D), TYPES_sd_unsigned (S, D)
+#define TYPES_sd_integer(S, D, T) \
+ TYPES_sd_signed (S, D, T), TYPES_sd_unsigned (S, D, T)
-#define TYPES_sd_data(S, D) \
- TYPES_s_data (S, D), \
- TYPES_d_data (S, D)
+#define TYPES_sd_data(S, D, T) \
+ TYPES_s_data (S, D, T), \
+ TYPES_d_data (S, D, T)
/* _f16 _f32 _f64
_s32 _s64
_u32 _u64. */
-#define TYPES_all_float_and_sd_integer(S, D) \
- TYPES_all_float (S, D), TYPES_sd_integer (S, D)
+#define TYPES_all_float_and_sd_integer(S, D, T) \
+ TYPES_all_float (S, D, T), TYPES_sd_integer (S, D, T)
/* _f64. */
-#define TYPES_d_float(S, D) \
+#define TYPES_d_float(S, D, T) \
S (f64)
/* _u64. */
-#define TYPES_d_unsigned(S, D) \
+#define TYPES_d_unsigned(S, D, T) \
S (u64)
/* _s64
_u64. */
-#define TYPES_d_integer(S, D) \
- S (s64), TYPES_d_unsigned (S, D)
+#define TYPES_d_integer(S, D, T) \
+ S (s64), TYPES_d_unsigned (S, D, T)
/* _f64
_s64
_u64. */
-#define TYPES_d_data(S, D) \
- TYPES_d_float (S, D), TYPES_d_integer (S, D)
+#define TYPES_d_data(S, D, T) \
+ TYPES_d_float (S, D, T), TYPES_d_integer (S, D, T)
/* All the type combinations allowed by svcvt. */
-#define TYPES_cvt(S, D) \
+#define TYPES_cvt(S, D, T) \
D (f16, f32), D (f16, f64), \
D (f16, s16), D (f16, s32), D (f16, s64), \
D (f16, u16), D (f16, u32), D (f16, u64), \
@@ -462,35 +462,35 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
D (u64, f16), D (u64, f32), D (u64, f64)
/* _bf16_f32. */
-#define TYPES_cvt_bfloat(S, D) \
+#define TYPES_cvt_bfloat(S, D, T) \
D (bf16, f32)
/* { _bf16 _f16 } x _f32. */
-#define TYPES_cvt_h_s_float(S, D) \
+#define TYPES_cvt_h_s_float(S, D, T) \
D (bf16, f32), D (f16, f32)
/* _f32_f16. */
-#define TYPES_cvt_f32_f16(S, D) \
+#define TYPES_cvt_f32_f16(S, D, T) \
D (f32, f16)
/* _f32_f16
_f64_f32. */
-#define TYPES_cvt_long(S, D) \
+#define TYPES_cvt_long(S, D, T) \
D (f32, f16), D (f64, f32)
/* _f16_f32. */
-#define TYPES_cvt_narrow_s(S, D) \
+#define TYPES_cvt_narrow_s(S, D, T) \
D (f32, f64)
/* _f16_f32
_f32_f64. */
-#define TYPES_cvt_narrow(S, D) \
- D (f16, f32), TYPES_cvt_narrow_s (S, D)
+#define TYPES_cvt_narrow(S, D, T) \
+ D (f16, f32), TYPES_cvt_narrow_s (S, D, T)
/* { _s32 _u32 } x _f32
_f32 x { _s32 _u32 }. */
-#define TYPES_cvt_s_s(S, D) \
+#define TYPES_cvt_s_s(S, D, T) \
D (s32, f32), \
D (u32, f32), \
D (f32, s32), \
@@ -498,23 +498,23 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
/* _f16_mf8
_bf16_mf8. */
-#define TYPES_cvt_mf8(S, D) \
+#define TYPES_cvt_mf8(S, D, T) \
D (f16, mf8), D (bf16, mf8)
/* _mf8_f16
_mf8_bf16. */
-#define TYPES_cvtn_mf8(S, D) \
+#define TYPES_cvtn_mf8(S, D, T) \
D (mf8, f16), D (mf8, bf16)
/* _mf8_f32. */
-#define TYPES_cvtnx_mf8(S, D) \
+#define TYPES_cvtnx_mf8(S, D, T) \
D (mf8, f32)
/* { _s32 _s64 } x { _b8 _b16 _b32 _b64 }
{ _u32 _u64 }. */
#define TYPES_inc_dec_n1(D, A) \
D (A, b8), D (A, b16), D (A, b32), D (A, b64)
-#define TYPES_inc_dec_n(S, D) \
+#define TYPES_inc_dec_n(S, D, T) \
TYPES_inc_dec_n1 (D, s32), \
TYPES_inc_dec_n1 (D, s64), \
TYPES_inc_dec_n1 (D, u32), \
@@ -523,7 +523,7 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
/* { _s16 _u16 } x _s32
{ _u16 } x _u32. */
-#define TYPES_qcvt_x2(S, D) \
+#define TYPES_qcvt_x2(S, D, T) \
D (s16, s32), \
D (u16, u32), \
D (u16, s32)
@@ -535,7 +535,7 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
{ _s16 _u16 } x _s64
{ _u16 } x _u64. */
-#define TYPES_qcvt_x4(S, D) \
+#define TYPES_qcvt_x4(S, D, T) \
D (s8, s32), \
D (u8, u32), \
D (u8, s32), \
@@ -545,19 +545,19 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
/* _s16_s32
_u16_u32. */
-#define TYPES_qrshr_x2(S, D) \
+#define TYPES_qrshr_x2(S, D, T) \
D (s16, s32), \
D (u16, u32)
/* _u16_s32. */
-#define TYPES_qrshru_x2(S, D) \
+#define TYPES_qrshru_x2(S, D, T) \
D (u16, s32)
/* _s8_s32
_s16_s64
_u8_u32
_u16_u64. */
-#define TYPES_qrshr_x4(S, D) \
+#define TYPES_qrshr_x4(S, D, T) \
D (s8, s32), \
D (s16, s64), \
D (u8, u32), \
@@ -565,7 +565,7 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
/* _u8_s32
_u16_s64. */
-#define TYPES_qrshru_x4(S, D) \
+#define TYPES_qrshru_x4(S, D, T) \
D (u8, s32), \
D (u16, s64)
@@ -579,7 +579,7 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
D (A, f16), D (A, f32), D (A, f64), \
D (A, s8), D (A, s16), D (A, s32), D (A, s64), \
D (A, u8), D (A, u16), D (A, u32), D (A, u64)
-#define TYPES_reinterpret(S, D) \
+#define TYPES_reinterpret(S, D, T) \
TYPES_reinterpret1 (D, mf8), \
TYPES_reinterpret1 (D, bf16), \
TYPES_reinterpret1 (D, f16), \
@@ -596,7 +596,7 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
/* _b_c
_c_b. */
-#define TYPES_reinterpret_b(S, D) \
+#define TYPES_reinterpret_b(S, D, T) \
D (b, c), \
D (c, b)
@@ -604,7 +604,7 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
{ _u32 _u64 } */
#define TYPES_while1(D, bn) \
D (bn, s32), D (bn, s64), D (bn, u32), D (bn, u64)
-#define TYPES_while(S, D) \
+#define TYPES_while(S, D, T) \
TYPES_while1 (D, b8), \
TYPES_while1 (D, b16), \
TYPES_while1 (D, b32), \
@@ -612,7 +612,7 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
/* { _b8 _b16 _b32 _b64 } x { _s64 }
{ _u64 } */
-#define TYPES_while_x(S, D) \
+#define TYPES_while_x(S, D, T) \
D (b8, s64), D (b8, u64), \
D (b16, s64), D (b16, u64), \
D (b32, s64), D (b32, u64), \
@@ -620,7 +620,7 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
/* { _c8 _c16 _c32 _c64 } x { _s64 }
{ _u64 } */
-#define TYPES_while_x_c(S, D) \
+#define TYPES_while_x_c(S, D, T) \
D (c8, s64), D (c8, u64), \
D (c16, s64), D (c16, u64), \
D (c32, s64), D (c32, u64), \
@@ -629,15 +629,15 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
/* _f32_f16
_s32_s16
_u32_u16. */
-#define TYPES_s_narrow_fsu(S, D) \
+#define TYPES_s_narrow_fsu(S, D, T) \
D (f32, f16), D (s32, s16), D (u32, u16)
/* _za8 _za16 _za32 _za64 _za128. */
-#define TYPES_all_za(S, D) \
+#define TYPES_all_za(S, D, T) \
S (za8), S (za16), S (za32), S (za64), S (za128)
/* _za64. */
-#define TYPES_d_za(S, D) \
+#define TYPES_d_za(S, D, T) \
S (za64)
/* { _za8 } x { _s8 _u8 }
@@ -647,7 +647,7 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
{ _za32 } x { _f32 _s32 _u32 }
{ _za64 } x { _f64 _s64 _u64 }. */
-#define TYPES_za_bhsd_data(S, D) \
+#define TYPES_za_bhsd_data(S, D, T) \
D (za8, s8), D (za8, u8), \
D (za16, bf16), D (za16, f16), D (za16, s16), D (za16, u16), \
D (za32, f32), D (za32, s32), D (za32, u32), \
@@ -660,112 +660,118 @@ CONSTEXPR const group_suffix_info group_suffixes[] = {
{ _s8 _s16 _s32 _s64 }
{ _u8 _u16 _u32 _u64 }. */
-#define TYPES_za_all_data(S, D) \
- TYPES_za_bhsd_data (S, D), \
+#define TYPES_za_all_data(S, D, T) \
+ TYPES_za_bhsd_data (S, D, T), \
TYPES_reinterpret1 (D, za128)
/* _za16_bf16. */
-#define TYPES_za_h_bfloat(S, D) \
+#define TYPES_za_h_bfloat(S, D, T) \
D (za16, bf16)
/* _za16_f16. */
-#define TYPES_za_h_float(S, D) \
+#define TYPES_za_h_float(S, D, T) \
D (za16, f16)
/* _za32_s8. */
-#define TYPES_za_s_b_signed(S, D) \
+#define TYPES_za_s_b_signed(S, D, T) \
D (za32, s8)
/* _za32_u8. */
-#define TYPES_za_s_b_unsigned(S, D) \
+#define TYPES_za_s_b_unsigned(S, D, T) \
D (za32, u8)
/* _za32 x { _s8 _u8 }. */
-#define TYPES_za_s_b_integer(S, D) \
+#define TYPES_za_s_b_integer(S, D, T) \
D (za32, s8), D (za32, u8)
/* _za32 x { _s16 _u16 }. */
-#define TYPES_za_s_h_integer(S, D) \
+#define TYPES_za_s_h_integer(S, D, T) \
D (za32, s16), D (za32, u16)
/* _za32 x { _bf16 _f16 _s16 _u16 }. */
-#define TYPES_za_s_h_data(S, D) \
+#define TYPES_za_s_h_data(S, D, T) \
D (za32, bf16), D (za32, f16), D (za32, s16), D (za32, u16)
/* _za32_u32. */
-#define TYPES_za_s_unsigned(S, D) \
+#define TYPES_za_s_unsigned(S, D, T) \
D (za32, u32)
/* _za32 x { _s32 _u32 }. */
-#define TYPES_za_s_integer(S, D) \
+#define TYPES_za_s_integer(S, D, T) \
D (za32, s32), D (za32, u32)
/* _za32_f32. */
-#define TYPES_za_s_float(S, D) \
+#define TYPES_za_s_float(S, D, T) \
D (za32, f32)
/* _za32 x { _f32 _s32 _u32 }. */
-#define TYPES_za_s_data(S, D) \
+#define TYPES_za_s_data(S, D, T) \
D (za32, f32), D (za32, s32), D (za32, u32)
/* _za64 x { _s16 _u16 }. */
-#define TYPES_za_d_h_integer(S, D) \
+#define TYPES_za_d_h_integer(S, D, T) \
D (za64, s16), D (za64, u16)
/* _za64_f64. */
-#define TYPES_za_d_float(S, D) \
+#define TYPES_za_d_float(S, D, T) \
D (za64, f64)
/* _za64 x { _s64 _u64 }. */
-#define TYPES_za_d_integer(S, D) \
+#define TYPES_za_d_integer(S, D, T) \
D (za64, s64), D (za64, u64)
/* _za32 x { _s8 _u8 _bf16 _f16 _f32 }. */
-#define TYPES_mop_base(S, D) \
+#define TYPES_mop_base(S, D, T) \
D (za32, s8), D (za32, u8), D (za32, bf16), D (za32, f16), D (za32, f32)
/* _za32_s8. */
-#define TYPES_mop_base_signed(S, D) \
+#define TYPES_mop_base_signed(S, D, T) \
D (za32, s8)
/* _za32_u8. */
-#define TYPES_mop_base_unsigned(S, D) \
+#define TYPES_mop_base_unsigned(S, D, T) \
D (za32, u8)
/* _za64 x { _s16 _u16 }. */
-#define TYPES_mop_i16i64(S, D) \
+#define TYPES_mop_i16i64(S, D, T) \
D (za64, s16), D (za64, u16)
/* _za64_s16. */
-#define TYPES_mop_i16i64_signed(S, D) \
+#define TYPES_mop_i16i64_signed(S, D, T) \
D (za64, s16)
/* _za64_u16. */
-#define TYPES_mop_i16i64_unsigned(S, D) \
+#define TYPES_mop_i16i64_unsigned(S, D, T) \
D (za64, u16)
/* _za. */
-#define TYPES_za(S, D) \
+#define TYPES_za(S, D, T) \
S (za)
-/* Describe a pair of type suffixes in which only the first is used. */
-#define DEF_VECTOR_TYPE(X) { TYPE_SUFFIX_ ## X, NUM_TYPE_SUFFIXES }
+/* Describe a tuple of type suffixes in which only the first is used. */
+#define DEF_VECTOR_TYPE(X) \
+ { TYPE_SUFFIX_ ## X, NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES }
-/* Describe a pair of type suffixes in which both are used. */
-#define DEF_DOUBLE_TYPE(X, Y) { TYPE_SUFFIX_ ## X, TYPE_SUFFIX_ ## Y }
+/* Describe a tuple of type suffixes in which only the first two are used. */
+#define DEF_DOUBLE_TYPE(X, Y) \
+ { TYPE_SUFFIX_ ## X, TYPE_SUFFIX_ ## Y, NUM_TYPE_SUFFIXES }
+
+/* Describe a tuple of type suffixes in which three elements are used. */
+#define DEF_TRIPLE_TYPE(X, Y, Z) \
+ { TYPE_SUFFIX_ ## X, TYPE_SUFFIX_ ## Y, TYPE_SUFFIX_ ## Z }
/* Create an array that can be used in aarch64-sve-builtins.def to
select the type suffixes in TYPES_<NAME>. */
#define DEF_SVE_TYPES_ARRAY(NAME) \
- static const type_suffix_pair types_##NAME[] = { \
- TYPES_##NAME (DEF_VECTOR_TYPE, DEF_DOUBLE_TYPE), \
- { NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES } \
+ static const type_suffix_triple types_##NAME[] = { \
+ TYPES_##NAME (DEF_VECTOR_TYPE, DEF_DOUBLE_TYPE, DEF_TRIPLE_TYPE), \
+ { NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES } \
}
/* For functions that don't take any type suffixes. */
-static const type_suffix_pair types_none[] = {
- { NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES },
- { NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES }
+static const type_suffix_triple types_none[] = {
+ { NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES },
+ { NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES }
};
/* Create an array for each TYPES_<combination> macro above. */
@@ -1207,6 +1213,7 @@ function_instance::hash () const
h.add_int (mode_suffix_id);
h.add_int (type_suffix_ids[0]);
h.add_int (type_suffix_ids[1]);
+ h.add_int (type_suffix_ids[2]);
h.add_int (group_suffix_id);
h.add_int (pred);
h.add_int (fpm_mode);
@@ -1378,7 +1385,7 @@ function_builder::get_name (const function_instance &instance,
}
else
append_name (instance.mode_suffix ().string);
- for (unsigned int i = 0; i < 2; ++i)
+ for (unsigned int i = 0; i < 3; ++i)
if (!overloaded_p || instance.shape->explicit_type_suffix_p (i))
append_name (instance.type_suffix (i).string);
if (!overloaded_p || instance.shape->explicit_group_suffix_p ())
@@ -1623,8 +1630,9 @@ function_builder::add_overloaded_functions (const function_group_info &group,
{
bool explicit_type0 = (*group.shape)->explicit_type_suffix_p (0);
bool explicit_type1 = (*group.shape)->explicit_type_suffix_p (1);
+ bool explicit_type2 = (*group.shape)->explicit_type_suffix_p (2);
bool explicit_group = (*group.shape)->explicit_group_suffix_p ();
- auto add_function = [&](const type_suffix_pair &types,
+ auto add_function = [&](const type_suffix_triple &types,
group_suffix_index group_suffix_id,
unsigned int pi)
{
@@ -1652,9 +1660,10 @@ function_builder::add_overloaded_functions (const function_group_info &group,
{
/* Stub out the types that are determined by overload
resolution. */
- type_suffix_pair types = {
+ type_suffix_triple types = {
explicit_type0 ? group.types[ti][0] : NUM_TYPE_SUFFIXES,
- explicit_type1 ? group.types[ti][1] : NUM_TYPE_SUFFIXES
+ explicit_type1 ? group.types[ti][1] : NUM_TYPE_SUFFIXES,
+ explicit_type2 ? group.types[ti][2] : NUM_TYPE_SUFFIXES
};
add_function (types, group_suffix_id, pi);
}
@@ -1805,9 +1814,10 @@ tree
function_resolver::lookup_form (mode_suffix_index mode,
type_suffix_index type0,
type_suffix_index type1,
+ type_suffix_index type2,
group_suffix_index group)
{
- type_suffix_pair types = { type0, type1 };
+ type_suffix_triple types = { type0, type1, type2 };
function_instance instance (base_name, base, shape, mode, types, group, pred,
fpm_mode);
registered_function *rfn
@@ -1827,13 +1837,14 @@ function_resolver::lookup_form (mode_suffix_index mode, sve_type type)
{
type_suffix_index type0 = type_suffix_ids[0];
type_suffix_index type1 = type_suffix_ids[1];
+ type_suffix_index type2 = type_suffix_ids[2];
(type0 == NUM_TYPE_SUFFIXES ? type0 : type1) = type.type;
group_suffix_index group = group_suffix_id;
if (group == GROUP_none && type.num_vectors != vectors_per_tuple ())
group = num_vectors_to_group (type.num_vectors);
- return lookup_form (mode, type0, type1, group);
+ return lookup_form (mode, type0, type1, type2, group);
}
/* Resolve the function to one with the mode suffix given by MODE, the
@@ -1844,9 +1855,10 @@ tree
function_resolver::resolve_to (mode_suffix_index mode,
type_suffix_index type0,
type_suffix_index type1,
+ type_suffix_index type2,
group_suffix_index group)
{
- tree res = lookup_form (mode, type0, type1, group);
+ tree res = lookup_form (mode, type0, type1, type2, group);
if (!res)
{
if (type1 == NUM_TYPE_SUFFIXES)
@@ -3207,7 +3219,8 @@ function_resolver::resolve_unary (type_class_index merge_tclass,
/* Handle convert-like functions in which the first type suffix is
explicit. */
if (type_suffix_ids[0] != NUM_TYPE_SUFFIXES)
- return resolve_to (mode_suffix_id, type_suffix_ids[0], type);
+ return resolve_to (mode_suffix_id, type_suffix_ids[0], type,
+ NUM_TYPE_SUFFIXES, group_suffix_id);
return resolve_to (mode_suffix_id, type);
}
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h b/gcc/config/aarch64/aarch64-sve-builtins.h
index 6098d8ff229..2d0fb0501da 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.h
+++ b/gcc/config/aarch64/aarch64-sve-builtins.h
@@ -38,7 +38,7 @@
- mode_suffix_index represents the mode suffix
- type_suffix_index represents individual type suffixes, while
- type_suffix_pair represents a pair of them
+ type_suffix_triple represents a tuple of them
- prediction_index extends the predication suffix with an additional
alternative: PRED_implicit for implicitly-predicated operations
@@ -227,8 +227,8 @@ enum group_suffix_index
NUM_GROUP_SUFFIXES
};
-/* Combines two type suffixes. */
-typedef enum type_suffix_index type_suffix_pair[2];
+/* Combines three type suffixes. */
+typedef enum type_suffix_index type_suffix_triple[3];
class function_base;
class function_shape;
@@ -367,12 +367,12 @@ struct function_group_info
/* A list of the available type suffixes, group suffixes, and predication
types. The function supports every combination of the three.
- The list of type suffixes is terminated by two NUM_TYPE_SUFFIXES.
+ The list of type suffixes is terminated by three NUM_TYPE_SUFFIXES.
It is lexicographically ordered based on the index value.
The list of group suffixes is terminated by NUM_GROUP_SUFFIXES
and the list of predication types is terminated by NUM_PREDS. */
- const type_suffix_pair *types;
+ const type_suffix_triple *types;
const group_suffix_index *groups;
const predication_index *preds;
@@ -390,7 +390,7 @@ class GTY((user)) function_instance
public:
function_instance (const char *, const function_base *,
const function_shape *, mode_suffix_index,
- const type_suffix_pair &, group_suffix_index,
+ const type_suffix_triple &, group_suffix_index,
predication_index, fpm_mode_index);
bool operator== (const function_instance &) const;
@@ -434,7 +434,7 @@ public:
const function_base *base;
const function_shape *shape;
mode_suffix_index mode_suffix_id;
- type_suffix_pair type_suffix_ids;
+ type_suffix_triple type_suffix_ids;
group_suffix_index group_suffix_id;
predication_index pred;
fpm_mode_index fpm_mode;
@@ -525,11 +525,13 @@ public:
tree report_no_such_form (sve_type);
tree lookup_form (mode_suffix_index,
+ type_suffix_index = NUM_TYPE_SUFFIXES,
type_suffix_index = NUM_TYPE_SUFFIXES,
type_suffix_index = NUM_TYPE_SUFFIXES,
group_suffix_index = GROUP_none);
tree lookup_form (mode_suffix_index, sve_type);
tree resolve_to (mode_suffix_index,
+ type_suffix_index = NUM_TYPE_SUFFIXES,
type_suffix_index = NUM_TYPE_SUFFIXES,
type_suffix_index = NUM_TYPE_SUFFIXES,
group_suffix_index = GROUP_none);
@@ -907,7 +909,7 @@ inline function_instance::
function_instance (const char *base_name_in, const function_base *base_in,
const function_shape *shape_in,
mode_suffix_index mode_suffix_id_in,
- const type_suffix_pair &type_suffix_ids_in,
+ const type_suffix_triple &type_suffix_ids_in,
group_suffix_index group_suffix_id_in,
predication_index pred_in, fpm_mode_index fpm_mode_in)
: base_name (base_name_in), base (base_in), shape (shape_in),
@@ -925,6 +927,7 @@ function_instance::operator== (const function_instance &other) const
&& mode_suffix_id == other.mode_suffix_id
&& type_suffix_ids[0] == other.type_suffix_ids[0]
&& type_suffix_ids[1] == other.type_suffix_ids[1]
+ && type_suffix_ids[2] == other.type_suffix_ids[2]
&& group_suffix_id == other.group_suffix_id
&& pred == other.pred
&& fpm_mode == other.fpm_mode);