1 /* ACLE support for AArch64 SVE (function shapes)
2 Copyright (C) 2018-2024 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>
99 p - a predicate (represented as TYPE_SUFFIX_b)
100 q<elt> - a quarter-sized version of <elt>
101 s<bits> - a signed type with the given number of bits
102 s[01] - a signed type with the same width as type suffix 0 or 1
103 u<bits> - an unsigned type with the given number of bits
104 u[01] - an unsigned type with the same width as type suffix 0 or 1
105 w<elt> - a 64-bit version of <elt> if <elt> is integral, otherwise <elt>
107 where <elt> is another element type. */
108 static type_suffix_index
109 parse_element_type (const function_instance
&instance
, const char *&format
)
113 if (ch
== 'f' || ch
== 's' || ch
== 'u')
115 type_class_index tclass
= (ch
== 'f' ? TYPE_float
116 : ch
== 's' ? TYPE_signed
119 unsigned int bits
= strtol (format
, &end
, 10);
121 if (bits
== 0 || bits
== 1)
122 bits
= instance
.type_suffix (bits
).element_bits
;
123 return find_type_suffix (tclass
, bits
);
128 type_suffix_index suffix
= parse_element_type (instance
, format
);
129 if (type_suffixes
[suffix
].integer_p
)
130 return find_type_suffix (type_suffixes
[suffix
].tclass
, 64);
135 return TYPE_SUFFIX_c
;
138 return TYPE_SUFFIX_b
;
141 return TYPE_SUFFIX_bf16
;
145 type_suffix_index suffix
= parse_element_type (instance
, format
);
146 return find_type_suffix (type_suffixes
[suffix
].tclass
,
147 type_suffixes
[suffix
].element_bits
/ 4);
152 type_suffix_index suffix
= parse_element_type (instance
, format
);
153 /* Widening and narrowing doesn't change the type for predicates;
154 everything's still an svbool_t. */
155 if (suffix
== TYPE_SUFFIX_b
)
157 return find_type_suffix (type_suffixes
[suffix
].tclass
,
158 type_suffixes
[suffix
].element_bits
/ 2);
161 if (ch
== '0' || ch
== '1')
162 return instance
.type_suffix_ids
[ch
- '0'];
167 /* Read and return a type from FORMAT for function INSTANCE. Advance
168 FORMAT beyond the type string. The format is:
171 al - array pointer for loads
172 ap - array pointer for prefetches
173 as - array pointer for stores
174 b - base vector type (from a _<m0>base suffix)
175 c0 - the result of a conversion, based on type and group suffixes
176 c1 - the source of a conversion, based on type and group suffixes
177 d - displacement vector type (from a _<m1>index or _<m1>offset suffix)
178 e<name> - an enum with the given name
179 s<elt> - a scalar type with the given element suffix
180 t<elt> - a vector or tuple type with given element suffix [*1]
181 v<elt> - a vector with the given element suffix
182 D<elt> - a 64 bit neon vector
183 Q<elt> - a 128 bit neon vector
185 where <elt> has the format described above parse_element_type
187 [*1] the vectors_per_tuple function indicates whether the type should
188 be a tuple, and if so, how many vectors it should contain. */
190 parse_type (const function_instance
&instance
, const char *&format
)
195 return void_type_node
;
201 return build_const_pointer (instance
.memory_scalar_type ());
203 return const_ptr_type_node
;
205 return build_pointer_type (instance
.memory_scalar_type ());
210 return instance
.base_vector_type ();
215 gcc_assert (ch
== '0' || ch
== '1');
216 unsigned int id
= (ch
== '0' ? 0 : 1);
217 auto vector_type
= instance
.type_suffix (id
).vector_type
;
218 unsigned int num_vectors
= instance
.group_suffix ().vectors_per_tuple
;
219 if (num_vectors
!= 1)
221 unsigned int bits
= instance
.type_suffix (id
).element_bits
;
222 unsigned int other_bits
= instance
.type_suffix (1 - id
).element_bits
;
223 if (other_bits
> bits
)
224 num_vectors
/= other_bits
/ bits
;
226 return acle_vector_types
[num_vectors
- 1][vector_type
];
230 return instance
.displacement_vector_type ();
234 if (startswith (format
, "pattern"))
237 return acle_svpattern
;
239 if (startswith (format
, "prfop"))
249 type_suffix_index suffix
= parse_element_type (instance
, format
);
250 return scalar_types
[type_suffixes
[suffix
].vector_type
];
255 type_suffix_index suffix
= parse_element_type (instance
, format
);
256 vector_type_index vector_type
= type_suffixes
[suffix
].vector_type
;
257 unsigned int num_vectors
= instance
.vectors_per_tuple ();
258 return acle_vector_types
[num_vectors
- 1][vector_type
];
263 type_suffix_index suffix
= parse_element_type (instance
, format
);
264 return acle_vector_types
[0][type_suffixes
[suffix
].vector_type
];
269 type_suffix_index suffix
= parse_element_type (instance
, format
);
270 int neon_index
= type_suffixes
[suffix
].neon64_type
;
271 return aarch64_simd_types
[neon_index
].itype
;
276 type_suffix_index suffix
= parse_element_type (instance
, format
);
277 int neon_index
= type_suffixes
[suffix
].neon128_type
;
278 return aarch64_simd_types
[neon_index
].itype
;
284 /* Read and move past any argument count at FORMAT for the function
285 signature of INSTANCE. The counts are:
287 *q: one argument per element in a 128-bit quadword (as for svdupq)
288 *t: one argument per vector in a tuple (as for svcreate)
290 Otherwise the count is 1. */
292 parse_count (const function_instance
&instance
, const char *&format
)
294 if (format
[0] == '*' && format
[1] == 'q')
297 return instance
.elements_per_vq (0);
299 if (format
[0] == '*' && format
[1] == 't')
302 return instance
.vectors_per_tuple ();
307 /* Read a type signature for INSTANCE from FORMAT. Add the argument types
308 to ARGUMENT_TYPES and return the return type.
310 The format is a comma-separated list of types (as for parse_type),
311 with the first type being the return type and the rest being the
312 argument types. Each argument type can be followed by an optional
313 count (as for parse_count). */
315 parse_signature (const function_instance
&instance
, const char *format
,
316 vec
<tree
> &argument_types
)
318 tree return_type
= parse_type (instance
, format
);
319 while (format
[0] == ',')
322 tree argument_type
= parse_type (instance
, format
);
323 unsigned int count
= parse_count (instance
, format
);
324 for (unsigned int i
= 0; i
< count
; ++i
)
325 argument_types
.quick_push (argument_type
);
327 gcc_assert (format
[0] == 0);
331 /* Add one function instance for GROUP, using mode suffix MODE_SUFFIX_ID,
332 the type suffixes at index TI, the group suffixes at index GI, and the
333 predication suffix at index PI. The other arguments are as for
336 build_one (function_builder
&b
, const char *signature
,
337 const function_group_info
&group
, mode_suffix_index mode_suffix_id
,
338 unsigned int ti
, unsigned int gi
, unsigned int pi
,
339 bool force_direct_overloads
)
341 /* For simplicity, function definitions are allowed to use the group
342 suffix lists vg2 and vg4 for shapes that have _single forms,
343 even though the _single form applies only to vgNx2 and vgNx4,
345 if (mode_suffix_id
== MODE_single
346 && group_suffixes
[group
.groups
[gi
]].vectors_per_tuple
== 1)
349 /* Byte forms of svdupq take 16 arguments. */
350 auto_vec
<tree
, 16> argument_types
;
351 function_instance
instance (group
.base_name
, *group
.base
, *group
.shape
,
352 mode_suffix_id
, group
.types
[ti
],
353 group
.groups
[gi
], group
.preds
[pi
]);
354 tree return_type
= parse_signature (instance
, signature
, argument_types
);
355 apply_predication (instance
, return_type
, argument_types
);
356 b
.add_unique_function (instance
, return_type
, argument_types
,
357 group
.required_extensions
, force_direct_overloads
);
360 /* GROUP describes some sort of gather or scatter operation. There are
363 - If the function has any type suffixes (as for loads and stores), the
364 first function type suffix specifies either a 32-bit or a 64-bit type,
365 which in turn selects either MODE32 or MODE64 as the addressing mode.
366 Add a function instance for every type and predicate combination
367 in GROUP for which the associated addressing mode is not MODE_none.
369 - If the function has no type suffixes (as for prefetches), add one
370 MODE32 form and one MODE64 form for each predication type.
372 The other arguments are as for build_all. */
374 build_32_64 (function_builder
&b
, const char *signature
,
375 const function_group_info
&group
, mode_suffix_index mode32
,
376 mode_suffix_index mode64
, bool force_direct_overloads
= false)
378 for (unsigned int pi
= 0; group
.preds
[pi
] != NUM_PREDS
; ++pi
)
379 for (unsigned int gi
= 0; group
.groups
[gi
] != NUM_GROUP_SUFFIXES
; ++gi
)
380 if (group
.types
[0][0] == NUM_TYPE_SUFFIXES
)
382 gcc_assert (mode32
!= MODE_none
&& mode64
!= MODE_none
);
383 build_one (b
, signature
, group
, mode32
, 0, gi
, pi
,
384 force_direct_overloads
);
385 build_one (b
, signature
, group
, mode64
, 0, gi
, pi
,
386 force_direct_overloads
);
389 for (unsigned int ti
= 0; group
.types
[ti
][0] != NUM_TYPE_SUFFIXES
;
392 unsigned int bits
= type_suffixes
[group
.types
[ti
][0]].element_bits
;
393 gcc_assert (bits
== 32 || bits
== 64);
394 mode_suffix_index mode
= bits
== 32 ? mode32
: mode64
;
395 if (mode
!= MODE_none
)
396 build_one (b
, signature
, group
, mode
, ti
, gi
, pi
,
397 force_direct_overloads
);
401 /* For every type and predicate combination in GROUP, add one function
402 that takes a scalar (pointer) base and a signed vector array index,
403 and another that instead takes an unsigned vector array index.
404 The vector array index has the same element size as the first
405 function type suffix. SIGNATURE is as for build_all. */
407 build_sv_index (function_builder
&b
, const char *signature
,
408 const function_group_info
&group
)
410 build_32_64 (b
, signature
, group
, MODE_s32index
, MODE_s64index
);
411 build_32_64 (b
, signature
, group
, MODE_u32index
, MODE_u64index
);
414 /* Like build_sv_index, but only handle 64-bit types. */
416 build_sv_index64 (function_builder
&b
, const char *signature
,
417 const function_group_info
&group
)
419 build_32_64 (b
, signature
, group
, MODE_none
, MODE_s64index
);
420 build_32_64 (b
, signature
, group
, MODE_none
, MODE_u64index
);
423 /* Like build_sv_index, but taking vector byte offsets instead of vector
426 build_sv_offset (function_builder
&b
, const char *signature
,
427 const function_group_info
&group
)
429 build_32_64 (b
, signature
, group
, MODE_s32offset
, MODE_s64offset
);
430 build_32_64 (b
, signature
, group
, MODE_u32offset
, MODE_u64offset
);
433 /* Like build_sv_offset, but exclude offsets that must be interpreted
434 as signed (i.e. s32offset). */
436 build_sv_uint_offset (function_builder
&b
, const char *signature
,
437 const function_group_info
&group
)
439 build_32_64 (b
, signature
, group
, MODE_none
, MODE_s64offset
);
440 build_32_64 (b
, signature
, group
, MODE_u32offset
, MODE_u64offset
);
443 /* For every type and predicate combination in GROUP, add a function
444 that takes a vector base address and no displacement. The vector
445 base has the same element size as the first type suffix.
447 The other arguments are as for build_all. */
449 build_v_base (function_builder
&b
, const char *signature
,
450 const function_group_info
&group
,
451 bool force_direct_overloads
= false)
453 build_32_64 (b
, signature
, group
, MODE_u32base
, MODE_u64base
,
454 force_direct_overloads
);
457 /* Like build_v_base, but for functions that also take a scalar array
460 build_vs_index (function_builder
&b
, const char *signature
,
461 const function_group_info
&group
,
462 bool force_direct_overloads
= false)
464 build_32_64 (b
, signature
, group
, MODE_u32base_index
, MODE_u64base_index
,
465 force_direct_overloads
);
468 /* Like build_v_base, but for functions that also take a scalar byte
471 build_vs_offset (function_builder
&b
, const char *signature
,
472 const function_group_info
&group
,
473 bool force_direct_overloads
= false)
475 build_32_64 (b
, signature
, group
, MODE_u32base_offset
, MODE_u64base_offset
,
476 force_direct_overloads
);
479 /* Add a function instance for every type and predicate combination
480 in GROUP. Take the function base name from GROUP and the mode suffix
481 from MODE_SUFFIX_ID. Use SIGNATURE to construct the function signature
482 without a governing predicate, then use apply_predication to add in the
483 predicate. FORCE_DIRECT_OVERLOADS is true if there is a one-to-one
484 mapping between "short" and "full" names, and if standard overload
485 resolution therefore isn't necessary. */
487 build_all (function_builder
&b
, const char *signature
,
488 const function_group_info
&group
, mode_suffix_index mode_suffix_id
,
489 bool force_direct_overloads
= false)
491 for (unsigned int pi
= 0; group
.preds
[pi
] != NUM_PREDS
; ++pi
)
492 for (unsigned int gi
= 0; group
.groups
[gi
] != NUM_GROUP_SUFFIXES
; ++gi
)
493 for (unsigned int ti
= 0;
494 ti
== 0 || group
.types
[ti
][0] != NUM_TYPE_SUFFIXES
; ++ti
)
495 build_one (b
, signature
, group
, mode_suffix_id
, ti
, gi
, pi
,
496 force_direct_overloads
);
499 /* TYPE is the largest type suffix associated with the arguments of R,
500 but the result is twice as wide. Return the associated type suffix
501 if it exists, otherwise report an appropriate error and return
502 NUM_TYPE_SUFFIXES. */
503 static type_suffix_index
504 long_type_suffix (function_resolver
&r
, type_suffix_index type
)
506 unsigned int element_bits
= type_suffixes
[type
].element_bits
;
507 if (type_suffixes
[type
].integer_p
&& element_bits
< 64)
508 return find_type_suffix (type_suffixes
[type
].tclass
, element_bits
* 2);
510 r
.report_no_such_form (type
);
511 return NUM_TYPE_SUFFIXES
;
514 /* Declare the function shape NAME, pointing it to an instance
515 of class <NAME>_def. */
516 #define SHAPE(NAME) \
517 static CONSTEXPR const NAME##_def NAME##_obj; \
518 namespace shapes { const function_shape *const NAME = &NAME##_obj; }
520 /* Base class for functions that are not overloaded. */
521 struct nonoverloaded_base
: public function_shape
524 explicit_type_suffix_p (unsigned int) const override
530 resolve (function_resolver
&) const override
536 /* Base class for overloaded functions. Bit N of EXPLICIT_MASK is true
537 if type suffix N appears in the overloaded name. */
538 template<unsigned int EXPLICIT_MASK
>
539 struct overloaded_base
: public function_shape
542 explicit_type_suffix_p (unsigned int i
) const override
544 return (EXPLICIT_MASK
>> i
) & 1;
548 /* Base class for adr_index and adr_offset. */
549 struct adr_base
: public overloaded_base
<0>
551 /* The function takes two arguments: a vector base and a vector displacement
552 (either an index or an offset). Resolve based on them both. */
554 resolve (function_resolver
&r
) const override
556 unsigned int i
, nargs
;
557 mode_suffix_index mode
;
558 if (!r
.check_gp_argument (2, i
, nargs
)
559 || (mode
= r
.resolve_adr_address (0)) == MODE_none
)
560 return error_mark_node
;
562 return r
.resolve_to (mode
);
566 /* Base class for narrowing bottom binary functions that take an
567 immediate second operand. The result is half the size of input
568 and has class CLASS. */
569 template<type_class_index CLASS
= function_resolver::SAME_TYPE_CLASS
>
570 struct binary_imm_narrowb_base
: public overloaded_base
<0>
573 build (function_builder
&b
, const function_group_info
&group
) const override
575 b
.add_overloaded_functions (group
, MODE_n
);
576 STATIC_ASSERT (CLASS
== function_resolver::SAME_TYPE_CLASS
577 || CLASS
== TYPE_unsigned
);
578 if (CLASS
== TYPE_unsigned
)
579 build_all (b
, "vhu0,v0,su64", group
, MODE_n
);
581 build_all (b
, "vh0,v0,su64", group
, MODE_n
);
585 resolve (function_resolver
&r
) const override
587 return r
.resolve_uniform (1, 1);
591 /* The top equivalent of binary_imm_narrowb_base. It takes three arguments,
592 with the first being the values of the even elements, which are typically
593 the result of the narrowb operation. */
594 template<type_class_index CLASS
= function_resolver::SAME_TYPE_CLASS
>
595 struct binary_imm_narrowt_base
: public overloaded_base
<0>
598 build (function_builder
&b
, const function_group_info
&group
) const override
600 b
.add_overloaded_functions (group
, MODE_n
);
601 STATIC_ASSERT (CLASS
== function_resolver::SAME_TYPE_CLASS
602 || CLASS
== TYPE_unsigned
);
603 if (CLASS
== TYPE_unsigned
)
604 build_all (b
, "vhu0,vhu0,v0,su64", group
, MODE_n
);
606 build_all (b
, "vh0,vh0,v0,su64", group
, MODE_n
);
610 resolve (function_resolver
&r
) const override
612 unsigned int i
, nargs
;
613 type_suffix_index type
;
614 if (!r
.check_gp_argument (3, i
, nargs
)
615 || (type
= r
.infer_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
616 || !r
.require_derived_vector_type (i
, i
+ 1, type
, CLASS
, r
.HALF_SIZE
)
617 || !r
.require_integer_immediate (i
+ 2))
618 return error_mark_node
;
620 return r
.resolve_to (r
.mode_suffix_id
, type
);
624 /* Base class for long (i.e. narrow op narrow -> wide) binary functions
625 that take an immediate second operand. The type suffix specifies
627 struct binary_imm_long_base
: public overloaded_base
<0>
630 build (function_builder
&b
, const function_group_info
&group
) const override
632 b
.add_overloaded_functions (group
, MODE_n
);
633 build_all (b
, "v0,vh0,su64", group
, MODE_n
);
637 resolve (function_resolver
&r
) const override
639 unsigned int i
, nargs
;
640 type_suffix_index type
, result_type
;
641 if (!r
.check_gp_argument (2, i
, nargs
)
642 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
643 || !r
.require_integer_immediate (i
+ 1)
644 || (result_type
= long_type_suffix (r
, type
)) == NUM_TYPE_SUFFIXES
)
645 return error_mark_node
;
647 if (tree res
= r
.lookup_form (r
.mode_suffix_id
, result_type
))
650 return r
.report_no_such_form (type
);
654 /* Base class for binary_za_m and similar shapes. */
655 template<type_class_index TCLASS
= function_resolver::SAME_TYPE_CLASS
,
656 unsigned int BITS
= function_resolver::SAME_SIZE
>
657 struct binary_za_m_base
: public overloaded_base
<1>
660 resolve (function_resolver
&r
) const override
662 type_suffix_index type
;
663 if (!r
.check_num_arguments (5)
664 || !r
.require_integer_immediate (0)
665 || !r
.require_vector_type (1, VECTOR_TYPE_svbool_t
)
666 || !r
.require_vector_type (2, VECTOR_TYPE_svbool_t
)
667 || (type
= r
.infer_vector_type (3)) == NUM_TYPE_SUFFIXES
668 || !r
.require_derived_vector_type (4, 3, type
, TCLASS
, BITS
))
669 return error_mark_node
;
671 return r
.resolve_to (r
.mode_suffix_id
, r
.type_suffix_ids
[0], type
);
675 check (function_checker
&c
) const override
677 return c
.require_immediate_range (0, 0, c
.num_za_tiles () - 1);
681 /* Base class for shapes like binary_za_slice_lane. TCLASS is the type
682 class of the final vector argument. */
683 template<type_class_index TCLASS
= function_resolver::SAME_TYPE_CLASS
>
684 struct binary_za_slice_lane_base
: public overloaded_base
<1>
686 constexpr binary_za_slice_lane_base (unsigned int lane_type_suffix
)
687 : m_lane_type_suffix (lane_type_suffix
) {}
690 build (function_builder
&b
, const function_group_info
&group
) const override
692 b
.add_overloaded_functions (group
, MODE_none
);
693 build_all (b
, "_,su32,t1,v1,su64", group
, MODE_none
);
697 resolve (function_resolver
&r
) const override
700 if (!r
.check_num_arguments (4)
701 || !r
.require_scalar_type (0, "uint32_t")
702 || !(type
= r
.infer_tuple_type (1))
703 || !r
.require_derived_vector_type (2, 1, type
, TCLASS
)
704 || !r
.require_integer_immediate (3))
705 return error_mark_node
;
707 return r
.resolve_to (r
.mode_suffix_id
, type
);
711 check (function_checker
&c
) const override
713 unsigned int bytes
= c
.type_suffix (m_lane_type_suffix
).element_bytes
;
714 return c
.require_immediate_range (3, 0, 16 / bytes
- 1);
717 unsigned int m_lane_type_suffix
;
720 /* Base class for shapes like binary_za_slice_opt_single. TCLASS is the
721 type class of the final argument. */
722 template<type_class_index TCLASS
= function_resolver::SAME_TYPE_CLASS
>
723 struct binary_za_slice_opt_single_base
: public overloaded_base
<1>
726 resolve (function_resolver
&r
) const override
729 if (!r
.check_num_arguments (3)
730 || !r
.require_scalar_type (0, "uint32_t")
731 || !(type
= r
.infer_tuple_type (1)))
732 return error_mark_node
;
734 return r
.finish_opt_single_resolution (2, 1, type
, TCLASS
);
738 /* Base class for inc_dec and inc_dec_pat. */
739 struct inc_dec_base
: public overloaded_base
<0>
741 CONSTEXPR
inc_dec_base (bool pat_p
) : m_pat_p (pat_p
) {}
743 /* Resolve based on the first argument only, which must be either a
744 scalar or a vector. If it's a scalar, it must be a 32-bit or
747 resolve (function_resolver
&r
) const
749 unsigned int i
, nargs
;
750 if (!r
.check_gp_argument (m_pat_p
? 3 : 2, i
, nargs
)
751 || !r
.require_vector_or_scalar_type (i
))
752 return error_mark_node
;
754 mode_suffix_index mode
;
755 type_suffix_index type
;
756 if (r
.scalar_argument_p (i
))
759 type
= r
.infer_integer_scalar_type (i
);
764 type
= r
.infer_vector_type (i
);
766 if (type
== NUM_TYPE_SUFFIXES
)
767 return error_mark_node
;
769 for (++i
; i
< nargs
; ++i
)
770 if (!r
.require_integer_immediate (i
))
771 return error_mark_node
;
773 return r
.resolve_to (mode
, type
);
777 check (function_checker
&c
) const override
779 return c
.require_immediate_range (m_pat_p
? 2 : 1, 1, 16);
785 /* Base class for load and load_replicate. */
786 struct load_contiguous_base
: public overloaded_base
<0>
788 /* Resolve a call based purely on a pointer argument. The other arguments
789 are a governing predicate and (for MODE_vnum) a vnum offset. */
791 resolve (function_resolver
&r
) const override
793 bool vnum_p
= r
.mode_suffix_id
== MODE_vnum
;
794 gcc_assert (r
.mode_suffix_id
== MODE_none
|| vnum_p
);
796 unsigned int i
, nargs
;
797 type_suffix_index type
;
798 if (!r
.check_gp_argument (vnum_p
? 2 : 1, i
, nargs
)
799 || (type
= r
.infer_pointer_type (i
)) == NUM_TYPE_SUFFIXES
800 || (vnum_p
&& !r
.require_scalar_type (i
+ 1, "int64_t")))
801 return error_mark_node
;
803 return r
.resolve_to (r
.mode_suffix_id
, type
, NUM_TYPE_SUFFIXES
,
808 /* Base class for gather loads that take a scalar base and a vector
809 displacement (either an offset or an index). */
810 struct load_gather_sv_base
: public overloaded_base
<0>
813 resolve (function_resolver
&r
) const override
815 unsigned int i
, nargs
;
816 mode_suffix_index mode
;
817 type_suffix_index type
;
818 if (!r
.check_gp_argument (2, i
, nargs
)
819 || (type
= r
.infer_pointer_type (i
, true)) == NUM_TYPE_SUFFIXES
820 || (mode
= r
.resolve_sv_displacement (i
+ 1, type
, true),
822 return error_mark_node
;
824 return r
.resolve_to (mode
, type
);
828 /* Base class for load_ext_gather_index and load_ext_gather_offset,
829 which differ only in the units of the displacement. */
830 struct load_ext_gather_base
: public overloaded_base
<1>
832 /* Resolve a gather load that takes one of:
834 - a scalar pointer base and a vector displacement
835 - a vector base with no displacement or
836 - a vector base and a scalar displacement
838 The function has an explicit type suffix that determines the type
839 of the loaded data. */
841 resolve (function_resolver
&r
) const override
843 /* No resolution is needed for a vector base with no displacement;
844 there's a one-to-one mapping between short and long names. */
845 gcc_assert (r
.displacement_units () != UNITS_none
);
847 type_suffix_index type
= r
.type_suffix_ids
[0];
849 unsigned int i
, nargs
;
850 mode_suffix_index mode
;
851 if (!r
.check_gp_argument (2, i
, nargs
)
852 || (mode
= r
.resolve_gather_address (i
, type
, true)) == MODE_none
)
853 return error_mark_node
;
855 return r
.resolve_to (mode
, type
);
859 /* sv<t0>x<g>_t svfoo_t0_g(uint64_t, svuint8_t, uint64_t)
861 where the first argument is the ZT register number (currently always 0)
862 and the final argument is a constant index. The instruction divides
863 the vector argument in BITS-bit quantities. */
864 template<unsigned int BITS
>
865 struct luti_lane_zt_base
: public nonoverloaded_base
868 build (function_builder
&b
, const function_group_info
&group
) const override
870 build_all (b
, "t0,su64,vu8,su64", group
, MODE_none
);
874 check (function_checker
&c
) const override
876 auto nvectors
= c
.vectors_per_tuple ();
877 return (c
.require_immediate_range (0, 0, 0)
878 && c
.require_immediate_range (2, 0, 32 / BITS
/ nvectors
- 1));
882 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:quarter>_t,
883 sv<t0:quarter>_t) (for integer t0)
884 sv<t0>_t svmmla[_t0](sv<t0>_t, sv<t0>_t, sv<t0>_t) (for floating-point t0)
886 The functions act like the equivalent of "ternary_qq" for integer elements
887 and normal vector-only ternary functions for floating-point elements. */
888 struct mmla_def
: public overloaded_base
<0>
891 build (function_builder
&b
, const function_group_info
&group
) const override
893 b
.add_overloaded_functions (group
, MODE_none
);
894 /* svmmla is distributed over several extensions. Allow the common
895 denominator to define the overloaded svmmla function without
896 defining any specific versions. */
897 if (group
.types
[0][0] != NUM_TYPE_SUFFIXES
)
899 if (type_suffixes
[group
.types
[0][0]].float_p
)
900 build_all (b
, "v0,v0,v0,v0", group
, MODE_none
);
902 build_all (b
, "v0,v0,vq0,vq0", group
, MODE_none
);
907 resolve (function_resolver
&r
) const override
909 unsigned int i
, nargs
;
910 type_suffix_index type
;
911 if (!r
.check_gp_argument (3, i
, nargs
)
912 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
913 return error_mark_node
;
915 /* Make sure that the function exists now, since not all forms
916 follow a set pattern after this point. */
917 tree res
= r
.resolve_to (r
.mode_suffix_id
, type
);
918 if (res
== error_mark_node
)
921 bool float_p
= type_suffixes
[type
].float_p
;
922 unsigned int modifier
= float_p
? r
.SAME_SIZE
: r
.QUARTER_SIZE
;
923 if (!r
.require_derived_vector_type (i
+ 1, i
, type
, r
.SAME_TYPE_CLASS
,
925 || !r
.require_derived_vector_type (i
+ 2, i
, type
, r
.SAME_TYPE_CLASS
,
927 return error_mark_node
;
934 /* Base class for prefetch_gather_index and prefetch_gather_offset,
935 which differ only in the units of the displacement. */
936 struct prefetch_gather_base
: public overloaded_base
<0>
938 /* Resolve a gather prefetch that takes one of:
940 - a scalar pointer base (const void *) and a vector displacement
941 - a vector base with no displacement or
942 - a vector base and a scalar displacement
944 The prefetch operation is the final argument. This is purely a
945 mode-based resolution; there are no type suffixes. */
947 resolve (function_resolver
&r
) const override
949 bool has_displacement_p
= r
.displacement_units () != UNITS_none
;
951 unsigned int i
, nargs
;
952 mode_suffix_index mode
;
953 if (!r
.check_gp_argument (has_displacement_p
? 3 : 2, i
, nargs
)
954 || (mode
= r
.resolve_gather_address (i
, NUM_TYPE_SUFFIXES
,
956 || !r
.require_integer_immediate (nargs
- 1))
957 return error_mark_node
;
959 return r
.resolve_to (mode
);
963 /* Wraps BASE to provide a narrowing shift right function. Argument N
964 is an immediate shift amount in the range [1, sizeof(<t0>_t) * 4]. */
965 template<typename BASE
, unsigned int N
>
966 struct shift_right_imm_narrow_wrapper
: public BASE
969 check (function_checker
&c
) const override
971 unsigned int bits
= c
.type_suffix (0).element_bits
/ 2;
972 return c
.require_immediate_range (N
, 1, bits
);
976 /* Base class for store_scatter_index and store_scatter_offset,
977 which differ only in the units of the displacement. */
978 struct store_scatter_base
: public overloaded_base
<0>
980 /* Resolve a scatter store that takes one of:
982 - a scalar pointer base and a vector displacement
983 - a vector base with no displacement or
984 - a vector base and a scalar displacement
986 The stored data is the final argument, and it determines the
989 resolve (function_resolver
&r
) const override
991 bool has_displacement_p
= r
.displacement_units () != UNITS_none
;
993 unsigned int i
, nargs
;
994 mode_suffix_index mode
;
995 type_suffix_index type
;
996 if (!r
.check_gp_argument (has_displacement_p
? 3 : 2, i
, nargs
)
997 || (type
= r
.infer_sd_vector_type (nargs
- 1)) == NUM_TYPE_SUFFIXES
998 || (mode
= r
.resolve_gather_address (i
, type
, false)) == MODE_none
)
999 return error_mark_node
;
1001 return r
.resolve_to (mode
, type
);
1005 /* Base class for ternary operations in which the final argument is an
1006 immediate shift amount. The derived class should check the range. */
1007 struct ternary_shift_imm_base
: public overloaded_base
<0>
1010 build (function_builder
&b
, const function_group_info
&group
) const override
1012 b
.add_overloaded_functions (group
, MODE_n
);
1013 build_all (b
, "v0,v0,v0,su64", group
, MODE_n
);
1017 resolve (function_resolver
&r
) const override
1019 return r
.resolve_uniform (2, 1);
1023 /* Base class for ternary operations in which the first argument has the
1024 same element type as the result, and in which the second and third
1025 arguments have an element type that is derived the first.
1027 MODIFIER is the number of element bits in the second and third
1028 arguments, or a function_resolver modifier that says how this
1029 precision is derived from the first argument's elements.
1031 TYPE_CLASS2 and TYPE_CLASS3 are the type classes of the second and
1032 third arguments, or function_resolver::SAME_TYPE_CLASS if the type
1033 class is the same as the first argument. */
1034 template<unsigned int MODIFIER
,
1035 type_class_index TYPE_CLASS2
= function_resolver::SAME_TYPE_CLASS
,
1036 type_class_index TYPE_CLASS3
= function_resolver::SAME_TYPE_CLASS
>
1037 struct ternary_resize2_opt_n_base
: public overloaded_base
<0>
1040 resolve (function_resolver
&r
) const override
1042 unsigned int i
, nargs
;
1043 type_suffix_index type
;
1044 if (!r
.check_gp_argument (3, i
, nargs
)
1045 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1046 || !r
.require_derived_vector_type (i
+ 1, i
, type
, TYPE_CLASS2
,
1048 return error_mark_node
;
1050 return r
.finish_opt_n_resolution (i
+ 2, i
, type
, TYPE_CLASS3
, MODIFIER
);
1054 /* Like ternary_resize2_opt_n_base, but for functions that don't take
1055 a final scalar argument. */
1056 template<unsigned int MODIFIER
,
1057 type_class_index TYPE_CLASS2
= function_resolver::SAME_TYPE_CLASS
,
1058 type_class_index TYPE_CLASS3
= function_resolver::SAME_TYPE_CLASS
>
1059 struct ternary_resize2_base
: public overloaded_base
<0>
1062 resolve (function_resolver
&r
) const override
1064 unsigned int i
, nargs
;
1065 type_suffix_index type
;
1066 if (!r
.check_gp_argument (3, i
, nargs
)
1067 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1068 || !r
.require_derived_vector_type (i
+ 1, i
, type
, TYPE_CLASS2
,
1070 || !r
.require_derived_vector_type (i
+ 2, i
, type
, TYPE_CLASS3
,
1072 return error_mark_node
;
1074 return r
.resolve_to (r
.mode_suffix_id
, type
);
1078 /* Like ternary_resize2_opt_n_base, but for functions that take a final
1080 template<unsigned int MODIFIER
,
1081 type_class_index TYPE_CLASS2
= function_resolver::SAME_TYPE_CLASS
,
1082 type_class_index TYPE_CLASS3
= function_resolver::SAME_TYPE_CLASS
>
1083 struct ternary_resize2_lane_base
: public overloaded_base
<0>
1086 resolve (function_resolver
&r
) const override
1088 unsigned int i
, nargs
;
1089 type_suffix_index type
;
1090 if (!r
.check_gp_argument (4, i
, nargs
)
1091 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1092 || !r
.require_derived_vector_type (i
+ 1, i
, type
, TYPE_CLASS2
,
1094 || !r
.require_derived_vector_type (i
+ 2, i
, type
, TYPE_CLASS3
,
1096 || !r
.require_integer_immediate (i
+ 3))
1097 return error_mark_node
;
1099 return r
.resolve_to (r
.mode_suffix_id
, type
);
1103 /* A specialization of ternary_resize2_lane_base for bfloat16 elements,
1104 indexed in groups of N elements. */
1105 template<unsigned int N
>
1106 struct ternary_bfloat_lane_base
1107 : public ternary_resize2_lane_base
<16, TYPE_bfloat
, TYPE_bfloat
>
1110 build (function_builder
&b
, const function_group_info
&group
) const override
1112 b
.add_overloaded_functions (group
, MODE_none
);
1113 build_all (b
, "v0,v0,vB,vB,su64", group
, MODE_none
);
1117 check (function_checker
&c
) const override
1119 return c
.require_immediate_lane_index (3, 2, N
);
1123 /* A specialization of ternary_resize2_lane_base for quarter-sized
1125 template<type_class_index TYPE_CLASS2
= function_resolver::SAME_TYPE_CLASS
,
1126 type_class_index TYPE_CLASS3
= function_resolver::SAME_TYPE_CLASS
>
1127 struct ternary_qq_lane_base
1128 : public ternary_resize2_lane_base
<function_resolver::QUARTER_SIZE
,
1129 TYPE_CLASS2
, TYPE_CLASS3
>
1132 check (function_checker
&c
) const override
1134 return c
.require_immediate_lane_index (3, 0);
1138 /* Base class for narrowing bottom unary functions. The result is half
1139 the size of input and has class CLASS. */
1140 template<type_class_index CLASS
= function_resolver::SAME_TYPE_CLASS
>
1141 struct unary_narrowb_base
: public overloaded_base
<0>
1144 build (function_builder
&b
, const function_group_info
&group
) const override
1146 b
.add_overloaded_functions (group
, MODE_none
);
1147 STATIC_ASSERT (CLASS
== function_resolver::SAME_TYPE_CLASS
1148 || CLASS
== TYPE_unsigned
);
1149 if (CLASS
== TYPE_unsigned
)
1150 build_all (b
, "vhu0,v0", group
, MODE_none
);
1152 build_all (b
, "vh0,v0", group
, MODE_none
);
1156 resolve (function_resolver
&r
) const override
1158 return r
.resolve_unary (CLASS
, r
.HALF_SIZE
);
1162 /* The top equivalent of unary_imm_narrowb_base. All forms take the values
1163 of the even elements as an extra argument, before any governing predicate.
1164 These even elements are typically the result of the narrowb operation. */
1165 template<type_class_index CLASS
= function_resolver::SAME_TYPE_CLASS
>
1166 struct unary_narrowt_base
: public overloaded_base
<0>
1169 build (function_builder
&b
, const function_group_info
&group
) const override
1171 b
.add_overloaded_functions (group
, MODE_none
);
1172 STATIC_ASSERT (CLASS
== function_resolver::SAME_TYPE_CLASS
1173 || CLASS
== TYPE_unsigned
);
1174 if (CLASS
== TYPE_unsigned
)
1175 build_all (b
, "vhu0,vhu0,v0", group
, MODE_none
);
1177 build_all (b
, "vh0,vh0,v0", group
, MODE_none
);
1181 resolve (function_resolver
&r
) const override
1183 unsigned int i
, nargs
;
1184 type_suffix_index type
;
1185 if (!r
.check_gp_argument (2, i
, nargs
)
1186 || (type
= r
.infer_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
1187 || !r
.require_derived_vector_type (i
, i
+ 1, type
, CLASS
, r
.HALF_SIZE
))
1188 return error_mark_node
;
1190 return r
.resolve_to (r
.mode_suffix_id
, type
);
1194 /* sv<m0>_t svfoo[_m0base]_[m1]index(sv<m0>_t, sv<m1>_t)
1196 for all valid combinations of vector base type <m0> and vector
1197 displacement type <m1>. */
1198 struct adr_index_def
: public adr_base
1201 build (function_builder
&b
, const function_group_info
&group
) const override
1203 b
.add_overloaded_functions (group
, MODE_index
);
1204 build_all (b
, "b,b,d", group
, MODE_u32base_s32index
);
1205 build_all (b
, "b,b,d", group
, MODE_u32base_u32index
);
1206 build_all (b
, "b,b,d", group
, MODE_u64base_s64index
);
1207 build_all (b
, "b,b,d", group
, MODE_u64base_u64index
);
1212 /* sv<m0>_t svfoo[_m0base]_[m1]offset(sv<m0>_t, sv<m1>_t).
1214 for all valid combinations of vector base type <m0> and vector
1215 displacement type <m1>. */
1216 struct adr_offset_def
: public adr_base
1219 build (function_builder
&b
, const function_group_info
&group
) const override
1221 b
.add_overloaded_functions (group
, MODE_offset
);
1222 build_all (b
, "b,b,d", group
, MODE_u32base_s32offset
);
1223 build_all (b
, "b,b,d", group
, MODE_u32base_u32offset
);
1224 build_all (b
, "b,b,d", group
, MODE_u64base_s64offset
);
1225 build_all (b
, "b,b,d", group
, MODE_u64base_u64offset
);
1230 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
1232 i.e. a binary operation with uniform types, but with no scalar form. */
1233 struct binary_def
: public overloaded_base
<0>
1236 build (function_builder
&b
, const function_group_info
&group
) const override
1238 b
.add_overloaded_functions (group
, MODE_none
);
1239 build_all (b
, "v0,v0,v0", group
, MODE_none
);
1243 resolve (function_resolver
&r
) const override
1245 return r
.resolve_uniform (2);
1250 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:int>_t)
1251 sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0:int>_t).
1253 i.e. a version of the standard binary shape binary_opt_n in which
1254 the final argument is always a signed integer. */
1255 struct binary_int_opt_n_def
: public overloaded_base
<0>
1258 build (function_builder
&b
, const function_group_info
&group
) const override
1260 b
.add_overloaded_functions (group
, MODE_none
);
1261 build_all (b
, "v0,v0,vs0", group
, MODE_none
);
1262 build_all (b
, "v0,v0,ss0", group
, MODE_n
);
1266 resolve (function_resolver
&r
) const override
1268 unsigned int i
, nargs
;
1269 type_suffix_index type
;
1270 if (!r
.check_gp_argument (2, i
, nargs
)
1271 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
1272 return error_mark_node
;
1274 return r
.finish_opt_n_resolution (i
+ 1, i
, type
, TYPE_signed
);
1277 SHAPE (binary_int_opt_n
)
1279 /* Like binary_int_opt_n for single vectors. For tuples:
1281 sv<t0>x<g>_t svfoo[_t0_g](sv<t0>x<g>_t, sv<t0:int>x<g>_t)
1282 sv<t0>x<g>_t svfoo[_single_t0_g](sv<t0>x<g>_t, sv<t0:int>_t). */
1283 struct binary_int_opt_single_n_def
: public overloaded_base
<0>
1285 bool explicit_group_suffix_p () const override
{ return false; }
1288 build (function_builder
&b
, const function_group_info
&group
) const override
1290 b
.add_overloaded_functions (group
, MODE_none
);
1291 build_all (b
, "t0,t0,ts0", group
, MODE_none
);
1292 if (group
.groups
[0] == GROUP_none
)
1293 build_all (b
, "v0,v0,ss0", group
, MODE_n
);
1295 build_all (b
, "t0,t0,vs0", group
, MODE_single
);
1299 resolve (function_resolver
&r
) const override
1301 unsigned int i
, nargs
;
1303 if (!r
.check_gp_argument (2, i
, nargs
)
1304 || !(type
= r
.infer_sve_type (i
)))
1305 return error_mark_node
;
1307 return (type
.num_vectors
== 1 && r
.scalar_argument_p (i
+ 1)
1308 ? r
.finish_opt_n_resolution (i
+ 1, i
, type
.type
, TYPE_signed
)
1309 : r
.finish_opt_single_resolution (i
+ 1, i
, type
, TYPE_signed
));
1312 SHAPE (binary_int_opt_single_n
)
1314 /* sv<t0>_t svfoo_<t0>(sv<t0>_t, sv<t0>_t, uint64_t)
1316 where the final argument is an integer constant expression in the
1317 range [0, 16 / sizeof (<t0>_t) - 1]. */
1318 struct binary_lane_def
: public overloaded_base
<0>
1321 build (function_builder
&b
, const function_group_info
&group
) const override
1323 b
.add_overloaded_functions (group
, MODE_none
);
1324 build_all (b
, "v0,v0,v0,su64", group
, MODE_none
);
1328 resolve (function_resolver
&r
) const override
1330 return r
.resolve_uniform (2, 1);
1334 check (function_checker
&c
) const override
1336 return c
.require_immediate_lane_index (2, 1);
1341 /* sv<t0>_t svfoo[_t0](sv<t0:half>_t, sv<t0:half>_t, uint64_t).
1343 where the final argument is an integer constant expression in the
1344 range [0, 32 / sizeof (<t0>_t) - 1]. */
1345 struct binary_long_lane_def
: public overloaded_base
<0>
1348 build (function_builder
&b
, const function_group_info
&group
) const override
1350 b
.add_overloaded_functions (group
, MODE_none
);
1351 build_all (b
, "v0,vh0,vh0,su64", group
, MODE_none
);
1355 resolve (function_resolver
&r
) const override
1357 unsigned int i
, nargs
;
1358 type_suffix_index type
, result_type
;
1359 if (!r
.check_gp_argument (3, i
, nargs
)
1360 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1361 || !r
.require_matching_vector_type (i
+ 1, i
, type
)
1362 || !r
.require_integer_immediate (i
+ 2)
1363 || (result_type
= long_type_suffix (r
, type
)) == NUM_TYPE_SUFFIXES
)
1364 return error_mark_node
;
1366 if (tree res
= r
.lookup_form (r
.mode_suffix_id
, result_type
))
1369 return r
.report_no_such_form (type
);
1373 check (function_checker
&c
) const override
1375 return c
.require_immediate_lane_index (2, 1);
1378 SHAPE (binary_long_lane
)
1380 /* sv<t0>_t svfoo[_t0](sv<t0:half>_t, sv<t0:half>_t)
1381 sv<t0>_t svfoo[_n_t0](sv<t0:half>_t, <t0:half>_t). */
1382 struct binary_long_opt_n_def
: public overloaded_base
<0>
1385 build (function_builder
&b
, const function_group_info
&group
) const override
1387 b
.add_overloaded_functions (group
, MODE_none
);
1388 build_all (b
, "v0,vh0,vh0", group
, MODE_none
);
1389 build_all (b
, "v0,vh0,sh0", group
, MODE_n
);
1393 resolve (function_resolver
&r
) const override
1395 unsigned int i
, nargs
;
1396 type_suffix_index type
, result_type
;
1397 if (!r
.check_gp_argument (2, i
, nargs
)
1398 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1399 || (result_type
= long_type_suffix (r
, type
)) == NUM_TYPE_SUFFIXES
)
1400 return error_mark_node
;
1402 return r
.finish_opt_n_resolution (i
+ 1, i
, type
, r
.SAME_TYPE_CLASS
,
1403 r
.SAME_SIZE
, result_type
);
1406 SHAPE (binary_long_opt_n
)
1408 /* sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0>_t).
1410 i.e. a binary operation in which the final argument is always a scalar
1411 rather than a vector. */
1412 struct binary_n_def
: public overloaded_base
<0>
1415 build (function_builder
&b
, const function_group_info
&group
) const override
1417 b
.add_overloaded_functions (group
, MODE_n
);
1418 build_all (b
, "v0,v0,s0", group
, MODE_n
);
1422 resolve (function_resolver
&r
) const override
1424 unsigned int i
, nargs
;
1425 type_suffix_index type
;
1426 if (!r
.check_gp_argument (2, i
, nargs
)
1427 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1428 || !r
.require_derived_scalar_type (i
+ 1, r
.SAME_TYPE_CLASS
))
1429 return error_mark_node
;
1431 return r
.resolve_to (r
.mode_suffix_id
, type
);
1436 /* sv<t0:half>_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
1437 sv<t0:half>_t svfoo[_n_t0](sv<t0>_t, <t0>_t)
1439 i.e. a version of binary_opt_n in which the output elements are half the
1440 width of the input elements. */
1441 struct binary_narrowb_opt_n_def
: public overloaded_base
<0>
1444 build (function_builder
&b
, const function_group_info
&group
) const override
1446 b
.add_overloaded_functions (group
, MODE_none
);
1447 build_all (b
, "vh0,v0,v0", group
, MODE_none
);
1448 build_all (b
, "vh0,v0,s0", group
, MODE_n
);
1452 resolve (function_resolver
&r
) const override
1454 return r
.resolve_uniform_opt_n (2);
1457 SHAPE (binary_narrowb_opt_n
)
1459 /* sv<t0:half>_t svfoo[_t0](sv<t0:half>_t, sv<t0>_t, sv<t0>_t)
1460 sv<t0:half>_t svfoo[_n_t0](sv<t0:half>_t, sv<t0>_t, <t0>_t)
1462 This is the "top" counterpart to binary_narrowb_opt_n. */
1463 struct binary_narrowt_opt_n_def
: public overloaded_base
<0>
1466 build (function_builder
&b
, const function_group_info
&group
) const override
1468 b
.add_overloaded_functions (group
, MODE_none
);
1469 build_all (b
, "vh0,vh0,v0,v0", group
, MODE_none
);
1470 build_all (b
, "vh0,vh0,v0,s0", group
, MODE_n
);
1474 resolve (function_resolver
&r
) const override
1476 unsigned int i
, nargs
;
1477 type_suffix_index type
;
1478 if (!r
.check_gp_argument (3, i
, nargs
)
1479 || (type
= r
.infer_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
1480 || !r
.require_derived_vector_type (i
, i
+ 1, type
, r
.SAME_TYPE_CLASS
,
1482 return error_mark_node
;
1484 return r
.finish_opt_n_resolution (i
+ 2, i
+ 1, type
);
1487 SHAPE (binary_narrowt_opt_n
)
1489 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
1490 sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0>_t)
1492 i.e. the standard shape for binary operations that operate on
1494 struct binary_opt_n_def
: public overloaded_base
<0>
1497 build (function_builder
&b
, const function_group_info
&group
) const override
1499 b
.add_overloaded_functions (group
, MODE_none
);
1500 build_all (b
, "v0,v0,v0", group
, MODE_none
);
1501 /* _b functions do not have an _n form, but are classified as
1502 binary_opt_n so that they can be overloaded with vector
1504 if (group
.types
[0][0] == TYPE_SUFFIX_b
)
1505 gcc_assert (group
.types
[0][1] == NUM_TYPE_SUFFIXES
);
1507 build_all (b
, "v0,v0,s0", group
, MODE_n
);
1511 resolve (function_resolver
&r
) const override
1513 return r
.resolve_uniform_opt_n (2);
1516 SHAPE (binary_opt_n
)
1518 /* Like binary_opt_n for single vectors. For tuples:
1520 sv<t0>x<g>_t svfoo[_t0_g](sv<t0>x<g>_t, sv<t0>x<g>_t)
1521 sv<t0>x<g>_t svfoo[_single_t0_g](sv<t0>x<g>_t, sv<t0>_t). */
1522 struct binary_opt_single_n_def
: public overloaded_base
<0>
1524 bool explicit_group_suffix_p () const override
{ return false; }
1527 build (function_builder
&b
, const function_group_info
&group
) const override
1529 b
.add_overloaded_functions (group
, MODE_none
);
1530 build_all (b
, "t0,t0,t0", group
, MODE_none
);
1531 if (group
.groups
[0] == GROUP_none
)
1532 build_all (b
, "v0,v0,s0", group
, MODE_n
);
1534 build_all (b
, "t0,t0,v0", group
, MODE_single
);
1538 resolve (function_resolver
&r
) const override
1540 unsigned int i
, nargs
;
1542 if (!r
.check_gp_argument (2, i
, nargs
)
1543 || !(type
= r
.infer_sve_type (i
)))
1544 return error_mark_node
;
1546 return (type
.num_vectors
== 1 && r
.scalar_argument_p (i
+ 1)
1547 ? r
.finish_opt_n_resolution (i
+ 1, i
, type
.type
)
1548 : r
.finish_opt_single_resolution (i
+ 1, i
, type
));
1551 SHAPE (binary_opt_single_n
)
1553 /* svbool_t svfoo(svbool_t, svbool_t). */
1554 struct binary_pred_def
: public nonoverloaded_base
1557 build (function_builder
&b
, const function_group_info
&group
) const override
1559 build_all (b
, "v0,v0,v0", group
, MODE_none
);
1564 /* sv<t0>_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, uint64_t)
1566 where the final argument must be 90 or 270. */
1567 struct binary_rotate_def
: public overloaded_base
<0>
1570 build (function_builder
&b
, const function_group_info
&group
) const override
1572 b
.add_overloaded_functions (group
, MODE_none
);
1573 build_all (b
, "v0,v0,v0,su64", group
, MODE_none
);
1577 resolve (function_resolver
&r
) const override
1579 return r
.resolve_uniform (2, 1);
1583 check (function_checker
&c
) const override
1585 return c
.require_immediate_either_or (2, 90, 270);
1588 SHAPE (binary_rotate
)
1590 /* sv<t0>_t svfoo_t0(<t0>_t, <t0>_t)
1592 i.e. a binary function that takes two scalars and returns a vector.
1593 An explicit type suffix is required. */
1594 struct binary_scalar_def
: public nonoverloaded_base
1597 build (function_builder
&b
, const function_group_info
&group
) const override
1599 build_all (b
, "v0,s0,s0", group
, MODE_none
);
1602 SHAPE (binary_scalar
)
1604 /* sv<t0>x<g>_t svfoo[_single_t0_g](sv<t0>x<g>_t, sv<t0>_t). */
1605 struct binary_single_def
: public overloaded_base
<0>
1607 bool explicit_group_suffix_p () const override
{ return false; }
1610 build (function_builder
&b
, const function_group_info
&group
) const override
1612 b
.add_overloaded_functions (group
, MODE_none
);
1613 build_all (b
, "t0,t0,v0", group
, MODE_single
);
1617 resolve (function_resolver
&r
) const override
1620 if (!r
.check_num_arguments (2)
1621 || !(type
= r
.infer_sve_type (0))
1622 || !r
.require_derived_vector_type (1, 0, type
, r
.SAME_TYPE_CLASS
,
1624 return error_mark_node
;
1626 return r
.resolve_to (MODE_single
, type
);
1629 SHAPE (binary_single
)
1631 /* sv<t0:uint>_t svfoo[_t0](sv<t0>_t, sv<t0>_t).
1633 i.e. a version of "binary" that returns unsigned integers. */
1634 struct binary_to_uint_def
: public overloaded_base
<0>
1637 build (function_builder
&b
, const function_group_info
&group
) const override
1639 b
.add_overloaded_functions (group
, MODE_none
);
1640 build_all (b
, "vu0,v0,v0", group
, MODE_none
);
1644 resolve (function_resolver
&r
) const override
1646 return r
.resolve_uniform (2);
1649 SHAPE (binary_to_uint
)
1651 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:uint>_t)
1653 i.e. a version of "binary" in which the final argument is always an
1654 unsigned integer. */
1655 struct binary_uint_def
: public overloaded_base
<0>
1658 build (function_builder
&b
, const function_group_info
&group
) const override
1660 b
.add_overloaded_functions (group
, MODE_none
);
1661 build_all (b
, "v0,v0,vu0", group
, MODE_none
);
1665 resolve (function_resolver
&r
) const override
1667 unsigned int i
, nargs
;
1668 type_suffix_index type
;
1669 if (!r
.check_gp_argument (2, i
, nargs
)
1670 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1671 || !r
.require_derived_vector_type (i
+ 1, i
, type
, TYPE_unsigned
))
1672 return error_mark_node
;
1674 return r
.resolve_to (r
.mode_suffix_id
, type
);
1679 /* sv<t0>_t svfoo[_t0](sv<t0>_t, <t0:uint>_t)
1681 i.e. a version of binary_n in which the final argument is always an
1682 unsigned integer. */
1683 struct binary_uint_n_def
: public overloaded_base
<0>
1686 build (function_builder
&b
, const function_group_info
&group
) const override
1688 b
.add_overloaded_functions (group
, MODE_none
);
1689 build_all (b
, "v0,v0,su0", group
, MODE_none
);
1693 resolve (function_resolver
&r
) const override
1695 unsigned int i
, nargs
;
1696 type_suffix_index type
;
1697 if (!r
.check_gp_argument (2, i
, nargs
)
1698 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1699 || !r
.require_derived_scalar_type (i
+ 1, TYPE_unsigned
))
1700 return error_mark_node
;
1702 return r
.resolve_to (r
.mode_suffix_id
, type
);
1705 SHAPE (binary_uint_n
)
1707 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:uint>_t)
1708 sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0:uint>_t)
1710 i.e. a version of the standard binary shape binary_opt_n in which
1711 the final argument is always an unsigned integer. */
1712 struct binary_uint_opt_n_def
: public overloaded_base
<0>
1715 build (function_builder
&b
, const function_group_info
&group
) const override
1717 b
.add_overloaded_functions (group
, MODE_none
);
1718 build_all (b
, "v0,v0,vu0", group
, MODE_none
);
1719 build_all (b
, "v0,v0,su0", group
, MODE_n
);
1723 resolve (function_resolver
&r
) const override
1725 unsigned int i
, nargs
;
1726 type_suffix_index type
;
1727 if (!r
.check_gp_argument (2, i
, nargs
)
1728 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
1729 return error_mark_node
;
1731 return r
.finish_opt_n_resolution (i
+ 1, i
, type
, TYPE_unsigned
);
1734 SHAPE (binary_uint_opt_n
)
1736 /* sv<t0>_t svfoo[_t0](sv<t0>_t, uint64_t).
1738 i.e. a version of binary_n in which the final argument is always
1739 a 64-bit unsigned integer. */
1740 struct binary_uint64_n_def
: public overloaded_base
<0>
1743 build (function_builder
&b
, const function_group_info
&group
) const override
1745 b
.add_overloaded_functions (group
, MODE_none
);
1746 build_all (b
, "v0,v0,su64", group
, MODE_none
);
1750 resolve (function_resolver
&r
) const override
1752 unsigned int i
, nargs
;
1753 type_suffix_index type
;
1754 if (!r
.check_gp_argument (2, i
, nargs
)
1755 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1756 || !r
.require_scalar_type (i
+ 1, "uint64_t"))
1757 return error_mark_node
;
1759 return r
.resolve_to (r
.mode_suffix_id
, type
);
1762 SHAPE (binary_uint64_n
)
1764 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svuint64_t)
1765 sv<t0>_t svfoo[_n_t0](sv<t0>_t, uint64_t)
1767 i.e. a version of the standard binary shape binary_opt_n in which
1768 the final argument is always a uint64_t. */
1769 struct binary_uint64_opt_n_def
: public overloaded_base
<0>
1772 build (function_builder
&b
, const function_group_info
&group
) const override
1774 b
.add_overloaded_functions (group
, MODE_none
);
1775 build_all (b
, "v0,v0,vu64", group
, MODE_none
);
1776 build_all (b
, "v0,v0,su64", group
, MODE_n
);
1780 resolve (function_resolver
&r
) const override
1782 unsigned int i
, nargs
;
1783 type_suffix_index type
;
1784 if (!r
.check_gp_argument (2, i
, nargs
)
1785 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
1786 return error_mark_node
;
1788 return r
.finish_opt_n_resolution (i
+ 1, i
, type
, TYPE_unsigned
, 64);
1791 SHAPE (binary_uint64_opt_n
)
1793 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:half>_t). */
1794 struct binary_wide_def
: public overloaded_base
<0>
1797 build (function_builder
&b
, const function_group_info
&group
) const override
1799 b
.add_overloaded_functions (group
, MODE_none
);
1800 build_all (b
, "v0,v0,vh0", group
, MODE_none
);
1804 resolve (function_resolver
&r
) const override
1806 unsigned int i
, nargs
;
1807 type_suffix_index type
;
1808 if (!r
.check_gp_argument (2, i
, nargs
)
1809 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
1810 || !r
.require_derived_vector_type (i
+ 1, i
, type
, r
.SAME_TYPE_CLASS
,
1812 return error_mark_node
;
1814 return r
.resolve_to (r
.mode_suffix_id
, type
);
1819 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:half>_t)
1820 sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0:half>_t). */
1821 struct binary_wide_opt_n_def
: public overloaded_base
<0>
1824 build (function_builder
&b
, const function_group_info
&group
) const override
1826 b
.add_overloaded_functions (group
, MODE_none
);
1827 build_all (b
, "v0,v0,vh0", group
, MODE_none
);
1828 build_all (b
, "v0,v0,sh0", group
, MODE_n
);
1832 resolve (function_resolver
&r
) const override
1834 unsigned int i
, nargs
;
1835 type_suffix_index type
;
1836 if (!r
.check_gp_argument (2, i
, nargs
)
1837 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
1838 return error_mark_node
;
1840 return r
.finish_opt_n_resolution (i
+ 1, i
, type
, r
.SAME_TYPE_CLASS
,
1844 SHAPE (binary_wide_opt_n
)
1846 /* void svfoo_t0[_t1]_g(uint64_t, svbool_t, svbool_t, sv<t1>x<g>_t,
1849 where the first argument is a ZA tile. */
1850 struct binary_za_int_m_def
: public binary_za_m_base
<TYPE_signed
>
1853 build (function_builder
&b
, const function_group_info
&group
) const override
1855 b
.add_overloaded_functions (group
, MODE_none
);
1856 build_all (b
, "_,su64,vp,vp,t1,ts1", group
, MODE_none
);
1859 SHAPE (binary_za_int_m
)
1861 /* void svfoo_t0[_t1]_g(uint64_t, svbool_t, svbool_t, sv<t1>x<g>_t,
1864 where the first argument is a ZA tile. */
1865 struct binary_za_m_def
: public binary_za_m_base
<>
1868 build (function_builder
&b
, const function_group_info
&group
) const override
1870 b
.add_overloaded_functions (group
, MODE_none
);
1871 /* Allow the overloaded form to be specified seperately, with just
1872 a single suffix. This is necessary for the 64-bit SME MOP intrinsics,
1873 which have some forms dependent on FEAT_SME_I16I64 and some forms
1874 dependent on FEAT_SME_F64F64. The resolver needs to be defined
1876 if (group
.types
[0][1] != NUM_TYPE_SUFFIXES
)
1877 build_all (b
, "_,su64,vp,vp,t1,t1", group
, MODE_none
);
1882 /* void svfoo_lane_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1>_t, uint64_t)
1884 where the first argument is a variable ZA slice and the final argument
1885 indexes a single element in the preceding vector argument. */
1886 struct binary_za_slice_lane_def
: public binary_za_slice_lane_base
<>
1888 constexpr binary_za_slice_lane_def () : binary_za_slice_lane_base
<> (1) {}
1890 SHAPE (binary_za_slice_lane
)
1892 /* void svfoo_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1:int>x<g>_t)
1893 void svfoo[_single]_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1:int>_t).
1895 where the first argument is a variable ZA slice. */
1896 struct binary_za_slice_int_opt_single_def
1897 : public binary_za_slice_opt_single_base
<TYPE_signed
>
1900 build (function_builder
&b
, const function_group_info
&group
) const override
1902 b
.add_overloaded_functions (group
, MODE_none
);
1903 build_all (b
, "_,su32,t1,ts1", group
, MODE_none
);
1904 build_all (b
, "_,su32,t1,vs1", group
, MODE_single
);
1907 SHAPE (binary_za_slice_int_opt_single
)
1909 /* void svfoo_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1>x<g>_t)
1910 void svfoo[_single]_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1>_t)
1912 where the first argument is a variable ZA slice. */
1913 struct binary_za_slice_opt_single_def
1914 : public binary_za_slice_opt_single_base
<>
1917 build (function_builder
&b
, const function_group_info
&group
) const override
1919 b
.add_overloaded_functions (group
, MODE_none
);
1920 build_all (b
, "_,su32,t1,t1", group
, MODE_none
);
1921 build_all (b
, "_,su32,t1,v1", group
, MODE_single
);
1924 SHAPE (binary_za_slice_opt_single
)
1926 /* void svfoo_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1:uint>x<g>_t)
1927 void svfoo[_single]_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1:uint>_t)
1929 where the first argument is a variable ZA slice. */
1930 struct binary_za_slice_uint_opt_single_def
1931 : public binary_za_slice_opt_single_base
<TYPE_unsigned
>
1934 build (function_builder
&b
, const function_group_info
&group
) const override
1936 b
.add_overloaded_functions (group
, MODE_none
);
1937 build_all (b
, "_,su32,t1,tu1", group
, MODE_none
);
1938 build_all (b
, "_,su32,t1,vu1", group
, MODE_single
);
1941 SHAPE (binary_za_slice_uint_opt_single
)
1943 /* void svfoo_t0[_t1]_g(uint64_t, svbool_t, svbool_t, sv<t1>x<g>_t,
1946 where the first argument is a ZA tile. */
1947 struct binary_za_uint_m_def
: public binary_za_m_base
<TYPE_unsigned
>
1950 build (function_builder
&b
, const function_group_info
&group
) const override
1952 b
.add_overloaded_functions (group
, MODE_none
);
1953 build_all (b
, "_,su64,vp,vp,t1,tu1", group
, MODE_none
);
1956 SHAPE (binary_za_uint_m
)
1958 /* sv<t0>x<g>_t svfoo[_t0_t1_g](sv<t0>x<g>_t, sv<t0>x<g>_t). */
1959 struct binaryxn_def
: public overloaded_base
<0>
1961 bool explicit_group_suffix_p () const override
{ return false; }
1964 build (function_builder
&b
, const function_group_info
&group
) const override
1966 b
.add_overloaded_functions (group
, MODE_none
);
1967 build_all (b
, "t0,t0,t0", group
, MODE_none
);
1971 resolve (function_resolver
&r
) const override
1973 vector_type_index pred_type
;
1975 if (!r
.check_num_arguments (3)
1976 || (pred_type
= r
.infer_predicate_type (0)) == NUM_VECTOR_TYPES
1977 || !(type
= r
.infer_sve_type (1))
1978 || !r
.require_matching_predicate_type (pred_type
, type
)
1979 || !r
.require_matching_vector_type (2, 1, type
))
1980 return error_mark_node
;
1982 return r
.resolve_to (r
.mode_suffix_id
, type
);
1988 struct bool_inherent_def
: public nonoverloaded_base
1991 build (function_builder
&b
, const function_group_info
&group
) const override
1993 build_all (b
, "sp", group
, MODE_none
);
1996 SHAPE (bool_inherent
)
2000 sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t, sv<t0>_t)
2002 for single vectors or:
2004 sv<t0>x<g>_t svfoo[_single_t0_g](sv<t0>x<g>_t, sv<t0>_t, sv<t0>_t)
2007 struct clamp_def
: public overloaded_base
<0>
2009 bool explicit_group_suffix_p () const override
{ return false; }
2012 build (function_builder
&b
, const function_group_info
&group
) const override
2014 b
.add_overloaded_functions (group
, MODE_none
);
2015 build_all (b
, "t0,t0,v0,v0", group
,
2016 group
.groups
[0] == GROUP_none
? MODE_none
: MODE_single
);
2020 resolve (function_resolver
&r
) const override
2023 if (!r
.check_num_arguments (3)
2024 || !(type
= r
.infer_sve_type (0))
2025 || !r
.require_derived_vector_type (1, 0, type
, r
.SAME_TYPE_CLASS
,
2027 || !r
.require_derived_vector_type (2, 0, type
, r
.SAME_TYPE_CLASS
,
2029 return error_mark_node
;
2031 auto mode
= type
.num_vectors
== 1 ? MODE_none
: MODE_single
;
2032 return r
.resolve_to (mode
, type
);
2037 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
2038 <t0>_t svfoo[_n_t0](<t0>_t, sv<t0>_t). */
2039 struct clast_def
: public overloaded_base
<0>
2042 build (function_builder
&b
, const function_group_info
&group
) const override
2044 b
.add_overloaded_functions (group
, MODE_none
);
2045 build_all (b
, "v0,v0,v0", group
, MODE_none
);
2046 build_all (b
, "s0,s0,v0", group
, MODE_n
);
2050 resolve (function_resolver
&r
) const override
2052 unsigned int i
, nargs
;
2053 if (!r
.check_gp_argument (2, i
, nargs
)
2054 || !r
.require_vector_or_scalar_type (i
))
2055 return error_mark_node
;
2057 if (r
.scalar_argument_p (i
))
2059 type_suffix_index type
;
2060 if (!r
.require_derived_scalar_type (i
, r
.SAME_TYPE_CLASS
)
2061 || (type
= r
.infer_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
)
2062 return error_mark_node
;
2063 return r
.resolve_to (MODE_n
, type
);
2067 type_suffix_index type
;
2068 if ((type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
2069 || !r
.require_matching_vector_type (i
+ 1, i
, type
))
2070 return error_mark_node
;
2071 return r
.resolve_to (MODE_none
, type
);
2077 /* svbool_t svfoo[_t0](sv<t0>_t, sv<t0>_t). */
2078 struct compare_def
: public overloaded_base
<0>
2081 build (function_builder
&b
, const function_group_info
&group
) const override
2083 b
.add_overloaded_functions (group
, MODE_none
);
2084 build_all (b
, "vp,v0,v0", group
, MODE_none
);
2088 resolve (function_resolver
&r
) const override
2090 return r
.resolve_uniform (2);
2095 /* svbool_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
2096 svbool_t svfoo[_n_t0](sv<t0>_t, <t0>_t)
2098 i.e. a comparison between two vectors, or between a vector and a scalar. */
2099 struct compare_opt_n_def
: public overloaded_base
<0>
2102 build (function_builder
&b
, const function_group_info
&group
) const override
2104 b
.add_overloaded_functions (group
, MODE_none
);
2105 build_all (b
, "vp,v0,v0", group
, MODE_none
);
2106 build_all (b
, "vp,v0,s0", group
, MODE_n
);
2110 resolve (function_resolver
&r
) const override
2112 return r
.resolve_uniform_opt_n (2);
2115 SHAPE (compare_opt_n
)
2117 /* svbool_t svfoo[_t0](const <t0>_t *, const <t0>_t *). */
2118 struct compare_ptr_def
: public overloaded_base
<0>
2121 build (function_builder
&b
, const function_group_info
&group
) const override
2123 b
.add_overloaded_functions (group
, MODE_none
);
2124 build_all (b
, "vp,al,al", group
, MODE_none
);
2128 resolve (function_resolver
&r
) const override
2130 unsigned int i
, nargs
;
2131 type_suffix_index type
;
2132 if (!r
.check_gp_argument (2, i
, nargs
)
2133 || (type
= r
.infer_pointer_type (i
)) == NUM_TYPE_SUFFIXES
2134 || !r
.require_matching_pointer_type (i
+ 1, i
, type
))
2135 return error_mark_node
;
2137 return r
.resolve_to (r
.mode_suffix_id
, type
);
2142 /* svboolx<g>_t svfoo_t0[_t1]_g(<t1>_t, <t1>_t)
2144 where _t0 is a _b<bits> suffix that describes the predicate result.
2145 There is no direct relationship between the element sizes of _t0
2147 struct compare_scalar_def
: public overloaded_base
<1>
2150 build (function_builder
&b
, const function_group_info
&group
) const override
2152 b
.add_overloaded_functions (group
, MODE_none
);
2153 build_all (b
, "tp,s1,s1", group
, MODE_none
);
2157 resolve (function_resolver
&r
) const override
2159 unsigned int i
, nargs
;
2160 type_suffix_index type
;
2161 if (!r
.check_gp_argument (2, i
, nargs
)
2162 || (type
= r
.infer_integer_scalar_type (i
)) == NUM_TYPE_SUFFIXES
2163 || !r
.require_matching_integer_scalar_type (i
+ 1, i
, type
))
2164 return error_mark_node
;
2166 return r
.resolve_to (r
.mode_suffix_id
, r
.type_suffix_ids
[0], type
,
2170 SHAPE (compare_scalar
)
2172 /* svcount_t svfoo_t0[_t1](<t1>_t, <t1>_t, uint64_t)
2174 where _t0 is a _c<bits> suffix that describes the predicate-as-counter
2175 result. The final argument is an integer constant that specifies the
2176 number of vectors (2 or 4). */
2177 struct compare_scalar_count_def
: public overloaded_base
<1>
2180 build (function_builder
&b
, const function_group_info
&group
) const override
2182 b
.add_overloaded_functions (group
, MODE_none
);
2183 build_all (b
, "v0,s1,s1,su64", group
, MODE_none
);
2187 resolve (function_resolver
&r
) const override
2189 unsigned int i
, nargs
;
2190 type_suffix_index type
;
2191 if (!r
.check_gp_argument (3, i
, nargs
)
2192 || (type
= r
.infer_64bit_scalar_integer_pair (i
)) == NUM_TYPE_SUFFIXES
2193 || !r
.require_integer_immediate (i
+ 2))
2194 return error_mark_node
;
2196 return r
.resolve_to (r
.mode_suffix_id
, r
.type_suffix_ids
[0], type
);
2200 check (function_checker
&c
) const override
2202 return c
.require_immediate_either_or (2, 2, 4);
2205 SHAPE (compare_scalar_count
)
2207 /* svbool_t svfoo[_t0](sv<t0>_t, svint64_t) (for signed t0)
2208 svbool_t svfoo[_n_t0](sv<t0>_t, int64_t) (for signed t0)
2209 svbool_t svfoo[_t0](sv<t0>_t, svuint64_t) (for unsigned t0)
2210 svbool_t svfoo[_n_t0](sv<t0>_t, uint64_t) (for unsigned t0)
2212 i.e. a comparison in which the second argument is 64 bits. */
2213 struct compare_wide_opt_n_def
: public overloaded_base
<0>
2216 build (function_builder
&b
, const function_group_info
&group
) const override
2218 b
.add_overloaded_functions (group
, MODE_none
);
2219 build_all (b
, "vp,v0,vw0", group
, MODE_none
);
2220 build_all (b
, "vp,v0,sw0", group
, MODE_n
);
2224 resolve (function_resolver
&r
) const override
2226 unsigned int i
, nargs
;
2227 type_suffix_index type
;
2228 if (!r
.check_gp_argument (2, i
, nargs
)
2229 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
2230 return error_mark_node
;
2232 return r
.finish_opt_n_resolution (i
+ 1, i
, type
, r
.SAME_TYPE_CLASS
, 64);
2235 SHAPE (compare_wide_opt_n
)
2237 /* uint64_t svfoo(). */
2238 struct count_inherent_def
: public nonoverloaded_base
2241 build (function_builder
&b
, const function_group_info
&group
) const override
2243 build_all (b
, "su64", group
, MODE_none
);
2246 SHAPE (count_inherent
)
2248 /* uint64_t svfoo(enum svpattern). */
2249 struct count_pat_def
: public nonoverloaded_base
2252 build (function_builder
&b
, const function_group_info
&group
) const override
2254 build_all (b
, "su64,epattern", group
, MODE_none
);
2259 /* uint64_t svfoo(svbool_t). */
2260 struct count_pred_def
: public nonoverloaded_base
2263 build (function_builder
&b
, const function_group_info
&group
) const override
2265 build_all (b
, "su64,vp", group
, MODE_none
);
2270 /* uint64_t svfoo_t0(sv<t0>_t, uint64_t)
2272 where the final argument must be 2 or 4. */
2273 struct count_pred_c_def
: public nonoverloaded_base
2276 build (function_builder
&b
, const function_group_info
&group
) const override
2278 build_all (b
, "su64,v0,su64", group
, MODE_none
);
2282 check (function_checker
&c
) const override
2284 return c
.require_immediate_either_or (1, 2, 4);
2287 SHAPE (count_pred_c
)
2289 /* uint64_t svfoo[_t0](sv<t0>_t). */
2290 struct count_vector_def
: public overloaded_base
<0>
2293 build (function_builder
&b
, const function_group_info
&group
) const override
2295 b
.add_overloaded_functions (group
, MODE_none
);
2296 build_all (b
, "su64,v0", group
, MODE_none
);
2300 resolve (function_resolver
&r
) const override
2302 return r
.resolve_uniform (1);
2305 SHAPE (count_vector
)
2307 /* sv<t0>xN_t svfoo[_t0](sv<t0>_t, ..., sv<t0>_t)
2309 where there are N arguments in total. */
2310 struct create_def
: public overloaded_base
<0>
2313 build (function_builder
&b
, const function_group_info
&group
) const override
2315 b
.add_overloaded_functions (group
, MODE_none
);
2316 build_all (b
, "t0,v0*t", group
, MODE_none
);
2320 resolve (function_resolver
&r
) const override
2322 return r
.resolve_uniform (r
.vectors_per_tuple ());
2327 /* void svfoo_lane_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1:int>_t, uint64_t)
2329 where the final argument indexes a <t0>-sized group of elements in the
2330 preceding vector argument. */
2331 struct dot_za_slice_int_lane_def
2332 : public binary_za_slice_lane_base
<TYPE_signed
>
2334 constexpr dot_za_slice_int_lane_def ()
2335 : binary_za_slice_lane_base
<TYPE_signed
> (0) {}
2338 build (function_builder
&b
, const function_group_info
&group
) const override
2340 b
.add_overloaded_functions (group
, MODE_none
);
2341 build_all (b
, "_,su32,t1,vs1,su64", group
, MODE_none
);
2344 SHAPE (dot_za_slice_int_lane
)
2346 /* void svfoo_lane_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1>_t, uint64_t)
2348 where the final argument indexes a <t0>-sized group of elements in the
2349 preceding vector argument. */
2350 struct dot_za_slice_lane_def
: public binary_za_slice_lane_base
<>
2352 constexpr dot_za_slice_lane_def () : binary_za_slice_lane_base
<> (0) {}
2354 SHAPE (dot_za_slice_lane
)
2356 /* void svfoo_lane_t0[_t1]_g(uint32_t, sv<t1>x<g>_t, sv<t1:uint>_t, uint64_t)
2358 where the final argument indexes a <t0>-sized group of elements in the
2359 preceding vector argument. */
2360 struct dot_za_slice_uint_lane_def
2361 : public binary_za_slice_lane_base
<TYPE_unsigned
>
2363 constexpr dot_za_slice_uint_lane_def ()
2364 : binary_za_slice_lane_base
<TYPE_unsigned
> (0) {}
2367 build (function_builder
&b
, const function_group_info
&group
) const override
2369 b
.add_overloaded_functions (group
, MODE_none
);
2370 build_all (b
, "_,su32,t1,vu1,su64", group
, MODE_none
);
2373 SHAPE (dot_za_slice_uint_lane
)
2375 /* sv<t0>_t svfoo[_n]_t0(<t0>_t, ..., <t0>_t)
2377 where there are enough arguments to fill 128 bits of data (or to
2378 control 128 bits of data in the case of predicates). */
2379 struct dupq_def
: public overloaded_base
<1>
2382 build (function_builder
&b
, const function_group_info
&group
) const override
2384 /* The "_n" suffix is optional; the full name has it, but the short
2386 build_all (b
, "v0,s0*q", group
, MODE_n
, true);
2390 resolve (function_resolver
&) const override
2392 /* The short forms just make "_n" implicit, so no resolution is needed. */
2398 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t, uint64_t)
2400 where the final argument is an integer constant expression that when
2401 multiplied by the number of bytes in t0 is in the range [0, 255]. */
2402 struct ext_def
: public overloaded_base
<0>
2405 build (function_builder
&b
, const function_group_info
&group
) const override
2407 b
.add_overloaded_functions (group
, MODE_none
);
2408 build_all (b
, "v0,v0,v0,su64", group
, MODE_none
);
2412 resolve (function_resolver
&r
) const override
2414 return r
.resolve_uniform (2, 1);
2418 check (function_checker
&c
) const override
2420 unsigned int bytes
= c
.type_suffix (0).element_bytes
;
2421 return c
.require_immediate_range (2, 0, 256 / bytes
- 1);
2426 /* svboolx<g>_t svfoo_t0_g(sv<t0>_t, sv<t0>_t, uint32_t). */
2427 struct extract_pred_def
: public nonoverloaded_base
2430 build (function_builder
&b
, const function_group_info
&group
) const override
2432 build_all (b
, "tp,vc,su64", group
, MODE_none
);
2436 check (function_checker
&c
) const override
2438 unsigned int size
= c
.vectors_per_tuple ();
2439 return c
.require_immediate_range (1, 0, 4 / size
- 1);
2442 SHAPE (extract_pred
)
2444 /* <t0>_t svfoo[_t0](<t0>_t, sv<t0>_t). */
2445 struct fold_left_def
: public overloaded_base
<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
, "s0,s0,v0", group
, MODE_none
);
2455 resolve (function_resolver
&r
) const override
2457 unsigned int i
, nargs
;
2458 type_suffix_index type
;
2459 if (!r
.check_gp_argument (2, i
, nargs
)
2460 || !r
.require_derived_scalar_type (i
, r
.SAME_TYPE_CLASS
)
2461 || (type
= r
.infer_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
)
2462 return error_mark_node
;
2464 return r
.resolve_to (r
.mode_suffix_id
, type
);
2469 /* sv<t0>_t svfoo[_t0](sv<t0>xN_t, uint64_t)
2471 where the final argument is an integer constant expression in
2472 the range [0, N - 1]. */
2473 struct get_def
: public overloaded_base
<0>
2476 build (function_builder
&b
, const function_group_info
&group
) const override
2478 b
.add_overloaded_functions (group
, MODE_none
);
2479 build_all (b
, "v0,t0,su64", group
, MODE_none
);
2483 resolve (function_resolver
&r
) const override
2485 unsigned int i
, nargs
;
2487 if (!r
.check_gp_argument (2, i
, nargs
)
2488 || !(type
= r
.infer_tuple_type (i
))
2489 || !r
.require_integer_immediate (i
+ 1))
2490 return error_mark_node
;
2492 return r
.resolve_to (r
.mode_suffix_id
, type
);
2496 check (function_checker
&c
) const override
2498 unsigned int nvectors
= c
.vectors_per_tuple ();
2499 return c
.require_immediate_range (1, 0, nvectors
- 1);
2504 /* <t0>xN_t svfoo[_t0](sv<t0>_t). */
2505 struct get_neonq_def
: public overloaded_base
<0>
2508 build (function_builder
&b
, const function_group_info
&group
) const override
2510 b
.add_overloaded_functions (group
, MODE_none
);
2511 build_all (b
, "Q0,v0", group
, MODE_none
);
2514 resolve (function_resolver
&r
) const override
2516 return r
.resolve_unary ();
2521 /* sv<t0>_t svfoo[_t0](sv<t0>_t, <t0>xN_t). */
2522 struct set_neonq_def
: public overloaded_base
<0>
2525 build (function_builder
&b
, const function_group_info
&group
) const override
2527 b
.add_overloaded_functions (group
, MODE_none
);
2528 build_all (b
, "v0,v0,Q0", group
, MODE_none
);
2531 resolve (function_resolver
&r
) const override
2533 unsigned int i
, nargs
;
2534 type_suffix_index type
;
2535 if (!r
.check_gp_argument (2, i
, nargs
)
2536 || (type
= r
.infer_neon128_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
)
2537 return error_mark_node
;
2538 return r
.resolve_to (r
.mode_suffix_id
, type
);
2543 /* sv<t0>_t svfoo[_t0](<t0>xN_t). */
2544 struct dup_neonq_def
: public overloaded_base
<0>
2547 build (function_builder
&b
, const function_group_info
&group
) const override
2549 b
.add_overloaded_functions (group
, MODE_none
);
2550 build_all (b
, "v0,Q0", group
, MODE_none
);
2553 resolve (function_resolver
&r
) const override
2555 unsigned int i
, nargs
;
2556 type_suffix_index type
;
2557 if (!r
.check_gp_argument (1, i
, nargs
)
2558 || (type
= r
.infer_neon128_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
2559 return error_mark_node
;
2560 return r
.resolve_to (r
.mode_suffix_id
, type
);
2565 /* sv<t0>_t svfoo[_t0](sv<t0>_t, uint64_t)
2566 <t0>_t svfoo[_n_t0](<t0>_t, uint64_t)
2568 where the t0 in the vector form is a signed or unsigned integer
2569 whose size is tied to the [bhwd] suffix of "svfoo". */
2570 struct inc_dec_def
: public inc_dec_base
2572 CONSTEXPR
inc_dec_def () : inc_dec_base (false) {}
2575 build (function_builder
&b
, const function_group_info
&group
) const override
2577 b
.add_overloaded_functions (group
, MODE_none
);
2578 /* These functions are unusual in that the type suffixes for
2579 the scalar and vector forms are not related. The vector
2580 form always has exactly two potential suffixes while the
2581 scalar form always has four. */
2582 if (group
.types
[2][0] == NUM_TYPE_SUFFIXES
)
2583 build_all (b
, "v0,v0,su64", group
, MODE_none
);
2585 build_all (b
, "s0,s0,su64", group
, MODE_n
);
2590 /* sv<t0>_t svfoo[_t0](sv<t0>_t, enum svpattern, uint64_t)
2591 <t0>_t svfoo[_n_t0](<t0>_t, enum svpattern, uint64_t)
2593 where the t0 in the vector form is a signed or unsigned integer
2594 whose size is tied to the [bhwd] suffix of "svfoo". */
2595 struct inc_dec_pat_def
: public inc_dec_base
2597 CONSTEXPR
inc_dec_pat_def () : inc_dec_base (true) {}
2600 build (function_builder
&b
, const function_group_info
&group
) const override
2602 b
.add_overloaded_functions (group
, MODE_none
);
2603 /* These functions are unusual in that the type suffixes for
2604 the scalar and vector forms are not related. The vector
2605 form always has exactly two potential suffixes while the
2606 scalar form always has four. */
2607 if (group
.types
[2][0] == NUM_TYPE_SUFFIXES
)
2608 build_all (b
, "v0,v0,epattern,su64", group
, MODE_none
);
2610 build_all (b
, "s0,s0,epattern,su64", group
, MODE_n
);
2615 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbool_t). */
2616 struct inc_dec_pred_def
: public overloaded_base
<0>
2619 build (function_builder
&b
, const function_group_info
&group
) const override
2621 b
.add_overloaded_functions (group
, MODE_none
);
2622 build_all (b
, "v0,v0,vp", group
, MODE_none
);
2626 resolve (function_resolver
&r
) const override
2628 unsigned int i
, nargs
;
2629 type_suffix_index type
;
2630 if (!r
.check_gp_argument (2, i
, nargs
)
2631 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
2632 || !r
.require_vector_type (i
+ 1, VECTOR_TYPE_svbool_t
))
2633 return error_mark_node
;
2635 return r
.resolve_to (r
.mode_suffix_id
, type
);
2638 SHAPE (inc_dec_pred
)
2640 /* <t0>_t svfoo[_n_t0]_t1(<t0>_t, svbool_t)
2642 where _t1 is a _b<bits> suffix that describes the svbool_t argument. */
2643 struct inc_dec_pred_scalar_def
: public overloaded_base
<2>
2646 build (function_builder
&b
, const function_group_info
&group
) const override
2648 b
.add_overloaded_functions (group
, MODE_n
);
2649 build_all (b
, "s0,s0,vp", group
, MODE_n
);
2653 resolve (function_resolver
&r
) const override
2655 unsigned int i
, nargs
;
2656 type_suffix_index type
;
2657 if (!r
.check_gp_argument (2, i
, nargs
)
2658 || (type
= r
.infer_integer_scalar_type (i
)) == NUM_TYPE_SUFFIXES
2659 || !r
.require_vector_type (i
+ 1, VECTOR_TYPE_svbool_t
))
2660 return error_mark_node
;
2662 return r
.resolve_to (r
.mode_suffix_id
, type
, r
.type_suffix_ids
[1]);
2665 SHAPE (inc_dec_pred_scalar
)
2667 /* sv<t0>[xN]_t svfoo_t0(). */
2668 struct inherent_def
: public nonoverloaded_base
2671 build (function_builder
&b
, const function_group_info
&group
) const override
2673 build_all (b
, "t0", group
, MODE_none
);
2678 /* svbool_t svfoo[_b](). */
2679 struct inherent_b_def
: public overloaded_base
<0>
2682 build (function_builder
&b
, const function_group_info
&group
) const override
2684 /* The "_b" suffix is optional; the full name has it, but the short
2686 build_all (b
, "v0", group
, MODE_none
, true);
2690 resolve (function_resolver
&) const override
2692 /* The short forms just make "_b" implicit, so no resolution is needed. */
2698 /* void svfoo_t0(). */
2699 struct inherent_za_def
: public nonoverloaded_base
2702 build (function_builder
&b
, const function_group_info
&group
) const override
2704 build_all (b
, "_", group
, MODE_none
);
2709 /* void svfoo_zt(uint64_t)
2711 where the argument must be zero. */
2712 struct inherent_zt_def
: public nonoverloaded_base
2715 build (function_builder
&b
, const function_group_info
&group
) const override
2717 build_all (b
, "_,su64", group
, MODE_none
);
2721 check (function_checker
&c
) const override
2723 return c
.require_immediate_range (0, 0, 0);
2728 /* void svfoo_t0(uint64_t)
2730 where the argument is an integer constant that specifies an 8-bit mask. */
2731 struct inherent_mask_za_def
: public nonoverloaded_base
2734 build (function_builder
&b
, const function_group_info
&group
) const override
2736 build_all (b
, "_,su64", group
, MODE_none
);
2740 check (function_checker
&c
) const override
2742 return c
.require_immediate_range (0, 0, 255);
2745 SHAPE (inherent_mask_za
)
2747 /* void svfoo_t0(uint32_t, const void *)
2748 void svfoo_vnum_t0(uint32_t, const void *, int64_t)
2750 where the first argument is a variable ZA slice. */
2751 struct ldr_za_def
: public nonoverloaded_base
2754 build (function_builder
&b
, const function_group_info
&group
) const override
2756 build_all (b
, "_,su32,al", group
, MODE_none
);
2757 build_all (b
, "_,su32,al,ss64", group
, MODE_vnum
);
2762 /* void svfoo_zt(uint64_t, const void *)
2764 where the first argument must be zero. */
2765 struct ldr_zt_def
: public nonoverloaded_base
2768 build (function_builder
&b
, const function_group_info
&group
) const override
2770 build_all (b
, "_,su64,al", group
, MODE_none
);
2774 check (function_checker
&c
) const override
2776 return c
.require_immediate_range (0, 0, 0);
2781 /* sv<t0>[xN]_t svfoo[_t0]_g(const <t0>_t *)
2782 sv<t0>[xN]_t svfoo_vnum[_t0]_g(const <t0>_t *, int64_t). */
2783 struct load_def
: public load_contiguous_base
2786 build (function_builder
&b
, const function_group_info
&group
) const override
2788 b
.add_overloaded_functions (group
, MODE_none
);
2789 b
.add_overloaded_functions (group
, MODE_vnum
);
2790 build_all (b
, "t0,al", group
, MODE_none
);
2791 build_all (b
, "t0,al,ss64", group
, MODE_vnum
);
2796 /* sv<t0>_t svfoo_t0(const <X>_t *)
2797 sv<t0>_t svfoo_vnum_t0(const <X>_t *, int64_t)
2799 where <X> is determined by the function base name. */
2800 struct load_ext_def
: public nonoverloaded_base
2803 build (function_builder
&b
, const function_group_info
&group
) const override
2805 build_all (b
, "t0,al", group
, MODE_none
);
2806 build_all (b
, "t0,al,ss64", group
, MODE_vnum
);
2811 /* sv<t0>_t svfoo_[s32]index_t0(const <X>_t *, svint32_t)
2812 sv<t0>_t svfoo_[s64]index_t0(const <X>_t *, svint64_t)
2813 sv<t0>_t svfoo_[u32]index_t0(const <X>_t *, svuint32_t)
2814 sv<t0>_t svfoo_[u64]index_t0(const <X>_t *, svuint64_t)
2816 sv<t0>_t svfoo[_u32base]_index_t0(svuint32_t, int64_t)
2817 sv<t0>_t svfoo[_u64base]_index_t0(svuint64_t, int64_t)
2819 where <X> is determined by the function base name. */
2820 struct load_ext_gather_index_def
: public load_ext_gather_base
2823 build (function_builder
&b
, const function_group_info
&group
) const override
2825 b
.add_overloaded_functions (group
, MODE_index
);
2826 build_sv_index (b
, "t0,al,d", group
);
2827 build_vs_index (b
, "t0,b,ss64", group
);
2830 SHAPE (load_ext_gather_index
)
2832 /* sv<t0>_t svfoo_[s64]index_t0(const <X>_t *, svint64_t)
2833 sv<t0>_t svfoo_[u64]index_t0(const <X>_t *, svuint64_t)
2835 sv<t0>_t svfoo[_u32base]_index_t0(svuint32_t, int64_t)
2836 sv<t0>_t svfoo[_u64base]_index_t0(svuint64_t, int64_t)
2838 where <X> is determined by the function base name. This is
2839 load_ext_gather_index that doesn't support 32-bit vector indices. */
2840 struct load_ext_gather_index_restricted_def
: public load_ext_gather_base
2843 build (function_builder
&b
, const function_group_info
&group
) const override
2845 b
.add_overloaded_functions (group
, MODE_index
);
2846 build_sv_index64 (b
, "t0,al,d", group
);
2847 build_vs_index (b
, "t0,b,ss64", group
);
2850 SHAPE (load_ext_gather_index_restricted
)
2852 /* sv<t0>_t svfoo_[s32]offset_t0(const <X>_t *, svint32_t)
2853 sv<t0>_t svfoo_[s64]offset_t0(const <X>_t *, svint64_t)
2854 sv<t0>_t svfoo_[u32]offset_t0(const <X>_t *, svuint32_t)
2855 sv<t0>_t svfoo_[u64]offset_t0(const <X>_t *, svuint64_t)
2857 sv<t0>_t svfoo[_u32base]_t0(svuint32_t)
2858 sv<t0>_t svfoo[_u64base]_t0(svuint64_t)
2860 sv<t0>_t svfoo[_u32base]_offset_t0(svuint32_t, int64_t)
2861 sv<t0>_t svfoo[_u64base]_offset_t0(svuint64_t, int64_t)
2863 where <X> is determined by the function base name. */
2864 struct load_ext_gather_offset_def
: public load_ext_gather_base
2867 build (function_builder
&b
, const function_group_info
&group
) const override
2869 b
.add_overloaded_functions (group
, MODE_offset
);
2870 build_sv_offset (b
, "t0,al,d", group
);
2871 build_v_base (b
, "t0,b", group
, true);
2872 build_vs_offset (b
, "t0,b,ss64", group
);
2875 SHAPE (load_ext_gather_offset
)
2877 /* sv<t0>_t svfoo_[s64]offset_t0(const <X>_t *, svint64_t)
2878 sv<t0>_t svfoo_[u32]offset_t0(const <X>_t *, svuint32_t)
2879 sv<t0>_t svfoo_[u64]offset_t0(const <X>_t *, svuint64_t)
2881 sv<t0>_t svfoo[_u32base]_t0(svuint32_t)
2882 sv<t0>_t svfoo[_u64base]_t0(svuint64_t)
2884 sv<t0>_t svfoo[_u32base]_offset_t0(svuint32_t, int64_t)
2885 sv<t0>_t svfoo[_u64base]_offset_t0(svuint64_t, int64_t)
2887 where <X> is determined by the function base name. This is
2888 load_ext_gather_offset without the s32 vector offset form. */
2889 struct load_ext_gather_offset_restricted_def
: public load_ext_gather_base
2892 build (function_builder
&b
, const function_group_info
&group
) const override
2894 b
.add_overloaded_functions (group
, MODE_offset
);
2895 build_sv_uint_offset (b
, "t0,al,d", group
);
2896 build_v_base (b
, "t0,b", group
, true);
2897 build_vs_offset (b
, "t0,b,ss64", group
);
2900 SHAPE (load_ext_gather_offset_restricted
)
2902 /* sv<t0>_t svfoo_[s32]index[_t0](const <t0>_t *, svint32_t)
2903 sv<t0>_t svfoo_[s64]index[_t0](const <t0>_t *, svint64_t)
2904 sv<t0>_t svfoo_[u32]index[_t0](const <t0>_t *, svuint32_t)
2905 sv<t0>_t svfoo_[u64]index[_t0](const <t0>_t *, svuint64_t)
2907 sv<t0>_t svfoo_[s32]offset[_t0](const <t0>_t *, svint32_t)
2908 sv<t0>_t svfoo_[s64]offset[_t0](const <t0>_t *, svint64_t)
2909 sv<t0>_t svfoo_[u32]offset[_t0](const <t0>_t *, svuint32_t)
2910 sv<t0>_t svfoo_[u64]offset[_t0](const <t0>_t *, svuint64_t). */
2911 struct load_gather_sv_def
: public load_gather_sv_base
2914 build (function_builder
&b
, const function_group_info
&group
) const override
2916 b
.add_overloaded_functions (group
, MODE_index
);
2917 b
.add_overloaded_functions (group
, MODE_offset
);
2918 build_sv_index (b
, "t0,al,d", group
);
2919 build_sv_offset (b
, "t0,al,d", group
);
2922 SHAPE (load_gather_sv
)
2924 /* sv<t0>_t svfoo_[u32]index[_t0](const <t0>_t *, svuint32_t)
2925 sv<t0>_t svfoo_[u64]index[_t0](const <t0>_t *, svuint64_t)
2927 sv<t0>_t svfoo_[s64]offset[_t0](const <t0>_t *, svint64_t)
2928 sv<t0>_t svfoo_[u32]offset[_t0](const <t0>_t *, svuint32_t)
2929 sv<t0>_t svfoo_[u64]offset[_t0](const <t0>_t *, svuint64_t)
2931 This is load_gather_sv without the 32-bit vector index forms and
2932 without the s32 vector offset form. */
2933 struct load_gather_sv_restricted_def
: public load_gather_sv_base
2936 build (function_builder
&b
, const function_group_info
&group
) const override
2938 b
.add_overloaded_functions (group
, MODE_index
);
2939 b
.add_overloaded_functions (group
, MODE_offset
);
2940 build_sv_index64 (b
, "t0,al,d", group
);
2941 build_sv_uint_offset (b
, "t0,al,d", group
);
2944 SHAPE (load_gather_sv_restricted
)
2946 /* sv<t0>_t svfoo[_u32base]_t0(svuint32_t)
2947 sv<t0>_t svfoo[_u64base]_t0(svuint64_t)
2949 sv<t0>_t svfoo[_u32base]_index_t0(svuint32_t, int64_t)
2950 sv<t0>_t svfoo[_u64base]_index_t0(svuint64_t, int64_t)
2952 sv<t0>_t svfoo[_u32base]_offset_t0(svuint32_t, int64_t)
2953 sv<t0>_t svfoo[_u64base]_offset_t0(svuint64_t, int64_t). */
2954 struct load_gather_vs_def
: public overloaded_base
<1>
2957 build (function_builder
&b
, const function_group_info
&group
) const override
2959 /* The base vector mode is optional; the full name has it but the
2960 short name doesn't. There is no ambiguity with SHAPE_load_gather_sv
2961 because the latter uses an implicit type suffix. */
2962 build_v_base (b
, "t0,b", group
, true);
2963 build_vs_index (b
, "t0,b,ss64", group
, true);
2964 build_vs_offset (b
, "t0,b,ss64", group
, true);
2968 resolve (function_resolver
&) const override
2970 /* The short name just makes the base vector mode implicit;
2971 no resolution is needed. */
2975 SHAPE (load_gather_vs
)
2977 /* sv<t0>_t svfoo[_t0](const <t0>_t *)
2979 The only difference from "load" is that this shape has no vnum form. */
2980 struct load_replicate_def
: public load_contiguous_base
2983 build (function_builder
&b
, const function_group_info
&group
) const override
2985 b
.add_overloaded_functions (group
, MODE_none
);
2986 build_all (b
, "t0,al", group
, MODE_none
);
2989 SHAPE (load_replicate
)
2991 /* void svfoo_t0(uint64_t, uint32_t, svbool_t, const void *)
2992 void svfoo_vnum_t0(uint64_t, uint32_t, svbool_t, const void *, int64_t)
2994 where the first two fields form a (ZA tile, slice) pair. */
2995 struct load_za_def
: public nonoverloaded_base
2998 build (function_builder
&b
, const function_group_info
&group
) const override
3000 build_all (b
, "_,su64,su32,vp,al", group
, MODE_none
);
3001 build_all (b
, "_,su64,su32,vp,al,ss64", group
, MODE_vnum
);
3005 check (function_checker
&c
) const override
3007 return c
.require_immediate_range (0, 0, c
.num_za_tiles () - 1);
3012 using luti2_lane_zt_def
= luti_lane_zt_base
<2>;
3013 SHAPE (luti2_lane_zt
)
3015 using luti4_lane_zt_def
= luti_lane_zt_base
<4>;
3016 SHAPE (luti4_lane_zt
)
3018 /* svbool_t svfoo(enum svpattern). */
3019 struct pattern_pred_def
: public nonoverloaded_base
3022 build (function_builder
&b
, const function_group_info
&group
) const override
3024 build_all (b
, "vp,epattern", group
, MODE_none
);
3027 SHAPE (pattern_pred
)
3029 /* void svfoo(const void *, svprfop)
3030 void svfoo_vnum(const void *, int64_t, svprfop). */
3031 struct prefetch_def
: public nonoverloaded_base
3034 build (function_builder
&b
, const function_group_info
&group
) const override
3036 build_all (b
, "_,ap,eprfop", group
, MODE_none
);
3037 build_all (b
, "_,ap,ss64,eprfop", group
, MODE_vnum
);
3042 /* void svfoo_[s32]index(const void *, svint32_t, svprfop)
3043 void svfoo_[s64]index(const void *, svint64_t, svprfop)
3044 void svfoo_[u32]index(const void *, svuint32_t, svprfop)
3045 void svfoo_[u64]index(const void *, svuint64_t, svprfop)
3047 void svfoo[_u32base](svuint32_t, svprfop)
3048 void svfoo[_u64base](svuint64_t, svprfop)
3050 void svfoo[_u32base]_index(svuint32_t, int64_t, svprfop)
3051 void svfoo[_u64base]_index(svuint64_t, int64_t, svprfop). */
3052 struct prefetch_gather_index_def
: public prefetch_gather_base
3055 build (function_builder
&b
, const function_group_info
&group
) const override
3057 b
.add_overloaded_functions (group
, MODE_none
);
3058 b
.add_overloaded_functions (group
, MODE_index
);
3059 build_sv_index (b
, "_,ap,d,eprfop", group
);
3060 build_v_base (b
, "_,b,eprfop", group
);
3061 build_vs_index (b
, "_,b,ss64,eprfop", group
);
3064 SHAPE (prefetch_gather_index
)
3066 /* void svfoo_[s32]offset(const void *, svint32_t, svprfop)
3067 void svfoo_[s64]offset(const void *, svint64_t, svprfop)
3068 void svfoo_[u32]offset(const void *, svuint32_t, svprfop)
3069 void svfoo_[u64]offset(const void *, svuint64_t, svprfop)
3071 void svfoo[_u32base](svuint32_t, svprfop)
3072 void svfoo[_u64base](svuint64_t, svprfop)
3074 void svfoo[_u32base]_offset(svuint32_t, int64_t, svprfop)
3075 void svfoo[_u64base]_offset(svuint64_t, int64_t, svprfop). */
3076 struct prefetch_gather_offset_def
: public prefetch_gather_base
3079 build (function_builder
&b
, const function_group_info
&group
) const override
3081 b
.add_overloaded_functions (group
, MODE_none
);
3082 b
.add_overloaded_functions (group
, MODE_offset
);
3083 build_sv_offset (b
, "_,ap,d,eprfop", group
);
3084 build_v_base (b
, "_,b,eprfop", group
);
3085 build_vs_offset (b
, "_,b,ss64,eprfop", group
);
3088 SHAPE (prefetch_gather_offset
)
3090 /* bool svfoo(svbool_t). */
3091 struct ptest_def
: public nonoverloaded_base
3094 build (function_builder
&b
, const function_group_info
&group
) const override
3096 build_all (b
, "sp,vp", group
, MODE_none
);
3101 /* svbool_t svfoo(). */
3102 struct rdffr_def
: public nonoverloaded_base
3105 build (function_builder
&b
, const function_group_info
&group
) const override
3107 build_all (b
, "vp", group
, MODE_none
);
3112 /* sv<t1>x<g>_t svfoo_t0_t1_g(uint64_t, uint32_t). */
3113 struct read_za_def
: public nonoverloaded_base
3116 build (function_builder
&b
, const function_group_info
&group
) const override
3118 build_all (b
, "t1,su64,su32", group
, MODE_none
);
3122 check (function_checker
&c
) const override
3124 return c
.require_immediate_range (0, 0, c
.num_za_tiles () - 1);
3129 /* sv<t1>_t svfoo_t0[_t1](uint64_t, uint32_t)
3131 where the first two fields form a (ZA tile, slice) pair. */
3132 struct read_za_m_def
: public overloaded_base
<1>
3135 has_merge_argument_p (const function_instance
&, unsigned int) const override
3141 build (function_builder
&b
, const function_group_info
&group
) const override
3143 b
.add_overloaded_functions (group
, MODE_none
);
3144 build_all (b
, "t1,su64,su32", group
, MODE_none
);
3148 resolve (function_resolver
&r
) const override
3150 gcc_assert (r
.pred
== PRED_m
);
3151 type_suffix_index type
;
3152 if (!r
.check_num_arguments (4)
3153 || (type
= r
.infer_vector_type (0)) == NUM_TYPE_SUFFIXES
3154 || !r
.require_vector_type (1, VECTOR_TYPE_svbool_t
)
3155 || !r
.require_integer_immediate (2)
3156 || !r
.require_scalar_type (3, "uint32_t"))
3157 return error_mark_node
;
3159 return r
.resolve_to (r
.mode_suffix_id
, r
.type_suffix_ids
[0], type
);
3163 check (function_checker
&c
) const override
3165 gcc_assert (c
.pred
== PRED_m
);
3166 return c
.require_immediate_range (1, 0, c
.num_za_tiles () - 1);
3171 /* sv<t1>x<g>_t svfoo_t0_t1_g(uint32_t). */
3172 struct read_za_slice_def
: public nonoverloaded_base
3175 build (function_builder
&b
, const function_group_info
&group
) const override
3177 build_all (b
, "t1,su32", group
, MODE_none
);
3180 SHAPE (read_za_slice
)
3182 /* <t0>_t svfoo[_t0](sv<t0>_t). */
3183 struct reduction_def
: public overloaded_base
<0>
3186 build (function_builder
&b
, const function_group_info
&group
) const override
3188 b
.add_overloaded_functions (group
, MODE_none
);
3189 build_all (b
, "s0,v0", group
, MODE_none
);
3193 resolve (function_resolver
&r
) const override
3195 return r
.resolve_uniform (1);
3200 /* int64_t svfoo[_t0](sv<t0>_t) (for signed t0)
3201 uint64_t svfoo[_t0](sv<t0>_t) (for unsigned t0)
3202 <t0>_t svfoo[_t0](sv<t0>_t) (for floating-point t0)
3204 i.e. a version of "reduction" in which the return type for integers
3205 always has 64 bits. */
3206 struct reduction_wide_def
: public overloaded_base
<0>
3209 build (function_builder
&b
, const function_group_info
&group
) const override
3211 b
.add_overloaded_functions (group
, MODE_none
);
3212 build_all (b
, "sw0,v0", group
, MODE_none
);
3216 resolve (function_resolver
&r
) const override
3218 return r
.resolve_uniform (1);
3221 SHAPE (reduction_wide
)
3223 /* sv<t0>x<g>_t svfoo_t0[_t1_g](sv<t1>x<g>_t)
3225 where the target type <t0> must be specified explicitly but the source
3226 type <t1> can be inferred. */
3227 struct reinterpret_def
: public overloaded_base
<1>
3229 bool explicit_group_suffix_p () const override
{ return false; }
3232 build (function_builder
&b
, const function_group_info
&group
) const override
3234 b
.add_overloaded_functions (group
, MODE_none
);
3235 build_all (b
, "t0,t1", group
, MODE_none
);
3239 resolve (function_resolver
&r
) const override
3242 if (!r
.check_num_arguments (1)
3243 || !(type
= r
.infer_sve_type (0)))
3244 return error_mark_node
;
3246 return r
.resolve_to (r
.mode_suffix_id
, type
);
3251 /* sv<t0>_t svfoo_t0(sv<t0>_t, sv<t0>_t, uint32_t). */
3252 struct select_pred_def
: public nonoverloaded_base
3255 build (function_builder
&b
, const function_group_info
&group
) const override
3257 build_all (b
, "v0,v0,vp,su32", group
, MODE_none
);
3262 /* sv<t0>xN_t svfoo[_t0](sv<t0>xN_t, uint64_t, sv<t0>_t)
3264 where the second argument is an integer constant expression in the
3265 range [0, N - 1]. */
3266 struct set_def
: public overloaded_base
<0>
3269 build (function_builder
&b
, const function_group_info
&group
) const override
3271 b
.add_overloaded_functions (group
, MODE_none
);
3272 build_all (b
, "t0,t0,su64,v0", group
, MODE_none
);
3276 resolve (function_resolver
&r
) const override
3278 unsigned int i
, nargs
;
3280 if (!r
.check_gp_argument (3, i
, nargs
)
3281 || !(type
= r
.infer_tuple_type (i
))
3282 || !r
.require_integer_immediate (i
+ 1)
3283 || !r
.require_derived_vector_type (i
+ 2, i
, type
))
3284 return error_mark_node
;
3286 return r
.resolve_to (r
.mode_suffix_id
, type
);
3290 check (function_checker
&c
) const override
3292 unsigned int nvectors
= c
.vectors_per_tuple ();
3293 return c
.require_immediate_range (1, 0, nvectors
- 1);
3299 struct setffr_def
: public nonoverloaded_base
3302 build (function_builder
&b
, const function_group_info
&group
) const override
3304 build_all (b
, "_", group
, MODE_none
);
3309 /* sv<t0>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
3311 where the final argument must be an integer constant expression in the
3312 range [0, sizeof (<t0>_t) * 8 - 1]. */
3313 struct shift_left_imm_def
: public overloaded_base
<0>
3316 build (function_builder
&b
, const function_group_info
&group
) const override
3318 b
.add_overloaded_functions (group
, MODE_n
);
3319 build_all (b
, "v0,v0,su64", group
, MODE_n
);
3323 resolve (function_resolver
&r
) const override
3325 return r
.resolve_uniform (1, 1);
3329 check (function_checker
&c
) const override
3331 unsigned int bits
= c
.type_suffix (0).element_bits
;
3332 return c
.require_immediate_range (1, 0, bits
- 1);
3335 SHAPE (shift_left_imm
)
3337 /* sv<t0>_t svfoo[_n_t0])(sv<t0:half>_t, uint64_t)
3339 where the final argument must be an integer constant expression in the
3340 range [0, sizeof (<t0>_t) * 4 - 1]. */
3341 struct shift_left_imm_long_def
: public binary_imm_long_base
3344 check (function_checker
&c
) const override
3346 unsigned int bits
= c
.type_suffix (0).element_bits
/ 2;
3347 return c
.require_immediate_range (1, 0, bits
- 1);
3350 SHAPE (shift_left_imm_long
)
3352 /* sv<t0:uint>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
3354 where the final argument must be an integer constant expression in the
3355 range [0, sizeof (<t0>_t) * 8 - 1]. */
3356 struct shift_left_imm_to_uint_def
: public shift_left_imm_def
3359 build (function_builder
&b
, const function_group_info
&group
) const override
3361 b
.add_overloaded_functions (group
, MODE_n
);
3362 build_all (b
, "vu0,v0,su64", group
, MODE_n
);
3365 SHAPE (shift_left_imm_to_uint
)
3367 /* sv<t0>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
3369 where the final argument must be an integer constant expression in the
3370 range [1, sizeof (<t0>_t) * 8]. */
3371 struct shift_right_imm_def
: public overloaded_base
<0>
3374 build (function_builder
&b
, const function_group_info
&group
) const override
3376 b
.add_overloaded_functions (group
, MODE_n
);
3377 build_all (b
, "v0,v0,su64", group
, MODE_n
);
3381 resolve (function_resolver
&r
) const override
3383 return r
.resolve_uniform (1, 1);
3387 check (function_checker
&c
) const override
3389 unsigned int bits
= c
.type_suffix (0).element_bits
;
3390 return c
.require_immediate_range (1, 1, bits
);
3393 SHAPE (shift_right_imm
)
3395 /* sv<t0:half>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
3397 where the final argument must be an integer constant expression in the
3398 range [1, sizeof (<t0>_t) * 4]. */
3399 typedef shift_right_imm_narrow_wrapper
<binary_imm_narrowb_base
<>, 1>
3400 shift_right_imm_narrowb_def
;
3401 SHAPE (shift_right_imm_narrowb
)
3403 /* sv<t0:half>_t svfoo[_n_t0])(sv<t0:half>_t, sv<t0>_t, uint64_t)
3405 where the final argument must be an integer constant expression in the
3406 range [1, sizeof (<t0>_t) * 4]. */
3407 typedef shift_right_imm_narrow_wrapper
<binary_imm_narrowt_base
<>, 2>
3408 shift_right_imm_narrowt_def
;
3409 SHAPE (shift_right_imm_narrowt
)
3411 /* sv<t0:uint:half>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
3413 where the final argument must be an integer constant expression in the
3414 range [1, sizeof (<t0>_t) * 4]. */
3415 typedef binary_imm_narrowb_base
<TYPE_unsigned
>
3416 binary_imm_narrowb_base_unsigned
;
3417 typedef shift_right_imm_narrow_wrapper
<binary_imm_narrowb_base_unsigned
, 1>
3418 shift_right_imm_narrowb_to_uint_def
;
3419 SHAPE (shift_right_imm_narrowb_to_uint
)
3421 /* sv<t0:uint:half>_t svfoo[_n_t0])(sv<t0:uint:half>_t, sv<t0>_t, uint64_t)
3423 where the final argument must be an integer constant expression in the
3424 range [1, sizeof (<t0>_t) * 4]. */
3425 typedef binary_imm_narrowt_base
<TYPE_unsigned
>
3426 binary_imm_narrowt_base_unsigned
;
3427 typedef shift_right_imm_narrow_wrapper
<binary_imm_narrowt_base_unsigned
, 2>
3428 shift_right_imm_narrowt_to_uint_def
;
3429 SHAPE (shift_right_imm_narrowt_to_uint
)
3431 /* sv<t0>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
3433 where the final argument must be an integer constant expression in the
3434 range [1, sizeof (<t0>_t) * 8]. */
3435 struct shift_right_imm_narrowxn_def
: public overloaded_base
<1>
3437 bool explicit_group_suffix_p () const override
{ return false; }
3440 build (function_builder
&b
, const function_group_info
&group
) const override
3442 b
.add_overloaded_functions (group
, MODE_n
);
3443 build_all (b
, "c0,c1,su64", group
, MODE_n
);
3447 resolve (function_resolver
&r
) const override
3450 if (!r
.check_num_arguments (2)
3451 || !(type
= r
.infer_sve_type (0))
3452 || !r
.require_integer_immediate (1))
3453 return error_mark_node
;
3454 return r
.resolve_to (r
.mode_suffix_id
, type
);
3458 check (function_checker
&c
) const override
3460 unsigned int suffix
= c
.group_suffix_id
== GROUP_x4
? 1 : 0;
3461 unsigned int bits
= c
.type_suffix (suffix
).element_bits
;
3462 return c
.require_immediate_range (1, 1, bits
);
3465 SHAPE (shift_right_imm_narrowxn
)
3467 /* void svfoo[_t0](<X>_t *, sv<t0>[xN]_t)
3468 void svfoo_vnum[_t0](<X>_t *, int64_t, sv<t0>[xN]_t)
3470 where <X> might be tied to <t0> (for non-truncating stores) or might
3471 depend on the function base name (for truncating stores). */
3472 struct store_def
: public overloaded_base
<0>
3475 build (function_builder
&b
, const function_group_info
&group
) const override
3477 b
.add_overloaded_functions (group
, MODE_none
);
3478 b
.add_overloaded_functions (group
, MODE_vnum
);
3479 build_all (b
, "_,as,t0", group
, MODE_none
);
3480 build_all (b
, "_,as,ss64,t0", group
, MODE_vnum
);
3484 resolve (function_resolver
&r
) const override
3486 bool vnum_p
= r
.mode_suffix_id
== MODE_vnum
;
3487 gcc_assert (r
.mode_suffix_id
== MODE_none
|| vnum_p
);
3489 unsigned int i
, nargs
;
3491 if (!r
.check_gp_argument (vnum_p
? 3 : 2, i
, nargs
)
3492 || !r
.require_pointer_type (i
)
3493 || (vnum_p
&& !r
.require_scalar_type (i
+ 1, "int64_t"))
3494 || !(type
= r
.infer_tuple_type (nargs
- 1)))
3495 return error_mark_node
;
3497 return r
.resolve_to (r
.mode_suffix_id
, type
);
3502 /* void svfoo_[s32]index[_t0](<X>_t *, svint32_t, sv<t0>_t)
3503 void svfoo_[s64]index[_t0](<X>_t *, svint64_t, sv<t0>_t)
3504 void svfoo_[u32]index[_t0](<X>_t *, svuint32_t, sv<t0>_t)
3505 void svfoo_[u64]index[_t0](<X>_t *, svuint64_t, sv<t0>_t)
3507 void svfoo[_u32base]_index[_t0](svuint32_t, int64_t, sv<t0>_t)
3508 void svfoo[_u64base]_index[_t0](svuint64_t, int64_t, sv<t0>_t)
3510 where <X> might be tied to <t0> (for non-truncating stores) or might
3511 depend on the function base name (for truncating stores). */
3512 struct store_scatter_index_def
: public store_scatter_base
3515 build (function_builder
&b
, const function_group_info
&group
) const override
3517 b
.add_overloaded_functions (group
, MODE_index
);
3518 build_sv_index (b
, "_,as,d,t0", group
);
3519 build_vs_index (b
, "_,b,ss64,t0", group
);
3522 SHAPE (store_scatter_index
)
3524 /* void svfoo_[s64]index[_t0](<X>_t *, svint64_t, sv<t0>_t)
3525 void svfoo_[u64]index[_t0](<X>_t *, svuint64_t, sv<t0>_t)
3527 void svfoo[_u32base]_index[_t0](svuint32_t, int64_t, sv<t0>_t)
3528 void svfoo[_u64base]_index[_t0](svuint64_t, int64_t, sv<t0>_t)
3530 i.e. a version of store_scatter_index that doesn't support 32-bit
3532 struct store_scatter_index_restricted_def
: public store_scatter_base
3535 build (function_builder
&b
, const function_group_info
&group
) const override
3537 b
.add_overloaded_functions (group
, MODE_index
);
3538 build_sv_index64 (b
, "_,as,d,t0", group
);
3539 build_vs_index (b
, "_,b,ss64,t0", group
);
3542 SHAPE (store_scatter_index_restricted
)
3544 /* void svfoo_[s32]offset[_t0](<X>_t *, svint32_t, sv<t0>_t)
3545 void svfoo_[s64]offset[_t0](<X>_t *, svint64_t, sv<t0>_t)
3546 void svfoo_[u32]offset[_t0](<X>_t *, svuint32_t, sv<t0>_t)
3547 void svfoo_[u64]offset[_t0](<X>_t *, svuint64_t, sv<t0>_t)
3549 void svfoo[_u32base_t0](svuint32_t, sv<t0>_t)
3550 void svfoo[_u64base_t0](svuint64_t, sv<t0>_t)
3552 void svfoo[_u32base]_offset[_t0](svuint32_t, int64_t, sv<t0>_t)
3553 void svfoo[_u64base]_offset[_t0](svuint64_t, int64_t, sv<t0>_t)
3555 where <X> might be tied to <t0> (for non-truncating stores) or might
3556 depend on the function base name (for truncating stores). */
3557 struct store_scatter_offset_def
: public store_scatter_base
3560 build (function_builder
&b
, const function_group_info
&group
) const override
3562 b
.add_overloaded_functions (group
, MODE_none
);
3563 b
.add_overloaded_functions (group
, MODE_offset
);
3564 build_sv_offset (b
, "_,as,d,t0", group
);
3565 build_v_base (b
, "_,b,t0", group
);
3566 build_vs_offset (b
, "_,b,ss64,t0", group
);
3569 SHAPE (store_scatter_offset
)
3571 /* void svfoo_[s64]offset[_t0](<X>_t *, svint64_t, sv<t0>_t)
3572 void svfoo_[u32]offset[_t0](<X>_t *, svuint32_t, sv<t0>_t)
3573 void svfoo_[u64]offset[_t0](<X>_t *, svuint64_t, sv<t0>_t)
3575 void svfoo[_u32base_t0](svuint32_t, sv<t0>_t)
3576 void svfoo[_u64base_t0](svuint64_t, sv<t0>_t)
3578 void svfoo[_u32base]_offset[_t0](svuint32_t, int64_t, sv<t0>_t)
3579 void svfoo[_u64base]_offset[_t0](svuint64_t, int64_t, sv<t0>_t)
3581 i.e. a version of store_scatter_offset that doesn't support svint32_t
3583 struct store_scatter_offset_restricted_def
: public store_scatter_base
3586 build (function_builder
&b
, const function_group_info
&group
) const override
3588 b
.add_overloaded_functions (group
, MODE_none
);
3589 b
.add_overloaded_functions (group
, MODE_offset
);
3590 build_sv_uint_offset (b
, "_,as,d,t0", group
);
3591 build_v_base (b
, "_,b,t0", group
);
3592 build_vs_offset (b
, "_,b,ss64,t0", group
);
3595 SHAPE (store_scatter_offset_restricted
)
3597 /* void svfoo_t0(uint64_t, uint32_t, svbool_t, void *)
3598 void svfoo_vnum_t0(uint64_t, uint32_t, svbool_t, void *, int64_t)
3600 where the first two fields form a (ZA tile, slice) pair. */
3601 struct store_za_def
: public nonoverloaded_base
3604 build (function_builder
&b
, const function_group_info
&group
) const override
3606 build_all (b
, "_,su64,su32,vp,as", group
, MODE_none
);
3607 build_all (b
, "_,su64,su32,vp,as,ss64", group
, MODE_vnum
);
3611 check (function_checker
&c
) const override
3613 return c
.require_immediate_range (0, 0, c
.num_za_tiles () - 1);
3618 /* void svfoo[_t0_g](<X>_t *, sv<t0>x<g>_t)
3619 void svfoo_vnum[_t0_g](<X>_t *, int64_t, sv<t0>x<g>_t)
3621 where <X> might be tied to <t0> (for non-truncating stores) or might
3622 depend on the function base name (for truncating stores). */
3623 struct storexn_def
: public store_def
3625 bool explicit_group_suffix_p () const override
{ return false; }
3628 resolve (function_resolver
&r
) const override
3630 bool vnum_p
= r
.mode_suffix_id
== MODE_vnum
;
3631 gcc_assert (r
.mode_suffix_id
== MODE_none
|| vnum_p
);
3633 unsigned int nargs
= vnum_p
? 4 : 3;
3634 vector_type_index pred_type
;
3636 if (!r
.check_num_arguments (nargs
)
3637 || (pred_type
= r
.infer_predicate_type (0)) == NUM_VECTOR_TYPES
3638 || !r
.require_pointer_type (1)
3639 || (vnum_p
&& !r
.require_scalar_type (2, "int64_t"))
3640 || !(type
= r
.infer_sve_type (nargs
- 1))
3641 || !r
.require_matching_predicate_type (pred_type
, type
))
3642 return error_mark_node
;
3644 return r
.resolve_to (r
.mode_suffix_id
, type
);
3649 /* void svfoo_t0(uint32_t, void *)
3650 void svfoo_vnum_t0(uint32_t, void *, int64_t)
3652 where the first argument is a variable ZA slice. */
3653 struct str_za_def
: public nonoverloaded_base
3656 build (function_builder
&b
, const function_group_info
&group
) const override
3658 build_all (b
, "_,su32,as", group
, MODE_none
);
3659 build_all (b
, "_,su32,as,ss64", group
, MODE_vnum
);
3664 /* void svfoo_zt(uint64_t, void *)
3666 where the first argument must be zero. */
3667 struct str_zt_def
: public nonoverloaded_base
3670 build (function_builder
&b
, const function_group_info
&group
) const override
3672 build_all (b
, "_,su64,as", group
, MODE_none
);
3676 check (function_checker
&c
) const override
3678 return c
.require_immediate_range (0, 0, 0);
3683 /* sv<t0>_t svfoo[_t0](sv<t0>xN_t, sv<t0:uint>_t). */
3684 struct tbl_tuple_def
: public overloaded_base
<0>
3687 build (function_builder
&b
, const function_group_info
&group
) const override
3689 b
.add_overloaded_functions (group
, MODE_none
);
3690 build_all (b
, "v0,t0,vu0", group
, MODE_none
);
3694 resolve (function_resolver
&r
) const override
3696 unsigned int i
, nargs
;
3698 if (!r
.check_gp_argument (2, i
, nargs
)
3699 || !(type
= r
.infer_tuple_type (i
))
3700 || !r
.require_derived_vector_type (i
+ 1, i
, type
, TYPE_unsigned
))
3701 return error_mark_node
;
3703 return r
.resolve_to (r
.mode_suffix_id
, type
);
3708 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbfloatt16_t, svbfloat16_t). */
3709 struct ternary_bfloat_def
3710 : public ternary_resize2_base
<16, TYPE_bfloat
, TYPE_bfloat
>
3713 build (function_builder
&b
, const function_group_info
&group
) const override
3715 b
.add_overloaded_functions (group
, MODE_none
);
3716 build_all (b
, "v0,v0,vB,vB", group
, MODE_none
);
3719 SHAPE (ternary_bfloat
)
3721 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbfloat16_t, svbfloat16_t, uint64_t)
3723 where the final argument is an integer constant expression in the range
3725 typedef ternary_bfloat_lane_base
<1> ternary_bfloat_lane_def
;
3726 SHAPE (ternary_bfloat_lane
)
3728 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbfloat16_t, svbfloat16_t, uint64_t)
3730 where the final argument is an integer constant expression in the range
3732 typedef ternary_bfloat_lane_base
<2> ternary_bfloat_lanex2_def
;
3733 SHAPE (ternary_bfloat_lanex2
)
3735 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbfloatt16_t, svbfloat16_t)
3736 sv<t0>_t svfoo[_n_t0](sv<t0>_t, svbfloat16_t, bfloat16_t). */
3737 struct ternary_bfloat_opt_n_def
3738 : public ternary_resize2_opt_n_base
<16, TYPE_bfloat
, TYPE_bfloat
>
3741 build (function_builder
&b
, const function_group_info
&group
) const override
3743 b
.add_overloaded_functions (group
, MODE_none
);
3744 build_all (b
, "v0,v0,vB,vB", group
, MODE_none
);
3745 build_all (b
, "v0,v0,vB,sB", group
, MODE_n
);
3748 SHAPE (ternary_bfloat_opt_n
)
3750 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:int:quarter>_t, sv<t0:uint:quarter>_t,
3753 where the final argument is an integer constant expression in the range
3754 [0, 16 / sizeof (<t0>_t) - 1]. */
3755 struct ternary_intq_uintq_lane_def
3756 : public ternary_qq_lane_base
<TYPE_signed
, TYPE_unsigned
>
3759 build (function_builder
&b
, const function_group_info
&group
) const override
3761 b
.add_overloaded_functions (group
, MODE_none
);
3762 build_all (b
, "v0,v0,vqs0,vqu0,su64", group
, MODE_none
);
3765 SHAPE (ternary_intq_uintq_lane
)
3767 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:int:quarter>_t, sv<t0:uint:quarter>_t)
3768 sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0:int:quarter>_t,
3769 <t0:uint:quarter>_t). */
3770 struct ternary_intq_uintq_opt_n_def
3771 : public ternary_resize2_opt_n_base
<function_resolver::QUARTER_SIZE
,
3772 TYPE_signed
, TYPE_unsigned
>
3775 build (function_builder
&b
, const function_group_info
&group
) const override
3777 b
.add_overloaded_functions (group
, MODE_none
);
3778 build_all (b
, "v0,v0,vqs0,vqu0", group
, MODE_none
);
3779 build_all (b
, "v0,v0,vqs0,squ0", group
, MODE_n
);
3782 SHAPE (ternary_intq_uintq_opt_n
)
3784 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, sv<t0>_t, uint64_t)
3786 where the final argument is an integer constant expression in the
3787 range [0, 16 / sizeof (<t0>_t) - 1]. */
3788 struct ternary_lane_def
: public overloaded_base
<0>
3791 build (function_builder
&b
, const function_group_info
&group
) const override
3793 b
.add_overloaded_functions (group
, MODE_none
);
3794 build_all (b
, "v0,v0,v0,v0,su64", group
, MODE_none
);
3798 resolve (function_resolver
&r
) const override
3800 return r
.resolve_uniform (3, 1);
3804 check (function_checker
&c
) const override
3806 return c
.require_immediate_lane_index (3, 2);
3809 SHAPE (ternary_lane
)
3811 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, sv<t0>_t, uint64_t, uint64_t)
3813 where the penultimate argument is an integer constant expression in
3814 the range [0, 8 / sizeof (<t0>_t) - 1] and where the final argument
3815 is an integer constant expression in {0, 90, 180, 270}. */
3816 struct ternary_lane_rotate_def
: public overloaded_base
<0>
3819 build (function_builder
&b
, const function_group_info
&group
) const override
3821 b
.add_overloaded_functions (group
, MODE_none
);
3822 build_all (b
, "v0,v0,v0,v0,su64,su64", group
, MODE_none
);
3826 resolve (function_resolver
&r
) const override
3828 return r
.resolve_uniform (3, 2);
3832 check (function_checker
&c
) const override
3834 return (c
.require_immediate_lane_index (3, 2, 2)
3835 && c
.require_immediate_one_of (4, 0, 90, 180, 270));
3838 SHAPE (ternary_lane_rotate
)
3840 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:half>_t, sv<t0:half>_t, uint64_t)
3842 where the final argument is an integer constant expression in the range
3843 [0, 32 / sizeof (<t0>_t) - 1]. */
3844 struct ternary_long_lane_def
3845 : public ternary_resize2_lane_base
<function_resolver::HALF_SIZE
>
3848 build (function_builder
&b
, const function_group_info
&group
) const override
3850 b
.add_overloaded_functions (group
, MODE_none
);
3851 build_all (b
, "v0,v0,vh0,vh0,su64", group
, MODE_none
);
3855 check (function_checker
&c
) const override
3857 return c
.require_immediate_lane_index (3, 2);
3860 SHAPE (ternary_long_lane
)
3862 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:half>_t, sv<t0:half>_t)
3863 sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0:half>_t, <t0:half>_t)
3865 i.e. a version of the standard ternary shape ternary_opt_n in which
3866 the element type of the last two arguments is the half-sized
3867 equivalent of <t0>. */
3868 struct ternary_long_opt_n_def
3869 : public ternary_resize2_opt_n_base
<function_resolver::HALF_SIZE
>
3872 build (function_builder
&b
, const function_group_info
&group
) const override
3874 b
.add_overloaded_functions (group
, MODE_none
);
3875 build_all (b
, "v0,v0,vh0,vh0", group
, MODE_none
);
3876 build_all (b
, "v0,v0,vh0,sh0", group
, MODE_n
);
3879 SHAPE (ternary_long_opt_n
)
3881 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t, sv<t0>_t)
3882 sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0>_t, <t0>_t)
3884 i.e. the standard shape for ternary operations that operate on
3886 struct ternary_opt_n_def
: public overloaded_base
<0>
3889 build (function_builder
&b
, const function_group_info
&group
) const override
3891 b
.add_overloaded_functions (group
, MODE_none
);
3892 build_all (b
, "v0,v0,v0,v0", group
, MODE_none
);
3893 build_all (b
, "v0,v0,v0,s0", group
, MODE_n
);
3897 resolve (function_resolver
&r
) const override
3899 return r
.resolve_uniform_opt_n (3);
3902 SHAPE (ternary_opt_n
)
3904 /* A choice between:
3906 (1) sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:quarter>_t, sv<t0:quarter>_t,
3909 (2) sv<t0>_t svfoo[_t0_t1](sv<t0>_t, sv<t1>_t, sv<t1>_t, uint64_t)
3911 where the final argument is an integer constant expression in the range
3912 [0, 16 / sizeof (<t0>_t) - 1]. */
3913 struct ternary_qq_or_011_lane_def
: public ternary_qq_lane_base
<>
3916 build (function_builder
&b
, const function_group_info
&group
) const override
3918 b
.add_overloaded_functions (group
, MODE_none
);
3919 if (group
.types
[0][1] == NUM_TYPE_SUFFIXES
)
3920 build_all (b
, "v0,v0,vq0,vq0,su64", group
, MODE_none
);
3922 build_all (b
, "v0,v0,v1,v1,su64", group
, MODE_none
);
3926 resolve (function_resolver
&r
) const override
3928 unsigned int i
, nargs
;
3929 type_suffix_index type0
, type1
;
3930 if (!r
.check_gp_argument (4, i
, nargs
)
3931 || (type0
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
3932 || (type1
= r
.infer_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
3933 || !r
.require_matching_vector_type (i
+ 2, i
+ 1, type1
)
3934 || !r
.require_integer_immediate (i
+ 3))
3935 return error_mark_node
;
3937 if ((type_suffixes
[type0
].element_bits
3938 == 4 * type_suffixes
[type1
].element_bits
)
3939 && type_suffixes
[type0
].tclass
== type_suffixes
[type1
].tclass
)
3940 if (tree res
= r
.lookup_form (MODE_none
, type0
))
3943 return r
.resolve_to (r
.mode_suffix_id
, type0
, type1
);
3946 SHAPE (ternary_qq_or_011_lane
)
3948 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0:quarter>_t, sv<t0:quarter>_t,
3951 where the final argument is an integer constant expression in
3952 {0, 90, 180, 270}. */
3953 struct ternary_qq_lane_rotate_def
: public overloaded_base
<0>
3956 build (function_builder
&b
, const function_group_info
&group
) const override
3958 b
.add_overloaded_functions (group
, MODE_none
);
3959 build_all (b
, "v0,v0,vq0,vq0,su64,su64", group
, MODE_none
);
3963 resolve (function_resolver
&r
) const override
3965 unsigned int i
, nargs
;
3966 type_suffix_index type
;
3967 if (!r
.check_gp_argument (5, i
, nargs
)
3968 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
3969 || !r
.require_derived_vector_type (i
+ 1, i
, type
, r
.SAME_TYPE_CLASS
,
3971 || !r
.require_derived_vector_type (i
+ 2, i
, type
, r
.SAME_TYPE_CLASS
,
3973 || !r
.require_integer_immediate (i
+ 3)
3974 || !r
.require_integer_immediate (i
+ 4))
3975 return error_mark_node
;
3977 return r
.resolve_to (r
.mode_suffix_id
, type
);
3981 check (function_checker
&c
) const override
3983 return (c
.require_immediate_lane_index (3, 0)
3984 && c
.require_immediate_one_of (4, 0, 90, 180, 270));
3987 SHAPE (ternary_qq_lane_rotate
)
3989 /* A choice between:
3991 (1) sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:quarter>_t, sv<t0:quarter>_t)
3992 sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0:quarter>_t, <t0:quarter>_t)
3994 i.e. a version of the standard ternary shape ternary_opt_n in which
3995 the element type of the last two arguments is the quarter-sized
3998 (2) sv<t0>_t svfoo[_t0_t1](sv<t0>_t, sv<t1>_t, sv<t1>_t)
4000 where the element type of the last two arguments is specified
4002 struct ternary_qq_opt_n_or_011_def
4003 : public ternary_resize2_opt_n_base
<function_resolver::QUARTER_SIZE
>
4006 build (function_builder
&b
, const function_group_info
&group
) const override
4008 b
.add_overloaded_functions (group
, MODE_none
);
4009 if (group
.types
[0][1] == NUM_TYPE_SUFFIXES
)
4011 build_all (b
, "v0,v0,vq0,vq0", group
, MODE_none
);
4012 build_all (b
, "v0,v0,vq0,sq0", group
, MODE_n
);
4015 build_all (b
, "v0,v0,v1,v1", group
, MODE_none
);
4019 resolve (function_resolver
&r
) const override
4021 unsigned int i
, nargs
;
4022 type_suffix_index type0
, type1
;
4023 if (!r
.check_gp_argument (3, i
, nargs
)
4024 || (type0
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
4025 || (type1
= r
.infer_vector_type (i
+ 1)) == NUM_TYPE_SUFFIXES
4026 || !r
.require_vector_or_scalar_type (i
+ 2))
4027 return error_mark_node
;
4029 auto mode
= r
.scalar_argument_p (i
+ 2) ? MODE_n
: MODE_none
;
4030 if (mode
== MODE_none
4031 && !r
.require_matching_vector_type (i
+ 2, i
+ 1, type1
))
4032 return error_mark_node
;
4034 if ((type_suffixes
[type0
].element_bits
4035 == 4 * type_suffixes
[type1
].element_bits
)
4036 && type_suffixes
[type0
].tclass
== type_suffixes
[type1
].tclass
)
4037 if (tree res
= r
.lookup_form (mode
, type0
))
4040 if (!r
.require_nonscalar_type (i
+ 2))
4041 return error_mark_node
;
4043 return r
.resolve_to (r
.mode_suffix_id
, type0
, type1
);
4046 SHAPE (ternary_qq_opt_n_or_011
)
4048 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0:quarter>_t, sv<t0:quarter>_t,
4051 where the final argument is an integer constant expression in
4052 {0, 90, 180, 270}. */
4053 struct ternary_qq_rotate_def
: public overloaded_base
<0>
4056 build (function_builder
&b
, const function_group_info
&group
) const override
4058 b
.add_overloaded_functions (group
, MODE_none
);
4059 build_all (b
, "v0,v0,vq0,vq0,su64", group
, MODE_none
);
4063 resolve (function_resolver
&r
) const override
4065 unsigned int i
, nargs
;
4066 type_suffix_index type
;
4067 if (!r
.check_gp_argument (4, i
, nargs
)
4068 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
4069 || !r
.require_derived_vector_type (i
+ 1, i
, type
, r
.SAME_TYPE_CLASS
,
4071 || !r
.require_derived_vector_type (i
+ 2, i
, type
, r
.SAME_TYPE_CLASS
,
4073 || !r
.require_integer_immediate (i
+ 3))
4074 return error_mark_node
;
4076 return r
.resolve_to (r
.mode_suffix_id
, type
);
4080 check (function_checker
&c
) const override
4082 return c
.require_immediate_one_of (3, 0, 90, 180, 270);
4085 SHAPE (ternary_qq_rotate
)
4087 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, sv<t0>_t, uint64_t)
4089 where the final argument is an integer constant expression in
4090 {0, 90, 180, 270}. */
4091 struct ternary_rotate_def
: public overloaded_base
<0>
4094 build (function_builder
&b
, const function_group_info
&group
) const override
4096 b
.add_overloaded_functions (group
, MODE_none
);
4097 build_all (b
, "v0,v0,v0,v0,su64", group
, MODE_none
);
4101 resolve (function_resolver
&r
) const override
4103 return r
.resolve_uniform (3, 1);
4107 check (function_checker
&c
) const override
4109 return c
.require_immediate_one_of (3, 0, 90, 180, 270);
4112 SHAPE (ternary_rotate
)
4114 /* sv<t0>_t svfoo[_n_t0])(sv<t0>_t, sv<t0>_t, uint64_t)
4116 where the final argument must be an integer constant expression in the
4117 range [0, sizeof (<t0>_t) * 8 - 1]. */
4118 struct ternary_shift_left_imm_def
: public ternary_shift_imm_base
4121 check (function_checker
&c
) const override
4123 unsigned int bits
= c
.type_suffix (0).element_bits
;
4124 return c
.require_immediate_range (2, 0, bits
- 1);
4127 SHAPE (ternary_shift_left_imm
)
4129 /* sv<t0>_t svfoo[_n_t0])(sv<t0>_t, sv<t0>_t, uint64_t)
4131 where the final argument must be an integer constant expression in the
4132 range [1, sizeof (<t0>_t) * 8]. */
4133 struct ternary_shift_right_imm_def
: public ternary_shift_imm_base
4136 check (function_checker
&c
) const override
4138 unsigned int bits
= c
.type_suffix (0).element_bits
;
4139 return c
.require_immediate_range (2, 1, bits
);
4142 SHAPE (ternary_shift_right_imm
)
4144 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t, sv<t0:uint>_t). */
4145 struct ternary_uint_def
: public overloaded_base
<0>
4148 build (function_builder
&b
, const function_group_info
&group
) const override
4150 b
.add_overloaded_functions (group
, MODE_none
);
4151 build_all (b
, "v0,v0,v0,vu0", group
, MODE_none
);
4155 resolve (function_resolver
&r
) const override
4157 unsigned int i
, nargs
;
4158 type_suffix_index type
;
4159 if (!r
.check_gp_argument (3, i
, nargs
)
4160 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
4161 || !r
.require_matching_vector_type (i
+ 1, i
, type
)
4162 || !r
.require_derived_vector_type (i
+ 2, i
, type
, TYPE_unsigned
))
4163 return error_mark_node
;
4165 return r
.resolve_to (r
.mode_suffix_id
, type
);
4168 SHAPE (ternary_uint
)
4170 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svu<t0:uint:quarter>_t,
4171 sv<t0:int:quarter>_t). */
4172 struct ternary_uintq_intq_def
4173 : public ternary_resize2_base
<function_resolver::QUARTER_SIZE
,
4174 TYPE_unsigned
, TYPE_signed
>
4177 build (function_builder
&b
, const function_group_info
&group
) const override
4179 b
.add_overloaded_functions (group
, MODE_none
);
4180 build_all (b
, "v0,v0,vqu0,vqs0", group
, MODE_none
);
4183 SHAPE (ternary_uintq_intq
)
4185 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:uint:quarter>_t, sv<t0:int:quarter>_t,
4188 where the final argument is an integer constant expression in the range
4189 [0, 16 / sizeof (<t0>_t) - 1]. */
4190 struct ternary_uintq_intq_lane_def
4191 : public ternary_qq_lane_base
<TYPE_unsigned
, TYPE_signed
>
4194 build (function_builder
&b
, const function_group_info
&group
) const override
4196 b
.add_overloaded_functions (group
, MODE_none
);
4197 build_all (b
, "v0,v0,vqu0,vqs0,su64", group
, MODE_none
);
4200 SHAPE (ternary_uintq_intq_lane
)
4202 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:uint:quarter>_t, sv<t0:int:quarter>_t)
4203 sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0:uint:quarter>_t,
4204 <t0:int:quarter>_t). */
4205 struct ternary_uintq_intq_opt_n_def
4206 : public ternary_resize2_opt_n_base
<function_resolver::QUARTER_SIZE
,
4207 TYPE_unsigned
, TYPE_signed
>
4210 build (function_builder
&b
, const function_group_info
&group
) const override
4212 b
.add_overloaded_functions (group
, MODE_none
);
4213 build_all (b
, "v0,v0,vqu0,vqs0", group
, MODE_none
);
4214 build_all (b
, "v0,v0,vqu0,sqs0", group
, MODE_n
);
4217 SHAPE (ternary_uintq_intq_opt_n
)
4219 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, uint64_t)
4221 where the final argument is an integer constant expression in the
4223 struct tmad_def
: public overloaded_base
<0>
4226 build (function_builder
&b
, const function_group_info
&group
) const override
4228 b
.add_overloaded_functions (group
, MODE_none
);
4229 build_all (b
, "v0,v0,v0,su64", group
, MODE_none
);
4233 resolve (function_resolver
&r
) const override
4235 return r
.resolve_uniform (2, 1);
4239 check (function_checker
&c
) const override
4241 return c
.require_immediate_range (2, 0, 7);
4246 /* sv<t0>_t svfoo[_t0](sv<t0>_t)
4248 i.e. the standard shape for unary operations that operate on
4250 struct unary_def
: public overloaded_base
<0>
4253 build (function_builder
&b
, const function_group_info
&group
) const override
4255 b
.add_overloaded_functions (group
, MODE_none
);
4256 build_all (b
, "t0,t0", group
, MODE_none
);
4260 resolve (function_resolver
&r
) const override
4262 return r
.resolve_unary ();
4267 /* sv<t0>_t svfoo_t0[_t1](sv<t1>_t)
4269 where the target type <t0> must be specified explicitly but the source
4270 type <t1> can be inferred. */
4271 struct unary_convert_def
: public overloaded_base
<1>
4274 build (function_builder
&b
, const function_group_info
&group
) const override
4276 b
.add_overloaded_functions (group
, MODE_none
);
4277 build_all (b
, "c0,c1", group
, MODE_none
);
4281 resolve (function_resolver
&r
) const override
4283 return r
.resolve_unary (r
.type_suffix (0).tclass
,
4284 r
.type_suffix (0).element_bits
);
4287 SHAPE (unary_convert
)
4289 /* sv<t0>_t svfoo_t0[_t1](sv<t0>_t, sv<t1>_t)
4291 This is a version of unary_convert in which the even-indexed
4292 elements are passed in as a first parameter, before any governing
4294 struct unary_convert_narrowt_def
: public overloaded_base
<1>
4297 has_merge_argument_p (const function_instance
&, unsigned int) const override
4303 build (function_builder
&b
, const function_group_info
&group
) const override
4305 b
.add_overloaded_functions (group
, MODE_none
);
4306 build_all (b
, "v0,v1", group
, MODE_none
);
4310 resolve (function_resolver
&r
) const override
4312 return r
.resolve_unary (r
.type_suffix (0).tclass
,
4313 r
.type_suffix (0).element_bits
, true);
4316 SHAPE (unary_convert_narrowt
)
4318 /* sv<t0>x<g0>_t svfoo_t0[_t1_g](sv<t1>x<g1>_t)
4320 where the target type <t0> must be specified explicitly but the
4321 source type <t1> can be inferred.
4323 Functions with a group suffix are unpredicated. For them:
4325 - If <t0> is N times wider than <t1>, the return value has N times
4326 more vectors than the argument.
4328 - If <t1> is N times wider than <t0>, the argument has N times
4329 more vectors than the return type. */
4330 struct unary_convertxn_def
: public unary_convert_def
4332 bool explicit_group_suffix_p () const override
{ return false; }
4335 resolve (function_resolver
&r
) const override
4337 if (r
.pred
!= PRED_none
)
4338 return unary_convert_def::resolve (r
);
4341 if (!r
.check_num_arguments (1)
4342 || !(type
= r
.infer_sve_type (0)))
4343 return error_mark_node
;
4345 return r
.resolve_conversion (r
.mode_suffix_id
, type
);
4348 SHAPE (unary_convertxn
)
4350 /* sv<t0>_t svfoo[_t0](sv<t0:half>_t). */
4351 struct unary_long_def
: public overloaded_base
<0>
4354 build (function_builder
&b
, const function_group_info
&group
) const override
4356 b
.add_overloaded_functions (group
, MODE_none
);
4357 build_all (b
, "v0,vh0", group
, MODE_none
);
4361 resolve (function_resolver
&r
) const override
4363 unsigned int i
, nargs
;
4364 type_suffix_index type
, result_type
;
4365 if (!r
.check_gp_argument (1, i
, nargs
)
4366 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
4367 || (result_type
= long_type_suffix (r
, type
)) == NUM_TYPE_SUFFIXES
)
4368 return error_mark_node
;
4370 if (tree res
= r
.lookup_form (r
.mode_suffix_id
, result_type
))
4373 return r
.report_no_such_form (type
);
4378 /* sv<t0>_t svfoo[_n]_t0(<t0>_t). */
4379 struct unary_n_def
: public overloaded_base
<1>
4382 build (function_builder
&b
, const function_group_info
&group
) const override
4384 /* The "_n" suffix is optional; the full name has it, but the short
4386 build_all (b
, "v0,s0", group
, MODE_n
, true);
4390 resolve (function_resolver
&) const override
4392 /* The short forms just make "_n" implicit, so no resolution is needed. */
4398 /* sv<t0:half>_t svfoo[_t0](sv<t0>_t). */
4399 typedef unary_narrowb_base
<> unary_narrowb_def
;
4400 SHAPE (unary_narrowb
)
4402 /* sv<t0:half>_t svfoo[_t0](sv<t0:half>_t, sv<t0>_t). */
4403 typedef unary_narrowt_base
<> unary_narrowt_def
;
4404 SHAPE (unary_narrowt
)
4406 /* sv<t0:uint:half>_t svfoo[_t0](sv<t0>_t). */
4407 typedef unary_narrowb_base
<TYPE_unsigned
> unary_narrowb_to_uint_def
;
4408 SHAPE (unary_narrowb_to_uint
)
4410 /* sv<t0:uint:half>_t svfoo[_t0](sv<t0:uint:half>_t, sv<t0>_t). */
4411 typedef unary_narrowt_base
<TYPE_unsigned
> unary_narrowt_to_uint_def
;
4412 SHAPE (unary_narrowt_to_uint
)
4414 /* svbool_t svfoo(svbool_t). */
4415 struct unary_pred_def
: public nonoverloaded_base
4418 build (function_builder
&b
, const function_group_info
&group
) const override
4420 build_all (b
, "v0,v0", group
, MODE_none
);
4425 /* sv<t0:int>_t svfoo[_t0](sv<t0>_t)
4427 i.e. a version of "unary" in which the returned vector contains
4429 struct unary_to_int_def
: public overloaded_base
<0>
4432 build (function_builder
&b
, const function_group_info
&group
) const override
4434 b
.add_overloaded_functions (group
, MODE_none
);
4435 build_all (b
, "vs0,v0", group
, MODE_none
);
4439 resolve (function_resolver
&r
) const override
4441 return r
.resolve_unary (TYPE_signed
);
4444 SHAPE (unary_to_int
)
4446 /* sv<t0:uint>_t svfoo[_t0](sv<t0>_t)
4448 i.e. a version of "unary" in which the returned vector contains
4449 unsigned integers. */
4450 struct unary_to_uint_def
: public overloaded_base
<0>
4453 build (function_builder
&b
, const function_group_info
&group
) const override
4455 b
.add_overloaded_functions (group
, MODE_none
);
4456 build_all (b
, "vu0,v0", group
, MODE_none
);
4460 resolve (function_resolver
&r
) const override
4462 return r
.resolve_unary (TYPE_unsigned
);
4465 SHAPE (unary_to_uint
)
4467 /* sv<t0>_t svfoo[_t0](sv<t0:uint>_t)
4469 where <t0> always belongs a certain type class, and where <t0:uint>
4470 therefore uniquely determines <t0>. */
4471 struct unary_uint_def
: public overloaded_base
<0>
4474 build (function_builder
&b
, const function_group_info
&group
) const override
4476 b
.add_overloaded_functions (group
, MODE_none
);
4477 build_all (b
, "v0,vu0", group
, MODE_none
);
4481 resolve (function_resolver
&r
) const override
4483 unsigned int i
, nargs
;
4484 type_suffix_index type
;
4485 if (!r
.check_gp_argument (1, i
, nargs
)
4486 || (type
= r
.infer_unsigned_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
4487 return error_mark_node
;
4489 /* Search for a valid suffix with the same number of bits as TYPE. */
4490 unsigned int element_bits
= type_suffixes
[type
].element_bits
;
4491 if (type_suffixes
[type
].unsigned_p
)
4492 for (unsigned int j
= 0; j
< NUM_TYPE_SUFFIXES
; ++j
)
4493 if (type_suffixes
[j
].element_bits
== element_bits
)
4494 if (tree res
= r
.lookup_form (r
.mode_suffix_id
,
4495 type_suffix_index (j
)))
4498 return r
.report_no_such_form (type
);
4503 /* sv<t0>_t svfoo[_<t0>](sv<t0:half>_t)
4505 i.e. a version of "unary" in which the source elements are half the
4506 size of the destination elements, but have the same type class. */
4507 struct unary_widen_def
: public overloaded_base
<0>
4510 build (function_builder
&b
, const function_group_info
&group
) const override
4512 b
.add_overloaded_functions (group
, MODE_none
);
4513 build_all (b
, "v0,vh0", group
, MODE_none
);
4517 resolve (function_resolver
&r
) const override
4519 unsigned int i
, nargs
;
4520 type_suffix_index type
;
4521 if (!r
.check_gp_argument (1, i
, nargs
)
4522 || (type
= r
.infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
4523 return error_mark_node
;
4525 /* There is only a single form for predicates. */
4526 if (type
== TYPE_SUFFIX_b
)
4527 return r
.resolve_to (r
.mode_suffix_id
, type
);
4529 if (type_suffixes
[type
].integer_p
4530 && type_suffixes
[type
].element_bits
< 64)
4532 type_suffix_index wide_suffix
4533 = find_type_suffix (type_suffixes
[type
].tclass
,
4534 type_suffixes
[type
].element_bits
* 2);
4535 if (tree res
= r
.lookup_form (r
.mode_suffix_id
, wide_suffix
))
4539 return r
.report_no_such_form (type
);
4544 /* void svfoo_t0[_t1](uint64_t, svbool_t, svbool_t, sv<t1>_t)
4546 where the first argument is a ZA tile. */
4547 struct unary_za_m_def
: public overloaded_base
<1>
4550 build (function_builder
&b
, const function_group_info
&group
) const override
4552 b
.add_overloaded_functions (group
, MODE_none
);
4553 build_all (b
, "_,su64,vp,vp,t1", group
, MODE_none
);
4557 resolve (function_resolver
&r
) const override
4559 type_suffix_index type
;
4560 if (!r
.check_num_arguments (4)
4561 || !r
.require_integer_immediate (0)
4562 || !r
.require_vector_type (1, VECTOR_TYPE_svbool_t
)
4563 || !r
.require_vector_type (2, VECTOR_TYPE_svbool_t
)
4564 || (type
= r
.infer_vector_type (3)) == NUM_TYPE_SUFFIXES
)
4565 return error_mark_node
;
4567 return r
.resolve_to (r
.mode_suffix_id
, r
.type_suffix_ids
[0], type
);
4571 check (function_checker
&c
) const override
4573 return c
.require_immediate_range (0, 0, c
.num_za_tiles () - 1);
4578 /* void svfoo_t0[_t1]_g(uint32_t, sv<t1>x<g>_t). */
4579 struct unary_za_slice_def
: public overloaded_base
<1>
4582 build (function_builder
&b
, const function_group_info
&group
) const override
4584 b
.add_overloaded_functions (group
, MODE_none
);
4585 if (!za_group_is_pure_overload (group
))
4586 build_all (b
, "_,su32,t1", group
, MODE_none
);
4590 resolve (function_resolver
&r
) const override
4593 if (!r
.check_num_arguments (2)
4594 || !r
.require_scalar_type (0, "uint32_t")
4595 || !(type
= r
.infer_tuple_type (1)))
4596 return error_mark_node
;
4598 return r
.resolve_to (r
.mode_suffix_id
, type
);
4601 SHAPE (unary_za_slice
)
4603 /* sv<t0>x<g>_t svfoo[_t0_g](sv<t0>x<g>_t). */
4604 struct unaryxn_def
: public unary_def
4606 bool explicit_group_suffix_p () const override
{ return false; }
4609 resolve (function_resolver
&r
) const override
4611 if (r
.pred
!= PRED_none
)
4612 return unary_def::resolve (r
);
4615 if (!r
.check_num_arguments (1)
4616 || !(type
= r
.infer_sve_type (0)))
4617 return error_mark_node
;
4619 return r
.resolve_to (r
.mode_suffix_id
, type
);
4624 /* void svfoo_t0[_t1_g](uint64_t, uint32_t, sv<t1>x<g>_t). */
4625 struct write_za_def
: public overloaded_base
<1>
4628 build (function_builder
&b
, const function_group_info
&group
) const override
4630 b
.add_overloaded_functions (group
, MODE_none
);
4631 build_all (b
, "_,su64,su32,t1", group
, MODE_none
);
4635 resolve (function_resolver
&r
) const override
4638 if (!r
.check_num_arguments (3)
4639 || !r
.require_integer_immediate (0)
4640 || !r
.require_scalar_type (1, "uint32_t")
4641 || !(type
= r
.infer_tuple_type (2)))
4642 return error_mark_node
;
4644 return r
.resolve_to (r
.mode_suffix_id
, type
);
4648 check (function_checker
&c
) const override
4650 return c
.require_immediate_range (0, 0, c
.num_za_tiles () - 1);
4655 /* void svfoo_t0[_t1](uint64_t, uint32_t, svbool_t, sv<t1>_t)
4657 where the first two fields form a (ZA tile, slice) pair. */
4658 struct write_za_m_def
: public overloaded_base
<1>
4661 build (function_builder
&b
, const function_group_info
&group
) const override
4663 b
.add_overloaded_functions (group
, MODE_none
);
4664 build_all (b
, "_,su64,su32,vp,t1", group
, MODE_none
);
4668 resolve (function_resolver
&r
) const override
4670 type_suffix_index type
;
4671 if (!r
.check_num_arguments (4)
4672 || !r
.require_integer_immediate (0)
4673 || !r
.require_scalar_type (1, "uint32_t")
4674 || !r
.require_vector_type (2, VECTOR_TYPE_svbool_t
)
4675 || (type
= r
.infer_vector_type (3)) == NUM_TYPE_SUFFIXES
)
4676 return error_mark_node
;
4678 return r
.resolve_to (r
.mode_suffix_id
, r
.type_suffix_ids
[0], type
);
4682 check (function_checker
&c
) const override
4684 return c
.require_immediate_range (0, 0, c
.num_za_tiles () - 1);
4689 /* void svfoo_t0[_t1_g](uint32_t, sv<t1>x<g>_t). */
4690 struct write_za_slice_def
: public overloaded_base
<1>
4693 build (function_builder
&b
, const function_group_info
&group
) const override
4695 b
.add_overloaded_functions (group
, MODE_none
);
4696 build_all (b
, "_,su32,t1", group
, MODE_none
);
4700 resolve (function_resolver
&r
) const override
4703 if (!r
.check_num_arguments (2)
4704 || !r
.require_scalar_type (0, "uint32_t")
4705 || !(type
= r
.infer_tuple_type (1)))
4706 return error_mark_node
;
4708 return r
.resolve_to (r
.mode_suffix_id
, type
);
4711 SHAPE (write_za_slice
)