1 /* ACLE support for AArch64 SVE (function shapes)
2 Copyright (C) 2018-2025 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
28 #include "insn-codes.h"
30 #include "aarch64-sve-builtins.h"
31 #include "aarch64-sve-builtins-shapes.h"
32 #include "aarch64-builtins.h"
34 /* In the comments below, _t0 represents the first type suffix and _t1
35 represents the second. Square brackets enclose characters that are
36 present in only the full name, not the overloaded name. Governing
37 predicate arguments and predicate suffixes are not shown, since they
38 depend on the predication type, which is a separate piece of
39 information from the shape.
41 Non-overloaded functions may have additional suffixes beyond the
42 ones shown, if those suffixes don't affect the types in the type
43 signature. E.g. the predicate form of svtrn1 has a _b<bits> suffix,
44 but this does not affect the prototype, which is always
45 "svbool_t(svbool_t, svbool_t)". */
47 namespace aarch64_sve
{
49 /* Return a representation of "const T *". */
51 build_const_pointer (tree t
)
53 return build_pointer_type (build_qualified_type (t
, TYPE_QUAL_CONST
));
56 /* GROUP's first type suffix is a ZA-related one. Return true if the
57 group exists only for the purpose of defining C overloads. This is
58 useful if some forms of an instruction require one feature and other
59 forms require another feature, and neither feature implies the other. */
61 za_group_is_pure_overload (const function_group_info
&group
)
63 gcc_checking_assert (type_suffixes
[group
.types
[0][0]].za_p
);
64 return group
.types
[0][1] == NUM_TYPE_SUFFIXES
;
67 /* If INSTANCE has a governing predicate, add it to the list of argument
68 types in ARGUMENT_TYPES. RETURN_TYPE is the type returned by the
71 apply_predication (const function_instance
&instance
, tree return_type
,
72 vec
<tree
> &argument_types
)
74 /* There are currently no SME ZA instructions that have both merging and
75 unpredicated forms, so for simplicity, the predicates are always included
76 in the original format string. */
77 if (instance
.pred
!= PRED_none
&& instance
.pred
!= PRED_za_m
)
79 argument_types
.quick_insert (0, instance
.gp_type ());
80 /* For unary merge operations, the first argument is a vector with
81 the same type as the result. For unary_convert_narrowt it also
82 provides the "bottom" half of active elements, and is present
83 for all types of predication. */
84 auto nargs
= argument_types
.length () - 1;
85 if (instance
.shape
->has_merge_argument_p (instance
, nargs
))
86 argument_types
.quick_insert (0, return_type
);
90 /* Parse and move past an element type in FORMAT and return it as a type
91 suffix. The format is:
93 [01] - the element type in type suffix 0 or 1 of INSTANCE
94 f<bits> - a floating-point type with the given number of bits
95 f[01] - a floating-point type with the same width as type suffix 0 or 1
97 c - a predicate-as-counter
98 h<elt> - a half-sized version of <elt>
100 p - a predicate (represented as TYPE_SUFFIX_b)
101 q<elt> - a quarter-sized version of <elt>
102 s<bits> - a signed type with the given number of bits
103 s[01] - a signed type with the same width as type suffix 0 or 1
104 u<bits> - an unsigned type with the given number of bits
105 u[01] - an unsigned type with the same width as type suffix 0 or 1
106 w<elt> - a 64-bit version of <elt> if <elt> is integral, otherwise <elt>
108 where <elt> is another element type. */
109 static type_suffix_index
110 parse_element_type (const function_instance
&instance
, const char *&format
)
114 if (ch
== 'f' || ch
== 's' || ch
== 'u')
116 type_class_index tclass
= (ch
== 'f' ? TYPE_float
117 : ch
== 's' ? TYPE_signed
120 unsigned int bits
= strtol (format
, &end
, 10);
122 if (bits
== 0 || bits
== 1)
123 bits
= instance
.type_suffix (bits
).element_bits
;
124 return find_type_suffix (tclass
, bits
);
129 type_suffix_index suffix
= parse_element_type (instance
, format
);
130 if (type_suffixes
[suffix
].integer_p
)
131 return find_type_suffix (type_suffixes
[suffix
].tclass
, 64);
136 return TYPE_SUFFIX_c
;
139 return TYPE_SUFFIX_b
;
142 return TYPE_SUFFIX_bf16
;
145 return TYPE_SUFFIX_mf8
;
149 type_suffix_index suffix
= parse_element_type (instance
, format
);
150 return find_type_suffix (type_suffixes
[suffix
].tclass
,
151 type_suffixes
[suffix
].element_bits
/ 4);
156 type_suffix_index suffix
= parse_element_type (instance
, format
);
157 /* Widening and narrowing doesn't change the type for predicates;
158 everything's still an svbool_t. */
159 if (suffix
== TYPE_SUFFIX_b
)
161 return find_type_suffix (type_suffixes
[suffix
].tclass
,
162 type_suffixes
[suffix
].element_bits
/ 2);
165 if (ch
== '0' || ch
== '1')
166 return instance
.type_suffix_ids
[ch
- '0'];
171 /* Read and return a type from FORMAT for function INSTANCE. Advance
172 FORMAT beyond the type string. The format is:
175 al - array pointer for loads
176 ap - array pointer for prefetches
177 as - array pointer for stores
178 b - base vector type (from a _<m0>base suffix)
179 c0 - the result of a conversion, based on type and group suffixes
180 c1 - the source of a conversion, based on type and group suffixes
181 d - displacement vector type (from a _<m1>index or _<m1>offset suffix)
182 e<name> - an enum with the given name
183 s<elt> - a scalar type with the given element suffix
184 t<elt> - a vector or tuple type with given element suffix [*1]
185 v<elt> - a vector with the given element suffix
186 D<elt> - a 64 bit neon vector
187 Q<elt> - a 128 bit neon vector
189 where <elt> has the format described above parse_element_type
191 [*1] the vectors_per_tuple function indicates whether the type should
192 be a tuple, and if so, how many vectors it should contain. */
194 parse_type (const function_instance
&instance
, const char *&format
)
199 return void_type_node
;
205 return build_const_pointer (instance
.memory_scalar_type ());
207 return const_ptr_type_node
;
209 return build_pointer_type (instance
.memory_scalar_type ());
214 return instance
.base_vector_type ();
219 gcc_assert (ch
== '0' || ch
== '1');
220 unsigned int id
= (ch
== '0' ? 0 : 1);
221 auto vector_type
= instance
.type_suffix (id
).vector_type
;
222 unsigned int num_vectors
= instance
.group_suffix ().vectors_per_tuple
;
223 if (num_vectors
!= 1)
225 unsigned int bits
= instance
.type_suffix (id
).element_bits
;
226 unsigned int other_bits
= instance
.type_suffix (1 - id
).element_bits
;
227 if (other_bits
> bits
)
228 num_vectors
/= other_bits
/ bits
;
230 return acle_vector_types
[num_vectors
- 1][vector_type
];
234 return instance
.displacement_vector_type ();
238 if (startswith (format
, "pattern"))
241 return acle_svpattern
;
243 if (startswith (format
, "prfop"))
253 type_suffix_index suffix
= parse_element_type (instance
, format
);
254 return scalar_types
[type_suffixes
[suffix
].vector_type
];
259 type_suffix_index suffix
= parse_element_type (instance
, format
);
260 vector_type_index vector_type
= type_suffixes
[suffix
].vector_type
;
261 unsigned int num_vectors
= instance
.vectors_per_tuple ();
262 return acle_vector_types
[num_vectors
- 1][vector_type
];
267 type_suffix_index suffix
= parse_element_type (instance
, format
);
268 return acle_vector_types
[0][type_suffixes
[suffix
].vector_type
];
273 type_suffix_index suffix
= parse_element_type (instance
, format
);
274 int neon_index
= type_suffixes
[suffix
].neon64_type
;
275 return aarch64_simd_types_trees
[neon_index
].itype
;
280 type_suffix_index suffix
= parse_element_type (instance
, format
);
281 int neon_index
= type_suffixes
[suffix
].neon128_type
;
282 return aarch64_simd_types_trees
[neon_index
].itype
;
288 /* Read and move past any argument count at FORMAT for the function
289 signature of INSTANCE. The counts are:
291 *q: one argument per element in a 128-bit quadword (as for svdupq)
292 *t: one argument per vector in a tuple (as for svcreate)
294 Otherwise the count is 1. */
296 parse_count (const function_instance
&instance
, const char *&format
)
298 if (format
[0] == '*' && format
[1] == 'q')
301 return instance
.elements_per_vq (0);
303 if (format
[0] == '*' && format
[1] == 't')
306 return instance
.vectors_per_tuple ();
311 /* Read a type signature for INSTANCE from FORMAT. Add the argument types
312 to ARGUMENT_TYPES and return the return type.
314 The format is a comma-separated list of types (as for parse_type),
315 with the first type being the return type and the rest being the
316 argument types. Each argument type can be followed by an optional
317 count (as for parse_count). */
319 parse_signature (const function_instance
&instance
, const char *format
,
320 vec
<tree
> &argument_types
)
322 tree return_type
= parse_type (instance
, format
);
323 while (format
[0] == ',')
326 tree argument_type
= parse_type (instance
, format
);
327 unsigned int count
= parse_count (instance
, format
);
328 for (unsigned int i
= 0; i
< count
; ++i
)
329 argument_types
.quick_push (argument_type
);
331 gcc_assert (format
[0] == 0);
332 if (instance
.fpm_mode
== FPM_set
)
333 argument_types
.quick_push (get_typenode_from_name (UINT64_TYPE
));
337 /* Add one function instance for GROUP, using mode suffix MODE_SUFFIX_ID,
338 the type suffixes at index TI, the group suffixes at index GI, and the
339 predication suffix at index PI. The other arguments are as for
342 build_one (function_builder
&b
, const char *signature
,
343 const function_group_info
&group
, mode_suffix_index mode_suffix_id
,
344 unsigned int ti
, unsigned int gi
, unsigned int pi
,
345 bool force_direct_overloads
)
347 /* For simplicity, function definitions are allowed to use the group
348 suffix lists vg2 and vg4 for shapes that have _single forms,
349 even though the _single form applies only to vgNx2 and vgNx4,
351 if (mode_suffix_id
== MODE_single
352 && group_suffixes
[group
.groups
[gi
]].vectors_per_tuple
== 1)
355 /* Byte forms of svdupq take 16 arguments. */
356 auto_vec
<tree
, 16> argument_types
;
357 function_instance
instance (group
.base_name
, *group
.base
, *group
.shape
,
358 mode_suffix_id
, group
.types
[ti
], group
.groups
[gi
],
359 group
.preds
[pi
], group
.fpm_mode
);
360 tree return_type
= parse_signature (instance
, signature
, argument_types
);
361 apply_predication (instance
, return_type
, argument_types
);
362 b
.add_unique_function (instance
, return_type
, argument_types
,
363 group
.required_extensions
, force_direct_overloads
);
366 /* GROUP describes some sort of gather or scatter operation. There are
369 - If the function has any type suffixes (as for loads and stores), the
370 first function type suffix specifies either a 32-bit or a 64-bit type,
371 which in turn selects either MODE32 or MODE64 as the addressing mode.
372 Add a function instance for every type and predicate combination
373 in GROUP for which the associated addressing mode is not MODE_none.
375 - If the function has no type suffixes (as for prefetches), add one
376 MODE32 form and one MODE64 form for each predication type.
378 The other arguments are as for build_all. */
380 build_32_64 (function_builder
&b
, const char *signature
,
381 const function_group_info
&group
, mode_suffix_index mode32
,
382 mode_suffix_index mode64
, bool force_direct_overloads
= false)
384 for (unsigned int pi
= 0; group
.preds
[pi
] != NUM_PREDS
; ++pi
)
385 for (unsigned int gi
= 0; group
.groups
[gi
] != NUM_GROUP_SUFFIXES
; ++gi
)
386 if (group
.types
[0][0] == NUM_TYPE_SUFFIXES
)
388 gcc_assert (mode32
!= MODE_none
&& mode64
!= MODE_none
);
389 build_one (b
, signature
, group
, mode32
, 0, gi
, pi
,
390 force_direct_overloads
);
391 build_one (b
, signature
, group
, mode64
, 0, gi
, pi
,
392 force_direct_overloads
);
395 for (unsigned int ti
= 0; group
.types
[ti
][0] != NUM_TYPE_SUFFIXES
;
398 unsigned int bits
= type_suffixes
[group
.types
[ti
][0]].element_bits
;
399 gcc_assert (bits
== 32 || bits
== 64);
400 mode_suffix_index mode
= bits
== 32 ? mode32
: mode64
;
401 if (mode
!= MODE_none
)
402 build_one (b
, signature
, group
, mode
, ti
, gi
, pi
,
403 force_direct_overloads
);
407 /* For every type and predicate combination in GROUP, add one function
408 that takes a scalar (pointer) base and a signed vector array index,
409 and another that instead takes an unsigned vector array index.
410 The vector array index has the same element size as the first
411 function type suffix. SIGNATURE is as for build_all. */
413 build_sv_index (function_builder
&b
, const char *signature
,
414 const function_group_info
&group
)
416 build_32_64 (b
, signature
, group
, MODE_s32index
, MODE_s64index
);
417 build_32_64 (b
, signature
, group
, MODE_u32index
, MODE_u64index
);
420 /* Like build_sv_index, but only handle 64-bit types. */
422 build_sv_index64 (function_builder
&b
, const char *signature
,
423 const function_group_info
&group
)
425 build_32_64 (b
, signature
, group
, MODE_none
, MODE_s64index
);
426 build_32_64 (b
, signature
, group
, MODE_none
, MODE_u64index
);
429 /* Like build_sv_index, but taking vector byte offsets instead of vector
432 build_sv_offset (function_builder
&b
, const char *signature
,
433 const function_group_info
&group
)
435 build_32_64 (b
, signature
, group
, MODE_s32offset
, MODE_s64offset
);
436 build_32_64 (b
, signature
, group
, MODE_u32offset
, MODE_u64offset
);
439 /* Like build_sv_offset, but exclude offsets that must be interpreted
440 as signed (i.e. s32offset). */
442 build_sv_uint_offset (function_builder
&b
, const char *signature
,
443 const function_group_info
&group
)
445 build_32_64 (b
, signature
, group
, MODE_none
, MODE_s64offset
);
446 build_32_64 (b
, signature
, group
, MODE_u32offset
, MODE_u64offset
);
449 /* For every type and predicate combination in GROUP, add a function
450 that takes a vector base address and no displacement. The vector
451 base has the same element size as the first type suffix.
453 The other arguments are as for build_all. */
455 build_v_base (function_builder
&b
, const char *signature
,
456 const function_group_info
&group
,
457 bool force_direct_overloads
= false)
459 build_32_64 (b
, signature
, group
, MODE_u32base
, MODE_u64base
,
460 force_direct_overloads
);
463 /* Like build_v_base, but for functions that also take a scalar array
466 build_vs_index (function_builder
&b
, const char *signature
,
467 const function_group_info
&group
,
468 bool force_direct_overloads
= false)
470 build_32_64 (b
, signature
, group
, MODE_u32base_index
, MODE_u64base_index
,
471 force_direct_overloads
);
474 /* Like build_v_base, but for functions that also take a scalar byte
477 build_vs_offset (function_builder
&b
, const char *signature
,
478 const function_group_info
&group
,
479 bool force_direct_overloads
= false)
481 build_32_64 (b
, signature
, group
, MODE_u32base_offset
, MODE_u64base_offset
,
482 force_direct_overloads
);
485 /* Add a function instance for every type and predicate combination
486 in GROUP. Take the function base name from GROUP and the mode suffix
487 from MODE_SUFFIX_ID. Use SIGNATURE to construct the function signature
488 without a governing predicate, then use apply_predication to add in the
489 predicate. FORCE_DIRECT_OVERLOADS is true if there is a one-to-one
490 mapping between "short" and "full" names, and if standard overload
491 resolution therefore isn't necessary. */
493 build_all (function_builder
&b
, const char *signature
,
494 const function_group_info
&group
, mode_suffix_index mode_suffix_id
,
495 bool force_direct_overloads
= false)
497 for (unsigned int pi
= 0; group
.preds
[pi
] != NUM_PREDS
; ++pi
)
498 for (unsigned int gi
= 0; group
.groups
[gi
] != NUM_GROUP_SUFFIXES
; ++gi
)
499 for (unsigned int ti
= 0;
500 ti
== 0 || group
.types
[ti
][0] != NUM_TYPE_SUFFIXES
; ++ti
)
501 build_one (b
, signature
, group
, mode_suffix_id
, ti
, gi
, pi
,
502 force_direct_overloads
);
505 /* TYPE is the largest type suffix associated with the arguments of R,
506 but the result is twice as wide. Return the associated type suffix
507 if it exists, otherwise report an appropriate error and return
508 NUM_TYPE_SUFFIXES. */
509 static type_suffix_index
510 long_type_suffix (function_resolver
&r
, type_suffix_index type
)
512 unsigned int element_bits
= type_suffixes
[type
].element_bits
;
513 if (type_suffixes
[type
].integer_p
&& element_bits
< 64)
514 return find_type_suffix (type_suffixes
[type
].tclass
, element_bits
* 2);
516 r
.report_no_such_form (type
);
517 return NUM_TYPE_SUFFIXES
;
520 /* Declare the function shape NAME, pointing it to an instance
521 of class <NAME>_def. */
522 #define SHAPE(NAME) \
523 static CONSTEXPR const NAME##_def NAME##_obj; \
524 namespace shapes { const function_shape *const NAME = &NAME##_obj; }
526 /* Base class for functions that are not overloaded. */
527 struct nonoverloaded_base
: public function_shape
530 explicit_type_suffix_p (unsigned int) const override
536 resolve (function_resolver
&) const override
542 /* Base class for overloaded functions. Bit N of EXPLICIT_MASK is true
543 if type suffix N appears in the overloaded name. */
544 template<unsigned int EXPLICIT_MASK
>
545 struct overloaded_base
: public function_shape
548 explicit_type_suffix_p (unsigned int i
) const override
550 return (EXPLICIT_MASK
>> i
) & 1;
554 /* Base class for adr_index and adr_offset. */
555 struct adr_base
: public overloaded_base
<0>
557 /* The function takes two arguments: a vector base and a vector displacement
558 (either an index or an offset). Resolve based on them both. */
560 resolve (function_resolver
&r
) const override
562 unsigned int i
, nargs
;
563 mode_suffix_index mode
;
564 if (!r
.check_gp_argument (2, i
, nargs
)
565 || (mode
= r
.resolve_adr_address (0)) == MODE_none
)
566 return error_mark_node
;
568 return r
.resolve_to (mode
);
572 /* Base class for narrowing bottom binary functions that take an
573 immediate second operand. The result is half the size of input
574 and has class CLASS. */
575 template<type_class_index CLASS
= function_resolver::SAME_TYPE_CLASS
>
576 struct binary_imm_narrowb_base
: public overloaded_base
<0>
579 build (function_builder
&b
, const function_group_info
&group
) const override
581 b
.add_overloaded_functions (group
, MODE_n
);
582 STATIC_ASSERT (CLASS
== function_resolver::SAME_TYPE_CLASS
583 || CLASS
== TYPE_unsigned
);
584 if (CLASS
== TYPE_unsigned
)
585 build_all (b
, "vhu0,v0,su64", group
, MODE_n
);
587 build_all (b
, "vh0,v0,su64", group
, MODE_n
);
591 resolve (function_resolver
&r
) const override
593 return r
.resolve_uniform (1, 1);
597 /* The top equivalent of binary_imm_narrowb_base. It takes three arguments,
598 with the first being the values of the even elements, which are typically
599 the result of the narrowb operation. */
600 template<type_class_index CLASS
= function_resolver::SAME_TYPE_CLASS
>
601 struct binary_imm_narrowt_base
: public overloaded_base
<0>
604 build (function_builder
&b
, const function_group_info
&group
) const override
606 b
.add_overloaded_functions (group
, MODE_n
);
607 STATIC_ASSERT (CLASS
== function_resolver::SAME_TYPE_CLASS
608 || CLASS
== TYPE_unsigned
);
609 if (CLASS
== TYPE_unsigned
)
610 build_all (b
, "vhu0,vhu0,v0,su64", group
, MODE_n
);
612 build_all (b
, "vh0,vh0,v0,su64", group
, MODE_n
);
616 resolve (function_resolver
&r
) const override
618 unsigned int i
, nargs
;
619 type_suffix_index type
;
620 if (!r
.check_gp_argument (3, i
, nargs
)
621 || (type
= r
.infer_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
622 || !r
.require_derived_vector_type (i
, i
+ 1, type
, CLASS
, r
.HALF_SIZE
)
623 || !r
.require_integer_immediate (i
+ 2))
624 return error_mark_node
;
626 return r
.resolve_to (r
.mode_suffix_id
, type
);
630 /* Base class for long (i.e. narrow op narrow -> wide) binary functions
631 that take an immediate second operand. The type suffix specifies
633 struct binary_imm_long_base
: public overloaded_base
<0>
636 build (function_builder
&b
, const function_group_info
&group
) const override
638 b
.add_overloaded_functions (group
, MODE_n
);
639 build_all (b
, "v0,vh0,su64", group
, MODE_n
);
643 resolve (function_resolver
&r
) const override
645 unsigned int i
, nargs
;
646 type_suffix_index type
, result_type
;
647 if (!r
.check_gp_argument (2, i
, nargs
)
648 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
649 || !r
.require_integer_immediate (i
+ 1)
650 || (result_type
= long_type_suffix (r
, type
)) == NUM_TYPE_SUFFIXES
)
651 return error_mark_node
;
653 if (tree res
= r
.lookup_form (r
.mode_suffix_id
, result_type
))
656 return r
.report_no_such_form (type
);
660 /* Base class for binary_za_m and similar shapes. */
661 template<type_class_index TCLASS
= function_resolver::SAME_TYPE_CLASS
,
662 unsigned int BITS
= function_resolver::SAME_SIZE
>
663 struct binary_za_m_base
: public overloaded_base
<1>
666 resolve (function_resolver
&r
) const override
668 type_suffix_index type
;
669 if (!r
.check_num_arguments (5)
670 || !r
.require_integer_immediate (0)
671 || !r
.require_vector_type (1, VECTOR_TYPE_svbool_t
)
672 || !r
.require_vector_type (2, VECTOR_TYPE_svbool_t
)
673 || (type
= r
.infer_vector_type (3)) == NUM_TYPE_SUFFIXES
674 || !r
.require_derived_vector_type (4, 3, type
, TCLASS
, BITS
))
675 return error_mark_node
;
677 return r
.resolve_to (r
.mode_suffix_id
, r
.type_suffix_ids
[0], type
);
681 check (function_checker
&c
) const override
683 return c
.require_immediate_range (0, 0, c
.num_za_tiles () - 1);
687 /* Base class for shapes like binary_za_slice_lane. TCLASS is the type
688 class of the final vector argument. */
689 template<type_class_index TCLASS
= function_resolver::SAME_TYPE_CLASS
>
690 struct binary_za_slice_lane_base
: public overloaded_base
<1>
692 constexpr binary_za_slice_lane_base (unsigned int lane_type_suffix
)
693 : m_lane_type_suffix (lane_type_suffix
) {}
696 build (function_builder
&b
, const function_group_info
&group
) const override
698 b
.add_overloaded_functions (group
, MODE_none
);
699 build_all (b
, "_,su32,t1,v1,su64", group
, MODE_none
);
703 resolve (function_resolver
&r
) const override
706 if (!r
.check_num_arguments (4)
707 || !r
.require_scalar_type (0, "uint32_t")
708 || !(type
= r
.infer_tuple_type (1))
709 || !r
.require_derived_vector_type (2, 1, type
, TCLASS
)
710 || !r
.require_integer_immediate (3))
711 return error_mark_node
;
713 return r
.resolve_to (r
.mode_suffix_id
, type
);
717 check (function_checker
&c
) const override
719 unsigned int bytes
= c
.type_suffix (m_lane_type_suffix
).element_bytes
;
720 return c
.require_immediate_range (3, 0, 16 / bytes
- 1);
723 unsigned int m_lane_type_suffix
;
726 /* Base class for shapes like binary_za_slice_opt_single. TCLASS is the
727 type class of the final argument. */
728 template<type_class_index TCLASS
= function_resolver::SAME_TYPE_CLASS
>
729 struct binary_za_slice_opt_single_base
: public overloaded_base
<1>
732 resolve (function_resolver
&r
) const override
735 if (!r
.check_num_arguments (3)
736 || !r
.require_scalar_type (0, "uint32_t")
737 || !(type
= r
.infer_tuple_type (1)))
738 return error_mark_node
;
740 return r
.finish_opt_single_resolution (2, 1, type
, TCLASS
);
744 /* Base class for ext and extq. */
745 struct ext_base
: public overloaded_base
<0>
748 build (function_builder
&b
, const function_group_info
&group
) const override
750 b
.add_overloaded_functions (group
, MODE_none
);
751 build_all (b
, "v0,v0,v0,su64", group
, MODE_none
);
755 resolve (function_resolver
&r
) const override
757 return r
.resolve_uniform (2, 1);
761 /* Base class for inc_dec and inc_dec_pat. */
762 struct inc_dec_base
: public overloaded_base
<0>
764 CONSTEXPR
inc_dec_base (bool pat_p
) : m_pat_p (pat_p
) {}
766 /* Resolve based on the first argument only, which must be either a
767 scalar or a vector. If it's a scalar, it must be a 32-bit or
770 resolve (function_resolver
&r
) const
772 unsigned int i
, nargs
;
773 if (!r
.check_gp_argument (m_pat_p
? 3 : 2, i
, nargs
)
774 || !r
.require_vector_or_scalar_type (i
))
775 return error_mark_node
;
777 mode_suffix_index mode
;
778 type_suffix_index type
;
779 if (r
.scalar_argument_p (i
))
782 type
= r
.infer_integer_scalar_type (i
);
787 type
= r
.infer_vector_type (i
);
789 if (type
== NUM_TYPE_SUFFIXES
)
790 return error_mark_node
;
792 for (++i
; i
< nargs
; ++i
)
793 if (!r
.require_integer_immediate (i
))
794 return error_mark_node
;
796 return r
.resolve_to (mode
, type
);
800 check (function_checker
&c
) const override
802 return c
.require_immediate_range (m_pat_p
? 2 : 1, 1, 16);
808 /* Base class for load and load_replicate. */
809 struct load_contiguous_base
: public overloaded_base
<0>
811 /* Resolve a call based purely on a pointer argument. The other arguments
812 are a governing predicate and (for MODE_vnum) a vnum offset. */
814 resolve (function_resolver
&r
) const override
816 bool vnum_p
= r
.mode_suffix_id
== MODE_vnum
;
817 gcc_assert (r
.mode_suffix_id
== MODE_none
|| vnum_p
);
819 unsigned int i
, nargs
;
820 type_suffix_index type
;
821 if (!r
.check_gp_argument (vnum_p
? 2 : 1, i
, nargs
)
822 || (type
= r
.infer_pointer_type (i
)) == NUM_TYPE_SUFFIXES
823 || (vnum_p
&& !r
.require_scalar_type (i
+ 1, "int64_t")))
824 return error_mark_node
;
826 return r
.resolve_to (r
.mode_suffix_id
, type
, NUM_TYPE_SUFFIXES
,
831 /* Base class for gather loads that take a scalar base and a vector
832 displacement (either an offset or an index). */
833 struct load_gather_sv_base
: public overloaded_base
<0>
836 resolve (function_resolver
&r
) const override
838 unsigned int i
, nargs
;
839 mode_suffix_index mode
;
840 type_suffix_index type
;
841 auto restrictions
= get_target_type_restrictions (r
);
842 if (!r
.check_gp_argument (2, i
, nargs
)
843 || (type
= r
.infer_pointer_type (i
, true,
844 restrictions
)) == NUM_TYPE_SUFFIXES
845 || (mode
= r
.resolve_sv_displacement (i
+ 1, type
, true),
847 return error_mark_node
;
849 return r
.resolve_to (mode
, type
);
852 virtual function_resolver::target_type_restrictions
853 get_target_type_restrictions (const function_instance
&) const
855 return function_resolver::TARGET_32_64
;
859 /* Base class for load_gather64_sv_index and load_gather64_sv_offset. */
860 struct load_gather64_sv_base
: public load_gather_sv_base
863 vector_base_type (type_suffix_index
) const override
865 return TYPE_SUFFIX_u64
;
868 function_resolver::target_type_restrictions
869 get_target_type_restrictions (const function_instance
&) const override
871 return function_resolver::TARGET_ANY
;
875 /* Base class for load_ext_gather_index and load_ext_gather_offset,
876 which differ only in the units of the displacement. */
877 struct load_ext_gather_base
: public overloaded_base
<1>
879 /* Resolve a gather load that takes one of:
881 - a scalar pointer base and a vector displacement
882 - a vector base with no displacement or
883 - a vector base and a scalar displacement
885 The function has an explicit type suffix that determines the type
886 of the loaded data. */
888 resolve (function_resolver
&r
) const override
890 /* No resolution is needed for a vector base with no displacement;
891 there's a one-to-one mapping between short and long names. */
892 gcc_assert (r
.displacement_units () != UNITS_none
);
894 type_suffix_index type
= r
.type_suffix_ids
[0];
896 unsigned int i
, nargs
;
897 mode_suffix_index mode
;
898 if (!r
.check_gp_argument (2, i
, nargs
)
899 || (mode
= r
.resolve_gather_address (i
, type
, true)) == MODE_none
)
900 return error_mark_node
;
902 return r
.resolve_to (mode
, type
);
907 /* sv<v0>_t svlut[_<t0>_g](sv<t0>x<g>_t, svuint8_t, uint64_t)
909 where the final argument is a constant index, the instruction divides
910 the vector argument in BITS-bit quantities. */
911 template<unsigned int BITS
>
912 struct luti_base
: public overloaded_base
<0>
914 bool explicit_group_suffix_p () const override
{ return false; }
917 build (function_builder
&b
, const function_group_info
&group
) const override
919 /* Format: return type, table vector, indices vector, immediate value. */
920 b
.add_overloaded_functions (group
, MODE_none
);
921 build_all (b
, "v0,t0,vu8,su64", group
, MODE_none
);
925 check (function_checker
&c
) const override
927 auto max_range
= c
.type_suffix (0).element_bits
/ BITS
- 1;
928 return c
.require_immediate_range (2, 0, max_range
);
932 resolve (function_resolver
&r
) const override
935 if (!r
.check_num_arguments (3)
936 || !(type
= r
.infer_sve_type (0))
937 || !r
.require_vector_type (1, VECTOR_TYPE_svuint8_t
)
938 || !r
.require_scalar_type (2, "uint64_t"))
939 return error_mark_node
;
941 return r
.resolve_to (r
.mode_suffix_id
, type
);
945 /* Specializations for 2-bit and 4-bit indices. */
946 using luti2_def
= luti_base
<2>;
949 using luti4_def
= luti_base
<4>;
953 /* sv<t0>x<g>_t svfoo_t0_g(uint64_t, svuint8_t, uint64_t)
955 where the first argument is the ZT register number (currently always 0)
956 and the final argument is a constant index. The instruction divides
957 the vector argument in BITS-bit quantities. */
958 template<unsigned int BITS
>
959 struct luti_lane_zt_base
: public nonoverloaded_base
962 build (function_builder
&b
, const function_group_info
&group
) const override
964 build_all (b
, "t0,su64,vu8,su64", group
, MODE_none
);
968 check (function_checker
&c
) const override
970 auto nvectors
= c
.vectors_per_tuple ();
971 return (c
.require_immediate_range (0, 0, 0)
972 && c
.require_immediate_range (2, 0, 32 / BITS
/ nvectors
- 1));
976 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:quarter>_t,
977 sv<t0:quarter>_t) (for integer t0)
978 sv<t0>_t svmmla[_t0](sv<t0>_t, sv<t0>_t, sv<t0>_t) (for floating-point t0)
980 The functions act like the equivalent of "ternary_qq" for integer elements
981 and normal vector-only ternary functions for floating-point elements. */
982 struct mmla_def
: public overloaded_base
<0>
985 build (function_builder
&b
, const function_group_info
&group
) const override
987 b
.add_overloaded_functions (group
, MODE_none
);
988 if (type_suffixes
[group
.types
[0][0]].float_p
)
989 build_all (b
, "v0,v0,v0,v0", group
, MODE_none
);
991 build_all (b
, "v0,v0,vq0,vq0", group
, MODE_none
);
995 resolve (function_resolver
&r
) const override
997 unsigned int i
, nargs
;
998 type_suffix_index type
;
999 if (!r
.check_gp_argument (3, i
, nargs
)
1000 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
1001 return error_mark_node
;
1003 /* Make sure that the function exists now, since not all forms
1004 follow a set pattern after this point. */
1005 tree res
= r
.resolve_to (r
.mode_suffix_id
, type
);
1006 if (res
== error_mark_node
)
1009 bool float_p
= type_suffixes
[type
].float_p
;
1010 unsigned int modifier
= float_p
? r
.SAME_SIZE
: r
.QUARTER_SIZE
;
1011 if (!r
.require_derived_vector_type (i
+ 1, i
, type
, r
.SAME_TYPE_CLASS
,
1013 || !r
.require_derived_vector_type (i
+ 2, i
, type
, r
.SAME_TYPE_CLASS
,
1015 return error_mark_node
;
1022 /* Base class for prefetch_gather_index and prefetch_gather_offset,
1023 which differ only in the units of the displacement. */
1024 struct prefetch_gather_base
: public overloaded_base
<0>
1026 /* Resolve a gather prefetch that takes one of:
1028 - a scalar pointer base (const void *) and a vector displacement
1029 - a vector base with no displacement or
1030 - a vector base and a scalar displacement
1032 The prefetch operation is the final argument. This is purely a
1033 mode-based resolution; there are no type suffixes. */
1035 resolve (function_resolver
&r
) const override
1037 bool has_displacement_p
= r
.displacement_units () != UNITS_none
;
1039 unsigned int i
, nargs
;
1040 mode_suffix_index mode
;
1041 if (!r
.check_gp_argument (has_displacement_p
? 3 : 2, i
, nargs
)
1042 || (mode
= r
.resolve_gather_address (i
, NUM_TYPE_SUFFIXES
,
1043 false)) == MODE_none
1044 || !r
.require_integer_immediate (nargs
- 1))
1045 return error_mark_node
;
1047 return r
.resolve_to (mode
);
1051 /* Wraps BASE to provide a narrowing shift right function. Argument N
1052 is an immediate shift amount in the range [1, sizeof(<t0>_t) * 4]. */
1053 template<typename BASE
, unsigned int N
>
1054 struct shift_right_imm_narrow_wrapper
: public BASE
1057 check (function_checker
&c
) const override
1059 unsigned int bits
= c
.type_suffix (0).element_bits
/ 2;
1060 return c
.require_immediate_range (N
, 1, bits
);
1064 /* Base class for store_scatter_index and store_scatter_offset,
1065 which differ only in the units of the displacement. */
1066 struct store_scatter_base
: public overloaded_base
<0>
1068 /* Resolve a scatter store that takes one of:
1070 - a scalar pointer base and a vector displacement
1071 - a vector base with no displacement or
1072 - a vector base and a scalar displacement
1074 The stored data is the final argument, and it determines the
1077 resolve (function_resolver
&r
) const override
1079 bool has_displacement_p
= r
.displacement_units () != UNITS_none
;
1081 unsigned int i
, nargs
;
1082 mode_suffix_index mode
;
1083 type_suffix_index type
;
1084 if (!r
.check_gp_argument (has_displacement_p
? 3 : 2, i
, nargs
)
1085 || (type
= infer_vector_type (r
, nargs
- 1)) == NUM_TYPE_SUFFIXES
1086 || (mode
= r
.resolve_gather_address (i
, type
, false)) == MODE_none
)
1087 return error_mark_node
;
1089 return r
.resolve_to (mode
, type
);
1092 virtual type_suffix_index
1093 infer_vector_type (function_resolver
&r
, unsigned int argno
) const
1095 return r
.infer_sd_vector_type (argno
);
1099 /* Base class for store_scatter64_index and store_scatter64_offset. */
1100 struct store_scatter64_base
: public store_scatter_base
1103 vector_base_type (type_suffix_index
) const override
1105 return TYPE_SUFFIX_u64
;
1109 infer_vector_type (function_resolver
&r
, unsigned int argno
) const override
1111 return r
.infer_vector_type (argno
);
1115 /* Base class for ternary operations in which the final argument is an
1116 immediate shift amount. The derived class should check the range. */
1117 struct ternary_shift_imm_base
: public overloaded_base
<0>
1120 build (function_builder
&b
, const function_group_info
&group
) const override
1122 b
.add_overloaded_functions (group
, MODE_n
);
1123 build_all (b
, "v0,v0,v0,su64", group
, MODE_n
);
1127 resolve (function_resolver
&r
) const override
1129 return r
.resolve_uniform (2, 1);
1133 /* Base class for ternary operations in which the first argument has the
1134 same element type as the result, and in which the second and third
1135 arguments have an element type that is derived the first.
1137 MODIFIER is the number of element bits in the second and third
1138 arguments, or a function_resolver modifier that says how this
1139 precision is derived from the first argument's elements.
1141 TYPE_CLASS2 and TYPE_CLASS3 are the type classes of the second and
1142 third arguments, or function_resolver::SAME_TYPE_CLASS if the type
1143 class is the same as the first argument. */
1144 template<unsigned int MODIFIER
,
1145 type_class_index TYPE_CLASS2
= function_resolver::SAME_TYPE_CLASS
,
1146 type_class_index TYPE_CLASS3
= function_resolver::SAME_TYPE_CLASS
>
1147 struct ternary_resize2_opt_n_base
: public overloaded_base
<0>
1150 resolve (function_resolver
&r
) const override
1152 unsigned int i
, nargs
;
1153 type_suffix_index type
;
1154 if (!r
.check_gp_argument (3, i
, nargs
)
1155 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1156 || !r
.require_derived_vector_type (i
+ 1, i
, type
, TYPE_CLASS2
,
1158 return error_mark_node
;
1160 return r
.finish_opt_n_resolution (i
+ 2, i
, type
, TYPE_CLASS3
, MODIFIER
);
1164 /* Like ternary_resize2_opt_n_base, but for functions that don't take
1165 a final scalar argument. */
1166 template<unsigned int MODIFIER
,
1167 type_class_index TYPE_CLASS2
= function_resolver::SAME_TYPE_CLASS
,
1168 type_class_index TYPE_CLASS3
= function_resolver::SAME_TYPE_CLASS
>
1169 struct ternary_resize2_base
: public overloaded_base
<0>
1172 resolve (function_resolver
&r
) const override
1174 unsigned int i
, nargs
;
1175 type_suffix_index type
;
1176 if (!r
.check_gp_argument (3, i
, nargs
)
1177 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1178 || !r
.require_derived_vector_type (i
+ 1, i
, type
, TYPE_CLASS2
,
1180 || !r
.require_derived_vector_type (i
+ 2, i
, type
, TYPE_CLASS3
,
1182 return error_mark_node
;
1184 return r
.resolve_to (r
.mode_suffix_id
, type
);
1188 /* Like ternary_resize2_opt_n_base, but for functions that take a final
1190 template<unsigned int MODIFIER
,
1191 type_class_index TYPE_CLASS2
= function_resolver::SAME_TYPE_CLASS
,
1192 type_class_index TYPE_CLASS3
= function_resolver::SAME_TYPE_CLASS
>
1193 struct ternary_resize2_lane_base
: public overloaded_base
<0>
1196 resolve (function_resolver
&r
) const override
1198 unsigned int i
, nargs
;
1199 type_suffix_index type
;
1200 if (!r
.check_gp_argument (4, i
, nargs
)
1201 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1202 || !r
.require_derived_vector_type (i
+ 1, i
, type
, TYPE_CLASS2
,
1204 || !r
.require_derived_vector_type (i
+ 2, i
, type
, TYPE_CLASS3
,
1206 || !r
.require_integer_immediate (i
+ 3))
1207 return error_mark_node
;
1209 return r
.resolve_to (r
.mode_suffix_id
, type
);
1213 /* A specialization of ternary_resize2_lane_base for bfloat16 elements,
1214 indexed in groups of N elements. */
1215 template<unsigned int N
>
1216 struct ternary_bfloat_lane_base
1217 : public ternary_resize2_lane_base
<16, TYPE_bfloat
, TYPE_bfloat
>
1220 build (function_builder
&b
, const function_group_info
&group
) const override
1222 b
.add_overloaded_functions (group
, MODE_none
);
1223 build_all (b
, "v0,v0,vB,vB,su64", group
, MODE_none
);
1227 check (function_checker
&c
) const override
1229 return c
.require_immediate_lane_index (3, 2, N
);
1233 /* A specialization of ternary_resize2_lane_base for quarter-sized
1235 template<type_class_index TYPE_CLASS2
= function_resolver::SAME_TYPE_CLASS
,
1236 type_class_index TYPE_CLASS3
= function_resolver::SAME_TYPE_CLASS
>
1237 struct ternary_qq_lane_base
1238 : public ternary_resize2_lane_base
<function_resolver::QUARTER_SIZE
,
1239 TYPE_CLASS2
, TYPE_CLASS3
>
1242 check (function_checker
&c
) const override
1244 return c
.require_immediate_lane_index (3, 0);
1248 /* Base class for narrowing bottom unary functions. The result is half
1249 the size of input and has class CLASS. */
1250 template<type_class_index CLASS
= function_resolver::SAME_TYPE_CLASS
>
1251 struct unary_narrowb_base
: public overloaded_base
<0>
1254 build (function_builder
&b
, const function_group_info
&group
) const override
1256 b
.add_overloaded_functions (group
, MODE_none
);
1257 STATIC_ASSERT (CLASS
== function_resolver::SAME_TYPE_CLASS
1258 || CLASS
== TYPE_unsigned
);
1259 if (CLASS
== TYPE_unsigned
)
1260 build_all (b
, "vhu0,v0", group
, MODE_none
);
1262 build_all (b
, "vh0,v0", group
, MODE_none
);
1266 resolve (function_resolver
&r
) const override
1268 return r
.resolve_unary (CLASS
, r
.HALF_SIZE
);
1272 /* The top equivalent of unary_imm_narrowb_base. All forms take the values
1273 of the even elements as an extra argument, before any governing predicate.
1274 These even elements are typically the result of the narrowb operation. */
1275 template<type_class_index CLASS
= function_resolver::SAME_TYPE_CLASS
>
1276 struct unary_narrowt_base
: public overloaded_base
<0>
1279 build (function_builder
&b
, const function_group_info
&group
) const override
1281 b
.add_overloaded_functions (group
, MODE_none
);
1282 STATIC_ASSERT (CLASS
== function_resolver::SAME_TYPE_CLASS
1283 || CLASS
== TYPE_unsigned
);
1284 if (CLASS
== TYPE_unsigned
)
1285 build_all (b
, "vhu0,vhu0,v0", group
, MODE_none
);
1287 build_all (b
, "vh0,vh0,v0", group
, MODE_none
);
1291 resolve (function_resolver
&r
) const override
1293 unsigned int i
, nargs
;
1294 type_suffix_index type
;
1295 if (!r
.check_gp_argument (2, i
, nargs
)
1296 || (type
= r
.infer_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
1297 || !r
.require_derived_vector_type (i
, i
+ 1, type
, CLASS
, r
.HALF_SIZE
))
1298 return error_mark_node
;
1300 return r
.resolve_to (r
.mode_suffix_id
, type
);
1304 /* sv<m0>_t svfoo[_m0base]_[m1]index(sv<m0>_t, sv<m1>_t)
1306 for all valid combinations of vector base type <m0> and vector
1307 displacement type <m1>. */
1308 struct adr_index_def
: public adr_base
1311 build (function_builder
&b
, const function_group_info
&group
) const override
1313 b
.add_overloaded_functions (group
, MODE_index
);
1314 build_all (b
, "b,b,d", group
, MODE_u32base_s32index
);
1315 build_all (b
, "b,b,d", group
, MODE_u32base_u32index
);
1316 build_all (b
, "b,b,d", group
, MODE_u64base_s64index
);
1317 build_all (b
, "b,b,d", group
, MODE_u64base_u64index
);
1322 /* sv<m0>_t svfoo[_m0base]_[m1]offset(sv<m0>_t, sv<m1>_t).
1324 for all valid combinations of vector base type <m0> and vector
1325 displacement type <m1>. */
1326 struct adr_offset_def
: public adr_base
1329 build (function_builder
&b
, const function_group_info
&group
) const override
1331 b
.add_overloaded_functions (group
, MODE_offset
);
1332 build_all (b
, "b,b,d", group
, MODE_u32base_s32offset
);
1333 build_all (b
, "b,b,d", group
, MODE_u32base_u32offset
);
1334 build_all (b
, "b,b,d", group
, MODE_u64base_s64offset
);
1335 build_all (b
, "b,b,d", group
, MODE_u64base_u64offset
);
1340 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
1342 i.e. a binary operation with uniform types, but with no scalar form. */
1343 struct binary_def
: public overloaded_base
<0>
1346 build (function_builder
&b
, const function_group_info
&group
) const override
1348 b
.add_overloaded_functions (group
, MODE_none
);
1349 build_all (b
, "v0,v0,v0", group
, MODE_none
);
1353 resolve (function_resolver
&r
) const override
1355 return r
.resolve_uniform (2);
1360 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:int>_t)
1361 sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0:int>_t).
1363 i.e. a version of the standard binary shape binary_opt_n in which
1364 the final argument is always a signed integer. */
1365 struct binary_int_opt_n_def
: public overloaded_base
<0>
1368 build (function_builder
&b
, const function_group_info
&group
) const override
1370 b
.add_overloaded_functions (group
, MODE_none
);
1371 build_all (b
, "v0,v0,vs0", group
, MODE_none
);
1372 build_all (b
, "v0,v0,ss0", group
, MODE_n
);
1376 resolve (function_resolver
&r
) const override
1378 unsigned int i
, nargs
;
1379 type_suffix_index type
;
1380 if (!r
.check_gp_argument (2, i
, nargs
)
1381 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
1382 return error_mark_node
;
1384 return r
.finish_opt_n_resolution (i
+ 1, i
, type
, TYPE_signed
);
1387 SHAPE (binary_int_opt_n
)
1389 /* Like binary_int_opt_n for single vectors. For tuples:
1391 sv<t0>x<g>_t svfoo[_t0_g](sv<t0>x<g>_t, sv<t0:int>x<g>_t)
1392 sv<t0>x<g>_t svfoo[_single_t0_g](sv<t0>x<g>_t, sv<t0:int>_t). */
1393 struct binary_int_opt_single_n_def
: public overloaded_base
<0>
1395 bool explicit_group_suffix_p () const override
{ return false; }
1398 build (function_builder
&b
, const function_group_info
&group
) const override
1400 b
.add_overloaded_functions (group
, MODE_none
);
1401 build_all (b
, "t0,t0,ts0", group
, MODE_none
);
1402 if (group
.groups
[0] == GROUP_none
)
1403 build_all (b
, "v0,v0,ss0", group
, MODE_n
);
1405 build_all (b
, "t0,t0,vs0", group
, MODE_single
);
1409 resolve (function_resolver
&r
) const override
1411 unsigned int i
, nargs
;
1413 if (!r
.check_gp_argument (2, i
, nargs
)
1414 || !(type
= r
.infer_sve_type (i
)))
1415 return error_mark_node
;
1417 return (type
.num_vectors
== 1 && r
.scalar_argument_p (i
+ 1)
1418 ? r
.finish_opt_n_resolution (i
+ 1, i
, type
.type
, TYPE_signed
)
1419 : r
.finish_opt_single_resolution (i
+ 1, i
, type
, TYPE_signed
));
1422 SHAPE (binary_int_opt_single_n
)
1424 /* sv<t0>_t svfoo_<t0>(sv<t0>_t, sv<t0>_t, uint64_t)
1426 where the final argument is an integer constant expression in the
1427 range [0, 16 / sizeof (<t0>_t) - 1]. */
1428 struct binary_lane_def
: public overloaded_base
<0>
1431 build (function_builder
&b
, const function_group_info
&group
) const override
1433 b
.add_overloaded_functions (group
, MODE_none
);
1434 build_all (b
, "v0,v0,v0,su64", group
, MODE_none
);
1438 resolve (function_resolver
&r
) const override
1440 return r
.resolve_uniform (2, 1);
1444 check (function_checker
&c
) const override
1446 return c
.require_immediate_lane_index (2, 1);
1451 /* sv<t0>_t svfoo[_t0](sv<t0:half>_t, sv<t0:half>_t, uint64_t).
1453 where the final argument is an integer constant expression in the
1454 range [0, 32 / sizeof (<t0>_t) - 1]. */
1455 struct binary_long_lane_def
: public overloaded_base
<0>
1458 build (function_builder
&b
, const function_group_info
&group
) const override
1460 b
.add_overloaded_functions (group
, MODE_none
);
1461 build_all (b
, "v0,vh0,vh0,su64", group
, MODE_none
);
1465 resolve (function_resolver
&r
) const override
1467 unsigned int i
, nargs
;
1468 type_suffix_index type
, result_type
;
1469 if (!r
.check_gp_argument (3, i
, nargs
)
1470 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1471 || !r
.require_matching_vector_type (i
+ 1, i
, type
)
1472 || !r
.require_integer_immediate (i
+ 2)
1473 || (result_type
= long_type_suffix (r
, type
)) == NUM_TYPE_SUFFIXES
)
1474 return error_mark_node
;
1476 if (tree res
= r
.lookup_form (r
.mode_suffix_id
, result_type
))
1479 return r
.report_no_such_form (type
);
1483 check (function_checker
&c
) const override
1485 return c
.require_immediate_lane_index (2, 1);
1488 SHAPE (binary_long_lane
)
1490 /* sv<t0>_t svfoo[_t0](sv<t0:half>_t, sv<t0:half>_t)
1491 sv<t0>_t svfoo[_n_t0](sv<t0:half>_t, <t0:half>_t). */
1492 struct binary_long_opt_n_def
: public overloaded_base
<0>
1495 build (function_builder
&b
, const function_group_info
&group
) const override
1497 b
.add_overloaded_functions (group
, MODE_none
);
1498 build_all (b
, "v0,vh0,vh0", group
, MODE_none
);
1499 build_all (b
, "v0,vh0,sh0", group
, MODE_n
);
1503 resolve (function_resolver
&r
) const override
1505 unsigned int i
, nargs
;
1506 type_suffix_index type
, result_type
;
1507 if (!r
.check_gp_argument (2, i
, nargs
)
1508 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1509 || (result_type
= long_type_suffix (r
, type
)) == NUM_TYPE_SUFFIXES
)
1510 return error_mark_node
;
1512 return r
.finish_opt_n_resolution (i
+ 1, i
, type
, r
.SAME_TYPE_CLASS
,
1513 r
.SAME_SIZE
, result_type
);
1516 SHAPE (binary_long_opt_n
)
1518 /* sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0>_t).
1520 i.e. a binary operation in which the final argument is always a scalar
1521 rather than a vector. */
1522 struct binary_n_def
: public overloaded_base
<0>
1525 build (function_builder
&b
, const function_group_info
&group
) const override
1527 b
.add_overloaded_functions (group
, MODE_n
);
1528 build_all (b
, "v0,v0,s0", group
, MODE_n
);
1532 resolve (function_resolver
&r
) const override
1534 unsigned int i
, nargs
;
1535 type_suffix_index type
;
1536 if (!r
.check_gp_argument (2, i
, nargs
)
1537 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1538 || !r
.require_derived_scalar_type (i
+ 1, r
.SAME_TYPE_CLASS
))
1539 return error_mark_node
;
1541 return r
.resolve_to (r
.mode_suffix_id
, type
);
1546 /* sv<t0:half>_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
1547 sv<t0:half>_t svfoo[_n_t0](sv<t0>_t, <t0>_t)
1549 i.e. a version of binary_opt_n in which the output elements are half the
1550 width of the input elements. */
1551 struct binary_narrowb_opt_n_def
: public overloaded_base
<0>
1554 build (function_builder
&b
, const function_group_info
&group
) const override
1556 b
.add_overloaded_functions (group
, MODE_none
);
1557 build_all (b
, "vh0,v0,v0", group
, MODE_none
);
1558 build_all (b
, "vh0,v0,s0", group
, MODE_n
);
1562 resolve (function_resolver
&r
) const override
1564 return r
.resolve_uniform_opt_n (2);
1567 SHAPE (binary_narrowb_opt_n
)
1569 /* sv<t0:half>_t svfoo[_t0](sv<t0:half>_t, sv<t0>_t, sv<t0>_t)
1570 sv<t0:half>_t svfoo[_n_t0](sv<t0:half>_t, sv<t0>_t, <t0>_t)
1572 This is the "top" counterpart to binary_narrowb_opt_n. */
1573 struct binary_narrowt_opt_n_def
: public overloaded_base
<0>
1576 build (function_builder
&b
, const function_group_info
&group
) const override
1578 b
.add_overloaded_functions (group
, MODE_none
);
1579 build_all (b
, "vh0,vh0,v0,v0", group
, MODE_none
);
1580 build_all (b
, "vh0,vh0,v0,s0", group
, MODE_n
);
1584 resolve (function_resolver
&r
) const override
1586 unsigned int i
, nargs
;
1587 type_suffix_index type
;
1588 if (!r
.check_gp_argument (3, i
, nargs
)
1589 || (type
= r
.infer_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
1590 || !r
.require_derived_vector_type (i
, i
+ 1, type
, r
.SAME_TYPE_CLASS
,
1592 return error_mark_node
;
1594 return r
.finish_opt_n_resolution (i
+ 2, i
+ 1, type
);
1597 SHAPE (binary_narrowt_opt_n
)
1599 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
1600 sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0>_t)
1602 i.e. the standard shape for binary operations that operate on
1604 struct binary_opt_n_def
: public overloaded_base
<0>
1607 build (function_builder
&b
, const function_group_info
&group
) const override
1609 b
.add_overloaded_functions (group
, MODE_none
);
1610 build_all (b
, "v0,v0,v0", group
, MODE_none
);
1611 /* _b functions do not have an _n form, but are classified as
1612 binary_opt_n so that they can be overloaded with vector
1614 if (group
.types
[0][0] == TYPE_SUFFIX_b
)
1615 gcc_assert (group
.types
[0][1] == NUM_TYPE_SUFFIXES
);
1617 build_all (b
, "v0,v0,s0", group
, MODE_n
);
1621 resolve (function_resolver
&r
) const override
1623 return r
.resolve_uniform_opt_n (2);
1626 SHAPE (binary_opt_n
)
1628 /* Like binary_opt_n for single vectors. For tuples:
1630 sv<t0>x<g>_t svfoo[_t0_g](sv<t0>x<g>_t, sv<t0>x<g>_t)
1631 sv<t0>x<g>_t svfoo[_single_t0_g](sv<t0>x<g>_t, sv<t0>_t). */
1632 struct binary_opt_single_n_def
: public overloaded_base
<0>
1634 bool explicit_group_suffix_p () const override
{ return false; }
1637 build (function_builder
&b
, const function_group_info
&group
) const override
1639 b
.add_overloaded_functions (group
, MODE_none
);
1640 build_all (b
, "t0,t0,t0", group
, MODE_none
);
1641 if (group
.groups
[0] == GROUP_none
)
1642 build_all (b
, "v0,v0,s0", group
, MODE_n
);
1644 build_all (b
, "t0,t0,v0", group
, MODE_single
);
1648 resolve (function_resolver
&r
) const override
1650 unsigned int i
, nargs
;
1652 if (!r
.check_gp_argument (2, i
, nargs
)
1653 || !(type
= r
.infer_sve_type (i
)))
1654 return error_mark_node
;
1656 return (type
.num_vectors
== 1 && r
.scalar_argument_p (i
+ 1)
1657 ? r
.finish_opt_n_resolution (i
+ 1, i
, type
.type
)
1658 : r
.finish_opt_single_resolution (i
+ 1, i
, type
));
1661 SHAPE (binary_opt_single_n
)
1663 /* svbool_t svfoo(svbool_t, svbool_t). */
1664 struct binary_pred_def
: public nonoverloaded_base
1667 build (function_builder
&b
, const function_group_info
&group
) const override
1669 build_all (b
, "v0,v0,v0", group
, MODE_none
);
1674 /* sv<t0>_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, uint64_t)
1676 where the final argument must be 90 or 270. */
1677 struct binary_rotate_def
: public overloaded_base
<0>
1680 build (function_builder
&b
, const function_group_info
&group
) const override
1682 b
.add_overloaded_functions (group
, MODE_none
);
1683 build_all (b
, "v0,v0,v0,su64", group
, MODE_none
);
1687 resolve (function_resolver
&r
) const override
1689 return r
.resolve_uniform (2, 1);
1693 check (function_checker
&c
) const override
1695 return c
.require_immediate_either_or (2, 90, 270);
1698 SHAPE (binary_rotate
)
1700 /* sv<t0>_t svfoo_t0(<t0>_t, <t0>_t)
1702 i.e. a binary function that takes two scalars and returns a vector.
1703 An explicit type suffix is required. */
1704 struct binary_scalar_def
: public nonoverloaded_base
1707 build (function_builder
&b
, const function_group_info
&group
) const override
1709 build_all (b
, "v0,s0,s0", group
, MODE_none
);
1712 SHAPE (binary_scalar
)
1714 /* sv<t0>x<g>_t svfoo[_single_t0_g](sv<t0>x<g>_t, sv<t0>_t). */
1715 struct binary_single_def
: public overloaded_base
<0>
1717 bool explicit_group_suffix_p () const override
{ return false; }
1720 build (function_builder
&b
, const function_group_info
&group
) const override
1722 b
.add_overloaded_functions (group
, MODE_none
);
1723 build_all (b
, "t0,t0,v0", group
, MODE_single
);
1727 resolve (function_resolver
&r
) const override
1730 if (!r
.check_num_arguments (2)
1731 || !(type
= r
.infer_sve_type (0))
1732 || !r
.require_derived_vector_type (1, 0, type
, r
.SAME_TYPE_CLASS
,
1734 return error_mark_node
;
1736 return r
.resolve_to (MODE_single
, type
);
1739 SHAPE (binary_single
)
1741 /* sv<t0:uint>_t svfoo[_t0](sv<t0>_t, sv<t0>_t).
1743 i.e. a version of "binary" that returns unsigned integers. */
1744 struct binary_to_uint_def
: public overloaded_base
<0>
1747 build (function_builder
&b
, const function_group_info
&group
) const override
1749 b
.add_overloaded_functions (group
, MODE_none
);
1750 build_all (b
, "vu0,v0,v0", group
, MODE_none
);
1754 resolve (function_resolver
&r
) const override
1756 return r
.resolve_uniform (2);
1759 SHAPE (binary_to_uint
)
1761 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:uint>_t)
1763 i.e. a version of "binary" in which the final argument is always an
1764 unsigned integer. */
1765 struct binary_uint_def
: public overloaded_base
<0>
1768 build (function_builder
&b
, const function_group_info
&group
) const override
1770 b
.add_overloaded_functions (group
, MODE_none
);
1771 build_all (b
, "v0,v0,vu0", group
, MODE_none
);
1775 resolve (function_resolver
&r
) const override
1777 unsigned int i
, nargs
;
1778 type_suffix_index type
;
1779 if (!r
.check_gp_argument (2, i
, nargs
)
1780 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1781 || !r
.require_derived_vector_type (i
+ 1, i
, type
, TYPE_unsigned
))
1782 return error_mark_node
;
1784 return r
.resolve_to (r
.mode_suffix_id
, type
);
1789 /* sv<t0>_t svfoo[_t0](sv<t0>_t, <t0:uint>_t)
1791 i.e. a version of binary_n in which the final argument is always an
1792 unsigned integer. */
1793 struct binary_uint_n_def
: public overloaded_base
<0>
1796 build (function_builder
&b
, const function_group_info
&group
) const override
1798 b
.add_overloaded_functions (group
, MODE_none
);
1799 build_all (b
, "v0,v0,su0", group
, MODE_none
);
1803 resolve (function_resolver
&r
) const override
1805 unsigned int i
, nargs
;
1806 type_suffix_index type
;
1807 if (!r
.check_gp_argument (2, i
, nargs
)
1808 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1809 || !r
.require_derived_scalar_type (i
+ 1, TYPE_unsigned
))
1810 return error_mark_node
;
1812 return r
.resolve_to (r
.mode_suffix_id
, type
);
1815 SHAPE (binary_uint_n
)
1817 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:uint>_t)
1818 sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0:uint>_t)
1820 i.e. a version of the standard binary shape binary_opt_n in which
1821 the final argument is always an unsigned integer. */
1822 struct binary_uint_opt_n_def
: public overloaded_base
<0>
1825 build (function_builder
&b
, const function_group_info
&group
) const override
1827 b
.add_overloaded_functions (group
, MODE_none
);
1828 build_all (b
, "v0,v0,vu0", group
, MODE_none
);
1829 build_all (b
, "v0,v0,su0", group
, MODE_n
);
1833 resolve (function_resolver
&r
) const override
1835 unsigned int i
, nargs
;
1836 type_suffix_index type
;
1837 if (!r
.check_gp_argument (2, i
, nargs
)
1838 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
1839 return error_mark_node
;
1841 return r
.finish_opt_n_resolution (i
+ 1, i
, type
, TYPE_unsigned
);
1844 SHAPE (binary_uint_opt_n
)
1846 /* sv<t0>_t svfoo[_t0](sv<t0>_t, uint64_t).
1848 i.e. a version of binary_n in which the final argument is always
1849 a 64-bit unsigned integer. */
1850 struct binary_uint64_n_def
: public overloaded_base
<0>
1853 build (function_builder
&b
, const function_group_info
&group
) const override
1855 b
.add_overloaded_functions (group
, MODE_none
);
1856 build_all (b
, "v0,v0,su64", group
, MODE_none
);
1860 resolve (function_resolver
&r
) const override
1862 unsigned int i
, nargs
;
1863 type_suffix_index type
;
1864 if (!r
.check_gp_argument (2, i
, nargs
)
1865 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1866 || !r
.require_scalar_type (i
+ 1, "uint64_t"))
1867 return error_mark_node
;
1869 return r
.resolve_to (r
.mode_suffix_id
, type
);
1872 SHAPE (binary_uint64_n
)
1874 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svuint64_t)
1875 sv<t0>_t svfoo[_n_t0](sv<t0>_t, uint64_t)
1877 i.e. a version of the standard binary shape binary_opt_n in which
1878 the final argument is always a uint64_t. */
1879 struct binary_uint64_opt_n_def
: public overloaded_base
<0>
1882 build (function_builder
&b
, const function_group_info
&group
) const override
1884 b
.add_overloaded_functions (group
, MODE_none
);
1885 build_all (b
, "v0,v0,vu64", group
, MODE_none
);
1886 build_all (b
, "v0,v0,su64", group
, MODE_n
);
1890 resolve (function_resolver
&r
) const override
1892 unsigned int i
, nargs
;
1893 type_suffix_index type
;
1894 if (!r
.check_gp_argument (2, i
, nargs
)
1895 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
1896 return error_mark_node
;
1898 return r
.finish_opt_n_resolution (i
+ 1, i
, type
, TYPE_unsigned
, 64);
1901 SHAPE (binary_uint64_opt_n
)
1903 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:half>_t). */
1904 struct binary_wide_def
: public overloaded_base
<0>
1907 build (function_builder
&b
, const function_group_info
&group
) const override
1909 b
.add_overloaded_functions (group
, MODE_none
);
1910 build_all (b
, "v0,v0,vh0", group
, MODE_none
);
1914 resolve (function_resolver
&r
) const override
1916 unsigned int i
, nargs
;
1917 type_suffix_index type
;
1918 if (!r
.check_gp_argument (2, i
, nargs
)
1919 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1920 || !r
.require_derived_vector_type (i
+ 1, i
, type
, r
.SAME_TYPE_CLASS
,
1922 return error_mark_node
;
1924 return r
.resolve_to (r
.mode_suffix_id
, type
);
1929 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:half>_t)
1930 sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0:half>_t). */
1931 struct binary_wide_opt_n_def
: public overloaded_base
<0>
1934 build (function_builder
&b
, const function_group_info
&group
) const override
1936 b
.add_overloaded_functions (group
, MODE_none
);
1937 build_all (b
, "v0,v0,vh0", group
, MODE_none
);
1938 build_all (b
, "v0,v0,sh0", group
, MODE_n
);
1942 resolve (function_resolver
&r
) const override
1944 unsigned int i
, nargs
;
1945 type_suffix_index type
;
1946 if (!r
.check_gp_argument (2, i
, nargs
)
1947 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
1948 return error_mark_node
;
1950 return r
.finish_opt_n_resolution (i
+ 1, i
, type
, r
.SAME_TYPE_CLASS
,
1954 SHAPE (binary_wide_opt_n
)
1956 /* void svfoo_t0[_t1]_g(uint64_t, svbool_t, svbool_t, sv<t1>x<g>_t,
1959 where the first argument is a ZA tile. */
1960 struct binary_za_int_m_def
: public binary_za_m_base
<TYPE_signed
>
1963 build (function_builder
&b
, const function_group_info
&group
) const override
1965 b
.add_overloaded_functions (group
, MODE_none
);
1966 build_all (b
, "_,su64,vp,vp,t1,ts1", group
, MODE_none
);
1969 SHAPE (binary_za_int_m
)
1971 /* void svfoo_t0[_t1]_g(uint64_t, svbool_t, svbool_t, sv<t1>x<g>_t,
1974 where the first argument is a ZA tile. */
1975 struct binary_za_m_def
: public binary_za_m_base
<>
1978 build (function_builder
&b
, const function_group_info
&group
) const override
1980 b
.add_overloaded_functions (group
, MODE_none
);
1981 /* Allow the overloaded form to be specified seperately, with just
1982 a single suffix. This is necessary for the 64-bit SME MOP intrinsics,
1983 which have some forms dependent on FEAT_SME_I16I64 and some forms
1984 dependent on FEAT_SME_F64F64. The resolver needs to be defined
1986 if (group
.types
[0][1] != NUM_TYPE_SUFFIXES
)
1987 build_all (b
, "_,su64,vp,vp,t1,t1", group
, MODE_none
);
1992 /* void svfoo_lane_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1>_t, uint64_t)
1994 where the first argument is a variable ZA slice and the final argument
1995 indexes a single element in the preceding vector argument. */
1996 struct binary_za_slice_lane_def
: public binary_za_slice_lane_base
<>
1998 constexpr binary_za_slice_lane_def () : binary_za_slice_lane_base
<> (1) {}
2000 SHAPE (binary_za_slice_lane
)
2002 /* void svfoo_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1:int>x<g>_t)
2003 void svfoo[_single]_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1:int>_t).
2005 where the first argument is a variable ZA slice. */
2006 struct binary_za_slice_int_opt_single_def
2007 : public binary_za_slice_opt_single_base
<TYPE_signed
>
2010 build (function_builder
&b
, const function_group_info
&group
) const override
2012 b
.add_overloaded_functions (group
, MODE_none
);
2013 build_all (b
, "_,su32,t1,ts1", group
, MODE_none
);
2014 build_all (b
, "_,su32,t1,vs1", group
, MODE_single
);
2017 SHAPE (binary_za_slice_int_opt_single
)
2019 /* void svfoo_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1>x<g>_t)
2020 void svfoo[_single]_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1>_t)
2022 where the first argument is a variable ZA slice. */
2023 struct binary_za_slice_opt_single_def
2024 : public binary_za_slice_opt_single_base
<>
2027 build (function_builder
&b
, const function_group_info
&group
) const override
2029 b
.add_overloaded_functions (group
, MODE_none
);
2030 build_all (b
, "_,su32,t1,t1", group
, MODE_none
);
2031 build_all (b
, "_,su32,t1,v1", group
, MODE_single
);
2034 SHAPE (binary_za_slice_opt_single
)
2036 /* void svfoo_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1:uint>x<g>_t)
2037 void svfoo[_single]_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1:uint>_t)
2039 where the first argument is a variable ZA slice. */
2040 struct binary_za_slice_uint_opt_single_def
2041 : public binary_za_slice_opt_single_base
<TYPE_unsigned
>
2044 build (function_builder
&b
, const function_group_info
&group
) const override
2046 b
.add_overloaded_functions (group
, MODE_none
);
2047 build_all (b
, "_,su32,t1,tu1", group
, MODE_none
);
2048 build_all (b
, "_,su32,t1,vu1", group
, MODE_single
);
2051 SHAPE (binary_za_slice_uint_opt_single
)
2053 /* void svfoo_t0[_t1]_g(uint64_t, svbool_t, svbool_t, sv<t1>x<g>_t,
2056 where the first argument is a ZA tile. */
2057 struct binary_za_uint_m_def
: public binary_za_m_base
<TYPE_unsigned
>
2060 build (function_builder
&b
, const function_group_info
&group
) const override
2062 b
.add_overloaded_functions (group
, MODE_none
);
2063 build_all (b
, "_,su64,vp,vp,t1,tu1", group
, MODE_none
);
2066 SHAPE (binary_za_uint_m
)
2068 /* sv<t0>x<g>_t svfoo[_t0_t1_g](sv<t0>x<g>_t, sv<t0>x<g>_t). */
2069 struct binaryxn_def
: public overloaded_base
<0>
2071 bool explicit_group_suffix_p () const override
{ return false; }
2074 build (function_builder
&b
, const function_group_info
&group
) const override
2076 b
.add_overloaded_functions (group
, MODE_none
);
2077 build_all (b
, "t0,t0,t0", group
, MODE_none
);
2081 resolve (function_resolver
&r
) const override
2083 vector_type_index pred_type
;
2085 if (!r
.check_num_arguments (3)
2086 || (pred_type
= r
.infer_predicate_type (0)) == NUM_VECTOR_TYPES
2087 || !(type
= r
.infer_sve_type (1))
2088 || !r
.require_matching_predicate_type (pred_type
, type
)
2089 || !r
.require_matching_vector_type (2, 1, type
))
2090 return error_mark_node
;
2092 return r
.resolve_to (r
.mode_suffix_id
, type
);
2098 struct bool_inherent_def
: public nonoverloaded_base
2101 build (function_builder
&b
, const function_group_info
&group
) const override
2103 build_all (b
, "sp", group
, MODE_none
);
2106 SHAPE (bool_inherent
)
2110 sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t, sv<t0>_t)
2112 for single vectors or:
2114 sv<t0>x<g>_t svfoo[_single_t0_g](sv<t0>x<g>_t, sv<t0>_t, sv<t0>_t)
2117 struct clamp_def
: public overloaded_base
<0>
2119 bool explicit_group_suffix_p () const override
{ return false; }
2122 build (function_builder
&b
, const function_group_info
&group
) const override
2124 b
.add_overloaded_functions (group
, MODE_none
);
2125 build_all (b
, "t0,t0,v0,v0", group
,
2126 group
.groups
[0] == GROUP_none
? MODE_none
: MODE_single
);
2130 resolve (function_resolver
&r
) const override
2133 if (!r
.check_num_arguments (3)
2134 || !(type
= r
.infer_sve_type (0))
2135 || !r
.require_derived_vector_type (1, 0, type
, r
.SAME_TYPE_CLASS
,
2137 || !r
.require_derived_vector_type (2, 0, type
, r
.SAME_TYPE_CLASS
,
2139 return error_mark_node
;
2141 auto mode
= type
.num_vectors
== 1 ? MODE_none
: MODE_single
;
2142 return r
.resolve_to (mode
, type
);
2147 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
2148 <t0>_t svfoo[_n_t0](<t0>_t, sv<t0>_t). */
2149 struct clast_def
: public overloaded_base
<0>
2152 build (function_builder
&b
, const function_group_info
&group
) const override
2154 b
.add_overloaded_functions (group
, MODE_none
);
2155 build_all (b
, "v0,v0,v0", group
, MODE_none
);
2156 build_all (b
, "s0,s0,v0", group
, MODE_n
);
2160 resolve (function_resolver
&r
) const override
2162 unsigned int i
, nargs
;
2163 if (!r
.check_gp_argument (2, i
, nargs
)
2164 || !r
.require_vector_or_scalar_type (i
))
2165 return error_mark_node
;
2167 if (r
.scalar_argument_p (i
))
2169 type_suffix_index type
;
2170 if (!r
.require_derived_scalar_type (i
, r
.SAME_TYPE_CLASS
)
2171 || (type
= r
.infer_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
)
2172 return error_mark_node
;
2173 return r
.resolve_to (MODE_n
, type
);
2177 type_suffix_index type
;
2178 if ((type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
2179 || !r
.require_matching_vector_type (i
+ 1, i
, type
))
2180 return error_mark_node
;
2181 return r
.resolve_to (MODE_none
, type
);
2187 /* svbool_t svfoo[_t0](sv<t0>_t, sv<t0>_t). */
2188 struct compare_def
: public overloaded_base
<0>
2191 build (function_builder
&b
, const function_group_info
&group
) const override
2193 b
.add_overloaded_functions (group
, MODE_none
);
2194 build_all (b
, "vp,v0,v0", group
, MODE_none
);
2198 resolve (function_resolver
&r
) const override
2200 return r
.resolve_uniform (2);
2205 /* svbool_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
2206 svbool_t svfoo[_n_t0](sv<t0>_t, <t0>_t)
2208 i.e. a comparison between two vectors, or between a vector and a scalar. */
2209 struct compare_opt_n_def
: public overloaded_base
<0>
2212 build (function_builder
&b
, const function_group_info
&group
) const override
2214 b
.add_overloaded_functions (group
, MODE_none
);
2215 build_all (b
, "vp,v0,v0", group
, MODE_none
);
2216 build_all (b
, "vp,v0,s0", group
, MODE_n
);
2220 resolve (function_resolver
&r
) const override
2222 return r
.resolve_uniform_opt_n (2);
2225 SHAPE (compare_opt_n
)
2227 /* svbool_t svfoo[_t0](const <t0>_t *, const <t0>_t *). */
2228 struct compare_ptr_def
: public overloaded_base
<0>
2231 build (function_builder
&b
, const function_group_info
&group
) const override
2233 b
.add_overloaded_functions (group
, MODE_none
);
2234 build_all (b
, "vp,al,al", group
, MODE_none
);
2238 resolve (function_resolver
&r
) const override
2240 unsigned int i
, nargs
;
2241 type_suffix_index type
;
2242 if (!r
.check_gp_argument (2, i
, nargs
)
2243 || (type
= r
.infer_pointer_type (i
)) == NUM_TYPE_SUFFIXES
2244 || !r
.require_matching_pointer_type (i
+ 1, i
, type
))
2245 return error_mark_node
;
2247 return r
.resolve_to (r
.mode_suffix_id
, type
);
2252 /* svboolx<g>_t svfoo_t0[_t1]_g(<t1>_t, <t1>_t)
2254 where _t0 is a _b<bits> suffix that describes the predicate result.
2255 There is no direct relationship between the element sizes of _t0
2257 struct compare_scalar_def
: public overloaded_base
<1>
2260 build (function_builder
&b
, const function_group_info
&group
) const override
2262 b
.add_overloaded_functions (group
, MODE_none
);
2263 build_all (b
, "tp,s1,s1", group
, MODE_none
);
2267 resolve (function_resolver
&r
) const override
2269 unsigned int i
, nargs
;
2270 type_suffix_index type
;
2271 if (!r
.check_gp_argument (2, i
, nargs
)
2272 || (type
= r
.infer_integer_scalar_type (i
)) == NUM_TYPE_SUFFIXES
2273 || !r
.require_matching_integer_scalar_type (i
+ 1, i
, type
))
2274 return error_mark_node
;
2276 return r
.resolve_to (r
.mode_suffix_id
, r
.type_suffix_ids
[0], type
,
2280 SHAPE (compare_scalar
)
2282 /* svcount_t svfoo_t0[_t1](<t1>_t, <t1>_t, uint64_t)
2284 where _t0 is a _c<bits> suffix that describes the predicate-as-counter
2285 result. The final argument is an integer constant that specifies the
2286 number of vectors (2 or 4). */
2287 struct compare_scalar_count_def
: public overloaded_base
<1>
2290 build (function_builder
&b
, const function_group_info
&group
) const override
2292 b
.add_overloaded_functions (group
, MODE_none
);
2293 build_all (b
, "v0,s1,s1,su64", group
, MODE_none
);
2297 resolve (function_resolver
&r
) const override
2299 unsigned int i
, nargs
;
2300 type_suffix_index type
;
2301 if (!r
.check_gp_argument (3, i
, nargs
)
2302 || (type
= r
.infer_64bit_scalar_integer_pair (i
)) == NUM_TYPE_SUFFIXES
2303 || !r
.require_integer_immediate (i
+ 2))
2304 return error_mark_node
;
2306 return r
.resolve_to (r
.mode_suffix_id
, r
.type_suffix_ids
[0], type
);
2310 check (function_checker
&c
) const override
2312 return c
.require_immediate_either_or (2, 2, 4);
2315 SHAPE (compare_scalar_count
)
2317 /* svbool_t svfoo[_t0](sv<t0>_t, svint64_t) (for signed t0)
2318 svbool_t svfoo[_n_t0](sv<t0>_t, int64_t) (for signed t0)
2319 svbool_t svfoo[_t0](sv<t0>_t, svuint64_t) (for unsigned t0)
2320 svbool_t svfoo[_n_t0](sv<t0>_t, uint64_t) (for unsigned t0)
2322 i.e. a comparison in which the second argument is 64 bits. */
2323 struct compare_wide_opt_n_def
: public overloaded_base
<0>
2326 build (function_builder
&b
, const function_group_info
&group
) const override
2328 b
.add_overloaded_functions (group
, MODE_none
);
2329 build_all (b
, "vp,v0,vw0", group
, MODE_none
);
2330 build_all (b
, "vp,v0,sw0", group
, MODE_n
);
2334 resolve (function_resolver
&r
) const override
2336 unsigned int i
, nargs
;
2337 type_suffix_index type
;
2338 if (!r
.check_gp_argument (2, i
, nargs
)
2339 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
2340 return error_mark_node
;
2342 return r
.finish_opt_n_resolution (i
+ 1, i
, type
, r
.SAME_TYPE_CLASS
, 64);
2345 SHAPE (compare_wide_opt_n
)
2347 /* uint64_t svfoo(). */
2348 struct count_inherent_def
: public nonoverloaded_base
2351 build (function_builder
&b
, const function_group_info
&group
) const override
2353 build_all (b
, "su64", group
, MODE_none
);
2356 SHAPE (count_inherent
)
2358 /* uint64_t svfoo(enum svpattern). */
2359 struct count_pat_def
: public nonoverloaded_base
2362 build (function_builder
&b
, const function_group_info
&group
) const override
2364 build_all (b
, "su64,epattern", group
, MODE_none
);
2369 /* uint64_t svfoo(svbool_t). */
2370 struct count_pred_def
: public nonoverloaded_base
2373 build (function_builder
&b
, const function_group_info
&group
) const override
2375 build_all (b
, "su64,vp", group
, MODE_none
);
2380 /* uint64_t svfoo_t0(sv<t0>_t, uint64_t)
2382 where the final argument must be 2 or 4. */
2383 struct count_pred_c_def
: public nonoverloaded_base
2386 build (function_builder
&b
, const function_group_info
&group
) const override
2388 build_all (b
, "su64,v0,su64", group
, MODE_none
);
2392 check (function_checker
&c
) const override
2394 return c
.require_immediate_either_or (1, 2, 4);
2397 SHAPE (count_pred_c
)
2399 /* uint64_t svfoo[_t0](sv<t0>_t). */
2400 struct count_vector_def
: public overloaded_base
<0>
2403 build (function_builder
&b
, const function_group_info
&group
) const override
2405 b
.add_overloaded_functions (group
, MODE_none
);
2406 build_all (b
, "su64,v0", group
, MODE_none
);
2410 resolve (function_resolver
&r
) const override
2412 return r
.resolve_uniform (1);
2415 SHAPE (count_vector
)
2417 /* sv<t0>xN_t svfoo[_t0](sv<t0>_t, ..., sv<t0>_t)
2419 where there are N arguments in total. */
2420 struct create_def
: public overloaded_base
<0>
2423 build (function_builder
&b
, const function_group_info
&group
) const override
2425 b
.add_overloaded_functions (group
, MODE_none
);
2426 build_all (b
, "t0,v0*t", group
, MODE_none
);
2430 resolve (function_resolver
&r
) const override
2432 return r
.resolve_uniform (r
.vectors_per_tuple ());
2437 /* void svfoo_lane_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1:int>_t, uint64_t)
2439 where the final argument indexes a <t0>-sized group of elements in the
2440 preceding vector argument. */
2441 struct dot_za_slice_int_lane_def
2442 : public binary_za_slice_lane_base
<TYPE_signed
>
2444 constexpr dot_za_slice_int_lane_def ()
2445 : binary_za_slice_lane_base
<TYPE_signed
> (0) {}
2448 build (function_builder
&b
, const function_group_info
&group
) const override
2450 b
.add_overloaded_functions (group
, MODE_none
);
2451 build_all (b
, "_,su32,t1,vs1,su64", group
, MODE_none
);
2454 SHAPE (dot_za_slice_int_lane
)
2456 /* void svfoo_lane_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1>_t, uint64_t)
2458 where the final argument indexes a <t0>-sized group of elements in the
2459 preceding vector argument. */
2460 struct dot_za_slice_lane_def
: public binary_za_slice_lane_base
<>
2462 constexpr dot_za_slice_lane_def () : binary_za_slice_lane_base
<> (0) {}
2464 SHAPE (dot_za_slice_lane
)
2466 /* void svfoo_lane_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1:uint>_t, uint64_t)
2468 where the final argument indexes a <t0>-sized group of elements in the
2469 preceding vector argument. */
2470 struct dot_za_slice_uint_lane_def
2471 : public binary_za_slice_lane_base
<TYPE_unsigned
>
2473 constexpr dot_za_slice_uint_lane_def ()
2474 : binary_za_slice_lane_base
<TYPE_unsigned
> (0) {}
2477 build (function_builder
&b
, const function_group_info
&group
) const override
2479 b
.add_overloaded_functions (group
, MODE_none
);
2480 build_all (b
, "_,su32,t1,vu1,su64", group
, MODE_none
);
2483 SHAPE (dot_za_slice_uint_lane
)
2485 /* sv<t0>_t svfoo[_n]_t0(<t0>_t, ..., <t0>_t)
2487 where there are enough arguments to fill 128 bits of data (or to
2488 control 128 bits of data in the case of predicates). */
2489 struct dupq_def
: public overloaded_base
<1>
2492 build (function_builder
&b
, const function_group_info
&group
) const override
2494 /* The "_n" suffix is optional; the full name has it, but the short
2496 build_all (b
, "v0,s0*q", group
, MODE_n
, true);
2500 resolve (function_resolver
&) const override
2502 /* The short forms just make "_n" implicit, so no resolution is needed. */
2508 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t, uint64_t)
2510 where the final argument is an integer constant expression that when
2511 multiplied by the number of bytes in t0 is in the range [0, 255]. */
2512 struct ext_def
: public ext_base
2515 check (function_checker
&c
) const override
2517 unsigned int bytes
= c
.type_suffix (0).element_bytes
;
2518 return c
.require_immediate_range (2, 0, 256 / bytes
- 1);
2523 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t, uint64_t)
2525 where the final argument is an integer constant expression that when
2526 multiplied by the number of bytes in t0 is in the range [0, 15]. */
2527 struct extq_def
: public ext_base
2530 check (function_checker
&c
) const override
2532 unsigned int bytes
= c
.type_suffix (0).element_bytes
;
2533 return c
.require_immediate_range (2, 0, 16 / bytes
- 1);
2538 /* svboolx<g>_t svfoo_t0_g(sv<t0>_t, sv<t0>_t, uint32_t). */
2539 struct extract_pred_def
: public nonoverloaded_base
2542 build (function_builder
&b
, const function_group_info
&group
) const override
2544 build_all (b
, "tp,vc,su64", group
, MODE_none
);
2548 check (function_checker
&c
) const override
2550 unsigned int size
= c
.vectors_per_tuple ();
2551 return c
.require_immediate_range (1, 0, 4 / size
- 1);
2554 SHAPE (extract_pred
)
2556 /* <t0>_t svfoo[_t0](<t0>_t, sv<t0>_t). */
2557 struct fold_left_def
: public overloaded_base
<0>
2560 build (function_builder
&b
, const function_group_info
&group
) const override
2562 b
.add_overloaded_functions (group
, MODE_none
);
2563 build_all (b
, "s0,s0,v0", group
, MODE_none
);
2567 resolve (function_resolver
&r
) const override
2569 unsigned int i
, nargs
;
2570 type_suffix_index type
;
2571 if (!r
.check_gp_argument (2, i
, nargs
)
2572 || !r
.require_derived_scalar_type (i
, r
.SAME_TYPE_CLASS
)
2573 || (type
= r
.infer_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
)
2574 return error_mark_node
;
2576 return r
.resolve_to (r
.mode_suffix_id
, type
);
2581 /* sv<t0>_t svfoo[_t0](sv<t0>xN_t, uint64_t)
2583 where the final argument is an integer constant expression in
2584 the range [0, N - 1]. */
2585 struct get_def
: public overloaded_base
<0>
2588 build (function_builder
&b
, const function_group_info
&group
) const override
2590 b
.add_overloaded_functions (group
, MODE_none
);
2591 build_all (b
, "v0,t0,su64", group
, MODE_none
);
2595 resolve (function_resolver
&r
) const override
2597 unsigned int i
, nargs
;
2599 if (!r
.check_gp_argument (2, i
, nargs
)
2600 || !(type
= r
.infer_tuple_type (i
))
2601 || !r
.require_integer_immediate (i
+ 1))
2602 return error_mark_node
;
2604 return r
.resolve_to (r
.mode_suffix_id
, type
);
2608 check (function_checker
&c
) const override
2610 unsigned int nvectors
= c
.vectors_per_tuple ();
2611 return c
.require_immediate_range (1, 0, nvectors
- 1);
2616 /* <t0>xN_t svfoo[_t0](sv<t0>_t). */
2617 struct get_neonq_def
: public overloaded_base
<0>
2620 build (function_builder
&b
, const function_group_info
&group
) const override
2622 b
.add_overloaded_functions (group
, MODE_none
);
2623 build_all (b
, "Q0,v0", group
, MODE_none
);
2626 resolve (function_resolver
&r
) const override
2628 return r
.resolve_unary ();
2633 /* sv<t0>_t svfoo[_t0](sv<t0>_t, <t0>xN_t). */
2634 struct set_neonq_def
: public overloaded_base
<0>
2637 build (function_builder
&b
, const function_group_info
&group
) const override
2639 b
.add_overloaded_functions (group
, MODE_none
);
2640 build_all (b
, "v0,v0,Q0", group
, MODE_none
);
2643 resolve (function_resolver
&r
) const override
2645 unsigned int i
, nargs
;
2646 type_suffix_index type
;
2647 if (!r
.check_gp_argument (2, i
, nargs
)
2648 || (type
= r
.infer_neon128_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
)
2649 return error_mark_node
;
2650 return r
.resolve_to (r
.mode_suffix_id
, type
);
2655 /* sv<t0>_t svfoo[_t0](<t0>xN_t). */
2656 struct dup_neonq_def
: public overloaded_base
<0>
2659 build (function_builder
&b
, const function_group_info
&group
) const override
2661 b
.add_overloaded_functions (group
, MODE_none
);
2662 build_all (b
, "v0,Q0", group
, MODE_none
);
2665 resolve (function_resolver
&r
) const override
2667 unsigned int i
, nargs
;
2668 type_suffix_index type
;
2669 if (!r
.check_gp_argument (1, i
, nargs
)
2670 || (type
= r
.infer_neon128_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
2671 return error_mark_node
;
2672 return r
.resolve_to (r
.mode_suffix_id
, type
);
2677 /* sv<t0>_t svfoo[_t0](sv<t0>_t, uint64_t)
2678 <t0>_t svfoo[_n_t0](<t0>_t, uint64_t)
2680 where the t0 in the vector form is a signed or unsigned integer
2681 whose size is tied to the [bhwd] suffix of "svfoo". */
2682 struct inc_dec_def
: public inc_dec_base
2684 CONSTEXPR
inc_dec_def () : inc_dec_base (false) {}
2687 build (function_builder
&b
, const function_group_info
&group
) const override
2689 b
.add_overloaded_functions (group
, MODE_none
);
2690 /* These functions are unusual in that the type suffixes for
2691 the scalar and vector forms are not related. The vector
2692 form always has exactly two potential suffixes while the
2693 scalar form always has four. */
2694 if (group
.types
[2][0] == NUM_TYPE_SUFFIXES
)
2695 build_all (b
, "v0,v0,su64", group
, MODE_none
);
2697 build_all (b
, "s0,s0,su64", group
, MODE_n
);
2702 /* sv<t0>_t svfoo[_t0](sv<t0>_t, enum svpattern, uint64_t)
2703 <t0>_t svfoo[_n_t0](<t0>_t, enum svpattern, uint64_t)
2705 where the t0 in the vector form is a signed or unsigned integer
2706 whose size is tied to the [bhwd] suffix of "svfoo". */
2707 struct inc_dec_pat_def
: public inc_dec_base
2709 CONSTEXPR
inc_dec_pat_def () : inc_dec_base (true) {}
2712 build (function_builder
&b
, const function_group_info
&group
) const override
2714 b
.add_overloaded_functions (group
, MODE_none
);
2715 /* These functions are unusual in that the type suffixes for
2716 the scalar and vector forms are not related. The vector
2717 form always has exactly two potential suffixes while the
2718 scalar form always has four. */
2719 if (group
.types
[2][0] == NUM_TYPE_SUFFIXES
)
2720 build_all (b
, "v0,v0,epattern,su64", group
, MODE_none
);
2722 build_all (b
, "s0,s0,epattern,su64", group
, MODE_n
);
2727 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbool_t). */
2728 struct inc_dec_pred_def
: public overloaded_base
<0>
2731 build (function_builder
&b
, const function_group_info
&group
) const override
2733 b
.add_overloaded_functions (group
, MODE_none
);
2734 build_all (b
, "v0,v0,vp", group
, MODE_none
);
2738 resolve (function_resolver
&r
) const override
2740 unsigned int i
, nargs
;
2741 type_suffix_index type
;
2742 if (!r
.check_gp_argument (2, i
, nargs
)
2743 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
2744 || !r
.require_vector_type (i
+ 1, VECTOR_TYPE_svbool_t
))
2745 return error_mark_node
;
2747 return r
.resolve_to (r
.mode_suffix_id
, type
);
2750 SHAPE (inc_dec_pred
)
2752 /* <t0>_t svfoo[_n_t0]_t1(<t0>_t, svbool_t)
2754 where _t1 is a _b<bits> suffix that describes the svbool_t argument. */
2755 struct inc_dec_pred_scalar_def
: public overloaded_base
<2>
2758 build (function_builder
&b
, const function_group_info
&group
) const override
2760 b
.add_overloaded_functions (group
, MODE_n
);
2761 build_all (b
, "s0,s0,vp", group
, MODE_n
);
2765 resolve (function_resolver
&r
) const override
2767 unsigned int i
, nargs
;
2768 type_suffix_index type
;
2769 if (!r
.check_gp_argument (2, i
, nargs
)
2770 || (type
= r
.infer_integer_scalar_type (i
)) == NUM_TYPE_SUFFIXES
2771 || !r
.require_vector_type (i
+ 1, VECTOR_TYPE_svbool_t
))
2772 return error_mark_node
;
2774 return r
.resolve_to (r
.mode_suffix_id
, type
, r
.type_suffix_ids
[1]);
2777 SHAPE (inc_dec_pred_scalar
)
2779 /* sv<t0>[xN]_t svfoo_t0(). */
2780 struct inherent_def
: public nonoverloaded_base
2783 build (function_builder
&b
, const function_group_info
&group
) const override
2785 build_all (b
, "t0", group
, MODE_none
);
2790 /* svbool_t svfoo[_b](). */
2791 struct inherent_b_def
: public overloaded_base
<0>
2794 build (function_builder
&b
, const function_group_info
&group
) const override
2796 /* The "_b" suffix is optional; the full name has it, but the short
2798 build_all (b
, "v0", group
, MODE_none
, true);
2802 resolve (function_resolver
&) const override
2804 /* The short forms just make "_b" implicit, so no resolution is needed. */
2810 /* void svfoo_t0(). */
2811 struct inherent_za_def
: public nonoverloaded_base
2814 build (function_builder
&b
, const function_group_info
&group
) const override
2816 build_all (b
, "_", group
, MODE_none
);
2821 /* void svfoo_t0(uint64_t). */
2822 struct inherent_za_slice_def
: public nonoverloaded_base
2825 build (function_builder
&b
, const function_group_info
&group
) const override
2827 build_all (b
, "_,su32", group
, MODE_none
);
2830 SHAPE (inherent_za_slice
)
2832 /* void svfoo_zt(uint64_t)
2834 where the argument must be zero. */
2835 struct inherent_zt_def
: public nonoverloaded_base
2838 build (function_builder
&b
, const function_group_info
&group
) const override
2840 build_all (b
, "_,su64", group
, MODE_none
);
2844 check (function_checker
&c
) const override
2846 return c
.require_immediate_range (0, 0, 0);
2851 /* void svfoo_t0(uint64_t)
2853 where the argument is an integer constant that specifies an 8-bit mask. */
2854 struct inherent_mask_za_def
: public nonoverloaded_base
2857 build (function_builder
&b
, const function_group_info
&group
) const override
2859 build_all (b
, "_,su64", group
, MODE_none
);
2863 check (function_checker
&c
) const override
2865 return c
.require_immediate_range (0, 0, 255);
2868 SHAPE (inherent_mask_za
)
2870 /* void svfoo_t0(uint32_t, const void *)
2871 void svfoo_vnum_t0(uint32_t, const void *, int64_t)
2873 where the first argument is a variable ZA slice. */
2874 struct ldr_za_def
: public nonoverloaded_base
2877 build (function_builder
&b
, const function_group_info
&group
) const override
2879 build_all (b
, "_,su32,al", group
, MODE_none
);
2880 build_all (b
, "_,su32,al,ss64", group
, MODE_vnum
);
2885 /* void svfoo_zt(uint64_t, const void *)
2887 where the first argument must be zero. */
2888 struct ldr_zt_def
: public nonoverloaded_base
2891 build (function_builder
&b
, const function_group_info
&group
) const override
2893 build_all (b
, "_,su64,al", group
, MODE_none
);
2897 check (function_checker
&c
) const override
2899 return c
.require_immediate_range (0, 0, 0);
2904 /* sv<t0>[xN]_t svfoo[_t0]_g(const <t0>_t *)
2905 sv<t0>[xN]_t svfoo_vnum[_t0]_g(const <t0>_t *, int64_t). */
2906 struct load_def
: public load_contiguous_base
2909 build (function_builder
&b
, const function_group_info
&group
) const override
2911 b
.add_overloaded_functions (group
, MODE_none
);
2912 b
.add_overloaded_functions (group
, MODE_vnum
);
2913 build_all (b
, "t0,al", group
, MODE_none
);
2914 build_all (b
, "t0,al,ss64", group
, MODE_vnum
);
2919 /* sv<t0>_t svfoo_t0(const <X>_t *)
2920 sv<t0>_t svfoo_vnum_t0(const <X>_t *, int64_t)
2922 where <X> is determined by the function base name. */
2923 struct load_ext_def
: public nonoverloaded_base
2926 build (function_builder
&b
, const function_group_info
&group
) const override
2928 build_all (b
, "t0,al", group
, MODE_none
);
2929 build_all (b
, "t0,al,ss64", group
, MODE_vnum
);
2934 /* sv<t0>_t svfoo_[s32]index_t0(const <X>_t *, svint32_t)
2935 sv<t0>_t svfoo_[s64]index_t0(const <X>_t *, svint64_t)
2936 sv<t0>_t svfoo_[u32]index_t0(const <X>_t *, svuint32_t)
2937 sv<t0>_t svfoo_[u64]index_t0(const <X>_t *, svuint64_t)
2939 sv<t0>_t svfoo[_u32base]_index_t0(svuint32_t, int64_t)
2940 sv<t0>_t svfoo[_u64base]_index_t0(svuint64_t, int64_t)
2942 where <X> is determined by the function base name. */
2943 struct load_ext_gather_index_def
: public load_ext_gather_base
2946 build (function_builder
&b
, const function_group_info
&group
) const override
2948 b
.add_overloaded_functions (group
, MODE_index
);
2949 build_sv_index (b
, "t0,al,d", group
);
2950 build_vs_index (b
, "t0,b,ss64", group
);
2953 SHAPE (load_ext_gather_index
)
2955 /* sv<t0>_t svfoo_[s64]index_t0(const <X>_t *, svint64_t)
2956 sv<t0>_t svfoo_[u64]index_t0(const <X>_t *, svuint64_t)
2958 sv<t0>_t svfoo[_u32base]_index_t0(svuint32_t, int64_t)
2959 sv<t0>_t svfoo[_u64base]_index_t0(svuint64_t, int64_t)
2961 where <X> is determined by the function base name. This is
2962 load_ext_gather_index that doesn't support 32-bit vector indices. */
2963 struct load_ext_gather_index_restricted_def
: public load_ext_gather_base
2966 build (function_builder
&b
, const function_group_info
&group
) const override
2968 b
.add_overloaded_functions (group
, MODE_index
);
2969 build_sv_index64 (b
, "t0,al,d", group
);
2970 build_vs_index (b
, "t0,b,ss64", group
);
2973 SHAPE (load_ext_gather_index_restricted
)
2975 /* sv<t0>_t svfoo_[s32]offset_t0(const <X>_t *, svint32_t)
2976 sv<t0>_t svfoo_[s64]offset_t0(const <X>_t *, svint64_t)
2977 sv<t0>_t svfoo_[u32]offset_t0(const <X>_t *, svuint32_t)
2978 sv<t0>_t svfoo_[u64]offset_t0(const <X>_t *, svuint64_t)
2980 sv<t0>_t svfoo[_u32base]_t0(svuint32_t)
2981 sv<t0>_t svfoo[_u64base]_t0(svuint64_t)
2983 sv<t0>_t svfoo[_u32base]_offset_t0(svuint32_t, int64_t)
2984 sv<t0>_t svfoo[_u64base]_offset_t0(svuint64_t, int64_t)
2986 where <X> is determined by the function base name. */
2987 struct load_ext_gather_offset_def
: public load_ext_gather_base
2990 build (function_builder
&b
, const function_group_info
&group
) const override
2992 b
.add_overloaded_functions (group
, MODE_offset
);
2993 build_sv_offset (b
, "t0,al,d", group
);
2994 build_v_base (b
, "t0,b", group
, true);
2995 build_vs_offset (b
, "t0,b,ss64", group
);
2998 SHAPE (load_ext_gather_offset
)
3000 /* sv<t0>_t svfoo_[s64]offset_t0(const <X>_t *, svint64_t)
3001 sv<t0>_t svfoo_[u32]offset_t0(const <X>_t *, svuint32_t)
3002 sv<t0>_t svfoo_[u64]offset_t0(const <X>_t *, svuint64_t)
3004 sv<t0>_t svfoo[_u32base]_t0(svuint32_t)
3005 sv<t0>_t svfoo[_u64base]_t0(svuint64_t)
3007 sv<t0>_t svfoo[_u32base]_offset_t0(svuint32_t, int64_t)
3008 sv<t0>_t svfoo[_u64base]_offset_t0(svuint64_t, int64_t)
3010 where <X> is determined by the function base name. This is
3011 load_ext_gather_offset without the s32 vector offset form. */
3012 struct load_ext_gather_offset_restricted_def
: public load_ext_gather_base
3015 build (function_builder
&b
, const function_group_info
&group
) const override
3017 b
.add_overloaded_functions (group
, MODE_offset
);
3018 build_sv_uint_offset (b
, "t0,al,d", group
);
3019 build_v_base (b
, "t0,b", group
, true);
3020 build_vs_offset (b
, "t0,b,ss64", group
);
3023 SHAPE (load_ext_gather_offset_restricted
)
3025 /* sv<t0>_t svfoo_[s32]index[_t0](const <t0>_t *, svint32_t)
3026 sv<t0>_t svfoo_[s64]index[_t0](const <t0>_t *, svint64_t)
3027 sv<t0>_t svfoo_[u32]index[_t0](const <t0>_t *, svuint32_t)
3028 sv<t0>_t svfoo_[u64]index[_t0](const <t0>_t *, svuint64_t)
3030 sv<t0>_t svfoo_[s32]offset[_t0](const <t0>_t *, svint32_t)
3031 sv<t0>_t svfoo_[s64]offset[_t0](const <t0>_t *, svint64_t)
3032 sv<t0>_t svfoo_[u32]offset[_t0](const <t0>_t *, svuint32_t)
3033 sv<t0>_t svfoo_[u64]offset[_t0](const <t0>_t *, svuint64_t). */
3034 struct load_gather_sv_def
: public load_gather_sv_base
3037 build (function_builder
&b
, const function_group_info
&group
) const override
3039 b
.add_overloaded_functions (group
, MODE_index
);
3040 b
.add_overloaded_functions (group
, MODE_offset
);
3041 build_sv_index (b
, "t0,al,d", group
);
3042 build_sv_offset (b
, "t0,al,d", group
);
3045 SHAPE (load_gather_sv
)
3047 /* sv<t0>_t svfoo_[u32]index[_t0](const <t0>_t *, svuint32_t)
3048 sv<t0>_t svfoo_[u64]index[_t0](const <t0>_t *, svuint64_t)
3050 sv<t0>_t svfoo_[s64]offset[_t0](const <t0>_t *, svint64_t)
3051 sv<t0>_t svfoo_[u32]offset[_t0](const <t0>_t *, svuint32_t)
3052 sv<t0>_t svfoo_[u64]offset[_t0](const <t0>_t *, svuint64_t)
3054 This is load_gather_sv without the 32-bit vector index forms and
3055 without the s32 vector offset form. */
3056 struct load_gather_sv_restricted_def
: public load_gather_sv_base
3059 build (function_builder
&b
, const function_group_info
&group
) const override
3061 b
.add_overloaded_functions (group
, MODE_index
);
3062 b
.add_overloaded_functions (group
, MODE_offset
);
3063 build_sv_index64 (b
, "t0,al,d", group
);
3064 build_sv_uint_offset (b
, "t0,al,d", group
);
3067 SHAPE (load_gather_sv_restricted
)
3069 /* sv<t0>_t svfoo[_u32base]_t0(svuint32_t)
3070 sv<t0>_t svfoo[_u64base]_t0(svuint64_t)
3072 sv<t0>_t svfoo[_u32base]_index_t0(svuint32_t, int64_t)
3073 sv<t0>_t svfoo[_u64base]_index_t0(svuint64_t, int64_t)
3075 sv<t0>_t svfoo[_u32base]_offset_t0(svuint32_t, int64_t)
3076 sv<t0>_t svfoo[_u64base]_offset_t0(svuint64_t, int64_t). */
3077 struct load_gather_vs_def
: public overloaded_base
<1>
3080 build (function_builder
&b
, const function_group_info
&group
) const override
3082 /* The base vector mode is optional; the full name has it but the
3083 short name doesn't. There is no ambiguity with SHAPE_load_gather_sv
3084 because the latter uses an implicit type suffix. */
3085 build_v_base (b
, "t0,b", group
, true);
3086 build_vs_index (b
, "t0,b,ss64", group
, true);
3087 build_vs_offset (b
, "t0,b,ss64", group
, true);
3091 resolve (function_resolver
&) const override
3093 /* The short name just makes the base vector mode implicit;
3094 no resolution is needed. */
3098 SHAPE (load_gather_vs
)
3100 /* sv<t0>_t svfoo_[s64]index[_t0](const <t0>_t *, svint64_t)
3101 sv<t0>_t svfoo_[u64]index[_t0](const <t0>_t *, svuint64_t). */
3102 struct load_gather64_sv_index_def
: public load_gather64_sv_base
3105 build (function_builder
&b
, const function_group_info
&group
) const override
3107 b
.add_overloaded_functions (group
, MODE_index
);
3108 build_all (b
, "t0,al,d", group
, MODE_s64index
);
3109 build_all (b
, "t0,al,d", group
, MODE_u64index
);
3112 SHAPE (load_gather64_sv_index
)
3114 /* sv<t0>_t svfoo_[s64]offset[_t0](const <t0>_t *, svint64_t)
3115 sv<t0>_t svfoo_[u64]offset[_t0](const <t0>_t *, svuint64_t). */
3116 struct load_gather64_sv_offset_def
: public load_gather64_sv_base
3119 build (function_builder
&b
, const function_group_info
&group
) const override
3121 b
.add_overloaded_functions (group
, MODE_offset
);
3122 build_all (b
, "t0,al,d", group
, MODE_s64offset
);
3123 build_all (b
, "t0,al,d", group
, MODE_u64offset
);
3126 SHAPE (load_gather64_sv_offset
)
3128 /* sv<t0>_t svfoo[_u64base]_index_t0(svuint64_t, int64_t). */
3129 struct load_gather64_vs_index_def
: public nonoverloaded_base
3132 build (function_builder
&b
, const function_group_info
&group
) const override
3134 build_all (b
, "t0,b,ss64", group
, MODE_u64base_index
, true);
3138 resolve (function_resolver
&) const override
3140 /* The short name just makes the base vector mode implicit;
3141 no resolution is needed. */
3145 SHAPE (load_gather64_vs_index
)
3147 /* sv<t0>_t svfoo[_u64base]_t0(svuint64_t)
3149 sv<t0>_t svfoo[_u64base]_offset_t0(svuint64_t, int64_t). */
3150 struct load_gather64_vs_offset_def
: public nonoverloaded_base
3153 build (function_builder
&b
, const function_group_info
&group
) const override
3155 build_all (b
, "t0,b", group
, MODE_u64base
, true);
3156 build_all (b
, "t0,b,ss64", group
, MODE_u64base_offset
, true);
3160 resolve (function_resolver
&) const override
3162 /* The short name just makes the base vector mode implicit;
3163 no resolution is needed. */
3167 SHAPE (load_gather64_vs_offset
)
3169 /* sv<t0>_t svfoo[_t0](const <t0>_t *)
3171 The only difference from "load" is that this shape has no vnum form. */
3172 struct load_replicate_def
: public load_contiguous_base
3175 build (function_builder
&b
, const function_group_info
&group
) const override
3177 b
.add_overloaded_functions (group
, MODE_none
);
3178 build_all (b
, "t0,al", group
, MODE_none
);
3181 SHAPE (load_replicate
)
3183 /* void svfoo_t0(uint64_t, uint32_t, svbool_t, const void *)
3184 void svfoo_vnum_t0(uint64_t, uint32_t, svbool_t, const void *, int64_t)
3186 where the first two fields form a (ZA tile, slice) pair. */
3187 struct load_za_def
: public nonoverloaded_base
3190 build (function_builder
&b
, const function_group_info
&group
) const override
3192 build_all (b
, "_,su64,su32,vp,al", group
, MODE_none
);
3193 build_all (b
, "_,su64,su32,vp,al,ss64", group
, MODE_vnum
);
3197 check (function_checker
&c
) const override
3199 return c
.require_immediate_range (0, 0, c
.num_za_tiles () - 1);
3204 using luti2_lane_zt_def
= luti_lane_zt_base
<2>;
3205 SHAPE (luti2_lane_zt
)
3207 using luti4_lane_zt_def
= luti_lane_zt_base
<4>;
3208 SHAPE (luti4_lane_zt
)
3210 /* svbool_t svfoo(enum svpattern). */
3211 struct pattern_pred_def
: public nonoverloaded_base
3214 build (function_builder
&b
, const function_group_info
&group
) const override
3216 build_all (b
, "vp,epattern", group
, MODE_none
);
3219 SHAPE (pattern_pred
)
3221 /* svbool_t svfoo[_t0](sv<t0>_t). */
3222 struct pmov_from_vector_def
: public overloaded_base
<0>
3225 build (function_builder
&b
, const function_group_info
&group
) const override
3227 b
.add_overloaded_functions (group
, MODE_none
);
3228 build_all (b
, "vp,v0", group
, MODE_none
);
3232 resolve (function_resolver
&r
) const override
3234 return r
.resolve_uniform (1);
3237 SHAPE (pmov_from_vector
)
3239 /* svbool_t svfoo[_t0](sv<t0>_t, uint64_t)
3241 where the final argument is an integer constant expression in the
3242 range [0, sizeof (<t0>_t) - 1]. */
3243 struct pmov_from_vector_lane_def
: public overloaded_base
<0>
3246 build (function_builder
&b
, const function_group_info
&group
) const override
3248 b
.add_overloaded_functions (group
, MODE_none
);
3249 build_all (b
, "vp,v0,su64", group
, MODE_none
);
3253 resolve (function_resolver
&r
) const override
3255 return r
.resolve_uniform (1, 1);
3259 check (function_checker
&c
) const override
3261 unsigned int bytes
= c
.type_suffix (0).element_bytes
;
3262 return c
.require_immediate_range (1, 0, bytes
- 1);
3265 SHAPE (pmov_from_vector_lane
)
3267 /* sv<t0>_t svfoo_t0(uint64_t)
3269 where the final argument is an integer constant expression in the
3270 range [1, sizeof (<t0>_t) - 1]. */
3271 struct pmov_to_vector_lane_def
: public overloaded_base
<0>
3274 build (function_builder
&b
, const function_group_info
&group
) const override
3276 b
.add_overloaded_functions (group
, MODE_none
);
3277 build_all (b
, "v0,su64", group
, MODE_none
);
3281 resolve (function_resolver
&r
) const override
3283 type_suffix_index type
;
3284 gcc_assert (r
.pred
== PRED_m
);
3285 if (!r
.check_num_arguments (3)
3286 || (type
= r
.infer_vector_type (0)) == NUM_TYPE_SUFFIXES
3287 || !r
.require_vector_type (1, VECTOR_TYPE_svbool_t
)
3288 || !r
.require_integer_immediate (2))
3289 return error_mark_node
;
3291 return r
.resolve_to (r
.mode_suffix_id
, type
);
3295 check (function_checker
&c
) const override
3297 unsigned int bytes
= c
.type_suffix (0).element_bytes
;
3298 /* 1 to account for the vector argument.
3300 ??? This should probably be folded into function_checker::m_base_arg,
3301 but it doesn't currently have the necessary information. */
3302 return c
.require_immediate_range (1, 1, bytes
- 1);
3305 SHAPE (pmov_to_vector_lane
)
3307 /* void svfoo(const void *, svprfop)
3308 void svfoo_vnum(const void *, int64_t, svprfop). */
3309 struct prefetch_def
: public nonoverloaded_base
3312 build (function_builder
&b
, const function_group_info
&group
) const override
3314 build_all (b
, "_,ap,eprfop", group
, MODE_none
);
3315 build_all (b
, "_,ap,ss64,eprfop", group
, MODE_vnum
);
3320 /* void svfoo_[s32]index(const void *, svint32_t, svprfop)
3321 void svfoo_[s64]index(const void *, svint64_t, svprfop)
3322 void svfoo_[u32]index(const void *, svuint32_t, svprfop)
3323 void svfoo_[u64]index(const void *, svuint64_t, svprfop)
3325 void svfoo[_u32base](svuint32_t, svprfop)
3326 void svfoo[_u64base](svuint64_t, svprfop)
3328 void svfoo[_u32base]_index(svuint32_t, int64_t, svprfop)
3329 void svfoo[_u64base]_index(svuint64_t, int64_t, svprfop). */
3330 struct prefetch_gather_index_def
: public prefetch_gather_base
3333 build (function_builder
&b
, const function_group_info
&group
) const override
3335 b
.add_overloaded_functions (group
, MODE_none
);
3336 b
.add_overloaded_functions (group
, MODE_index
);
3337 build_sv_index (b
, "_,ap,d,eprfop", group
);
3338 build_v_base (b
, "_,b,eprfop", group
);
3339 build_vs_index (b
, "_,b,ss64,eprfop", group
);
3342 SHAPE (prefetch_gather_index
)
3344 /* void svfoo_[s32]offset(const void *, svint32_t, svprfop)
3345 void svfoo_[s64]offset(const void *, svint64_t, svprfop)
3346 void svfoo_[u32]offset(const void *, svuint32_t, svprfop)
3347 void svfoo_[u64]offset(const void *, svuint64_t, svprfop)
3349 void svfoo[_u32base](svuint32_t, svprfop)
3350 void svfoo[_u64base](svuint64_t, svprfop)
3352 void svfoo[_u32base]_offset(svuint32_t, int64_t, svprfop)
3353 void svfoo[_u64base]_offset(svuint64_t, int64_t, svprfop). */
3354 struct prefetch_gather_offset_def
: public prefetch_gather_base
3357 build (function_builder
&b
, const function_group_info
&group
) const override
3359 b
.add_overloaded_functions (group
, MODE_none
);
3360 b
.add_overloaded_functions (group
, MODE_offset
);
3361 build_sv_offset (b
, "_,ap,d,eprfop", group
);
3362 build_v_base (b
, "_,b,eprfop", group
);
3363 build_vs_offset (b
, "_,b,ss64,eprfop", group
);
3366 SHAPE (prefetch_gather_offset
)
3368 /* bool svfoo(svbool_t). */
3369 struct ptest_def
: public nonoverloaded_base
3372 build (function_builder
&b
, const function_group_info
&group
) const override
3374 build_all (b
, "sp,vp", group
, MODE_none
);
3379 /* svbool_t svfoo(). */
3380 struct rdffr_def
: public nonoverloaded_base
3383 build (function_builder
&b
, const function_group_info
&group
) const override
3385 build_all (b
, "vp", group
, MODE_none
);
3390 /* sv<t1>x<g>_t svfoo_t0_t1_g(uint64_t, uint32_t). */
3391 struct read_za_def
: public nonoverloaded_base
3394 build (function_builder
&b
, const function_group_info
&group
) const override
3396 build_all (b
, "t1,su64,su32", group
, MODE_none
);
3400 check (function_checker
&c
) const override
3402 return c
.require_immediate_range (0, 0, c
.num_za_tiles () - 1);
3407 /* sv<t1>_t svfoo_t0[_t1](uint64_t, uint32_t)
3409 where the first two fields form a (ZA tile, slice) pair. */
3410 struct read_za_m_def
: public overloaded_base
<1>
3413 has_merge_argument_p (const function_instance
&, unsigned int) const override
3419 build (function_builder
&b
, const function_group_info
&group
) const override
3421 b
.add_overloaded_functions (group
, MODE_none
);
3422 build_all (b
, "t1,su64,su32", group
, MODE_none
);
3426 resolve (function_resolver
&r
) const override
3428 gcc_assert (r
.pred
== PRED_m
);
3429 type_suffix_index type
;
3430 if (!r
.check_num_arguments (4)
3431 || (type
= r
.infer_vector_type (0)) == NUM_TYPE_SUFFIXES
3432 || !r
.require_vector_type (1, VECTOR_TYPE_svbool_t
)
3433 || !r
.require_integer_immediate (2)
3434 || !r
.require_scalar_type (3, "uint32_t"))
3435 return error_mark_node
;
3437 return r
.resolve_to (r
.mode_suffix_id
, r
.type_suffix_ids
[0], type
);
3441 check (function_checker
&c
) const override
3443 gcc_assert (c
.pred
== PRED_m
);
3444 return c
.require_immediate_range (1, 0, c
.num_za_tiles () - 1);
3449 /* sv<t1>x<g>_t svfoo_t0_t1_g(uint32_t). */
3450 struct read_za_slice_def
: public nonoverloaded_base
3453 build (function_builder
&b
, const function_group_info
&group
) const override
3455 build_all (b
, "t1,su32", group
, MODE_none
);
3458 SHAPE (read_za_slice
)
3460 /* <t0>_t svfoo[_t0](sv<t0>_t). */
3461 struct reduction_def
: public overloaded_base
<0>
3464 build (function_builder
&b
, const function_group_info
&group
) const override
3466 b
.add_overloaded_functions (group
, MODE_none
);
3467 build_all (b
, "s0,v0", group
, MODE_none
);
3471 resolve (function_resolver
&r
) const override
3473 return r
.resolve_uniform (1);
3478 /* <t0>xN_t svfoo[_t0](sv<t0>_t). */
3479 struct reduction_neonq_def
: public overloaded_base
<0>
3482 build (function_builder
&b
, const function_group_info
&group
) const override
3484 b
.add_overloaded_functions (group
, MODE_none
);
3485 build_all (b
, "Q0,v0", group
, MODE_none
);
3489 resolve (function_resolver
&r
) const override
3491 return r
.resolve_uniform (1);
3494 SHAPE (reduction_neonq
)
3496 /* int64_t svfoo[_t0](sv<t0>_t) (for signed t0)
3497 uint64_t svfoo[_t0](sv<t0>_t) (for unsigned t0)
3498 <t0>_t svfoo[_t0](sv<t0>_t) (for floating-point t0)
3500 i.e. a version of "reduction" in which the return type for integers
3501 always has 64 bits. */
3502 struct reduction_wide_def
: public overloaded_base
<0>
3505 build (function_builder
&b
, const function_group_info
&group
) const override
3507 b
.add_overloaded_functions (group
, MODE_none
);
3508 build_all (b
, "sw0,v0", group
, MODE_none
);
3512 resolve (function_resolver
&r
) const override
3514 return r
.resolve_uniform (1);
3517 SHAPE (reduction_wide
)
3519 /* sv<t0>x<g>_t svfoo_t0[_t1_g](sv<t1>x<g>_t)
3521 where the target type <t0> must be specified explicitly but the source
3522 type <t1> can be inferred. */
3523 struct reinterpret_def
: public overloaded_base
<1>
3525 bool explicit_group_suffix_p () const override
{ return false; }
3528 build (function_builder
&b
, const function_group_info
&group
) const override
3530 b
.add_overloaded_functions (group
, MODE_none
);
3531 build_all (b
, "t0,t1", group
, MODE_none
);
3535 resolve (function_resolver
&r
) const override
3538 if (!r
.check_num_arguments (1)
3539 || !(type
= r
.infer_sve_type (0)))
3540 return error_mark_node
;
3542 return r
.resolve_to (r
.mode_suffix_id
, type
);
3547 /* sv<t0>_t svfoo_t0(sv<t0>_t, sv<t0>_t, uint32_t). */
3548 struct select_pred_def
: public nonoverloaded_base
3551 build (function_builder
&b
, const function_group_info
&group
) const override
3553 build_all (b
, "v0,v0,vp,su32", group
, MODE_none
);
3558 /* sv<t0>xN_t svfoo[_t0](sv<t0>xN_t, uint64_t, sv<t0>_t)
3560 where the second argument is an integer constant expression in the
3561 range [0, N - 1]. */
3562 struct set_def
: public overloaded_base
<0>
3565 build (function_builder
&b
, const function_group_info
&group
) const override
3567 b
.add_overloaded_functions (group
, MODE_none
);
3568 build_all (b
, "t0,t0,su64,v0", group
, MODE_none
);
3572 resolve (function_resolver
&r
) const override
3574 unsigned int i
, nargs
;
3576 if (!r
.check_gp_argument (3, i
, nargs
)
3577 || !(type
= r
.infer_tuple_type (i
))
3578 || !r
.require_integer_immediate (i
+ 1)
3579 || !r
.require_derived_vector_type (i
+ 2, i
, type
))
3580 return error_mark_node
;
3582 return r
.resolve_to (r
.mode_suffix_id
, type
);
3586 check (function_checker
&c
) const override
3588 unsigned int nvectors
= c
.vectors_per_tuple ();
3589 return c
.require_immediate_range (1, 0, nvectors
- 1);
3595 struct setffr_def
: public nonoverloaded_base
3598 build (function_builder
&b
, const function_group_info
&group
) const override
3600 build_all (b
, "_", group
, MODE_none
);
3605 /* sv<t0>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
3607 where the final argument must be an integer constant expression in the
3608 range [0, sizeof (<t0>_t) * 8 - 1]. */
3609 struct shift_left_imm_def
: public overloaded_base
<0>
3612 build (function_builder
&b
, const function_group_info
&group
) const override
3614 b
.add_overloaded_functions (group
, MODE_n
);
3615 build_all (b
, "v0,v0,su64", group
, MODE_n
);
3619 resolve (function_resolver
&r
) const override
3621 return r
.resolve_uniform (1, 1);
3625 check (function_checker
&c
) const override
3627 unsigned int bits
= c
.type_suffix (0).element_bits
;
3628 return c
.require_immediate_range (1, 0, bits
- 1);
3631 SHAPE (shift_left_imm
)
3633 /* sv<t0>_t svfoo[_n_t0])(sv<t0:half>_t, uint64_t)
3635 where the final argument must be an integer constant expression in the
3636 range [0, sizeof (<t0>_t) * 4 - 1]. */
3637 struct shift_left_imm_long_def
: public binary_imm_long_base
3640 check (function_checker
&c
) const override
3642 unsigned int bits
= c
.type_suffix (0).element_bits
/ 2;
3643 return c
.require_immediate_range (1, 0, bits
- 1);
3646 SHAPE (shift_left_imm_long
)
3648 /* sv<t0:uint>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
3650 where the final argument must be an integer constant expression in the
3651 range [0, sizeof (<t0>_t) * 8 - 1]. */
3652 struct shift_left_imm_to_uint_def
: public shift_left_imm_def
3655 build (function_builder
&b
, const function_group_info
&group
) const override
3657 b
.add_overloaded_functions (group
, MODE_n
);
3658 build_all (b
, "vu0,v0,su64", group
, MODE_n
);
3661 SHAPE (shift_left_imm_to_uint
)
3663 /* sv<t0>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
3665 where the final argument must be an integer constant expression in the
3666 range [1, sizeof (<t0>_t) * 8]. */
3667 struct shift_right_imm_def
: public overloaded_base
<0>
3670 build (function_builder
&b
, const function_group_info
&group
) const override
3672 b
.add_overloaded_functions (group
, MODE_n
);
3673 build_all (b
, "v0,v0,su64", group
, MODE_n
);
3677 resolve (function_resolver
&r
) const override
3679 return r
.resolve_uniform (1, 1);
3683 check (function_checker
&c
) const override
3685 unsigned int bits
= c
.type_suffix (0).element_bits
;
3686 return c
.require_immediate_range (1, 1, bits
);
3689 SHAPE (shift_right_imm
)
3691 /* sv<t0:half>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
3693 where the final argument must be an integer constant expression in the
3694 range [1, sizeof (<t0>_t) * 4]. */
3695 typedef shift_right_imm_narrow_wrapper
<binary_imm_narrowb_base
<>, 1>
3696 shift_right_imm_narrowb_def
;
3697 SHAPE (shift_right_imm_narrowb
)
3699 /* sv<t0:half>_t svfoo[_n_t0])(sv<t0:half>_t, sv<t0>_t, uint64_t)
3701 where the final argument must be an integer constant expression in the
3702 range [1, sizeof (<t0>_t) * 4]. */
3703 typedef shift_right_imm_narrow_wrapper
<binary_imm_narrowt_base
<>, 2>
3704 shift_right_imm_narrowt_def
;
3705 SHAPE (shift_right_imm_narrowt
)
3707 /* sv<t0:uint:half>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
3709 where the final argument must be an integer constant expression in the
3710 range [1, sizeof (<t0>_t) * 4]. */
3711 typedef binary_imm_narrowb_base
<TYPE_unsigned
>
3712 binary_imm_narrowb_base_unsigned
;
3713 typedef shift_right_imm_narrow_wrapper
<binary_imm_narrowb_base_unsigned
, 1>
3714 shift_right_imm_narrowb_to_uint_def
;
3715 SHAPE (shift_right_imm_narrowb_to_uint
)
3717 /* sv<t0:uint:half>_t svfoo[_n_t0])(sv<t0:uint:half>_t, sv<t0>_t, uint64_t)
3719 where the final argument must be an integer constant expression in the
3720 range [1, sizeof (<t0>_t) * 4]. */
3721 typedef binary_imm_narrowt_base
<TYPE_unsigned
>
3722 binary_imm_narrowt_base_unsigned
;
3723 typedef shift_right_imm_narrow_wrapper
<binary_imm_narrowt_base_unsigned
, 2>
3724 shift_right_imm_narrowt_to_uint_def
;
3725 SHAPE (shift_right_imm_narrowt_to_uint
)
3727 /* sv<t0>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
3729 where the final argument must be an integer constant expression in the
3730 range [1, sizeof (<t0>_t) * 8]. */
3731 struct shift_right_imm_narrowxn_def
: public overloaded_base
<1>
3733 bool explicit_group_suffix_p () const override
{ return false; }
3736 build (function_builder
&b
, const function_group_info
&group
) const override
3738 b
.add_overloaded_functions (group
, MODE_n
);
3739 build_all (b
, "c0,c1,su64", group
, MODE_n
);
3743 resolve (function_resolver
&r
) const override
3746 if (!r
.check_num_arguments (2)
3747 || !(type
= r
.infer_sve_type (0))
3748 || !r
.require_integer_immediate (1))
3749 return error_mark_node
;
3750 return r
.resolve_to (r
.mode_suffix_id
, type
);
3754 check (function_checker
&c
) const override
3756 unsigned int suffix
= c
.group_suffix_id
== GROUP_x4
? 1 : 0;
3757 unsigned int bits
= c
.type_suffix (suffix
).element_bits
;
3758 return c
.require_immediate_range (1, 1, bits
);
3761 SHAPE (shift_right_imm_narrowxn
)
3763 /* void svfoo[_t0](<X>_t *, sv<t0>[xN]_t)
3764 void svfoo_vnum[_t0](<X>_t *, int64_t, sv<t0>[xN]_t)
3766 where <X> might be tied to <t0> (for non-truncating stores) or might
3767 depend on the function base name (for truncating stores). */
3768 struct store_def
: public overloaded_base
<0>
3771 build (function_builder
&b
, const function_group_info
&group
) const override
3773 b
.add_overloaded_functions (group
, MODE_none
);
3774 b
.add_overloaded_functions (group
, MODE_vnum
);
3775 build_all (b
, "_,as,t0", group
, MODE_none
);
3776 build_all (b
, "_,as,ss64,t0", group
, MODE_vnum
);
3780 resolve (function_resolver
&r
) const override
3782 bool vnum_p
= r
.mode_suffix_id
== MODE_vnum
;
3783 gcc_assert (r
.mode_suffix_id
== MODE_none
|| vnum_p
);
3785 unsigned int i
, nargs
;
3787 if (!r
.check_gp_argument (vnum_p
? 3 : 2, i
, nargs
)
3788 || !r
.require_pointer_type (i
)
3789 || (vnum_p
&& !r
.require_scalar_type (i
+ 1, "int64_t"))
3790 || !(type
= r
.infer_tuple_type (nargs
- 1)))
3791 return error_mark_node
;
3793 return r
.resolve_to (r
.mode_suffix_id
, type
);
3798 /* void svfoo_[s32]index[_t0](<X>_t *, svint32_t, sv<t0>_t)
3799 void svfoo_[s64]index[_t0](<X>_t *, svint64_t, sv<t0>_t)
3800 void svfoo_[u32]index[_t0](<X>_t *, svuint32_t, sv<t0>_t)
3801 void svfoo_[u64]index[_t0](<X>_t *, svuint64_t, sv<t0>_t)
3803 void svfoo[_u32base]_index[_t0](svuint32_t, int64_t, sv<t0>_t)
3804 void svfoo[_u64base]_index[_t0](svuint64_t, int64_t, sv<t0>_t)
3806 where <X> might be tied to <t0> (for non-truncating stores) or might
3807 depend on the function base name (for truncating stores). */
3808 struct store_scatter_index_def
: public store_scatter_base
3811 build (function_builder
&b
, const function_group_info
&group
) const override
3813 b
.add_overloaded_functions (group
, MODE_index
);
3814 build_sv_index (b
, "_,as,d,t0", group
);
3815 build_vs_index (b
, "_,b,ss64,t0", group
);
3818 SHAPE (store_scatter_index
)
3820 /* void svfoo_[s64]index[_t0](<X>_t *, svint64_t, sv<t0>_t)
3821 void svfoo_[u64]index[_t0](<X>_t *, svuint64_t, sv<t0>_t)
3823 void svfoo[_u32base]_index[_t0](svuint32_t, int64_t, sv<t0>_t)
3824 void svfoo[_u64base]_index[_t0](svuint64_t, int64_t, sv<t0>_t)
3826 i.e. a version of store_scatter_index that doesn't support 32-bit
3828 struct store_scatter_index_restricted_def
: public store_scatter_base
3831 build (function_builder
&b
, const function_group_info
&group
) const override
3833 b
.add_overloaded_functions (group
, MODE_index
);
3834 build_sv_index64 (b
, "_,as,d,t0", group
);
3835 build_vs_index (b
, "_,b,ss64,t0", group
);
3838 SHAPE (store_scatter_index_restricted
)
3840 /* void svfoo_[s32]offset[_t0](<X>_t *, svint32_t, sv<t0>_t)
3841 void svfoo_[s64]offset[_t0](<X>_t *, svint64_t, sv<t0>_t)
3842 void svfoo_[u32]offset[_t0](<X>_t *, svuint32_t, sv<t0>_t)
3843 void svfoo_[u64]offset[_t0](<X>_t *, svuint64_t, sv<t0>_t)
3845 void svfoo[_u32base_t0](svuint32_t, sv<t0>_t)
3846 void svfoo[_u64base_t0](svuint64_t, sv<t0>_t)
3848 void svfoo[_u32base]_offset[_t0](svuint32_t, int64_t, sv<t0>_t)
3849 void svfoo[_u64base]_offset[_t0](svuint64_t, int64_t, sv<t0>_t)
3851 where <X> might be tied to <t0> (for non-truncating stores) or might
3852 depend on the function base name (for truncating stores). */
3853 struct store_scatter_offset_def
: public store_scatter_base
3856 build (function_builder
&b
, const function_group_info
&group
) const override
3858 b
.add_overloaded_functions (group
, MODE_none
);
3859 b
.add_overloaded_functions (group
, MODE_offset
);
3860 build_sv_offset (b
, "_,as,d,t0", group
);
3861 build_v_base (b
, "_,b,t0", group
);
3862 build_vs_offset (b
, "_,b,ss64,t0", group
);
3865 SHAPE (store_scatter_offset
)
3867 /* void svfoo_[s64]offset[_t0](<X>_t *, svint64_t, sv<t0>_t)
3868 void svfoo_[u32]offset[_t0](<X>_t *, svuint32_t, sv<t0>_t)
3869 void svfoo_[u64]offset[_t0](<X>_t *, svuint64_t, sv<t0>_t)
3871 void svfoo[_u32base_t0](svuint32_t, sv<t0>_t)
3872 void svfoo[_u64base_t0](svuint64_t, sv<t0>_t)
3874 void svfoo[_u32base]_offset[_t0](svuint32_t, int64_t, sv<t0>_t)
3875 void svfoo[_u64base]_offset[_t0](svuint64_t, int64_t, sv<t0>_t)
3877 i.e. a version of store_scatter_offset that doesn't support svint32_t
3879 struct store_scatter_offset_restricted_def
: public store_scatter_base
3882 build (function_builder
&b
, const function_group_info
&group
) const override
3884 b
.add_overloaded_functions (group
, MODE_none
);
3885 b
.add_overloaded_functions (group
, MODE_offset
);
3886 build_sv_uint_offset (b
, "_,as,d,t0", group
);
3887 build_v_base (b
, "_,b,t0", group
);
3888 build_vs_offset (b
, "_,b,ss64,t0", group
);
3891 SHAPE (store_scatter_offset_restricted
)
3893 /* void svfoo_[s64]index[_t0](<t0>_t *, svint64_t, sv<t0>_t)
3894 void svfoo_[u64]index[_t0](<t0>_t *, svuint64_t, sv<t0>_t)
3896 void svfoo[_u64base]_index[_t0](svuint64_t, int64_t, sv<t0>_t). */
3897 struct store_scatter64_index_def
: public store_scatter64_base
3900 build (function_builder
&b
, const function_group_info
&group
) const override
3902 b
.add_overloaded_functions (group
, MODE_index
);
3903 build_all (b
, "_,as,d,t0", group
, MODE_s64index
);
3904 build_all (b
, "_,as,d,t0", group
, MODE_u64index
);
3905 build_all (b
, "_,b,ss64,t0", group
, MODE_u64base_index
);
3908 SHAPE (store_scatter64_index
)
3910 /* void svfoo_[s64]offset[_t0](<t0>_t *, svint64_t, sv<t0>_t)
3911 void svfoo_[u64]offset[_t0](<t0>_t *, svuint64_t, sv<t0>_t)
3913 void svfoo[_u64base_t0](svuint64_t, sv<t0>_t)
3915 void svfoo[_u64base]_offset[_t0](svuint64_t, int64_t, sv<t0>_t). */
3916 struct store_scatter64_offset_def
: public store_scatter64_base
3919 build (function_builder
&b
, const function_group_info
&group
) const override
3921 b
.add_overloaded_functions (group
, MODE_none
);
3922 b
.add_overloaded_functions (group
, MODE_offset
);
3923 build_all (b
, "_,as,d,t0", group
, MODE_s64offset
);
3924 build_all (b
, "_,as,d,t0", group
, MODE_u64offset
);
3925 build_all (b
, "_,b,t0", group
, MODE_u64base
);
3926 build_all (b
, "_,b,ss64,t0", group
, MODE_u64base_offset
);
3929 SHAPE (store_scatter64_offset
)
3931 /* void svfoo_t0(uint64_t, uint32_t, svbool_t, void *)
3932 void svfoo_vnum_t0(uint64_t, uint32_t, svbool_t, void *, int64_t)
3934 where the first two fields form a (ZA tile, slice) pair. */
3935 struct store_za_def
: public nonoverloaded_base
3938 build (function_builder
&b
, const function_group_info
&group
) const override
3940 build_all (b
, "_,su64,su32,vp,as", group
, MODE_none
);
3941 build_all (b
, "_,su64,su32,vp,as,ss64", group
, MODE_vnum
);
3945 check (function_checker
&c
) const override
3947 return c
.require_immediate_range (0, 0, c
.num_za_tiles () - 1);
3952 /* void svfoo[_t0_g](<X>_t *, sv<t0>x<g>_t)
3953 void svfoo_vnum[_t0_g](<X>_t *, int64_t, sv<t0>x<g>_t)
3955 where <X> might be tied to <t0> (for non-truncating stores) or might
3956 depend on the function base name (for truncating stores). */
3957 struct storexn_def
: public store_def
3959 bool explicit_group_suffix_p () const override
{ return false; }
3962 resolve (function_resolver
&r
) const override
3964 bool vnum_p
= r
.mode_suffix_id
== MODE_vnum
;
3965 gcc_assert (r
.mode_suffix_id
== MODE_none
|| vnum_p
);
3967 unsigned int nargs
= vnum_p
? 4 : 3;
3968 vector_type_index pred_type
;
3970 if (!r
.check_num_arguments (nargs
)
3971 || (pred_type
= r
.infer_predicate_type (0)) == NUM_VECTOR_TYPES
3972 || !r
.require_pointer_type (1)
3973 || (vnum_p
&& !r
.require_scalar_type (2, "int64_t"))
3974 || !(type
= r
.infer_sve_type (nargs
- 1))
3975 || !r
.require_matching_predicate_type (pred_type
, type
))
3976 return error_mark_node
;
3978 return r
.resolve_to (r
.mode_suffix_id
, type
);
3983 /* void svfoo_t0(uint32_t, void *)
3984 void svfoo_vnum_t0(uint32_t, void *, int64_t)
3986 where the first argument is a variable ZA slice. */
3987 struct str_za_def
: public nonoverloaded_base
3990 build (function_builder
&b
, const function_group_info
&group
) const override
3992 build_all (b
, "_,su32,as", group
, MODE_none
);
3993 build_all (b
, "_,su32,as,ss64", group
, MODE_vnum
);
3998 /* void svfoo_zt(uint64_t, void *)
4000 where the first argument must be zero. */
4001 struct str_zt_def
: public nonoverloaded_base
4004 build (function_builder
&b
, const function_group_info
&group
) const override
4006 build_all (b
, "_,su64,as", group
, MODE_none
);
4010 check (function_checker
&c
) const override
4012 return c
.require_immediate_range (0, 0, 0);
4017 /* sv<t0>_t svfoo[_t0](sv<t0>xN_t, sv<t0:uint>_t). */
4018 struct tbl_tuple_def
: public overloaded_base
<0>
4021 build (function_builder
&b
, const function_group_info
&group
) const override
4023 b
.add_overloaded_functions (group
, MODE_none
);
4024 build_all (b
, "v0,t0,vu0", group
, MODE_none
);
4028 resolve (function_resolver
&r
) const override
4030 unsigned int i
, nargs
;
4032 if (!r
.check_gp_argument (2, i
, nargs
)
4033 || !(type
= r
.infer_tuple_type (i
))
4034 || !r
.require_derived_vector_type (i
+ 1, i
, type
, TYPE_unsigned
))
4035 return error_mark_node
;
4037 return r
.resolve_to (r
.mode_suffix_id
, type
);
4042 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbfloatt16_t, svbfloat16_t). */
4043 struct ternary_bfloat_def
4044 : public ternary_resize2_base
<16, TYPE_bfloat
, TYPE_bfloat
>
4047 build (function_builder
&b
, const function_group_info
&group
) const override
4049 b
.add_overloaded_functions (group
, MODE_none
);
4050 build_all (b
, "v0,v0,vB,vB", group
, MODE_none
);
4053 SHAPE (ternary_bfloat
)
4055 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svmfloat8_t, svmfloat8_t). */
4056 struct ternary_mfloat8_def
4057 : public ternary_resize2_base
<8, TYPE_mfloat
, TYPE_mfloat
>
4060 build (function_builder
&b
, const function_group_info
&group
) const override
4062 gcc_assert (group
.fpm_mode
== FPM_set
);
4063 b
.add_overloaded_functions (group
, MODE_none
);
4064 build_all (b
, "v0,v0,vM,vM", group
, MODE_none
);
4068 resolve (function_resolver
&r
) const override
4070 type_suffix_index type
;
4071 if (!r
.check_num_arguments (4)
4072 || (type
= r
.infer_vector_type (0)) == NUM_TYPE_SUFFIXES
4073 || !r
.require_vector_type (1, VECTOR_TYPE_svmfloat8_t
)
4074 || !r
.require_vector_type (2, VECTOR_TYPE_svmfloat8_t
)
4075 || !r
.require_scalar_type (3, "uint64_t"))
4076 return error_mark_node
;
4078 return r
.resolve_to (r
.mode_suffix_id
, type
, TYPE_SUFFIX_mf8
, GROUP_none
);
4081 SHAPE (ternary_mfloat8
)
4083 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbfloat16_t, svbfloat16_t, uint64_t)
4085 where the final argument is an integer constant expression in the range
4087 typedef ternary_bfloat_lane_base
<1> ternary_bfloat_lane_def
;
4088 SHAPE (ternary_bfloat_lane
)
4090 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbfloat16_t, svbfloat16_t, uint64_t)
4092 where the final argument is an integer constant expression in the range
4094 typedef ternary_bfloat_lane_base
<2> ternary_bfloat_lanex2_def
;
4095 SHAPE (ternary_bfloat_lanex2
)
4097 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svmfloat8_t, svmfloat8_t, uint64_t)
4099 where the final argument is an integer constant expression in the range
4101 struct ternary_mfloat8_lane_def
4102 : public ternary_resize2_lane_base
<8, TYPE_mfloat
, TYPE_mfloat
>
4105 build (function_builder
&b
, const function_group_info
&group
) const override
4107 gcc_assert (group
.fpm_mode
== FPM_set
);
4108 b
.add_overloaded_functions (group
, MODE_none
);
4109 build_all (b
, "v0,v0,vM,vM,su64", group
, MODE_none
);
4113 check (function_checker
&c
) const override
4115 return c
.require_immediate_lane_index (3, 2, 1);
4119 resolve (function_resolver
&r
) const override
4121 type_suffix_index type
;
4122 if (!r
.check_num_arguments (5)
4123 || (type
= r
.infer_vector_type (0)) == NUM_TYPE_SUFFIXES
4124 || !r
.require_vector_type (1, VECTOR_TYPE_svmfloat8_t
)
4125 || !r
.require_vector_type (2, VECTOR_TYPE_svmfloat8_t
)
4126 || !r
.require_integer_immediate (3)
4127 || !r
.require_scalar_type (4, "uint64_t"))
4128 return error_mark_node
;
4130 return r
.resolve_to (r
.mode_suffix_id
, type
, TYPE_SUFFIX_mf8
, GROUP_none
);
4133 SHAPE (ternary_mfloat8_lane
)
4135 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svmfloat8_t, svmfloat8_t, uint64_t)
4137 where the final argument is an integer constant expression in the range
4138 [0, 7] or [0, 3]. */
4139 struct ternary_mfloat8_lane_group_selection_def
4140 : public ternary_mfloat8_lane_def
4143 check (function_checker
&c
) const override
4145 machine_mode mode
= c
.vector_mode (0);
4146 if (mode
== E_VNx8HFmode
)
4147 return c
.require_immediate_lane_index (3, 2, 2);
4148 else if (mode
== E_VNx4SFmode
)
4149 return c
.require_immediate_lane_index (3, 2, 4);
4153 SHAPE (ternary_mfloat8_lane_group_selection
)
4155 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbfloatt16_t, svbfloat16_t)
4156 sv<t0>_t svfoo[_n_t0](sv<t0>_t, svbfloat16_t, bfloat16_t). */
4157 struct ternary_bfloat_opt_n_def
4158 : public ternary_resize2_opt_n_base
<16, TYPE_bfloat
, TYPE_bfloat
>
4161 build (function_builder
&b
, const function_group_info
&group
) const override
4163 b
.add_overloaded_functions (group
, MODE_none
);
4164 build_all (b
, "v0,v0,vB,vB", group
, MODE_none
);
4165 build_all (b
, "v0,v0,vB,sB", group
, MODE_n
);
4168 SHAPE (ternary_bfloat_opt_n
)
4170 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svmfloatt8_t, svmfloat8_t)
4171 sv<t0>_t svfoo[_n_t0](sv<t0>_t, svmfloat8_t, bfloat8_t). */
4172 struct ternary_mfloat8_opt_n_def
4173 : public ternary_resize2_opt_n_base
<8, TYPE_mfloat
, TYPE_mfloat
>
4176 build (function_builder
&b
, const function_group_info
&group
) const override
4178 gcc_assert (group
.fpm_mode
== FPM_set
);
4179 b
.add_overloaded_functions (group
, MODE_none
);
4180 build_all (b
, "v0,v0,vM,vM", group
, MODE_none
);
4181 build_all (b
, "v0,v0,vM,sM", group
, MODE_n
);
4185 resolve (function_resolver
&r
) const override
4187 type_suffix_index type
;
4188 if (!r
.check_num_arguments (4)
4189 || (type
= r
.infer_vector_type (0)) == NUM_TYPE_SUFFIXES
4190 || !r
.require_vector_type (1, VECTOR_TYPE_svmfloat8_t
)
4191 || !r
.require_vector_or_scalar_type (2)
4192 || !r
.require_scalar_type (3, "uint64_t"))
4193 return error_mark_node
;
4195 auto mode
= r
.mode_suffix_id
;
4196 if (r
.scalar_argument_p (2))
4198 else if (!r
.require_vector_type (2, VECTOR_TYPE_svmfloat8_t
))
4199 return error_mark_node
;
4201 return r
.resolve_to (mode
, type
, TYPE_SUFFIX_mf8
, GROUP_none
);
4204 SHAPE (ternary_mfloat8_opt_n
)
4206 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:int:quarter>_t, sv<t0:uint:quarter>_t,
4209 where the final argument is an integer constant expression in the range
4210 [0, 16 / sizeof (<t0>_t) - 1]. */
4211 struct ternary_intq_uintq_lane_def
4212 : public ternary_qq_lane_base
<TYPE_signed
, TYPE_unsigned
>
4215 build (function_builder
&b
, const function_group_info
&group
) const override
4217 b
.add_overloaded_functions (group
, MODE_none
);
4218 build_all (b
, "v0,v0,vqs0,vqu0,su64", group
, MODE_none
);
4221 SHAPE (ternary_intq_uintq_lane
)
4223 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:int:quarter>_t, sv<t0:uint:quarter>_t)
4224 sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0:int:quarter>_t,
4225 <t0:uint:quarter>_t). */
4226 struct ternary_intq_uintq_opt_n_def
4227 : public ternary_resize2_opt_n_base
<function_resolver::QUARTER_SIZE
,
4228 TYPE_signed
, TYPE_unsigned
>
4231 build (function_builder
&b
, const function_group_info
&group
) const override
4233 b
.add_overloaded_functions (group
, MODE_none
);
4234 build_all (b
, "v0,v0,vqs0,vqu0", group
, MODE_none
);
4235 build_all (b
, "v0,v0,vqs0,squ0", group
, MODE_n
);
4238 SHAPE (ternary_intq_uintq_opt_n
)
4240 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, sv<t0>_t, uint64_t)
4242 where the final argument is an integer constant expression in the
4243 range [0, 16 / sizeof (<t0>_t) - 1]. */
4244 struct ternary_lane_def
: public overloaded_base
<0>
4247 build (function_builder
&b
, const function_group_info
&group
) const override
4249 b
.add_overloaded_functions (group
, MODE_none
);
4250 build_all (b
, "v0,v0,v0,v0,su64", group
, MODE_none
);
4254 resolve (function_resolver
&r
) const override
4256 return r
.resolve_uniform (3, 1);
4260 check (function_checker
&c
) const override
4262 return c
.require_immediate_lane_index (3, 2);
4265 SHAPE (ternary_lane
)
4267 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, sv<t0>_t, uint64_t, uint64_t)
4269 where the penultimate argument is an integer constant expression in
4270 the range [0, 8 / sizeof (<t0>_t) - 1] and where the final argument
4271 is an integer constant expression in {0, 90, 180, 270}. */
4272 struct ternary_lane_rotate_def
: public overloaded_base
<0>
4275 build (function_builder
&b
, const function_group_info
&group
) const override
4277 b
.add_overloaded_functions (group
, MODE_none
);
4278 build_all (b
, "v0,v0,v0,v0,su64,su64", group
, MODE_none
);
4282 resolve (function_resolver
&r
) const override
4284 return r
.resolve_uniform (3, 2);
4288 check (function_checker
&c
) const override
4290 return (c
.require_immediate_lane_index (3, 2, 2)
4291 && c
.require_immediate_one_of (4, 0, 90, 180, 270));
4294 SHAPE (ternary_lane_rotate
)
4296 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:half>_t, sv<t0:half>_t, uint64_t)
4298 where the final argument is an integer constant expression in the range
4299 [0, 32 / sizeof (<t0>_t) - 1]. */
4300 struct ternary_long_lane_def
4301 : public ternary_resize2_lane_base
<function_resolver::HALF_SIZE
>
4304 build (function_builder
&b
, const function_group_info
&group
) const override
4306 b
.add_overloaded_functions (group
, MODE_none
);
4307 build_all (b
, "v0,v0,vh0,vh0,su64", group
, MODE_none
);
4311 check (function_checker
&c
) const override
4313 return c
.require_immediate_lane_index (3, 2);
4316 SHAPE (ternary_long_lane
)
4318 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:half>_t, sv<t0:half>_t)
4319 sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0:half>_t, <t0:half>_t)
4321 i.e. a version of the standard ternary shape ternary_opt_n in which
4322 the element type of the last two arguments is the half-sized
4323 equivalent of <t0>. */
4324 struct ternary_long_opt_n_def
4325 : public ternary_resize2_opt_n_base
<function_resolver::HALF_SIZE
>
4328 build (function_builder
&b
, const function_group_info
&group
) const override
4330 b
.add_overloaded_functions (group
, MODE_none
);
4331 build_all (b
, "v0,v0,vh0,vh0", group
, MODE_none
);
4332 build_all (b
, "v0,v0,vh0,sh0", group
, MODE_n
);
4335 SHAPE (ternary_long_opt_n
)
4337 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t, sv<t0>_t)
4338 sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0>_t, <t0>_t)
4340 i.e. the standard shape for ternary operations that operate on
4342 struct ternary_opt_n_def
: public overloaded_base
<0>
4345 build (function_builder
&b
, const function_group_info
&group
) const override
4347 b
.add_overloaded_functions (group
, MODE_none
);
4348 build_all (b
, "v0,v0,v0,v0", group
, MODE_none
);
4349 build_all (b
, "v0,v0,v0,s0", group
, MODE_n
);
4353 resolve (function_resolver
&r
) const override
4355 return r
.resolve_uniform_opt_n (3);
4358 SHAPE (ternary_opt_n
)
4360 /* A choice between:
4362 (1) sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:quarter>_t, sv<t0:quarter>_t,
4365 (2) sv<t0>_t svfoo[_t0_t1](sv<t0>_t, sv<t1>_t, sv<t1>_t, uint64_t)
4367 where the final argument is an integer constant expression in the range
4368 [0, 16 / sizeof (<t0>_t) - 1]. */
4369 struct ternary_qq_or_011_lane_def
: public ternary_qq_lane_base
<>
4372 build (function_builder
&b
, const function_group_info
&group
) const override
4374 b
.add_overloaded_functions (group
, MODE_none
);
4375 if (group
.types
[0][1] == NUM_TYPE_SUFFIXES
)
4376 build_all (b
, "v0,v0,vq0,vq0,su64", group
, MODE_none
);
4378 build_all (b
, "v0,v0,v1,v1,su64", group
, MODE_none
);
4382 resolve (function_resolver
&r
) const override
4384 unsigned int i
, nargs
;
4385 type_suffix_index type0
, type1
;
4386 if (!r
.check_gp_argument (4, i
, nargs
)
4387 || (type0
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
4388 || (type1
= r
.infer_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
4389 || !r
.require_matching_vector_type (i
+ 2, i
+ 1, type1
)
4390 || !r
.require_integer_immediate (i
+ 3))
4391 return error_mark_node
;
4393 if ((type_suffixes
[type0
].element_bits
4394 == 4 * type_suffixes
[type1
].element_bits
)
4395 && type_suffixes
[type0
].tclass
== type_suffixes
[type1
].tclass
)
4396 if (tree res
= r
.lookup_form (MODE_none
, type0
))
4399 return r
.resolve_to (r
.mode_suffix_id
, type0
, type1
);
4402 SHAPE (ternary_qq_or_011_lane
)
4404 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0:quarter>_t, sv<t0:quarter>_t,
4407 where the final argument is an integer constant expression in
4408 {0, 90, 180, 270}. */
4409 struct ternary_qq_lane_rotate_def
: public overloaded_base
<0>
4412 build (function_builder
&b
, const function_group_info
&group
) const override
4414 b
.add_overloaded_functions (group
, MODE_none
);
4415 build_all (b
, "v0,v0,vq0,vq0,su64,su64", group
, MODE_none
);
4419 resolve (function_resolver
&r
) const override
4421 unsigned int i
, nargs
;
4422 type_suffix_index type
;
4423 if (!r
.check_gp_argument (5, i
, nargs
)
4424 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
4425 || !r
.require_derived_vector_type (i
+ 1, i
, type
, r
.SAME_TYPE_CLASS
,
4427 || !r
.require_derived_vector_type (i
+ 2, i
, type
, r
.SAME_TYPE_CLASS
,
4429 || !r
.require_integer_immediate (i
+ 3)
4430 || !r
.require_integer_immediate (i
+ 4))
4431 return error_mark_node
;
4433 return r
.resolve_to (r
.mode_suffix_id
, type
);
4437 check (function_checker
&c
) const override
4439 return (c
.require_immediate_lane_index (3, 0)
4440 && c
.require_immediate_one_of (4, 0, 90, 180, 270));
4443 SHAPE (ternary_qq_lane_rotate
)
4445 /* A choice between:
4447 (1) sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:quarter>_t, sv<t0:quarter>_t)
4448 sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0:quarter>_t, <t0:quarter>_t)
4450 i.e. a version of the standard ternary shape ternary_opt_n in which
4451 the element type of the last two arguments is the quarter-sized
4454 (2) sv<t0>_t svfoo[_t0_t1](sv<t0>_t, sv<t1>_t, sv<t1>_t)
4456 where the element type of the last two arguments is specified
4458 struct ternary_qq_opt_n_or_011_def
4459 : public ternary_resize2_opt_n_base
<function_resolver::QUARTER_SIZE
>
4462 build (function_builder
&b
, const function_group_info
&group
) const override
4464 b
.add_overloaded_functions (group
, MODE_none
);
4465 if (group
.types
[0][1] == NUM_TYPE_SUFFIXES
)
4467 build_all (b
, "v0,v0,vq0,vq0", group
, MODE_none
);
4468 build_all (b
, "v0,v0,vq0,sq0", group
, MODE_n
);
4471 build_all (b
, "v0,v0,v1,v1", group
, MODE_none
);
4475 resolve (function_resolver
&r
) const override
4477 unsigned int i
, nargs
;
4478 type_suffix_index type0
, type1
;
4479 if (!r
.check_gp_argument (3, i
, nargs
)
4480 || (type0
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
4481 || (type1
= r
.infer_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
4482 || !r
.require_vector_or_scalar_type (i
+ 2))
4483 return error_mark_node
;
4485 auto mode
= r
.scalar_argument_p (i
+ 2) ? MODE_n
: MODE_none
;
4486 if (mode
== MODE_none
4487 && !r
.require_matching_vector_type (i
+ 2, i
+ 1, type1
))
4488 return error_mark_node
;
4490 if ((type_suffixes
[type0
].element_bits
4491 == 4 * type_suffixes
[type1
].element_bits
)
4492 && type_suffixes
[type0
].tclass
== type_suffixes
[type1
].tclass
)
4493 if (tree res
= r
.lookup_form (mode
, type0
))
4496 if (!r
.require_nonscalar_type (i
+ 2))
4497 return error_mark_node
;
4499 return r
.resolve_to (r
.mode_suffix_id
, type0
, type1
);
4502 SHAPE (ternary_qq_opt_n_or_011
)
4504 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0:quarter>_t, sv<t0:quarter>_t,
4507 where the final argument is an integer constant expression in
4508 {0, 90, 180, 270}. */
4509 struct ternary_qq_rotate_def
: public overloaded_base
<0>
4512 build (function_builder
&b
, const function_group_info
&group
) const override
4514 b
.add_overloaded_functions (group
, MODE_none
);
4515 build_all (b
, "v0,v0,vq0,vq0,su64", group
, MODE_none
);
4519 resolve (function_resolver
&r
) const override
4521 unsigned int i
, nargs
;
4522 type_suffix_index type
;
4523 if (!r
.check_gp_argument (4, i
, nargs
)
4524 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
4525 || !r
.require_derived_vector_type (i
+ 1, i
, type
, r
.SAME_TYPE_CLASS
,
4527 || !r
.require_derived_vector_type (i
+ 2, i
, type
, r
.SAME_TYPE_CLASS
,
4529 || !r
.require_integer_immediate (i
+ 3))
4530 return error_mark_node
;
4532 return r
.resolve_to (r
.mode_suffix_id
, type
);
4536 check (function_checker
&c
) const override
4538 return c
.require_immediate_one_of (3, 0, 90, 180, 270);
4541 SHAPE (ternary_qq_rotate
)
4543 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, sv<t0>_t, uint64_t)
4545 where the final argument is an integer constant expression in
4546 {0, 90, 180, 270}. */
4547 struct ternary_rotate_def
: public overloaded_base
<0>
4550 build (function_builder
&b
, const function_group_info
&group
) const override
4552 b
.add_overloaded_functions (group
, MODE_none
);
4553 build_all (b
, "v0,v0,v0,v0,su64", group
, MODE_none
);
4557 resolve (function_resolver
&r
) const override
4559 return r
.resolve_uniform (3, 1);
4563 check (function_checker
&c
) const override
4565 return c
.require_immediate_one_of (3, 0, 90, 180, 270);
4568 SHAPE (ternary_rotate
)
4570 /* sv<t0>_t svfoo[_n_t0])(sv<t0>_t, sv<t0>_t, uint64_t)
4572 where the final argument must be an integer constant expression in the
4573 range [0, sizeof (<t0>_t) * 8 - 1]. */
4574 struct ternary_shift_left_imm_def
: public ternary_shift_imm_base
4577 check (function_checker
&c
) const override
4579 unsigned int bits
= c
.type_suffix (0).element_bits
;
4580 return c
.require_immediate_range (2, 0, bits
- 1);
4583 SHAPE (ternary_shift_left_imm
)
4585 /* sv<t0>_t svfoo[_n_t0])(sv<t0>_t, sv<t0>_t, uint64_t)
4587 where the final argument must be an integer constant expression in the
4588 range [1, sizeof (<t0>_t) * 8]. */
4589 struct ternary_shift_right_imm_def
: public ternary_shift_imm_base
4592 check (function_checker
&c
) const override
4594 unsigned int bits
= c
.type_suffix (0).element_bits
;
4595 return c
.require_immediate_range (2, 1, bits
);
4598 SHAPE (ternary_shift_right_imm
)
4600 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t, sv<t0:uint>_t). */
4601 struct ternary_uint_def
: public overloaded_base
<0>
4604 build (function_builder
&b
, const function_group_info
&group
) const override
4606 b
.add_overloaded_functions (group
, MODE_none
);
4607 build_all (b
, "v0,v0,v0,vu0", group
, MODE_none
);
4611 resolve (function_resolver
&r
) const override
4613 unsigned int i
, nargs
;
4614 type_suffix_index type
;
4615 if (!r
.check_gp_argument (3, i
, nargs
)
4616 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
4617 || !r
.require_matching_vector_type (i
+ 1, i
, type
)
4618 || !r
.require_derived_vector_type (i
+ 2, i
, type
, TYPE_unsigned
))
4619 return error_mark_node
;
4621 return r
.resolve_to (r
.mode_suffix_id
, type
);
4624 SHAPE (ternary_uint
)
4626 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svu<t0:uint:quarter>_t,
4627 sv<t0:int:quarter>_t). */
4628 struct ternary_uintq_intq_def
4629 : public ternary_resize2_base
<function_resolver::QUARTER_SIZE
,
4630 TYPE_unsigned
, TYPE_signed
>
4633 build (function_builder
&b
, const function_group_info
&group
) const override
4635 b
.add_overloaded_functions (group
, MODE_none
);
4636 build_all (b
, "v0,v0,vqu0,vqs0", group
, MODE_none
);
4639 SHAPE (ternary_uintq_intq
)
4641 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:uint:quarter>_t, sv<t0:int:quarter>_t,
4644 where the final argument is an integer constant expression in the range
4645 [0, 16 / sizeof (<t0>_t) - 1]. */
4646 struct ternary_uintq_intq_lane_def
4647 : public ternary_qq_lane_base
<TYPE_unsigned
, TYPE_signed
>
4650 build (function_builder
&b
, const function_group_info
&group
) const override
4652 b
.add_overloaded_functions (group
, MODE_none
);
4653 build_all (b
, "v0,v0,vqu0,vqs0,su64", group
, MODE_none
);
4656 SHAPE (ternary_uintq_intq_lane
)
4658 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:uint:quarter>_t, sv<t0:int:quarter>_t)
4659 sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0:uint:quarter>_t,
4660 <t0:int:quarter>_t). */
4661 struct ternary_uintq_intq_opt_n_def
4662 : public ternary_resize2_opt_n_base
<function_resolver::QUARTER_SIZE
,
4663 TYPE_unsigned
, TYPE_signed
>
4666 build (function_builder
&b
, const function_group_info
&group
) const override
4668 b
.add_overloaded_functions (group
, MODE_none
);
4669 build_all (b
, "v0,v0,vqu0,vqs0", group
, MODE_none
);
4670 build_all (b
, "v0,v0,vqu0,sqs0", group
, MODE_n
);
4673 SHAPE (ternary_uintq_intq_opt_n
)
4675 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, uint64_t)
4677 where the final argument is an integer constant expression in the
4679 struct tmad_def
: public overloaded_base
<0>
4682 build (function_builder
&b
, const function_group_info
&group
) const override
4684 b
.add_overloaded_functions (group
, MODE_none
);
4685 build_all (b
, "v0,v0,v0,su64", group
, MODE_none
);
4689 resolve (function_resolver
&r
) const override
4691 return r
.resolve_uniform (2, 1);
4695 check (function_checker
&c
) const override
4697 return c
.require_immediate_range (2, 0, 7);
4702 /* sv<t0>_t svfoo[_t0](sv<t0>_t)
4704 i.e. the standard shape for unary operations that operate on
4706 struct unary_def
: public overloaded_base
<0>
4709 build (function_builder
&b
, const function_group_info
&group
) const override
4711 b
.add_overloaded_functions (group
, MODE_none
);
4712 build_all (b
, "t0,t0", group
, MODE_none
);
4716 resolve (function_resolver
&r
) const override
4718 return r
.resolve_unary ();
4723 /* sv<t0>_t svfoo_t0[_t1](sv<t1>_t)
4725 where the target type <t0> must be specified explicitly but the source
4726 type <t1> can be inferred. */
4727 struct unary_convert_def
: public overloaded_base
<1>
4730 build (function_builder
&b
, const function_group_info
&group
) const override
4732 b
.add_overloaded_functions (group
, MODE_none
);
4733 build_all (b
, "c0,c1", group
, MODE_none
);
4737 resolve (function_resolver
&r
) const override
4739 return r
.resolve_unary (r
.type_suffix (0).tclass
,
4740 r
.type_suffix (0).element_bits
);
4743 SHAPE (unary_convert
)
4745 /* sv<t0>_t svfoo_t0[_t1](sv<t0>_t, sv<t1>_t)
4747 This is a version of unary_convert in which the even-indexed
4748 elements are passed in as a first parameter, before any governing
4750 struct unary_convert_narrowt_def
: public overloaded_base
<1>
4753 has_merge_argument_p (const function_instance
&, unsigned int) const override
4759 build (function_builder
&b
, const function_group_info
&group
) const override
4761 b
.add_overloaded_functions (group
, MODE_none
);
4762 build_all (b
, "v0,v1", group
, MODE_none
);
4766 resolve (function_resolver
&r
) const override
4768 return r
.resolve_unary (r
.type_suffix (0).tclass
,
4769 r
.type_suffix (0).element_bits
, true);
4772 SHAPE (unary_convert_narrowt
)
4774 /* sv<t0>_t svfoo_t0[_t1_g](sv<t0>_t, sv<t1>x<g_t, fpm_t)
4776 Similar to unary_convert_narrowt but for tuple arguments with support for
4777 modal floating point. */
4778 struct unary_convertxn_narrowt_def
: public overloaded_base
<1>
4781 explicit_group_suffix_p () const override
4787 has_merge_argument_p (const function_instance
&, unsigned int) const override
4793 build (function_builder
&b
, const function_group_info
&group
) const override
4795 b
.add_overloaded_functions (group
, MODE_none
);
4796 build_all (b
, "v0,v0,t1", group
, MODE_none
);
4800 resolve (function_resolver
&r
) const override
4802 gcc_assert(r
.fpm_mode
== FPM_set
);
4804 if (!r
.check_num_arguments (3)
4805 || !(type
= r
.infer_sve_type (1))
4806 || !r
.require_scalar_type (2, "uint64_t"))
4807 return error_mark_node
;
4809 return r
.resolve_to (r
.mode_suffix_id
, type
);
4812 SHAPE (unary_convertxn_narrowt
)
4814 /* sv<t0>x<g0>_t svfoo_t0[_t1_g](sv<t1>x<g1>_t)
4816 where the target type <t0> must be specified explicitly but the
4817 source type <t1> can be inferred.
4819 Functions with a group suffix are unpredicated. For them:
4821 - If <t0> is N times wider than <t1>, the return value has N times
4822 more vectors than the argument.
4824 - If <t1> is N times wider than <t0>, the argument has N times
4825 more vectors than the return type. */
4826 struct unary_convertxn_def
: public unary_convert_def
4828 bool explicit_group_suffix_p () const override
{ return false; }
4831 resolve (function_resolver
&r
) const override
4833 if (r
.pred
!= PRED_none
)
4834 return unary_convert_def::resolve (r
);
4837 if (!r
.check_num_arguments (1)
4838 || !(type
= r
.infer_sve_type (0)))
4839 return error_mark_node
;
4841 return r
.resolve_conversion (r
.mode_suffix_id
, type
);
4844 SHAPE (unary_convertxn
)
4846 /* sv<t0>_t svfoo_t0[_t1_g](sv<t1>x<g1>_t)
4848 where the target type <t0> must be specified explicitly but the
4849 source type <t1> can be inferred.
4851 Functions with a group suffix are unpredicated. */
4852 struct unary_convertxn_narrow_def
: public unary_convert_def
4855 explicit_group_suffix_p () const override
4861 build (function_builder
&b
, const function_group_info
&group
) const override
4863 b
.add_overloaded_functions (group
, MODE_none
);
4864 build_all (b
, "v0,t1", group
, MODE_none
);
4868 resolve (function_resolver
&r
) const override
4870 gcc_assert(r
.fpm_mode
== FPM_set
);
4872 if (!r
.check_num_arguments (2)
4873 || !(type
= r
.infer_sve_type (0))
4874 || !r
.require_scalar_type (1, "uint64_t"))
4875 return error_mark_node
;
4877 return r
.resolve_to (r
.mode_suffix_id
, type
);
4880 SHAPE (unary_convertxn_narrow
)
4882 /* sv<t0>_t svfoo_<t0>(sv<t0>_t, uint64_t)
4884 where the final argument is an integer constant expression in the
4885 range [0, 16 / sizeof (<t0>_t) - 1]. */
4886 struct unary_lane_def
: public overloaded_base
<0>
4889 build (function_builder
&b
, const function_group_info
&group
) const override
4891 b
.add_overloaded_functions (group
, MODE_none
);
4892 build_all (b
, "v0,v0,su64", group
, MODE_none
);
4896 resolve (function_resolver
&r
) const override
4898 return r
.resolve_uniform (1, 1);
4902 check (function_checker
&c
) const override
4904 return c
.require_immediate_lane_index (1, 0);
4909 /* sv<t0>_t svfoo[_t0](sv<t0:half>_t). */
4910 struct unary_long_def
: public overloaded_base
<0>
4913 build (function_builder
&b
, const function_group_info
&group
) const override
4915 b
.add_overloaded_functions (group
, MODE_none
);
4916 build_all (b
, "v0,vh0", group
, MODE_none
);
4920 resolve (function_resolver
&r
) const override
4922 unsigned int i
, nargs
;
4923 type_suffix_index type
, result_type
;
4924 if (!r
.check_gp_argument (1, i
, nargs
)
4925 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
4926 || (result_type
= long_type_suffix (r
, type
)) == NUM_TYPE_SUFFIXES
)
4927 return error_mark_node
;
4929 if (tree res
= r
.lookup_form (r
.mode_suffix_id
, result_type
))
4932 return r
.report_no_such_form (type
);
4937 /* sv<t0>_t svfoo[_n]_t0(<t0>_t). */
4938 struct unary_n_def
: public overloaded_base
<1>
4941 build (function_builder
&b
, const function_group_info
&group
) const override
4943 /* The "_n" suffix is optional; the full name has it, but the short
4945 build_all (b
, "v0,s0", group
, MODE_n
, true);
4949 resolve (function_resolver
&) const override
4951 /* The short forms just make "_n" implicit, so no resolution is needed. */
4957 /* sv<t0:half>_t svfoo[_t0](sv<t0>_t). */
4958 typedef unary_narrowb_base
<> unary_narrowb_def
;
4959 SHAPE (unary_narrowb
)
4961 /* sv<t0:half>_t svfoo[_t0](sv<t0:half>_t, sv<t0>_t). */
4962 typedef unary_narrowt_base
<> unary_narrowt_def
;
4963 SHAPE (unary_narrowt
)
4965 /* sv<t0:uint:half>_t svfoo[_t0](sv<t0>_t). */
4966 typedef unary_narrowb_base
<TYPE_unsigned
> unary_narrowb_to_uint_def
;
4967 SHAPE (unary_narrowb_to_uint
)
4969 /* sv<t0:uint:half>_t svfoo[_t0](sv<t0:uint:half>_t, sv<t0>_t). */
4970 typedef unary_narrowt_base
<TYPE_unsigned
> unary_narrowt_to_uint_def
;
4971 SHAPE (unary_narrowt_to_uint
)
4973 /* svbool_t svfoo(svbool_t). */
4974 struct unary_pred_def
: public nonoverloaded_base
4977 build (function_builder
&b
, const function_group_info
&group
) const override
4979 build_all (b
, "v0,v0", group
, MODE_none
);
4984 /* sv<t0:int>_t svfoo[_t0](sv<t0>_t)
4986 i.e. a version of "unary" in which the returned vector contains
4988 struct unary_to_int_def
: public overloaded_base
<0>
4991 build (function_builder
&b
, const function_group_info
&group
) const override
4993 b
.add_overloaded_functions (group
, MODE_none
);
4994 build_all (b
, "vs0,v0", group
, MODE_none
);
4998 resolve (function_resolver
&r
) const override
5000 return r
.resolve_unary (TYPE_signed
);
5003 SHAPE (unary_to_int
)
5005 /* sv<t0:uint>_t svfoo[_t0](sv<t0>_t)
5007 i.e. a version of "unary" in which the returned vector contains
5008 unsigned integers. */
5009 struct unary_to_uint_def
: public overloaded_base
<0>
5012 build (function_builder
&b
, const function_group_info
&group
) const override
5014 b
.add_overloaded_functions (group
, MODE_none
);
5015 build_all (b
, "vu0,v0", group
, MODE_none
);
5019 resolve (function_resolver
&r
) const override
5021 return r
.resolve_unary (TYPE_unsigned
);
5024 SHAPE (unary_to_uint
)
5026 /* sv<t0>_t svfoo[_t0](sv<t0:uint>_t)
5028 where <t0> always belongs a certain type class, and where <t0:uint>
5029 therefore uniquely determines <t0>. */
5030 struct unary_uint_def
: public overloaded_base
<0>
5033 build (function_builder
&b
, const function_group_info
&group
) const override
5035 b
.add_overloaded_functions (group
, MODE_none
);
5036 build_all (b
, "v0,vu0", group
, MODE_none
);
5040 resolve (function_resolver
&r
) const override
5042 unsigned int i
, nargs
;
5043 type_suffix_index type
;
5044 if (!r
.check_gp_argument (1, i
, nargs
)
5045 || (type
= r
.infer_unsigned_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
5046 return error_mark_node
;
5048 /* Search for a valid suffix with the same number of bits as TYPE. */
5049 unsigned int element_bits
= type_suffixes
[type
].element_bits
;
5050 if (type_suffixes
[type
].unsigned_p
)
5051 for (unsigned int j
= 0; j
< NUM_TYPE_SUFFIXES
; ++j
)
5052 if (type_suffixes
[j
].element_bits
== element_bits
)
5053 if (tree res
= r
.lookup_form (r
.mode_suffix_id
,
5054 type_suffix_index (j
)))
5057 return r
.report_no_such_form (type
);
5062 /* sv<t0>_t svfoo[_<t0>](sv<t0:half>_t)
5064 i.e. a version of "unary" in which the source elements are half the
5065 size of the destination elements, but have the same type class. */
5066 struct unary_widen_def
: public overloaded_base
<0>
5069 build (function_builder
&b
, const function_group_info
&group
) const override
5071 b
.add_overloaded_functions (group
, MODE_none
);
5072 build_all (b
, "v0,vh0", group
, MODE_none
);
5076 resolve (function_resolver
&r
) const override
5078 unsigned int i
, nargs
;
5079 type_suffix_index type
;
5080 if (!r
.check_gp_argument (1, i
, nargs
)
5081 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
5082 return error_mark_node
;
5084 /* There is only a single form for predicates. */
5085 if (type
== TYPE_SUFFIX_b
)
5086 return r
.resolve_to (r
.mode_suffix_id
, type
);
5088 if (type_suffixes
[type
].integer_p
5089 && type_suffixes
[type
].element_bits
< 64)
5091 type_suffix_index wide_suffix
5092 = find_type_suffix (type_suffixes
[type
].tclass
,
5093 type_suffixes
[type
].element_bits
* 2);
5094 if (tree res
= r
.lookup_form (r
.mode_suffix_id
, wide_suffix
))
5098 return r
.report_no_such_form (type
);
5103 /* void svfoo_t0[_t1](uint64_t, svbool_t, svbool_t, sv<t1>_t)
5105 where the first argument is a ZA tile. */
5106 struct unary_za_m_def
: public overloaded_base
<1>
5109 build (function_builder
&b
, const function_group_info
&group
) const override
5111 b
.add_overloaded_functions (group
, MODE_none
);
5112 build_all (b
, "_,su64,vp,vp,t1", group
, MODE_none
);
5116 resolve (function_resolver
&r
) const override
5118 type_suffix_index type
;
5119 if (!r
.check_num_arguments (4)
5120 || !r
.require_integer_immediate (0)
5121 || !r
.require_vector_type (1, VECTOR_TYPE_svbool_t
)
5122 || !r
.require_vector_type (2, VECTOR_TYPE_svbool_t
)
5123 || (type
= r
.infer_vector_type (3)) == NUM_TYPE_SUFFIXES
)
5124 return error_mark_node
;
5126 return r
.resolve_to (r
.mode_suffix_id
, r
.type_suffix_ids
[0], type
);
5130 check (function_checker
&c
) const override
5132 return c
.require_immediate_range (0, 0, c
.num_za_tiles () - 1);
5137 /* void svfoo_t0[_t1]_g(uint32_t, sv<t1>x<g>_t). */
5138 struct unary_za_slice_def
: public overloaded_base
<1>
5141 build (function_builder
&b
, const function_group_info
&group
) const override
5143 b
.add_overloaded_functions (group
, MODE_none
);
5144 if (!za_group_is_pure_overload (group
))
5145 build_all (b
, "_,su32,t1", group
, MODE_none
);
5149 resolve (function_resolver
&r
) const override
5152 if (!r
.check_num_arguments (2)
5153 || !r
.require_scalar_type (0, "uint32_t")
5154 || !(type
= r
.infer_tuple_type (1)))
5155 return error_mark_node
;
5157 return r
.resolve_to (r
.mode_suffix_id
, type
);
5160 SHAPE (unary_za_slice
)
5162 /* sv<t0>x<g>_t svfoo[_t0_g](sv<t0>x<g>_t). */
5163 struct unaryxn_def
: public unary_def
5165 bool explicit_group_suffix_p () const override
{ return false; }
5168 resolve (function_resolver
&r
) const override
5170 if (r
.pred
!= PRED_none
)
5171 return unary_def::resolve (r
);
5174 if (!r
.check_num_arguments (1)
5175 || !(type
= r
.infer_sve_type (0)))
5176 return error_mark_node
;
5178 return r
.resolve_to (r
.mode_suffix_id
, type
);
5183 /* void svfoo_t0[_t1_g](uint64_t, uint32_t, sv<t1>x<g>_t). */
5184 struct write_za_def
: public overloaded_base
<1>
5187 build (function_builder
&b
, const function_group_info
&group
) const override
5189 b
.add_overloaded_functions (group
, MODE_none
);
5190 build_all (b
, "_,su64,su32,t1", group
, MODE_none
);
5194 resolve (function_resolver
&r
) const override
5197 if (!r
.check_num_arguments (3)
5198 || !r
.require_integer_immediate (0)
5199 || !r
.require_scalar_type (1, "uint32_t")
5200 || !(type
= r
.infer_tuple_type (2)))
5201 return error_mark_node
;
5203 return r
.resolve_to (r
.mode_suffix_id
, type
);
5207 check (function_checker
&c
) const override
5209 return c
.require_immediate_range (0, 0, c
.num_za_tiles () - 1);
5214 /* void svfoo_t0[_t1](uint64_t, uint32_t, svbool_t, sv<t1>_t)
5216 where the first two fields form a (ZA tile, slice) pair. */
5217 struct write_za_m_def
: public overloaded_base
<1>
5220 build (function_builder
&b
, const function_group_info
&group
) const override
5222 b
.add_overloaded_functions (group
, MODE_none
);
5223 build_all (b
, "_,su64,su32,vp,t1", group
, MODE_none
);
5227 resolve (function_resolver
&r
) const override
5229 type_suffix_index type
;
5230 if (!r
.check_num_arguments (4)
5231 || !r
.require_integer_immediate (0)
5232 || !r
.require_scalar_type (1, "uint32_t")
5233 || !r
.require_vector_type (2, VECTOR_TYPE_svbool_t
)
5234 || (type
= r
.infer_vector_type (3)) == NUM_TYPE_SUFFIXES
)
5235 return error_mark_node
;
5237 return r
.resolve_to (r
.mode_suffix_id
, r
.type_suffix_ids
[0], type
);
5241 check (function_checker
&c
) const override
5243 return c
.require_immediate_range (0, 0, c
.num_za_tiles () - 1);
5248 /* void svfoo_t0[_t1_g](uint32_t, sv<t1>x<g>_t). */
5249 struct write_za_slice_def
: public overloaded_base
<1>
5252 build (function_builder
&b
, const function_group_info
&group
) const override
5254 b
.add_overloaded_functions (group
, MODE_none
);
5255 build_all (b
, "_,su32,t1", group
, MODE_none
);
5259 resolve (function_resolver
&r
) const override
5262 if (!r
.check_num_arguments (2)
5263 || !r
.require_scalar_type (0, "uint32_t")
5264 || !(type
= r
.infer_tuple_type (1)))
5265 return error_mark_node
;
5267 return r
.resolve_to (r
.mode_suffix_id
, type
);
5270 SHAPE (write_za_slice
)