Home | History | Annotate | Line # | Download | only in aarch64
aarch64-sve-builtins-shapes.cc revision 1.1.1.2
      1 /* ACLE support for AArch64 SVE (function shapes)
      2    Copyright (C) 2018-2022 Free Software Foundation, Inc.
      3 
      4    This file is part of GCC.
      5 
      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)
      9    any later version.
     10 
     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.
     15 
     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/>.  */
     19 
     20 #include "config.h"
     21 #include "system.h"
     22 #include "coretypes.h"
     23 #include "tm.h"
     24 #include "tree.h"
     25 #include "rtl.h"
     26 #include "tm_p.h"
     27 #include "memmodel.h"
     28 #include "insn-codes.h"
     29 #include "optabs.h"
     30 #include "aarch64-sve-builtins.h"
     31 #include "aarch64-sve-builtins-shapes.h"
     32 
     33 /* In the comments below, _t0 represents the first type suffix and _t1
     34    represents the second.  Square brackets enclose characters that are
     35    present in only the full name, not the overloaded name.  Governing
     36    predicate arguments and predicate suffixes are not shown, since they
     37    depend on the predication type, which is a separate piece of
     38    information from the shape.
     39 
     40    Non-overloaded functions may have additional suffixes beyond the
     41    ones shown, if those suffixes don't affect the types in the type
     42    signature.  E.g. the predicate form of svtrn1 has a _b<bits> suffix,
     43    but this does not affect the prototype, which is always
     44    "svbool_t(svbool_t, svbool_t)".  */
     45 
     46 namespace aarch64_sve {
     47 
     48 /* Return a representation of "const T *".  */
     49 static tree
     50 build_const_pointer (tree t)
     51 {
     52   return build_pointer_type (build_qualified_type (t, TYPE_QUAL_CONST));
     53 }
     54 
     55 /* If INSTANCE has a governing predicate, add it to the list of argument
     56    types in ARGUMENT_TYPES.  RETURN_TYPE is the type returned by the
     57    function.  */
     58 static void
     59 apply_predication (const function_instance &instance, tree return_type,
     60 		   vec<tree> &argument_types)
     61 {
     62   if (instance.pred != PRED_none)
     63     {
     64       argument_types.quick_insert (0, get_svbool_t ());
     65       /* For unary merge operations, the first argument is a vector with
     66 	 the same type as the result.  For unary_convert_narrowt it also
     67 	 provides the "bottom" half of active elements, and is present
     68 	 for all types of predication.  */
     69       if ((argument_types.length () == 2 && instance.pred == PRED_m)
     70 	  || instance.shape == shapes::unary_convert_narrowt)
     71 	argument_types.quick_insert (0, return_type);
     72     }
     73 }
     74 
     75 /* Parse and move past an element type in FORMAT and return it as a type
     76    suffix.  The format is:
     77 
     78    [01]    - the element type in type suffix 0 or 1 of INSTANCE
     79    f<bits> - a floating-point type with the given number of bits
     80    f[01]   - a floating-point type with the same width as type suffix 0 or 1
     81    B       - bfloat16_t
     82    h<elt>  - a half-sized version of <elt>
     83    p       - a predicate (represented as TYPE_SUFFIX_b)
     84    q<elt>  - a quarter-sized version of <elt>
     85    s<bits> - a signed type with the given number of bits
     86    s[01]   - a signed type with the same width as type suffix 0 or 1
     87    u<bits> - an unsigned type with the given number of bits
     88    u[01]   - an unsigned type with the same width as type suffix 0 or 1
     89    w<elt>  - a 64-bit version of <elt> if <elt> is integral, otherwise <elt>
     90 
     91    where <elt> is another element type.  */
     92 static type_suffix_index
     93 parse_element_type (const function_instance &instance, const char *&format)
     94 {
     95   int ch = *format++;
     96 
     97   if (ch == 'f' || ch == 's' || ch == 'u')
     98     {
     99       type_class_index tclass = (ch == 'f' ? TYPE_float
    100 				 : ch == 's' ? TYPE_signed
    101 				 : TYPE_unsigned);
    102       char *end;
    103       unsigned int bits = strtol (format, &end, 10);
    104       format = end;
    105       if (bits == 0 || bits == 1)
    106 	bits = instance.type_suffix (bits).element_bits;
    107       return find_type_suffix (tclass, bits);
    108     }
    109 
    110   if (ch == 'w')
    111     {
    112       type_suffix_index suffix = parse_element_type (instance, format);
    113       if (type_suffixes[suffix].integer_p)
    114 	return find_type_suffix (type_suffixes[suffix].tclass, 64);
    115       return suffix;
    116     }
    117 
    118   if (ch == 'p')
    119     return TYPE_SUFFIX_b;
    120 
    121   if (ch == 'B')
    122     return TYPE_SUFFIX_bf16;
    123 
    124   if (ch == 'q')
    125     {
    126       type_suffix_index suffix = parse_element_type (instance, format);
    127       return find_type_suffix (type_suffixes[suffix].tclass,
    128 			       type_suffixes[suffix].element_bits / 4);
    129     }
    130 
    131   if (ch == 'h')
    132     {
    133       type_suffix_index suffix = parse_element_type (instance, format);
    134       /* Widening and narrowing doesn't change the type for predicates;
    135 	 everything's still an svbool_t.  */
    136       if (suffix == TYPE_SUFFIX_b)
    137 	return suffix;
    138       return find_type_suffix (type_suffixes[suffix].tclass,
    139 			       type_suffixes[suffix].element_bits / 2);
    140     }
    141 
    142   if (ch == '0' || ch == '1')
    143     return instance.type_suffix_ids[ch - '0'];
    144 
    145   gcc_unreachable ();
    146 }
    147 
    148 /* Read and return a type from FORMAT for function INSTANCE.  Advance
    149    FORMAT beyond the type string.  The format is:
    150 
    151    _       - void
    152    al      - array pointer for loads
    153    ap      - array pointer for prefetches
    154    as      - array pointer for stores
    155    b       - base vector type (from a _<m0>base suffix)
    156    d       - displacement vector type (from a _<m1>index or _<m1>offset suffix)
    157    e<name> - an enum with the given name
    158    s<elt>  - a scalar type with the given element suffix
    159    t<elt>  - a vector or tuple type with given element suffix [*1]
    160    v<elt>  - a vector with the given element suffix
    161 
    162    where <elt> has the format described above parse_element_type
    163 
    164    [*1] the vectors_per_tuple function indicates whether the type should
    165         be a tuple, and if so, how many vectors it should contain.  */
    166 static tree
    167 parse_type (const function_instance &instance, const char *&format)
    168 {
    169   int ch = *format++;
    170 
    171   if (ch == '_')
    172     return void_type_node;
    173 
    174   if (ch == 'a')
    175     {
    176       ch = *format++;
    177       if (ch == 'l')
    178 	return build_const_pointer (instance.memory_scalar_type ());
    179       if (ch == 'p')
    180 	return const_ptr_type_node;
    181       if (ch == 's')
    182 	return build_pointer_type (instance.memory_scalar_type ());
    183       gcc_unreachable ();
    184     }
    185 
    186   if (ch == 'b')
    187     return instance.base_vector_type ();
    188 
    189   if (ch == 'd')
    190     return instance.displacement_vector_type ();
    191 
    192   if (ch == 'e')
    193     {
    194       if (startswith (format, "pattern"))
    195 	{
    196 	  format += 7;
    197 	  return acle_svpattern;
    198 	}
    199       if (startswith (format, "prfop"))
    200 	{
    201 	  format += 5;
    202 	  return acle_svprfop;
    203 	}
    204       gcc_unreachable ();
    205     }
    206 
    207   if (ch == 's')
    208     {
    209       type_suffix_index suffix = parse_element_type (instance, format);
    210       return scalar_types[type_suffixes[suffix].vector_type];
    211     }
    212 
    213   if (ch == 't')
    214     {
    215       type_suffix_index suffix = parse_element_type (instance, format);
    216       vector_type_index vector_type = type_suffixes[suffix].vector_type;
    217       unsigned int num_vectors = instance.vectors_per_tuple ();
    218       return acle_vector_types[num_vectors - 1][vector_type];
    219     }
    220 
    221   if (ch == 'v')
    222     {
    223       type_suffix_index suffix = parse_element_type (instance, format);
    224       return acle_vector_types[0][type_suffixes[suffix].vector_type];
    225     }
    226 
    227   gcc_unreachable ();
    228 }
    229 
    230 /* Read and move past any argument count at FORMAT for the function
    231    signature of INSTANCE.  The counts are:
    232 
    233    *q: one argument per element in a 128-bit quadword (as for svdupq)
    234    *t: one argument per vector in a tuple (as for svcreate)
    235 
    236    Otherwise the count is 1.  */
    237 static unsigned int
    238 parse_count (const function_instance &instance, const char *&format)
    239 {
    240   if (format[0] == '*' && format[1] == 'q')
    241     {
    242       format += 2;
    243       return instance.elements_per_vq (0);
    244     }
    245   if (format[0] == '*' && format[1] == 't')
    246     {
    247       format += 2;
    248       return instance.vectors_per_tuple ();
    249     }
    250   return 1;
    251 }
    252 
    253 /* Read a type signature for INSTANCE from FORMAT.  Add the argument types
    254    to ARGUMENT_TYPES and return the return type.
    255 
    256    The format is a comma-separated list of types (as for parse_type),
    257    with the first type being the return type and the rest being the
    258    argument types.  Each argument type can be followed by an optional
    259    count (as for parse_count).  */
    260 static tree
    261 parse_signature (const function_instance &instance, const char *format,
    262 		 vec<tree> &argument_types)
    263 {
    264   tree return_type = parse_type (instance, format);
    265   while (format[0] == ',')
    266     {
    267       format += 1;
    268       tree argument_type = parse_type (instance, format);
    269       unsigned int count = parse_count (instance, format);
    270       for (unsigned int i = 0; i < count; ++i)
    271 	argument_types.quick_push (argument_type);
    272     }
    273   gcc_assert (format[0] == 0);
    274   return return_type;
    275 }
    276 
    277 /* Add one function instance for GROUP, using mode suffix MODE_SUFFIX_ID,
    278    the type suffixes at index TI and the predication suffix at index PI.
    279    The other arguments are as for build_all.  */
    280 static void
    281 build_one (function_builder &b, const char *signature,
    282 	   const function_group_info &group, mode_suffix_index mode_suffix_id,
    283 	   unsigned int ti, unsigned int pi, bool force_direct_overloads)
    284 {
    285   /* Byte forms of svdupq take 16 arguments.  */
    286   auto_vec<tree, 16> argument_types;
    287   function_instance instance (group.base_name, *group.base, *group.shape,
    288 			      mode_suffix_id, group.types[ti],
    289 			      group.preds[pi]);
    290   tree return_type = parse_signature (instance, signature, argument_types);
    291   apply_predication (instance, return_type, argument_types);
    292   b.add_unique_function (instance, return_type, argument_types,
    293 			 group.required_extensions, force_direct_overloads);
    294 }
    295 
    296 /* GROUP describes some sort of gather or scatter operation.  There are
    297    two cases:
    298 
    299    - If the function has any type suffixes (as for loads and stores), the
    300      first function type suffix specifies either a 32-bit or a 64-bit type,
    301      which in turn selects either MODE32 or MODE64 as the addressing mode.
    302      Add a function instance for every type and predicate combination
    303      in GROUP for which the associated addressing mode is not MODE_none.
    304 
    305    - If the function has no type suffixes (as for prefetches), add one
    306      MODE32 form and one MODE64 form for each predication type.
    307 
    308    The other arguments are as for build_all.  */
    309 static void
    310 build_32_64 (function_builder &b, const char *signature,
    311 	     const function_group_info &group, mode_suffix_index mode32,
    312 	     mode_suffix_index mode64, bool force_direct_overloads = false)
    313 {
    314   for (unsigned int pi = 0; group.preds[pi] != NUM_PREDS; ++pi)
    315     if (group.types[0][0] == NUM_TYPE_SUFFIXES)
    316       {
    317 	gcc_assert (mode32 != MODE_none && mode64 != MODE_none);
    318 	build_one (b, signature, group, mode32, 0, pi,
    319 		   force_direct_overloads);
    320 	build_one (b, signature, group, mode64, 0, pi,
    321 		   force_direct_overloads);
    322       }
    323     else
    324       for (unsigned int ti = 0; group.types[ti][0] != NUM_TYPE_SUFFIXES; ++ti)
    325 	{
    326 	  unsigned int bits = type_suffixes[group.types[ti][0]].element_bits;
    327 	  gcc_assert (bits == 32 || bits == 64);
    328 	  mode_suffix_index mode = bits == 32 ? mode32 : mode64;
    329 	  if (mode != MODE_none)
    330 	    build_one (b, signature, group, mode, ti, pi,
    331 		       force_direct_overloads);
    332 	}
    333 }
    334 
    335 /* For every type and predicate combination in GROUP, add one function
    336    that takes a scalar (pointer) base and a signed vector array index,
    337    and another that instead takes an unsigned vector array index.
    338    The vector array index has the same element size as the first
    339    function type suffix.  SIGNATURE is as for build_all.  */
    340 static void
    341 build_sv_index (function_builder &b, const char *signature,
    342 		const function_group_info &group)
    343 {
    344   build_32_64 (b, signature, group, MODE_s32index, MODE_s64index);
    345   build_32_64 (b, signature, group, MODE_u32index, MODE_u64index);
    346 }
    347 
    348 /* Like build_sv_index, but only handle 64-bit types.  */
    349 static void
    350 build_sv_index64 (function_builder &b, const char *signature,
    351 		  const function_group_info &group)
    352 {
    353   build_32_64 (b, signature, group, MODE_none, MODE_s64index);
    354   build_32_64 (b, signature, group, MODE_none, MODE_u64index);
    355 }
    356 
    357 /* Like build_sv_index, but taking vector byte offsets instead of vector
    358    array indices.  */
    359 static void
    360 build_sv_offset (function_builder &b, const char *signature,
    361 		 const function_group_info &group)
    362 {
    363   build_32_64 (b, signature, group, MODE_s32offset, MODE_s64offset);
    364   build_32_64 (b, signature, group, MODE_u32offset, MODE_u64offset);
    365 }
    366 
    367 /* Like build_sv_offset, but exclude offsets that must be interpreted
    368    as signed (i.e. s32offset).  */
    369 static void
    370 build_sv_uint_offset (function_builder &b, const char *signature,
    371 		      const function_group_info &group)
    372 {
    373   build_32_64 (b, signature, group, MODE_none, MODE_s64offset);
    374   build_32_64 (b, signature, group, MODE_u32offset, MODE_u64offset);
    375 }
    376 
    377 /* For every type and predicate combination in GROUP, add a function
    378    that takes a vector base address and no displacement.  The vector
    379    base has the same element size as the first type suffix.
    380 
    381    The other arguments are as for build_all.  */
    382 static void
    383 build_v_base (function_builder &b, const char *signature,
    384 	      const function_group_info &group,
    385 	      bool force_direct_overloads = false)
    386 {
    387   build_32_64 (b, signature, group, MODE_u32base, MODE_u64base,
    388 	       force_direct_overloads);
    389 }
    390 
    391 /* Like build_v_base, but for functions that also take a scalar array
    392    index.  */
    393 static void
    394 build_vs_index (function_builder &b, const char *signature,
    395 		const function_group_info &group,
    396 		bool force_direct_overloads = false)
    397 {
    398   build_32_64 (b, signature, group, MODE_u32base_index, MODE_u64base_index,
    399 	       force_direct_overloads);
    400 }
    401 
    402 /* Like build_v_base, but for functions that also take a scalar byte
    403    offset.  */
    404 static void
    405 build_vs_offset (function_builder &b, const char *signature,
    406 		 const function_group_info &group,
    407 		 bool force_direct_overloads = false)
    408 {
    409   build_32_64 (b, signature, group, MODE_u32base_offset, MODE_u64base_offset,
    410 	       force_direct_overloads);
    411 }
    412 
    413 /* Add a function instance for every type and predicate combination
    414    in GROUP.  Take the function base name from GROUP and the mode suffix
    415    from MODE_SUFFIX_ID.  Use SIGNATURE to construct the function signature
    416    without a governing predicate, then use apply_predication to add in the
    417    predicate.  FORCE_DIRECT_OVERLOADS is true if there is a one-to-one
    418    mapping between "short" and "full" names, and if standard overload
    419    resolution therefore isn't necessary.  */
    420 static void
    421 build_all (function_builder &b, const char *signature,
    422 	   const function_group_info &group, mode_suffix_index mode_suffix_id,
    423 	   bool force_direct_overloads = false)
    424 {
    425   for (unsigned int pi = 0; group.preds[pi] != NUM_PREDS; ++pi)
    426     for (unsigned int ti = 0;
    427 	 ti == 0 || group.types[ti][0] != NUM_TYPE_SUFFIXES; ++ti)
    428       build_one (b, signature, group, mode_suffix_id, ti, pi,
    429 		 force_direct_overloads);
    430 }
    431 
    432 /* TYPE is the largest type suffix associated with the arguments of R,
    433    but the result is twice as wide.  Return the associated type suffix
    434    if it exists, otherwise report an appropriate error and return
    435    NUM_TYPE_SUFFIXES.  */
    436 static type_suffix_index
    437 long_type_suffix (function_resolver &r, type_suffix_index type)
    438 {
    439   unsigned int element_bits = type_suffixes[type].element_bits;
    440   if (type_suffixes[type].integer_p && element_bits < 64)
    441     return find_type_suffix (type_suffixes[type].tclass, element_bits * 2);
    442 
    443   r.report_no_such_form (type);
    444   return NUM_TYPE_SUFFIXES;
    445 }
    446 
    447 /* Declare the function shape NAME, pointing it to an instance
    448    of class <NAME>_def.  */
    449 #define SHAPE(NAME) \
    450   static CONSTEXPR const NAME##_def NAME##_obj; \
    451   namespace shapes { const function_shape *const NAME = &NAME##_obj; }
    452 
    453 /* Base class for functions that are not overloaded.  */
    454 struct nonoverloaded_base : public function_shape
    455 {
    456   bool
    457   explicit_type_suffix_p (unsigned int) const OVERRIDE
    458   {
    459     return true;
    460   }
    461 
    462   tree
    463   resolve (function_resolver &) const OVERRIDE
    464   {
    465     gcc_unreachable ();
    466   }
    467 };
    468 
    469 /* Base class for overloaded functions.  Bit N of EXPLICIT_MASK is true
    470    if type suffix N appears in the overloaded name.  */
    471 template<unsigned int EXPLICIT_MASK>
    472 struct overloaded_base : public function_shape
    473 {
    474   bool
    475   explicit_type_suffix_p (unsigned int i) const OVERRIDE
    476   {
    477     return (EXPLICIT_MASK >> i) & 1;
    478   }
    479 };
    480 
    481 /* Base class for adr_index and adr_offset.  */
    482 struct adr_base : public overloaded_base<0>
    483 {
    484   /* The function takes two arguments: a vector base and a vector displacement
    485      (either an index or an offset).  Resolve based on them both.  */
    486   tree
    487   resolve (function_resolver &r) const OVERRIDE
    488   {
    489     unsigned int i, nargs;
    490     mode_suffix_index mode;
    491     if (!r.check_gp_argument (2, i, nargs)
    492 	|| (mode = r.resolve_adr_address (0)) == MODE_none)
    493       return error_mark_node;
    494 
    495     return r.resolve_to (mode);
    496   };
    497 };
    498 
    499 /* Base class for narrowing bottom binary functions that take an
    500    immediate second operand.  The result is half the size of input
    501    and has class CLASS.  */
    502 template<type_class_index CLASS = function_resolver::SAME_TYPE_CLASS>
    503 struct binary_imm_narrowb_base : public overloaded_base<0>
    504 {
    505   void
    506   build (function_builder &b, const function_group_info &group) const OVERRIDE
    507   {
    508     b.add_overloaded_functions (group, MODE_n);
    509     STATIC_ASSERT (CLASS == function_resolver::SAME_TYPE_CLASS
    510 		   || CLASS == TYPE_unsigned);
    511     if (CLASS == TYPE_unsigned)
    512       build_all (b, "vhu0,v0,su64", group, MODE_n);
    513     else
    514       build_all (b, "vh0,v0,su64", group, MODE_n);
    515   }
    516 
    517   tree
    518   resolve (function_resolver &r) const OVERRIDE
    519   {
    520     return r.resolve_uniform (1, 1);
    521   }
    522 };
    523 
    524 /* The top equivalent of binary_imm_narrowb_base.  It takes three arguments,
    525    with the first being the values of the even elements, which are typically
    526    the result of the narrowb operation.  */
    527 template<type_class_index CLASS = function_resolver::SAME_TYPE_CLASS>
    528 struct binary_imm_narrowt_base : public overloaded_base<0>
    529 {
    530   void
    531   build (function_builder &b, const function_group_info &group) const OVERRIDE
    532   {
    533     b.add_overloaded_functions (group, MODE_n);
    534     STATIC_ASSERT (CLASS == function_resolver::SAME_TYPE_CLASS
    535 		   || CLASS == TYPE_unsigned);
    536     if (CLASS == TYPE_unsigned)
    537       build_all (b, "vhu0,vhu0,v0,su64", group, MODE_n);
    538     else
    539       build_all (b, "vh0,vh0,v0,su64", group, MODE_n);
    540   }
    541 
    542   tree
    543   resolve (function_resolver &r) const OVERRIDE
    544   {
    545     unsigned int i, nargs;
    546     type_suffix_index type;
    547     if (!r.check_gp_argument (3, i, nargs)
    548 	|| (type = r.infer_vector_type (i + 1)) == NUM_TYPE_SUFFIXES
    549 	|| !r.require_derived_vector_type (i, i + 1, type, CLASS, r.HALF_SIZE)
    550 	|| !r.require_integer_immediate (i + 2))
    551       return error_mark_node;
    552 
    553     return r.resolve_to (r.mode_suffix_id, type);
    554   }
    555 };
    556 
    557 /* Base class for long (i.e. narrow op narrow -> wide) binary functions
    558    that take an immediate second operand.  The type suffix specifies
    559    the wider type.  */
    560 struct binary_imm_long_base : public overloaded_base<0>
    561 {
    562   void
    563   build (function_builder &b, const function_group_info &group) const OVERRIDE
    564   {
    565     b.add_overloaded_functions (group, MODE_n);
    566     build_all (b, "v0,vh0,su64", group, MODE_n);
    567   }
    568 
    569   tree
    570   resolve (function_resolver &r) const OVERRIDE
    571   {
    572     unsigned int i, nargs;
    573     type_suffix_index type, result_type;
    574     if (!r.check_gp_argument (2, i, nargs)
    575 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
    576 	|| !r.require_integer_immediate (i + 1)
    577 	|| (result_type = long_type_suffix (r, type)) == NUM_TYPE_SUFFIXES)
    578       return error_mark_node;
    579 
    580     if (tree res = r.lookup_form (r.mode_suffix_id, result_type))
    581       return res;
    582 
    583     return r.report_no_such_form (type);
    584   }
    585 };
    586 
    587 /* Base class for inc_dec and inc_dec_pat.  */
    588 struct inc_dec_base : public overloaded_base<0>
    589 {
    590   CONSTEXPR inc_dec_base (bool pat_p) : m_pat_p (pat_p) {}
    591 
    592   /* Resolve based on the first argument only, which must be either a
    593      scalar or a vector.  If it's a scalar, it must be a 32-bit or
    594      64-bit integer.  */
    595   tree
    596   resolve (function_resolver &r) const
    597   {
    598     unsigned int i, nargs;
    599     if (!r.check_gp_argument (m_pat_p ? 3 : 2, i, nargs)
    600 	|| !r.require_vector_or_scalar_type (i))
    601       return error_mark_node;
    602 
    603     mode_suffix_index mode;
    604     type_suffix_index type;
    605     if (r.scalar_argument_p (i))
    606       {
    607 	mode = MODE_n;
    608 	type = r.infer_integer_scalar_type (i);
    609       }
    610     else
    611       {
    612 	mode = MODE_none;
    613 	type = r.infer_vector_type (i);
    614       }
    615     if (type == NUM_TYPE_SUFFIXES)
    616       return error_mark_node;
    617 
    618     for (++i; i < nargs; ++i)
    619       if (!r.require_integer_immediate (i))
    620 	return error_mark_node;
    621 
    622     return r.resolve_to (mode, type);
    623   }
    624 
    625   bool
    626   check (function_checker &c) const OVERRIDE
    627   {
    628     return c.require_immediate_range (m_pat_p ? 2 : 1, 1, 16);
    629   }
    630 
    631   bool m_pat_p;
    632 };
    633 
    634 /* Base class for load and load_replicate.  */
    635 struct load_contiguous_base : public overloaded_base<0>
    636 {
    637   /* Resolve a call based purely on a pointer argument.  The other arguments
    638      are a governing predicate and (for MODE_vnum) a vnum offset.  */
    639   tree
    640   resolve (function_resolver &r) const OVERRIDE
    641   {
    642     bool vnum_p = r.mode_suffix_id == MODE_vnum;
    643     gcc_assert (r.mode_suffix_id == MODE_none || vnum_p);
    644 
    645     unsigned int i, nargs;
    646     type_suffix_index type;
    647     if (!r.check_gp_argument (vnum_p ? 2 : 1, i, nargs)
    648 	|| (type = r.infer_pointer_type (i)) == NUM_TYPE_SUFFIXES
    649 	|| (vnum_p && !r.require_scalar_type (i + 1, "int64_t")))
    650       return error_mark_node;
    651 
    652     return r.resolve_to (r.mode_suffix_id, type);
    653   }
    654 };
    655 
    656 /* Base class for gather loads that take a scalar base and a vector
    657    displacement (either an offset or an index).  */
    658 struct load_gather_sv_base : public overloaded_base<0>
    659 {
    660   tree
    661   resolve (function_resolver &r) const OVERRIDE
    662   {
    663     unsigned int i, nargs;
    664     mode_suffix_index mode;
    665     type_suffix_index type;
    666     if (!r.check_gp_argument (2, i, nargs)
    667 	|| (type = r.infer_pointer_type (i, true)) == NUM_TYPE_SUFFIXES
    668 	|| (mode = r.resolve_sv_displacement (i + 1, type, true),
    669 	    mode == MODE_none))
    670       return error_mark_node;
    671 
    672     return r.resolve_to (mode, type);
    673   }
    674 };
    675 
    676 /* Base class for load_ext_gather_index and load_ext_gather_offset,
    677    which differ only in the units of the displacement.  */
    678 struct load_ext_gather_base : public overloaded_base<1>
    679 {
    680   /* Resolve a gather load that takes one of:
    681 
    682      - a scalar pointer base and a vector displacement
    683      - a vector base with no displacement or
    684      - a vector base and a scalar displacement
    685 
    686      The function has an explicit type suffix that determines the type
    687      of the loaded data.  */
    688   tree
    689   resolve (function_resolver &r) const OVERRIDE
    690   {
    691     /* No resolution is needed for a vector base with no displacement;
    692        there's a one-to-one mapping between short and long names.  */
    693     gcc_assert (r.displacement_units () != UNITS_none);
    694 
    695     type_suffix_index type = r.type_suffix_ids[0];
    696 
    697     unsigned int i, nargs;
    698     mode_suffix_index mode;
    699     if (!r.check_gp_argument (2, i, nargs)
    700 	|| (mode = r.resolve_gather_address (i, type, true)) == MODE_none)
    701       return error_mark_node;
    702 
    703     return r.resolve_to (mode, type);
    704   }
    705 };
    706 
    707 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:quarter>_t,
    708 		       sv<t0:quarter>_t)  (for integer t0)
    709    sv<t0>_t svmmla[_t0](sv<t0>_t, sv<t0>_t, sv<t0>_t)  (for floating-point t0)
    710 
    711    The functions act like the equivalent of "ternary_qq" for integer elements
    712    and normal vector-only ternary functions for floating-point elements.  */
    713 struct mmla_def : public overloaded_base<0>
    714 {
    715   void
    716   build (function_builder &b, const function_group_info &group) const OVERRIDE
    717   {
    718     b.add_overloaded_functions (group, MODE_none);
    719     /* svmmla is distributed over several extensions.  Allow the common
    720        denominator to define the overloaded svmmla function without
    721        defining any specific versions.  */
    722     if (group.types[0][0] != NUM_TYPE_SUFFIXES)
    723       {
    724 	if (type_suffixes[group.types[0][0]].float_p)
    725 	  build_all (b, "v0,v0,v0,v0", group, MODE_none);
    726 	else
    727 	  build_all (b, "v0,v0,vq0,vq0", group, MODE_none);
    728       }
    729   }
    730 
    731   tree
    732   resolve (function_resolver &r) const OVERRIDE
    733   {
    734     unsigned int i, nargs;
    735     type_suffix_index type;
    736     if (!r.check_gp_argument (3, i, nargs)
    737 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES)
    738       return error_mark_node;
    739 
    740     /* Make sure that the function exists now, since not all forms
    741        follow a set pattern after this point.  */
    742     tree res = r.resolve_to (r.mode_suffix_id, type);
    743     if (res == error_mark_node)
    744       return res;
    745 
    746     bool float_p = type_suffixes[type].float_p;
    747     unsigned int modifier = float_p ? r.SAME_SIZE : r.QUARTER_SIZE;
    748     if (!r.require_derived_vector_type (i + 1, i, type, r.SAME_TYPE_CLASS,
    749 					modifier)
    750 	|| !r.require_derived_vector_type (i + 2, i, type, r.SAME_TYPE_CLASS,
    751 					   modifier))
    752       return error_mark_node;
    753 
    754     return res;
    755   }
    756 };
    757 SHAPE (mmla)
    758 
    759 /* Base class for prefetch_gather_index and prefetch_gather_offset,
    760    which differ only in the units of the displacement.  */
    761 struct prefetch_gather_base : public overloaded_base<0>
    762 {
    763   /* Resolve a gather prefetch that takes one of:
    764 
    765      - a scalar pointer base (const void *) and a vector displacement
    766      - a vector base with no displacement or
    767      - a vector base and a scalar displacement
    768 
    769      The prefetch operation is the final argument.  This is purely a
    770      mode-based resolution; there are no type suffixes.  */
    771   tree
    772   resolve (function_resolver &r) const OVERRIDE
    773   {
    774     bool has_displacement_p = r.displacement_units () != UNITS_none;
    775 
    776     unsigned int i, nargs;
    777     mode_suffix_index mode;
    778     if (!r.check_gp_argument (has_displacement_p ? 3 : 2, i, nargs)
    779 	|| (mode = r.resolve_gather_address (i, NUM_TYPE_SUFFIXES,
    780 					     false)) == MODE_none
    781 	|| !r.require_integer_immediate (nargs - 1))
    782       return error_mark_node;
    783 
    784     return r.resolve_to (mode);
    785   }
    786 };
    787 
    788 /* Wraps BASE to provide a narrowing shift right function.  Argument N
    789    is an immediate shift amount in the range [1, sizeof(<t0>_t) * 4].  */
    790 template<typename BASE, unsigned int N>
    791 struct shift_right_imm_narrow_wrapper : public BASE
    792 {
    793   bool
    794   check (function_checker &c) const OVERRIDE
    795   {
    796     unsigned int bits = c.type_suffix (0).element_bits / 2;
    797     return c.require_immediate_range (N, 1, bits);
    798   }
    799 };
    800 
    801 /* Base class for store_scatter_index and store_scatter_offset,
    802    which differ only in the units of the displacement.  */
    803 struct store_scatter_base : public overloaded_base<0>
    804 {
    805   /* Resolve a scatter store that takes one of:
    806 
    807      - a scalar pointer base and a vector displacement
    808      - a vector base with no displacement or
    809      - a vector base and a scalar displacement
    810 
    811      The stored data is the final argument, and it determines the
    812      type suffix.  */
    813   tree
    814   resolve (function_resolver &r) const OVERRIDE
    815   {
    816     bool has_displacement_p = r.displacement_units () != UNITS_none;
    817 
    818     unsigned int i, nargs;
    819     mode_suffix_index mode;
    820     type_suffix_index type;
    821     if (!r.check_gp_argument (has_displacement_p ? 3 : 2, i, nargs)
    822 	|| (type = r.infer_sd_vector_type (nargs - 1)) == NUM_TYPE_SUFFIXES
    823 	|| (mode = r.resolve_gather_address (i, type, false)) == MODE_none)
    824       return error_mark_node;
    825 
    826     return r.resolve_to (mode, type);
    827   }
    828 };
    829 
    830 /* Base class for ternary operations in which the final argument is an
    831    immediate shift amount.  The derived class should check the range.  */
    832 struct ternary_shift_imm_base : public overloaded_base<0>
    833 {
    834   void
    835   build (function_builder &b, const function_group_info &group) const OVERRIDE
    836   {
    837     b.add_overloaded_functions (group, MODE_n);
    838     build_all (b, "v0,v0,v0,su64", group, MODE_n);
    839   }
    840 
    841   tree
    842   resolve (function_resolver &r) const OVERRIDE
    843   {
    844     return r.resolve_uniform (2, 1);
    845   }
    846 };
    847 
    848 /* Base class for ternary operations in which the first argument has the
    849    same element type as the result, and in which the second and third
    850    arguments have an element type that is derived the first.
    851 
    852    MODIFIER is the number of element bits in the second and third
    853    arguments, or a function_resolver modifier that says how this
    854    precision is derived from the first argument's elements.
    855 
    856    TYPE_CLASS2 and TYPE_CLASS3 are the type classes of the second and
    857    third arguments, or function_resolver::SAME_TYPE_CLASS if the type
    858    class is the same as the first argument.  */
    859 template<unsigned int MODIFIER,
    860 	 type_class_index TYPE_CLASS2 = function_resolver::SAME_TYPE_CLASS,
    861 	 type_class_index TYPE_CLASS3 = function_resolver::SAME_TYPE_CLASS>
    862 struct ternary_resize2_opt_n_base : public overloaded_base<0>
    863 {
    864   tree
    865   resolve (function_resolver &r) const OVERRIDE
    866   {
    867     unsigned int i, nargs;
    868     type_suffix_index type;
    869     if (!r.check_gp_argument (3, i, nargs)
    870 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
    871 	|| !r.require_derived_vector_type (i + 1, i, type, TYPE_CLASS2,
    872 					   MODIFIER))
    873       return error_mark_node;
    874 
    875     return r.finish_opt_n_resolution (i + 2, i, type, TYPE_CLASS3, MODIFIER);
    876   }
    877 };
    878 
    879 /* Like ternary_resize2_opt_n_base, but for functions that don't take
    880    a final scalar argument.  */
    881 template<unsigned int MODIFIER,
    882 	 type_class_index TYPE_CLASS2 = function_resolver::SAME_TYPE_CLASS,
    883 	 type_class_index TYPE_CLASS3 = function_resolver::SAME_TYPE_CLASS>
    884 struct ternary_resize2_base : public overloaded_base<0>
    885 {
    886   tree
    887   resolve (function_resolver &r) const OVERRIDE
    888   {
    889     unsigned int i, nargs;
    890     type_suffix_index type;
    891     if (!r.check_gp_argument (3, i, nargs)
    892 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
    893 	|| !r.require_derived_vector_type (i + 1, i, type, TYPE_CLASS2,
    894 					   MODIFIER)
    895 	|| !r.require_derived_vector_type (i + 2, i, type, TYPE_CLASS3,
    896 					   MODIFIER))
    897       return error_mark_node;
    898 
    899     return r.resolve_to (r.mode_suffix_id, type);
    900   }
    901 };
    902 
    903 /* Like ternary_resize2_opt_n_base, but for functions that take a final
    904    lane argument.  */
    905 template<unsigned int MODIFIER,
    906 	 type_class_index TYPE_CLASS2 = function_resolver::SAME_TYPE_CLASS,
    907 	 type_class_index TYPE_CLASS3 = function_resolver::SAME_TYPE_CLASS>
    908 struct ternary_resize2_lane_base : public overloaded_base<0>
    909 {
    910   tree
    911   resolve (function_resolver &r) const OVERRIDE
    912   {
    913     unsigned int i, nargs;
    914     type_suffix_index type;
    915     if (!r.check_gp_argument (4, i, nargs)
    916 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
    917 	|| !r.require_derived_vector_type (i + 1, i, type, TYPE_CLASS2,
    918 					   MODIFIER)
    919 	|| !r.require_derived_vector_type (i + 2, i, type, TYPE_CLASS3,
    920 					   MODIFIER)
    921 	|| !r.require_integer_immediate (i + 3))
    922       return error_mark_node;
    923 
    924     return r.resolve_to (r.mode_suffix_id, type);
    925   }
    926 };
    927 
    928 /* A specialization of ternary_resize2_lane_base for bfloat16 elements,
    929    indexed in groups of N elements.  */
    930 template<unsigned int N>
    931 struct ternary_bfloat_lane_base
    932   : public ternary_resize2_lane_base<16, TYPE_bfloat, TYPE_bfloat>
    933 {
    934   void
    935   build (function_builder &b, const function_group_info &group) const OVERRIDE
    936   {
    937     b.add_overloaded_functions (group, MODE_none);
    938     build_all (b, "v0,v0,vB,vB,su64", group, MODE_none);
    939   }
    940 
    941   bool
    942   check (function_checker &c) const OVERRIDE
    943   {
    944     return c.require_immediate_lane_index (3, N);
    945   }
    946 };
    947 
    948 /* A specialization of ternary_resize2_lane_base for quarter-sized
    949    elements.  */
    950 template<type_class_index TYPE_CLASS2 = function_resolver::SAME_TYPE_CLASS,
    951 	 type_class_index TYPE_CLASS3 = function_resolver::SAME_TYPE_CLASS>
    952 struct ternary_qq_lane_base
    953   : public ternary_resize2_lane_base<function_resolver::QUARTER_SIZE,
    954 				     TYPE_CLASS2, TYPE_CLASS3>
    955 {
    956   bool
    957   check (function_checker &c) const OVERRIDE
    958   {
    959     return c.require_immediate_lane_index (3, 4);
    960   }
    961 };
    962 
    963 /* Base class for narrowing bottom unary functions.  The result is half
    964    the size of input and has class CLASS.  */
    965 template<type_class_index CLASS = function_resolver::SAME_TYPE_CLASS>
    966 struct unary_narrowb_base : public overloaded_base<0>
    967 {
    968   void
    969   build (function_builder &b, const function_group_info &group) const OVERRIDE
    970   {
    971     b.add_overloaded_functions (group, MODE_none);
    972     STATIC_ASSERT (CLASS == function_resolver::SAME_TYPE_CLASS
    973 		   || CLASS == TYPE_unsigned);
    974     if (CLASS == TYPE_unsigned)
    975       build_all (b, "vhu0,v0", group, MODE_none);
    976     else
    977       build_all (b, "vh0,v0", group, MODE_none);
    978   }
    979 
    980   tree
    981   resolve (function_resolver &r) const OVERRIDE
    982   {
    983     return r.resolve_unary (CLASS, r.HALF_SIZE);
    984   }
    985 };
    986 
    987 /* The top equivalent of unary_imm_narrowb_base.  All forms take the values
    988    of the even elements as an extra argument, before any governing predicate.
    989    These even elements are typically the result of the narrowb operation.  */
    990 template<type_class_index CLASS = function_resolver::SAME_TYPE_CLASS>
    991 struct unary_narrowt_base : public overloaded_base<0>
    992 {
    993   void
    994   build (function_builder &b, const function_group_info &group) const OVERRIDE
    995   {
    996     b.add_overloaded_functions (group, MODE_none);
    997     STATIC_ASSERT (CLASS == function_resolver::SAME_TYPE_CLASS
    998 		   || CLASS == TYPE_unsigned);
    999     if (CLASS == TYPE_unsigned)
   1000       build_all (b, "vhu0,vhu0,v0", group, MODE_none);
   1001     else
   1002       build_all (b, "vh0,vh0,v0", group, MODE_none);
   1003   }
   1004 
   1005   tree
   1006   resolve (function_resolver &r) const OVERRIDE
   1007   {
   1008     unsigned int i, nargs;
   1009     type_suffix_index type;
   1010     if (!r.check_gp_argument (2, i, nargs)
   1011 	|| (type = r.infer_vector_type (i + 1)) == NUM_TYPE_SUFFIXES
   1012 	|| !r.require_derived_vector_type (i, i + 1, type, CLASS, r.HALF_SIZE))
   1013       return error_mark_node;
   1014 
   1015     return r.resolve_to (r.mode_suffix_id, type);
   1016   }
   1017 };
   1018 
   1019 /* sv<m0>_t svfoo[_m0base]_[m1]index(sv<m0>_t, sv<m1>_t)
   1020 
   1021    for all valid combinations of vector base type <m0> and vector
   1022    displacement type <m1>.  */
   1023 struct adr_index_def : public adr_base
   1024 {
   1025   void
   1026   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1027   {
   1028     b.add_overloaded_functions (group, MODE_index);
   1029     build_all (b, "b,b,d", group, MODE_u32base_s32index);
   1030     build_all (b, "b,b,d", group, MODE_u32base_u32index);
   1031     build_all (b, "b,b,d", group, MODE_u64base_s64index);
   1032     build_all (b, "b,b,d", group, MODE_u64base_u64index);
   1033   }
   1034 };
   1035 SHAPE (adr_index)
   1036 
   1037 /* sv<m0>_t svfoo[_m0base]_[m1]offset(sv<m0>_t, sv<m1>_t).
   1038 
   1039    for all valid combinations of vector base type <m0> and vector
   1040    displacement type <m1>.  */
   1041 struct adr_offset_def : public adr_base
   1042 {
   1043   void
   1044   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1045   {
   1046     b.add_overloaded_functions (group, MODE_offset);
   1047     build_all (b, "b,b,d", group, MODE_u32base_s32offset);
   1048     build_all (b, "b,b,d", group, MODE_u32base_u32offset);
   1049     build_all (b, "b,b,d", group, MODE_u64base_s64offset);
   1050     build_all (b, "b,b,d", group, MODE_u64base_u64offset);
   1051   }
   1052 };
   1053 SHAPE (adr_offset)
   1054 
   1055 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
   1056 
   1057    i.e. a binary operation with uniform types, but with no scalar form.  */
   1058 struct binary_def : public overloaded_base<0>
   1059 {
   1060   void
   1061   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1062   {
   1063     b.add_overloaded_functions (group, MODE_none);
   1064     build_all (b, "v0,v0,v0", group, MODE_none);
   1065   }
   1066 
   1067   tree
   1068   resolve (function_resolver &r) const OVERRIDE
   1069   {
   1070     return r.resolve_uniform (2);
   1071   }
   1072 };
   1073 SHAPE (binary)
   1074 
   1075 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:int>_t)
   1076    sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0:int>_t).
   1077 
   1078    i.e. a version of the standard binary shape binary_opt_n in which
   1079    the final argument is always a signed integer.  */
   1080 struct binary_int_opt_n_def : public overloaded_base<0>
   1081 {
   1082   void
   1083   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1084   {
   1085     b.add_overloaded_functions (group, MODE_none);
   1086     build_all (b, "v0,v0,vs0", group, MODE_none);
   1087     build_all (b, "v0,v0,ss0", group, MODE_n);
   1088   }
   1089 
   1090   tree
   1091   resolve (function_resolver &r) const OVERRIDE
   1092   {
   1093     unsigned int i, nargs;
   1094     type_suffix_index type;
   1095     if (!r.check_gp_argument (2, i, nargs)
   1096 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES)
   1097       return error_mark_node;
   1098 
   1099     return r.finish_opt_n_resolution (i + 1, i, type, TYPE_signed);
   1100   }
   1101 };
   1102 SHAPE (binary_int_opt_n)
   1103 
   1104 /* sv<t0>_t svfoo_<t0>(sv<t0>_t, sv<t0>_t, uint64_t)
   1105 
   1106    where the final argument is an integer constant expression in the
   1107    range [0, 16 / sizeof (<t0>_t) - 1].  */
   1108 struct binary_lane_def : public overloaded_base<0>
   1109 {
   1110   void
   1111   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1112   {
   1113     b.add_overloaded_functions (group, MODE_none);
   1114     build_all (b, "v0,v0,v0,su64", group, MODE_none);
   1115   }
   1116 
   1117   tree
   1118   resolve (function_resolver &r) const OVERRIDE
   1119   {
   1120     return r.resolve_uniform (2, 1);
   1121   }
   1122 
   1123   bool
   1124   check (function_checker &c) const OVERRIDE
   1125   {
   1126     return c.require_immediate_lane_index (2);
   1127   }
   1128 };
   1129 SHAPE (binary_lane)
   1130 
   1131 /* sv<t0>_t svfoo[_t0](sv<t0:half>_t, sv<t0:half>_t, uint64_t).
   1132 
   1133    where the final argument is an integer constant expression in the
   1134    range [0, 32 / sizeof (<t0>_t) - 1].  */
   1135 struct binary_long_lane_def : public overloaded_base<0>
   1136 {
   1137   void
   1138   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1139   {
   1140     b.add_overloaded_functions (group, MODE_none);
   1141     build_all (b, "v0,vh0,vh0,su64", group, MODE_none);
   1142   }
   1143 
   1144   tree
   1145   resolve (function_resolver &r) const OVERRIDE
   1146   {
   1147     unsigned int i, nargs;
   1148     type_suffix_index type, result_type;
   1149     if (!r.check_gp_argument (3, i, nargs)
   1150 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
   1151 	|| !r.require_matching_vector_type (i + 1, type)
   1152 	|| !r.require_integer_immediate (i + 2)
   1153 	|| (result_type = long_type_suffix (r, type)) == NUM_TYPE_SUFFIXES)
   1154       return error_mark_node;
   1155 
   1156     if (tree res = r.lookup_form (r.mode_suffix_id, result_type))
   1157       return res;
   1158 
   1159     return r.report_no_such_form (type);
   1160   }
   1161 
   1162   bool
   1163   check (function_checker &c) const OVERRIDE
   1164   {
   1165     return c.require_immediate_lane_index (2);
   1166   }
   1167 };
   1168 SHAPE (binary_long_lane)
   1169 
   1170 /* sv<t0>_t svfoo[_t0](sv<t0:half>_t, sv<t0:half>_t)
   1171    sv<t0>_t svfoo[_n_t0](sv<t0:half>_t, <t0:half>_t).  */
   1172 struct binary_long_opt_n_def : public overloaded_base<0>
   1173 {
   1174   void
   1175   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1176   {
   1177     b.add_overloaded_functions (group, MODE_none);
   1178     build_all (b, "v0,vh0,vh0", group, MODE_none);
   1179     build_all (b, "v0,vh0,sh0", group, MODE_n);
   1180   }
   1181 
   1182   tree
   1183   resolve (function_resolver &r) const OVERRIDE
   1184   {
   1185     unsigned int i, nargs;
   1186     type_suffix_index type, result_type;
   1187     if (!r.check_gp_argument (2, i, nargs)
   1188 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
   1189 	|| (result_type = long_type_suffix (r, type)) == NUM_TYPE_SUFFIXES)
   1190       return error_mark_node;
   1191 
   1192     return r.finish_opt_n_resolution (i + 1, i, type, r.SAME_TYPE_CLASS,
   1193 				      r.SAME_SIZE, result_type);
   1194   }
   1195 };
   1196 SHAPE (binary_long_opt_n)
   1197 
   1198 /* sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0>_t).
   1199 
   1200    i.e. a binary operation in which the final argument is always a scalar
   1201    rather than a vector.  */
   1202 struct binary_n_def : public overloaded_base<0>
   1203 {
   1204   void
   1205   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1206   {
   1207     b.add_overloaded_functions (group, MODE_n);
   1208     build_all (b, "v0,v0,s0", group, MODE_n);
   1209   }
   1210 
   1211   tree
   1212   resolve (function_resolver &r) const OVERRIDE
   1213   {
   1214     unsigned int i, nargs;
   1215     type_suffix_index type;
   1216     if (!r.check_gp_argument (2, i, nargs)
   1217 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
   1218 	|| !r.require_derived_scalar_type (i + 1, r.SAME_TYPE_CLASS))
   1219       return error_mark_node;
   1220 
   1221     return r.resolve_to (r.mode_suffix_id, type);
   1222   }
   1223 };
   1224 SHAPE (binary_n)
   1225 
   1226 /* sv<t0:half>_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
   1227    sv<t0:half>_t svfoo[_n_t0](sv<t0>_t, <t0>_t)
   1228 
   1229    i.e. a version of binary_opt_n in which the output elements are half the
   1230    width of the input elements.  */
   1231 struct binary_narrowb_opt_n_def : public overloaded_base<0>
   1232 {
   1233   void
   1234   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1235   {
   1236     b.add_overloaded_functions (group, MODE_none);
   1237     build_all (b, "vh0,v0,v0", group, MODE_none);
   1238     build_all (b, "vh0,v0,s0", group, MODE_n);
   1239   }
   1240 
   1241   tree
   1242   resolve (function_resolver &r) const OVERRIDE
   1243   {
   1244     return r.resolve_uniform_opt_n (2);
   1245   }
   1246 };
   1247 SHAPE (binary_narrowb_opt_n)
   1248 
   1249 /* sv<t0:half>_t svfoo[_t0](sv<t0:half>_t, sv<t0>_t, sv<t0>_t)
   1250    sv<t0:half>_t svfoo[_n_t0](sv<t0:half>_t, sv<t0>_t, <t0>_t)
   1251 
   1252    This is the "top" counterpart to binary_narrowb_opt_n.  */
   1253 struct binary_narrowt_opt_n_def : public overloaded_base<0>
   1254 {
   1255   void
   1256   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1257   {
   1258     b.add_overloaded_functions (group, MODE_none);
   1259     build_all (b, "vh0,vh0,v0,v0", group, MODE_none);
   1260     build_all (b, "vh0,vh0,v0,s0", group, MODE_n);
   1261   }
   1262 
   1263   tree
   1264   resolve (function_resolver &r) const OVERRIDE
   1265   {
   1266     unsigned int i, nargs;
   1267     type_suffix_index type;
   1268     if (!r.check_gp_argument (3, i, nargs)
   1269 	|| (type = r.infer_vector_type (i + 1)) == NUM_TYPE_SUFFIXES
   1270 	|| !r.require_derived_vector_type (i, i + 1, type, r.SAME_TYPE_CLASS,
   1271 					   r.HALF_SIZE))
   1272       return error_mark_node;
   1273 
   1274     return r.finish_opt_n_resolution (i + 2, i + 1, type);
   1275   }
   1276 };
   1277 SHAPE (binary_narrowt_opt_n)
   1278 
   1279 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
   1280    sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0>_t)
   1281 
   1282    i.e. the standard shape for binary operations that operate on
   1283    uniform types.  */
   1284 struct binary_opt_n_def : public overloaded_base<0>
   1285 {
   1286   void
   1287   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1288   {
   1289     b.add_overloaded_functions (group, MODE_none);
   1290     build_all (b, "v0,v0,v0", group, MODE_none);
   1291     /* _b functions do not have an _n form, but are classified as
   1292        binary_opt_n so that they can be overloaded with vector
   1293        functions.  */
   1294     if (group.types[0][0] == TYPE_SUFFIX_b)
   1295       gcc_assert (group.types[0][1] == NUM_TYPE_SUFFIXES);
   1296     else
   1297       build_all (b, "v0,v0,s0", group, MODE_n);
   1298   }
   1299 
   1300   tree
   1301   resolve (function_resolver &r) const OVERRIDE
   1302   {
   1303     return r.resolve_uniform_opt_n (2);
   1304   }
   1305 };
   1306 SHAPE (binary_opt_n)
   1307 
   1308 /* svbool_t svfoo(svbool_t, svbool_t).  */
   1309 struct binary_pred_def : public nonoverloaded_base
   1310 {
   1311   void
   1312   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1313   {
   1314     build_all (b, "v0,v0,v0", group, MODE_none);
   1315   }
   1316 };
   1317 SHAPE (binary_pred)
   1318 
   1319 /* sv<t0>_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, uint64_t)
   1320 
   1321    where the final argument must be 90 or 270.  */
   1322 struct binary_rotate_def : public overloaded_base<0>
   1323 {
   1324   void
   1325   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1326   {
   1327     b.add_overloaded_functions (group, MODE_none);
   1328     build_all (b, "v0,v0,v0,su64", group, MODE_none);
   1329   }
   1330 
   1331   tree
   1332   resolve (function_resolver &r) const OVERRIDE
   1333   {
   1334     return r.resolve_uniform (2, 1);
   1335   }
   1336 
   1337   bool
   1338   check (function_checker &c) const OVERRIDE
   1339   {
   1340     return c.require_immediate_either_or (2, 90, 270);
   1341   }
   1342 };
   1343 SHAPE (binary_rotate)
   1344 
   1345 /* sv<t0>_t svfoo_t0(<t0>_t, <t0>_t)
   1346 
   1347    i.e. a binary function that takes two scalars and returns a vector.
   1348    An explicit type suffix is required.  */
   1349 struct binary_scalar_def : public nonoverloaded_base
   1350 {
   1351   void
   1352   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1353   {
   1354     build_all (b, "v0,s0,s0", group, MODE_none);
   1355   }
   1356 };
   1357 SHAPE (binary_scalar)
   1358 
   1359 /* sv<t0:uint>_t svfoo[_t0](sv<t0>_t, sv<t0>_t).
   1360 
   1361    i.e. a version of "binary" that returns unsigned integers.  */
   1362 struct binary_to_uint_def : public overloaded_base<0>
   1363 {
   1364   void
   1365   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1366   {
   1367     b.add_overloaded_functions (group, MODE_none);
   1368     build_all (b, "vu0,v0,v0", group, MODE_none);
   1369   }
   1370 
   1371   tree
   1372   resolve (function_resolver &r) const OVERRIDE
   1373   {
   1374     return r.resolve_uniform (2);
   1375   }
   1376 };
   1377 SHAPE (binary_to_uint)
   1378 
   1379 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:uint>_t)
   1380 
   1381    i.e. a version of "binary" in which the final argument is always an
   1382    unsigned integer.  */
   1383 struct binary_uint_def : public overloaded_base<0>
   1384 {
   1385   void
   1386   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1387   {
   1388     b.add_overloaded_functions (group, MODE_none);
   1389     build_all (b, "v0,v0,vu0", group, MODE_none);
   1390   }
   1391 
   1392   tree
   1393   resolve (function_resolver &r) const OVERRIDE
   1394   {
   1395     unsigned int i, nargs;
   1396     type_suffix_index type;
   1397     if (!r.check_gp_argument (2, i, nargs)
   1398 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
   1399 	|| !r.require_derived_vector_type (i + 1, i, type, TYPE_unsigned))
   1400       return error_mark_node;
   1401 
   1402     return r.resolve_to (r.mode_suffix_id, type);
   1403   }
   1404 };
   1405 SHAPE (binary_uint)
   1406 
   1407 /* sv<t0>_t svfoo[_t0](sv<t0>_t, <t0:uint>_t)
   1408 
   1409    i.e. a version of binary_n in which the final argument is always an
   1410    unsigned integer.  */
   1411 struct binary_uint_n_def : public overloaded_base<0>
   1412 {
   1413   void
   1414   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1415   {
   1416     b.add_overloaded_functions (group, MODE_none);
   1417     build_all (b, "v0,v0,su0", group, MODE_none);
   1418   }
   1419 
   1420   tree
   1421   resolve (function_resolver &r) const OVERRIDE
   1422   {
   1423     unsigned int i, nargs;
   1424     type_suffix_index type;
   1425     if (!r.check_gp_argument (2, i, nargs)
   1426 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
   1427 	|| !r.require_derived_scalar_type (i + 1, TYPE_unsigned))
   1428       return error_mark_node;
   1429 
   1430     return r.resolve_to (r.mode_suffix_id, type);
   1431   }
   1432 };
   1433 SHAPE (binary_uint_n)
   1434 
   1435 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:uint>_t)
   1436    sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0:uint>_t)
   1437 
   1438    i.e. a version of the standard binary shape binary_opt_n in which
   1439    the final argument is always an unsigned integer.  */
   1440 struct binary_uint_opt_n_def : public overloaded_base<0>
   1441 {
   1442   void
   1443   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1444   {
   1445     b.add_overloaded_functions (group, MODE_none);
   1446     build_all (b, "v0,v0,vu0", group, MODE_none);
   1447     build_all (b, "v0,v0,su0", group, MODE_n);
   1448   }
   1449 
   1450   tree
   1451   resolve (function_resolver &r) const OVERRIDE
   1452   {
   1453     unsigned int i, nargs;
   1454     type_suffix_index type;
   1455     if (!r.check_gp_argument (2, i, nargs)
   1456 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES)
   1457       return error_mark_node;
   1458 
   1459     return r.finish_opt_n_resolution (i + 1, i, type, TYPE_unsigned);
   1460   }
   1461 };
   1462 SHAPE (binary_uint_opt_n)
   1463 
   1464 /* sv<t0>_t svfoo[_t0](sv<t0>_t, uint64_t).
   1465 
   1466    i.e. a version of binary_n in which the final argument is always
   1467    a 64-bit unsigned integer.  */
   1468 struct binary_uint64_n_def : public overloaded_base<0>
   1469 {
   1470   void
   1471   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1472   {
   1473     b.add_overloaded_functions (group, MODE_none);
   1474     build_all (b, "v0,v0,su64", group, MODE_none);
   1475   }
   1476 
   1477   tree
   1478   resolve (function_resolver &r) const OVERRIDE
   1479   {
   1480     unsigned int i, nargs;
   1481     type_suffix_index type;
   1482     if (!r.check_gp_argument (2, i, nargs)
   1483 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
   1484 	|| !r.require_scalar_type (i + 1, "uint64_t"))
   1485       return error_mark_node;
   1486 
   1487     return r.resolve_to (r.mode_suffix_id, type);
   1488   }
   1489 };
   1490 SHAPE (binary_uint64_n)
   1491 
   1492 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svuint64_t)
   1493    sv<t0>_t svfoo[_n_t0](sv<t0>_t, uint64_t)
   1494 
   1495    i.e. a version of the standard binary shape binary_opt_n in which
   1496    the final argument is always a uint64_t.  */
   1497 struct binary_uint64_opt_n_def : public overloaded_base<0>
   1498 {
   1499   void
   1500   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1501   {
   1502     b.add_overloaded_functions (group, MODE_none);
   1503     build_all (b, "v0,v0,vu64", group, MODE_none);
   1504     build_all (b, "v0,v0,su64", group, MODE_n);
   1505   }
   1506 
   1507   tree
   1508   resolve (function_resolver &r) const OVERRIDE
   1509   {
   1510     unsigned int i, nargs;
   1511     type_suffix_index type;
   1512     if (!r.check_gp_argument (2, i, nargs)
   1513 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES)
   1514       return error_mark_node;
   1515 
   1516     return r.finish_opt_n_resolution (i + 1, i, type, TYPE_unsigned, 64);
   1517   }
   1518 };
   1519 SHAPE (binary_uint64_opt_n)
   1520 
   1521 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:half>_t).  */
   1522 struct binary_wide_def : public overloaded_base<0>
   1523 {
   1524   void
   1525   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1526   {
   1527     b.add_overloaded_functions (group, MODE_none);
   1528     build_all (b, "v0,v0,vh0", group, MODE_none);
   1529   }
   1530 
   1531   tree
   1532   resolve (function_resolver &r) const OVERRIDE
   1533   {
   1534     unsigned int i, nargs;
   1535     type_suffix_index type;
   1536     if (!r.check_gp_argument (2, i, nargs)
   1537 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
   1538 	|| !r.require_derived_vector_type (i + 1, i, type, r.SAME_TYPE_CLASS,
   1539 					   r.HALF_SIZE))
   1540       return error_mark_node;
   1541 
   1542     return r.resolve_to (r.mode_suffix_id, type);
   1543   }
   1544 };
   1545 SHAPE (binary_wide)
   1546 
   1547 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:half>_t)
   1548    sv<t0>_t svfoo[_n_t0](sv<t0>_t, <t0:half>_t).  */
   1549 struct binary_wide_opt_n_def : public overloaded_base<0>
   1550 {
   1551   void
   1552   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1553   {
   1554     b.add_overloaded_functions (group, MODE_none);
   1555     build_all (b, "v0,v0,vh0", group, MODE_none);
   1556     build_all (b, "v0,v0,sh0", group, MODE_n);
   1557   }
   1558 
   1559   tree
   1560   resolve (function_resolver &r) const OVERRIDE
   1561   {
   1562     unsigned int i, nargs;
   1563     type_suffix_index type;
   1564     if (!r.check_gp_argument (2, i, nargs)
   1565 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES)
   1566       return error_mark_node;
   1567 
   1568     return r.finish_opt_n_resolution (i + 1, i, type, r.SAME_TYPE_CLASS,
   1569 				      r.HALF_SIZE);
   1570   }
   1571 };
   1572 SHAPE (binary_wide_opt_n)
   1573 
   1574 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
   1575    <t0>_t svfoo[_n_t0](<t0>_t, sv<t0>_t).  */
   1576 struct clast_def : public overloaded_base<0>
   1577 {
   1578   void
   1579   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1580   {
   1581     b.add_overloaded_functions (group, MODE_none);
   1582     build_all (b, "v0,v0,v0", group, MODE_none);
   1583     build_all (b, "s0,s0,v0", group, MODE_n);
   1584   }
   1585 
   1586   tree
   1587   resolve (function_resolver &r) const OVERRIDE
   1588   {
   1589     unsigned int i, nargs;
   1590     if (!r.check_gp_argument (2, i, nargs)
   1591 	|| !r.require_vector_or_scalar_type (i))
   1592       return error_mark_node;
   1593 
   1594     if (r.scalar_argument_p (i))
   1595       {
   1596 	type_suffix_index type;
   1597 	if (!r.require_derived_scalar_type (i, r.SAME_TYPE_CLASS)
   1598 	    || (type = r.infer_vector_type (i + 1)) == NUM_TYPE_SUFFIXES)
   1599 	  return error_mark_node;
   1600 	return r.resolve_to (MODE_n, type);
   1601       }
   1602     else
   1603       {
   1604 	type_suffix_index type;
   1605 	if ((type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
   1606 	    || !r.require_matching_vector_type (i + 1, type))
   1607 	  return error_mark_node;
   1608 	return r.resolve_to (MODE_none, type);
   1609       }
   1610   }
   1611 };
   1612 SHAPE (clast)
   1613 
   1614 /* svbool_t svfoo[_t0](sv<t0>_t, sv<t0>_t).  */
   1615 struct compare_def : public overloaded_base<0>
   1616 {
   1617   void
   1618   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1619   {
   1620     b.add_overloaded_functions (group, MODE_none);
   1621     build_all (b, "vp,v0,v0", group, MODE_none);
   1622   }
   1623 
   1624   tree
   1625   resolve (function_resolver &r) const OVERRIDE
   1626   {
   1627     return r.resolve_uniform (2);
   1628   }
   1629 };
   1630 SHAPE (compare)
   1631 
   1632 /* svbool_t svfoo[_t0](sv<t0>_t, sv<t0>_t)
   1633    svbool_t svfoo[_n_t0](sv<t0>_t, <t0>_t)
   1634 
   1635    i.e. a comparison between two vectors, or between a vector and a scalar.  */
   1636 struct compare_opt_n_def : public overloaded_base<0>
   1637 {
   1638   void
   1639   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1640   {
   1641     b.add_overloaded_functions (group, MODE_none);
   1642     build_all (b, "vp,v0,v0", group, MODE_none);
   1643     build_all (b, "vp,v0,s0", group, MODE_n);
   1644   }
   1645 
   1646   tree
   1647   resolve (function_resolver &r) const OVERRIDE
   1648   {
   1649     return r.resolve_uniform_opt_n (2);
   1650   }
   1651 };
   1652 SHAPE (compare_opt_n)
   1653 
   1654 /* svbool_t svfoo[_t0](const <t0>_t *, const <t0>_t *).  */
   1655 struct compare_ptr_def : public overloaded_base<0>
   1656 {
   1657   void
   1658   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1659   {
   1660     b.add_overloaded_functions (group, MODE_none);
   1661     build_all (b, "vp,al,al", group, MODE_none);
   1662   }
   1663 
   1664   tree
   1665   resolve (function_resolver &r) const OVERRIDE
   1666   {
   1667     unsigned int i, nargs;
   1668     type_suffix_index type;
   1669     if (!r.check_gp_argument (2, i, nargs)
   1670 	|| (type = r.infer_pointer_type (i)) == NUM_TYPE_SUFFIXES
   1671 	|| !r.require_matching_pointer_type (i + 1, i, type))
   1672       return error_mark_node;
   1673 
   1674     return r.resolve_to (r.mode_suffix_id, type);
   1675   }
   1676 };
   1677 SHAPE (compare_ptr)
   1678 
   1679 /* svbool_t svfoo_t0[_t1](<t1>_t, <t1>_t)
   1680 
   1681    where _t0 is a _b<bits> suffix that describes the predicate result.
   1682    There is no direct relationship between the element sizes of _t0
   1683    and _t1.  */
   1684 struct compare_scalar_def : public overloaded_base<1>
   1685 {
   1686   void
   1687   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1688   {
   1689     b.add_overloaded_functions (group, MODE_none);
   1690     build_all (b, "vp,s1,s1", group, MODE_none);
   1691   }
   1692 
   1693   tree
   1694   resolve (function_resolver &r) const OVERRIDE
   1695   {
   1696     unsigned int i, nargs;
   1697     type_suffix_index type;
   1698     if (!r.check_gp_argument (2, i, nargs)
   1699 	|| (type = r.infer_integer_scalar_type (i)) == NUM_TYPE_SUFFIXES
   1700 	|| !r.require_matching_integer_scalar_type (i + 1, i, type))
   1701       return error_mark_node;
   1702 
   1703     return r.resolve_to (r.mode_suffix_id, r.type_suffix_ids[0], type);
   1704   }
   1705 };
   1706 SHAPE (compare_scalar)
   1707 
   1708 /* svbool_t svfoo[_t0](sv<t0>_t, svint64_t)  (for signed t0)
   1709    svbool_t svfoo[_n_t0](sv<t0>_t, int64_t)  (for signed t0)
   1710    svbool_t svfoo[_t0](sv<t0>_t, svuint64_t)  (for unsigned t0)
   1711    svbool_t svfoo[_n_t0](sv<t0>_t, uint64_t)  (for unsigned t0)
   1712 
   1713    i.e. a comparison in which the second argument is 64 bits.  */
   1714 struct compare_wide_opt_n_def : public overloaded_base<0>
   1715 {
   1716   void
   1717   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1718   {
   1719     b.add_overloaded_functions (group, MODE_none);
   1720     build_all (b, "vp,v0,vw0", group, MODE_none);
   1721     build_all (b, "vp,v0,sw0", group, MODE_n);
   1722   }
   1723 
   1724   tree
   1725   resolve (function_resolver &r) const OVERRIDE
   1726   {
   1727     unsigned int i, nargs;
   1728     type_suffix_index type;
   1729     if (!r.check_gp_argument (2, i, nargs)
   1730 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES)
   1731       return error_mark_node;
   1732 
   1733     return r.finish_opt_n_resolution (i + 1, i, type, r.SAME_TYPE_CLASS, 64);
   1734   }
   1735 };
   1736 SHAPE (compare_wide_opt_n)
   1737 
   1738 /* uint64_t svfoo().  */
   1739 struct count_inherent_def : public nonoverloaded_base
   1740 {
   1741   void
   1742   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1743   {
   1744     build_all (b, "su64", group, MODE_none);
   1745   }
   1746 };
   1747 SHAPE (count_inherent)
   1748 
   1749 /* uint64_t svfoo(enum svpattern).  */
   1750 struct count_pat_def : public nonoverloaded_base
   1751 {
   1752   void
   1753   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1754   {
   1755     build_all (b, "su64,epattern", group, MODE_none);
   1756   }
   1757 };
   1758 SHAPE (count_pat)
   1759 
   1760 /* uint64_t svfoo(svbool_t).  */
   1761 struct count_pred_def : public nonoverloaded_base
   1762 {
   1763   void
   1764   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1765   {
   1766     build_all (b, "su64,vp", group, MODE_none);
   1767   }
   1768 };
   1769 SHAPE (count_pred)
   1770 
   1771 /* uint64_t svfoo[_t0](sv<t0>_t).  */
   1772 struct count_vector_def : public overloaded_base<0>
   1773 {
   1774   void
   1775   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1776   {
   1777     b.add_overloaded_functions (group, MODE_none);
   1778     build_all (b, "su64,v0", group, MODE_none);
   1779   }
   1780 
   1781   tree
   1782   resolve (function_resolver &r) const OVERRIDE
   1783   {
   1784     return r.resolve_uniform (1);
   1785   }
   1786 };
   1787 SHAPE (count_vector)
   1788 
   1789 /* sv<t0>xN_t svfoo[_t0](sv<t0>_t, ..., sv<t0>_t)
   1790 
   1791    where there are N arguments in total.  */
   1792 struct create_def : public overloaded_base<0>
   1793 {
   1794   void
   1795   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1796   {
   1797     b.add_overloaded_functions (group, MODE_none);
   1798     build_all (b, "t0,v0*t", group, MODE_none);
   1799   }
   1800 
   1801   tree
   1802   resolve (function_resolver &r) const OVERRIDE
   1803   {
   1804     return r.resolve_uniform (r.vectors_per_tuple ());
   1805   }
   1806 };
   1807 SHAPE (create)
   1808 
   1809 /* sv<t0>_t svfoo[_n]_t0(<t0>_t, ..., <t0>_t)
   1810 
   1811    where there are enough arguments to fill 128 bits of data (or to
   1812    control 128 bits of data in the case of predicates).  */
   1813 struct dupq_def : public overloaded_base<1>
   1814 {
   1815   void
   1816   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1817   {
   1818     /* The "_n" suffix is optional; the full name has it, but the short
   1819        name doesn't.  */
   1820     build_all (b, "v0,s0*q", group, MODE_n, true);
   1821   }
   1822 
   1823   tree
   1824   resolve (function_resolver &) const OVERRIDE
   1825   {
   1826     /* The short forms just make "_n" implicit, so no resolution is needed.  */
   1827     gcc_unreachable ();
   1828   }
   1829 };
   1830 SHAPE (dupq)
   1831 
   1832 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t, uint64_t)
   1833 
   1834    where the final argument is an integer constant expression that when
   1835    multiplied by the number of bytes in t0 is in the range [0, 255].  */
   1836 struct ext_def : public overloaded_base<0>
   1837 {
   1838   void
   1839   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1840   {
   1841     b.add_overloaded_functions (group, MODE_none);
   1842     build_all (b, "v0,v0,v0,su64", group, MODE_none);
   1843   }
   1844 
   1845   tree
   1846   resolve (function_resolver &r) const OVERRIDE
   1847   {
   1848     return r.resolve_uniform (2, 1);
   1849   }
   1850 
   1851   bool
   1852   check (function_checker &c) const OVERRIDE
   1853   {
   1854     unsigned int bytes = c.type_suffix (0).element_bytes;
   1855     return c.require_immediate_range (2, 0, 256 / bytes - 1);
   1856   }
   1857 };
   1858 SHAPE (ext)
   1859 
   1860 /* <t0>_t svfoo[_t0](<t0>_t, sv<t0>_t).  */
   1861 struct fold_left_def : public overloaded_base<0>
   1862 {
   1863   void
   1864   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1865   {
   1866     b.add_overloaded_functions (group, MODE_none);
   1867     build_all (b, "s0,s0,v0", group, MODE_none);
   1868   }
   1869 
   1870   tree
   1871   resolve (function_resolver &r) const OVERRIDE
   1872   {
   1873     unsigned int i, nargs;
   1874     type_suffix_index type;
   1875     if (!r.check_gp_argument (2, i, nargs)
   1876 	|| !r.require_derived_scalar_type (i, r.SAME_TYPE_CLASS)
   1877 	|| (type = r.infer_vector_type (i + 1)) == NUM_TYPE_SUFFIXES)
   1878       return error_mark_node;
   1879 
   1880     return r.resolve_to (r.mode_suffix_id, type);
   1881   }
   1882 };
   1883 SHAPE (fold_left)
   1884 
   1885 /* sv<t0>_t svfoo[_t0](sv<t0>xN_t, uint64_t)
   1886 
   1887    where the final argument is an integer constant expression in
   1888    the range [0, N - 1].  */
   1889 struct get_def : public overloaded_base<0>
   1890 {
   1891   void
   1892   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1893   {
   1894     b.add_overloaded_functions (group, MODE_none);
   1895     build_all (b, "v0,t0,su64", group, MODE_none);
   1896   }
   1897 
   1898   tree
   1899   resolve (function_resolver &r) const OVERRIDE
   1900   {
   1901     unsigned int i, nargs;
   1902     type_suffix_index type;
   1903     if (!r.check_gp_argument (2, i, nargs)
   1904 	|| (type = r.infer_tuple_type (i)) == NUM_TYPE_SUFFIXES
   1905 	|| !r.require_integer_immediate (i + 1))
   1906       return error_mark_node;
   1907 
   1908     return r.resolve_to (r.mode_suffix_id, type);
   1909   }
   1910 
   1911   bool
   1912   check (function_checker &c) const OVERRIDE
   1913   {
   1914     unsigned int nvectors = c.vectors_per_tuple ();
   1915     return c.require_immediate_range (1, 0, nvectors - 1);
   1916   }
   1917 };
   1918 SHAPE (get)
   1919 
   1920 /* sv<t0>_t svfoo[_t0](sv<t0>_t, uint64_t)
   1921    <t0>_t svfoo[_n_t0](<t0>_t, uint64_t)
   1922 
   1923    where the t0 in the vector form is a signed or unsigned integer
   1924    whose size is tied to the [bhwd] suffix of "svfoo".  */
   1925 struct inc_dec_def : public inc_dec_base
   1926 {
   1927   CONSTEXPR inc_dec_def () : inc_dec_base (false) {}
   1928 
   1929   void
   1930   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1931   {
   1932     b.add_overloaded_functions (group, MODE_none);
   1933     /* These functions are unusual in that the type suffixes for
   1934        the scalar and vector forms are not related.  The vector
   1935        form always has exactly two potential suffixes while the
   1936        scalar form always has four.  */
   1937     if (group.types[2][0] == NUM_TYPE_SUFFIXES)
   1938       build_all (b, "v0,v0,su64", group, MODE_none);
   1939     else
   1940       build_all (b, "s0,s0,su64", group, MODE_n);
   1941   }
   1942 };
   1943 SHAPE (inc_dec)
   1944 
   1945 /* sv<t0>_t svfoo[_t0](sv<t0>_t, enum svpattern, uint64_t)
   1946    <t0>_t svfoo[_n_t0](<t0>_t, enum svpattern, uint64_t)
   1947 
   1948    where the t0 in the vector form is a signed or unsigned integer
   1949    whose size is tied to the [bhwd] suffix of "svfoo".  */
   1950 struct inc_dec_pat_def : public inc_dec_base
   1951 {
   1952   CONSTEXPR inc_dec_pat_def () : inc_dec_base (true) {}
   1953 
   1954   void
   1955   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1956   {
   1957     b.add_overloaded_functions (group, MODE_none);
   1958     /* These functions are unusual in that the type suffixes for
   1959        the scalar and vector forms are not related.  The vector
   1960        form always has exactly two potential suffixes while the
   1961        scalar form always has four.  */
   1962     if (group.types[2][0] == NUM_TYPE_SUFFIXES)
   1963       build_all (b, "v0,v0,epattern,su64", group, MODE_none);
   1964     else
   1965       build_all (b, "s0,s0,epattern,su64", group, MODE_n);
   1966   }
   1967 };
   1968 SHAPE (inc_dec_pat)
   1969 
   1970 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbool_t).  */
   1971 struct inc_dec_pred_def : public overloaded_base<0>
   1972 {
   1973   void
   1974   build (function_builder &b, const function_group_info &group) const OVERRIDE
   1975   {
   1976     b.add_overloaded_functions (group, MODE_none);
   1977     build_all (b, "v0,v0,vp", group, MODE_none);
   1978   }
   1979 
   1980   tree
   1981   resolve (function_resolver &r) const OVERRIDE
   1982   {
   1983     unsigned int i, nargs;
   1984     type_suffix_index type;
   1985     if (!r.check_gp_argument (2, i, nargs)
   1986 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
   1987 	|| !r.require_vector_type (i + 1, VECTOR_TYPE_svbool_t))
   1988       return error_mark_node;
   1989 
   1990     return r.resolve_to (r.mode_suffix_id, type);
   1991   }
   1992 };
   1993 SHAPE (inc_dec_pred)
   1994 
   1995 /* <t0>_t svfoo[_n_t0]_t1(<t0>_t, svbool_t)
   1996 
   1997    where _t1 is a _b<bits> suffix that describes the svbool_t argument.  */
   1998 struct inc_dec_pred_scalar_def : public overloaded_base<2>
   1999 {
   2000   void
   2001   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2002   {
   2003     b.add_overloaded_functions (group, MODE_n);
   2004     build_all (b, "s0,s0,vp", group, MODE_n);
   2005   }
   2006 
   2007   tree
   2008   resolve (function_resolver &r) const OVERRIDE
   2009   {
   2010     unsigned int i, nargs;
   2011     type_suffix_index type;
   2012     if (!r.check_gp_argument (2, i, nargs)
   2013 	|| (type = r.infer_integer_scalar_type (i)) == NUM_TYPE_SUFFIXES
   2014 	|| !r.require_vector_type (i + 1, VECTOR_TYPE_svbool_t))
   2015       return error_mark_node;
   2016 
   2017     return r.resolve_to (r.mode_suffix_id, type, r.type_suffix_ids[1]);
   2018   }
   2019 };
   2020 SHAPE (inc_dec_pred_scalar)
   2021 
   2022 /* sv<t0>[xN]_t svfoo_t0().  */
   2023 struct inherent_def : public nonoverloaded_base
   2024 {
   2025   void
   2026   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2027   {
   2028     build_all (b, "t0", group, MODE_none);
   2029   }
   2030 };
   2031 SHAPE (inherent)
   2032 
   2033 /* svbool_t svfoo[_b]().  */
   2034 struct inherent_b_def : public overloaded_base<0>
   2035 {
   2036   void
   2037   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2038   {
   2039     /* The "_b" suffix is optional; the full name has it, but the short
   2040        name doesn't.  */
   2041     build_all (b, "v0", group, MODE_none, true);
   2042   }
   2043 
   2044   tree
   2045   resolve (function_resolver &) const OVERRIDE
   2046   {
   2047     /* The short forms just make "_b" implicit, so no resolution is needed.  */
   2048     gcc_unreachable ();
   2049   }
   2050 };
   2051 SHAPE (inherent_b)
   2052 
   2053 /* sv<t0>[xN]_t svfoo[_t0](const <t0>_t *)
   2054    sv<t0>[xN]_t svfoo_vnum[_t0](const <t0>_t *, int64_t).  */
   2055 struct load_def : public load_contiguous_base
   2056 {
   2057   void
   2058   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2059   {
   2060     b.add_overloaded_functions (group, MODE_none);
   2061     b.add_overloaded_functions (group, MODE_vnum);
   2062     build_all (b, "t0,al", group, MODE_none);
   2063     build_all (b, "t0,al,ss64", group, MODE_vnum);
   2064   }
   2065 };
   2066 SHAPE (load)
   2067 
   2068 /* sv<t0>_t svfoo_t0(const <X>_t *)
   2069    sv<t0>_t svfoo_vnum_t0(const <X>_t *, int64_t)
   2070 
   2071    where <X> is determined by the function base name.  */
   2072 struct load_ext_def : public nonoverloaded_base
   2073 {
   2074   void
   2075   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2076   {
   2077     build_all (b, "t0,al", group, MODE_none);
   2078     build_all (b, "t0,al,ss64", group, MODE_vnum);
   2079   }
   2080 };
   2081 SHAPE (load_ext)
   2082 
   2083 /* sv<t0>_t svfoo_[s32]index_t0(const <X>_t *, svint32_t)
   2084    sv<t0>_t svfoo_[s64]index_t0(const <X>_t *, svint64_t)
   2085    sv<t0>_t svfoo_[u32]index_t0(const <X>_t *, svuint32_t)
   2086    sv<t0>_t svfoo_[u64]index_t0(const <X>_t *, svuint64_t)
   2087 
   2088    sv<t0>_t svfoo[_u32base]_index_t0(svuint32_t, int64_t)
   2089    sv<t0>_t svfoo[_u64base]_index_t0(svuint64_t, int64_t)
   2090 
   2091    where <X> is determined by the function base name.  */
   2092 struct load_ext_gather_index_def : public load_ext_gather_base
   2093 {
   2094   void
   2095   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2096   {
   2097     b.add_overloaded_functions (group, MODE_index);
   2098     build_sv_index (b, "t0,al,d", group);
   2099     build_vs_index (b, "t0,b,ss64", group);
   2100   }
   2101 };
   2102 SHAPE (load_ext_gather_index)
   2103 
   2104 /* sv<t0>_t svfoo_[s64]index_t0(const <X>_t *, svint64_t)
   2105    sv<t0>_t svfoo_[u64]index_t0(const <X>_t *, svuint64_t)
   2106 
   2107    sv<t0>_t svfoo[_u32base]_index_t0(svuint32_t, int64_t)
   2108    sv<t0>_t svfoo[_u64base]_index_t0(svuint64_t, int64_t)
   2109 
   2110    where <X> is determined by the function base name.  This is
   2111    load_ext_gather_index that doesn't support 32-bit vector indices.  */
   2112 struct load_ext_gather_index_restricted_def : public load_ext_gather_base
   2113 {
   2114   void
   2115   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2116   {
   2117     b.add_overloaded_functions (group, MODE_index);
   2118     build_sv_index64 (b, "t0,al,d", group);
   2119     build_vs_index (b, "t0,b,ss64", group);
   2120   }
   2121 };
   2122 SHAPE (load_ext_gather_index_restricted)
   2123 
   2124 /* sv<t0>_t svfoo_[s32]offset_t0(const <X>_t *, svint32_t)
   2125    sv<t0>_t svfoo_[s64]offset_t0(const <X>_t *, svint64_t)
   2126    sv<t0>_t svfoo_[u32]offset_t0(const <X>_t *, svuint32_t)
   2127    sv<t0>_t svfoo_[u64]offset_t0(const <X>_t *, svuint64_t)
   2128 
   2129    sv<t0>_t svfoo[_u32base]_t0(svuint32_t)
   2130    sv<t0>_t svfoo[_u64base]_t0(svuint64_t)
   2131 
   2132    sv<t0>_t svfoo[_u32base]_offset_t0(svuint32_t, int64_t)
   2133    sv<t0>_t svfoo[_u64base]_offset_t0(svuint64_t, int64_t)
   2134 
   2135    where <X> is determined by the function base name.  */
   2136 struct load_ext_gather_offset_def : public load_ext_gather_base
   2137 {
   2138   void
   2139   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2140   {
   2141     b.add_overloaded_functions (group, MODE_offset);
   2142     build_sv_offset (b, "t0,al,d", group);
   2143     build_v_base (b, "t0,b", group, true);
   2144     build_vs_offset (b, "t0,b,ss64", group);
   2145   }
   2146 };
   2147 SHAPE (load_ext_gather_offset)
   2148 
   2149 /* sv<t0>_t svfoo_[s64]offset_t0(const <X>_t *, svint64_t)
   2150    sv<t0>_t svfoo_[u32]offset_t0(const <X>_t *, svuint32_t)
   2151    sv<t0>_t svfoo_[u64]offset_t0(const <X>_t *, svuint64_t)
   2152 
   2153    sv<t0>_t svfoo[_u32base]_t0(svuint32_t)
   2154    sv<t0>_t svfoo[_u64base]_t0(svuint64_t)
   2155 
   2156    sv<t0>_t svfoo[_u32base]_offset_t0(svuint32_t, int64_t)
   2157    sv<t0>_t svfoo[_u64base]_offset_t0(svuint64_t, int64_t)
   2158 
   2159    where <X> is determined by the function base name.  This is
   2160    load_ext_gather_offset without the s32 vector offset form.  */
   2161 struct load_ext_gather_offset_restricted_def : public load_ext_gather_base
   2162 {
   2163   void
   2164   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2165   {
   2166     b.add_overloaded_functions (group, MODE_offset);
   2167     build_sv_uint_offset (b, "t0,al,d", group);
   2168     build_v_base (b, "t0,b", group, true);
   2169     build_vs_offset (b, "t0,b,ss64", group);
   2170   }
   2171 };
   2172 SHAPE (load_ext_gather_offset_restricted)
   2173 
   2174 /* sv<t0>_t svfoo_[s32]index[_t0](const <t0>_t *, svint32_t)
   2175    sv<t0>_t svfoo_[s64]index[_t0](const <t0>_t *, svint64_t)
   2176    sv<t0>_t svfoo_[u32]index[_t0](const <t0>_t *, svuint32_t)
   2177    sv<t0>_t svfoo_[u64]index[_t0](const <t0>_t *, svuint64_t)
   2178 
   2179    sv<t0>_t svfoo_[s32]offset[_t0](const <t0>_t *, svint32_t)
   2180    sv<t0>_t svfoo_[s64]offset[_t0](const <t0>_t *, svint64_t)
   2181    sv<t0>_t svfoo_[u32]offset[_t0](const <t0>_t *, svuint32_t)
   2182    sv<t0>_t svfoo_[u64]offset[_t0](const <t0>_t *, svuint64_t).  */
   2183 struct load_gather_sv_def : public load_gather_sv_base
   2184 {
   2185   void
   2186   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2187   {
   2188     b.add_overloaded_functions (group, MODE_index);
   2189     b.add_overloaded_functions (group, MODE_offset);
   2190     build_sv_index (b, "t0,al,d", group);
   2191     build_sv_offset (b, "t0,al,d", group);
   2192   }
   2193 };
   2194 SHAPE (load_gather_sv)
   2195 
   2196 /* sv<t0>_t svfoo_[u32]index[_t0](const <t0>_t *, svuint32_t)
   2197    sv<t0>_t svfoo_[u64]index[_t0](const <t0>_t *, svuint64_t)
   2198 
   2199    sv<t0>_t svfoo_[s64]offset[_t0](const <t0>_t *, svint64_t)
   2200    sv<t0>_t svfoo_[u32]offset[_t0](const <t0>_t *, svuint32_t)
   2201    sv<t0>_t svfoo_[u64]offset[_t0](const <t0>_t *, svuint64_t)
   2202 
   2203    This is load_gather_sv without the 32-bit vector index forms and
   2204    without the s32 vector offset form.  */
   2205 struct load_gather_sv_restricted_def : public load_gather_sv_base
   2206 {
   2207   void
   2208   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2209   {
   2210     b.add_overloaded_functions (group, MODE_index);
   2211     b.add_overloaded_functions (group, MODE_offset);
   2212     build_sv_index64 (b, "t0,al,d", group);
   2213     build_sv_uint_offset (b, "t0,al,d", group);
   2214   }
   2215 };
   2216 SHAPE (load_gather_sv_restricted)
   2217 
   2218 /* sv<t0>_t svfoo[_u32base]_t0(svuint32_t)
   2219    sv<t0>_t svfoo[_u64base]_t0(svuint64_t)
   2220 
   2221    sv<t0>_t svfoo[_u32base]_index_t0(svuint32_t, int64_t)
   2222    sv<t0>_t svfoo[_u64base]_index_t0(svuint64_t, int64_t)
   2223 
   2224    sv<t0>_t svfoo[_u32base]_offset_t0(svuint32_t, int64_t)
   2225    sv<t0>_t svfoo[_u64base]_offset_t0(svuint64_t, int64_t).  */
   2226 struct load_gather_vs_def : public overloaded_base<1>
   2227 {
   2228   void
   2229   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2230   {
   2231     /* The base vector mode is optional; the full name has it but the
   2232        short name doesn't.  There is no ambiguity with SHAPE_load_gather_sv
   2233        because the latter uses an implicit type suffix.  */
   2234     build_v_base (b, "t0,b", group, true);
   2235     build_vs_index (b, "t0,b,ss64", group, true);
   2236     build_vs_offset (b, "t0,b,ss64", group, true);
   2237   }
   2238 
   2239   tree
   2240   resolve (function_resolver &) const OVERRIDE
   2241   {
   2242     /* The short name just makes the base vector mode implicit;
   2243        no resolution is needed.  */
   2244     gcc_unreachable ();
   2245   }
   2246 };
   2247 SHAPE (load_gather_vs)
   2248 
   2249 /* sv<t0>_t svfoo[_t0](const <t0>_t *)
   2250 
   2251    The only difference from "load" is that this shape has no vnum form.  */
   2252 struct load_replicate_def : public load_contiguous_base
   2253 {
   2254   void
   2255   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2256   {
   2257     b.add_overloaded_functions (group, MODE_none);
   2258     build_all (b, "t0,al", group, MODE_none);
   2259   }
   2260 };
   2261 SHAPE (load_replicate)
   2262 
   2263 /* svbool_t svfoo(enum svpattern).  */
   2264 struct pattern_pred_def : public nonoverloaded_base
   2265 {
   2266   void
   2267   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2268   {
   2269     build_all (b, "vp,epattern", group, MODE_none);
   2270   }
   2271 };
   2272 SHAPE (pattern_pred)
   2273 
   2274 /* void svfoo(const void *, svprfop)
   2275    void svfoo_vnum(const void *, int64_t, svprfop).  */
   2276 struct prefetch_def : public nonoverloaded_base
   2277 {
   2278   void
   2279   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2280   {
   2281     build_all (b, "_,ap,eprfop", group, MODE_none);
   2282     build_all (b, "_,ap,ss64,eprfop", group, MODE_vnum);
   2283   }
   2284 };
   2285 SHAPE (prefetch)
   2286 
   2287 /* void svfoo_[s32]index(const void *, svint32_t, svprfop)
   2288    void svfoo_[s64]index(const void *, svint64_t, svprfop)
   2289    void svfoo_[u32]index(const void *, svuint32_t, svprfop)
   2290    void svfoo_[u64]index(const void *, svuint64_t, svprfop)
   2291 
   2292    void svfoo[_u32base](svuint32_t, svprfop)
   2293    void svfoo[_u64base](svuint64_t, svprfop)
   2294 
   2295    void svfoo[_u32base]_index(svuint32_t, int64_t, svprfop)
   2296    void svfoo[_u64base]_index(svuint64_t, int64_t, svprfop).  */
   2297 struct prefetch_gather_index_def : public prefetch_gather_base
   2298 {
   2299   void
   2300   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2301   {
   2302     b.add_overloaded_functions (group, MODE_none);
   2303     b.add_overloaded_functions (group, MODE_index);
   2304     build_sv_index (b, "_,ap,d,eprfop", group);
   2305     build_v_base (b, "_,b,eprfop", group);
   2306     build_vs_index (b, "_,b,ss64,eprfop", group);
   2307   }
   2308 };
   2309 SHAPE (prefetch_gather_index)
   2310 
   2311 /* void svfoo_[s32]offset(const void *, svint32_t, svprfop)
   2312    void svfoo_[s64]offset(const void *, svint64_t, svprfop)
   2313    void svfoo_[u32]offset(const void *, svuint32_t, svprfop)
   2314    void svfoo_[u64]offset(const void *, svuint64_t, svprfop)
   2315 
   2316    void svfoo[_u32base](svuint32_t, svprfop)
   2317    void svfoo[_u64base](svuint64_t, svprfop)
   2318 
   2319    void svfoo[_u32base]_offset(svuint32_t, int64_t, svprfop)
   2320    void svfoo[_u64base]_offset(svuint64_t, int64_t, svprfop).  */
   2321 struct prefetch_gather_offset_def : public prefetch_gather_base
   2322 {
   2323   void
   2324   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2325   {
   2326     b.add_overloaded_functions (group, MODE_none);
   2327     b.add_overloaded_functions (group, MODE_offset);
   2328     build_sv_offset (b, "_,ap,d,eprfop", group);
   2329     build_v_base (b, "_,b,eprfop", group);
   2330     build_vs_offset (b, "_,b,ss64,eprfop", group);
   2331   }
   2332 };
   2333 SHAPE (prefetch_gather_offset)
   2334 
   2335 /* bool svfoo(svbool_t).  */
   2336 struct ptest_def : public nonoverloaded_base
   2337 {
   2338   void
   2339   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2340   {
   2341     build_all (b, "sp,vp", group, MODE_none);
   2342   }
   2343 };
   2344 SHAPE (ptest)
   2345 
   2346 /* svbool_t svfoo().  */
   2347 struct rdffr_def : public nonoverloaded_base
   2348 {
   2349   void
   2350   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2351   {
   2352     build_all (b, "vp", group, MODE_none);
   2353   }
   2354 };
   2355 SHAPE (rdffr)
   2356 
   2357 /* <t0>_t svfoo[_t0](sv<t0>_t).  */
   2358 struct reduction_def : public overloaded_base<0>
   2359 {
   2360   void
   2361   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2362   {
   2363     b.add_overloaded_functions (group, MODE_none);
   2364     build_all (b, "s0,v0", group, MODE_none);
   2365   }
   2366 
   2367   tree
   2368   resolve (function_resolver &r) const OVERRIDE
   2369   {
   2370     return r.resolve_uniform (1);
   2371   }
   2372 };
   2373 SHAPE (reduction)
   2374 
   2375 /* int64_t svfoo[_t0](sv<t0>_t)  (for signed t0)
   2376    uint64_t svfoo[_t0](sv<t0>_t)  (for unsigned t0)
   2377    <t0>_t svfoo[_t0](sv<t0>_t)  (for floating-point t0)
   2378 
   2379    i.e. a version of "reduction" in which the return type for integers
   2380    always has 64 bits.  */
   2381 struct reduction_wide_def : public overloaded_base<0>
   2382 {
   2383   void
   2384   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2385   {
   2386     b.add_overloaded_functions (group, MODE_none);
   2387     build_all (b, "sw0,v0", group, MODE_none);
   2388   }
   2389 
   2390   tree
   2391   resolve (function_resolver &r) const OVERRIDE
   2392   {
   2393     return r.resolve_uniform (1);
   2394   }
   2395 };
   2396 SHAPE (reduction_wide)
   2397 
   2398 /* sv<t0>xN_t svfoo[_t0](sv<t0>xN_t, uint64_t, sv<t0>_t)
   2399 
   2400    where the second argument is an integer constant expression in the
   2401    range [0, N - 1].  */
   2402 struct set_def : public overloaded_base<0>
   2403 {
   2404   void
   2405   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2406   {
   2407     b.add_overloaded_functions (group, MODE_none);
   2408     build_all (b, "t0,t0,su64,v0", group, MODE_none);
   2409   }
   2410 
   2411   tree
   2412   resolve (function_resolver &r) const OVERRIDE
   2413   {
   2414     unsigned int i, nargs;
   2415     type_suffix_index type;
   2416     if (!r.check_gp_argument (3, i, nargs)
   2417 	|| (type = r.infer_tuple_type (i)) == NUM_TYPE_SUFFIXES
   2418 	|| !r.require_integer_immediate (i + 1)
   2419 	|| !r.require_derived_vector_type (i + 2, i, type))
   2420       return error_mark_node;
   2421 
   2422     return r.resolve_to (r.mode_suffix_id, type);
   2423   }
   2424 
   2425   bool
   2426   check (function_checker &c) const OVERRIDE
   2427   {
   2428     unsigned int nvectors = c.vectors_per_tuple ();
   2429     return c.require_immediate_range (1, 0, nvectors - 1);
   2430   }
   2431 };
   2432 SHAPE (set)
   2433 
   2434 /* void svfoo().  */
   2435 struct setffr_def : public nonoverloaded_base
   2436 {
   2437   void
   2438   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2439   {
   2440     build_all (b, "_", group, MODE_none);
   2441   }
   2442 };
   2443 SHAPE (setffr)
   2444 
   2445 /* sv<t0>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
   2446 
   2447    where the final argument must be an integer constant expression in the
   2448    range [0, sizeof (<t0>_t) * 8 - 1].  */
   2449 struct shift_left_imm_def : public overloaded_base<0>
   2450 {
   2451   void
   2452   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2453   {
   2454     b.add_overloaded_functions (group, MODE_n);
   2455     build_all (b, "v0,v0,su64", group, MODE_n);
   2456   }
   2457 
   2458   tree
   2459   resolve (function_resolver &r) const OVERRIDE
   2460   {
   2461     return r.resolve_uniform (1, 1);
   2462   }
   2463 
   2464   bool
   2465   check (function_checker &c) const OVERRIDE
   2466   {
   2467     unsigned int bits = c.type_suffix (0).element_bits;
   2468     return c.require_immediate_range (1, 0, bits - 1);
   2469   }
   2470 };
   2471 SHAPE (shift_left_imm)
   2472 
   2473 /* sv<t0>_t svfoo[_n_t0])(sv<t0:half>_t, uint64_t)
   2474 
   2475    where the final argument must be an integer constant expression in the
   2476    range [0, sizeof (<t0>_t) * 4 - 1].  */
   2477 struct shift_left_imm_long_def : public binary_imm_long_base
   2478 {
   2479   bool
   2480   check (function_checker &c) const OVERRIDE
   2481   {
   2482     unsigned int bits = c.type_suffix (0).element_bits / 2;
   2483     return c.require_immediate_range (1, 0, bits - 1);
   2484   }
   2485 };
   2486 SHAPE (shift_left_imm_long)
   2487 
   2488 /* sv<t0:uint>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
   2489 
   2490    where the final argument must be an integer constant expression in the
   2491    range [0, sizeof (<t0>_t) * 8 - 1].  */
   2492 struct shift_left_imm_to_uint_def : public shift_left_imm_def
   2493 {
   2494   void
   2495   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2496   {
   2497     b.add_overloaded_functions (group, MODE_n);
   2498     build_all (b, "vu0,v0,su64", group, MODE_n);
   2499   }
   2500 };
   2501 SHAPE (shift_left_imm_to_uint)
   2502 
   2503 /* sv<t0>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
   2504 
   2505    where the final argument must be an integer constant expression in the
   2506    range [1, sizeof (<t0>_t) * 8].  */
   2507 struct shift_right_imm_def : public overloaded_base<0>
   2508 {
   2509   void
   2510   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2511   {
   2512     b.add_overloaded_functions (group, MODE_n);
   2513     build_all (b, "v0,v0,su64", group, MODE_n);
   2514   }
   2515 
   2516   tree
   2517   resolve (function_resolver &r) const OVERRIDE
   2518   {
   2519     return r.resolve_uniform (1, 1);
   2520   }
   2521 
   2522   bool
   2523   check (function_checker &c) const OVERRIDE
   2524   {
   2525     unsigned int bits = c.type_suffix (0).element_bits;
   2526     return c.require_immediate_range (1, 1, bits);
   2527   }
   2528 };
   2529 SHAPE (shift_right_imm)
   2530 
   2531 /* sv<t0:half>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
   2532 
   2533    where the final argument must be an integer constant expression in the
   2534    range [1, sizeof (<t0>_t) * 4].  */
   2535 typedef shift_right_imm_narrow_wrapper<binary_imm_narrowb_base<>, 1>
   2536   shift_right_imm_narrowb_def;
   2537 SHAPE (shift_right_imm_narrowb)
   2538 
   2539 /* sv<t0:half>_t svfoo[_n_t0])(sv<t0:half>_t, sv<t0>_t, uint64_t)
   2540 
   2541    where the final argument must be an integer constant expression in the
   2542    range [1, sizeof (<t0>_t) * 4].  */
   2543 typedef shift_right_imm_narrow_wrapper<binary_imm_narrowt_base<>, 2>
   2544   shift_right_imm_narrowt_def;
   2545 SHAPE (shift_right_imm_narrowt)
   2546 
   2547 /* sv<t0:uint:half>_t svfoo[_n_t0])(sv<t0>_t, uint64_t)
   2548 
   2549    where the final argument must be an integer constant expression in the
   2550    range [1, sizeof (<t0>_t) * 4].  */
   2551 typedef binary_imm_narrowb_base<TYPE_unsigned>
   2552   binary_imm_narrowb_base_unsigned;
   2553 typedef shift_right_imm_narrow_wrapper<binary_imm_narrowb_base_unsigned, 1>
   2554   shift_right_imm_narrowb_to_uint_def;
   2555 SHAPE (shift_right_imm_narrowb_to_uint)
   2556 
   2557 /* sv<t0:uint:half>_t svfoo[_n_t0])(sv<t0:uint:half>_t, sv<t0>_t, uint64_t)
   2558 
   2559    where the final argument must be an integer constant expression in the
   2560    range [1, sizeof (<t0>_t) * 4].  */
   2561 typedef binary_imm_narrowt_base<TYPE_unsigned>
   2562   binary_imm_narrowt_base_unsigned;
   2563 typedef shift_right_imm_narrow_wrapper<binary_imm_narrowt_base_unsigned, 2>
   2564   shift_right_imm_narrowt_to_uint_def;
   2565 SHAPE (shift_right_imm_narrowt_to_uint)
   2566 
   2567 /* void svfoo[_t0](<X>_t *, sv<t0>[xN]_t)
   2568    void svfoo_vnum[_t0](<X>_t *, int64_t, sv<t0>[xN]_t)
   2569 
   2570    where <X> might be tied to <t0> (for non-truncating stores) or might
   2571    depend on the function base name (for truncating stores).  */
   2572 struct store_def : public overloaded_base<0>
   2573 {
   2574   void
   2575   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2576   {
   2577     b.add_overloaded_functions (group, MODE_none);
   2578     b.add_overloaded_functions (group, MODE_vnum);
   2579     build_all (b, "_,as,t0", group, MODE_none);
   2580     build_all (b, "_,as,ss64,t0", group, MODE_vnum);
   2581   }
   2582 
   2583   tree
   2584   resolve (function_resolver &r) const OVERRIDE
   2585   {
   2586     bool vnum_p = r.mode_suffix_id == MODE_vnum;
   2587     gcc_assert (r.mode_suffix_id == MODE_none || vnum_p);
   2588 
   2589     unsigned int i, nargs;
   2590     type_suffix_index type;
   2591     if (!r.check_gp_argument (vnum_p ? 3 : 2, i, nargs)
   2592 	|| !r.require_pointer_type (i)
   2593 	|| (vnum_p && !r.require_scalar_type (i + 1, "int64_t"))
   2594 	|| ((type = r.infer_tuple_type (nargs - 1)) == NUM_TYPE_SUFFIXES))
   2595       return error_mark_node;
   2596 
   2597     return r.resolve_to (r.mode_suffix_id, type);
   2598   }
   2599 };
   2600 SHAPE (store)
   2601 
   2602 /* void svfoo_[s32]index[_t0](<X>_t *, svint32_t, sv<t0>_t)
   2603    void svfoo_[s64]index[_t0](<X>_t *, svint64_t, sv<t0>_t)
   2604    void svfoo_[u32]index[_t0](<X>_t *, svuint32_t, sv<t0>_t)
   2605    void svfoo_[u64]index[_t0](<X>_t *, svuint64_t, sv<t0>_t)
   2606 
   2607    void svfoo[_u32base]_index[_t0](svuint32_t, int64_t, sv<t0>_t)
   2608    void svfoo[_u64base]_index[_t0](svuint64_t, int64_t, sv<t0>_t)
   2609 
   2610    where <X> might be tied to <t0> (for non-truncating stores) or might
   2611    depend on the function base name (for truncating stores).  */
   2612 struct store_scatter_index_def : public store_scatter_base
   2613 {
   2614   void
   2615   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2616   {
   2617     b.add_overloaded_functions (group, MODE_index);
   2618     build_sv_index (b, "_,as,d,t0", group);
   2619     build_vs_index (b, "_,b,ss64,t0", group);
   2620   }
   2621 };
   2622 SHAPE (store_scatter_index)
   2623 
   2624 /* void svfoo_[s64]index[_t0](<X>_t *, svint64_t, sv<t0>_t)
   2625    void svfoo_[u64]index[_t0](<X>_t *, svuint64_t, sv<t0>_t)
   2626 
   2627    void svfoo[_u32base]_index[_t0](svuint32_t, int64_t, sv<t0>_t)
   2628    void svfoo[_u64base]_index[_t0](svuint64_t, int64_t, sv<t0>_t)
   2629 
   2630    i.e. a version of store_scatter_index that doesn't support 32-bit
   2631    vector indices.  */
   2632 struct store_scatter_index_restricted_def : public store_scatter_base
   2633 {
   2634   void
   2635   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2636   {
   2637     b.add_overloaded_functions (group, MODE_index);
   2638     build_sv_index64 (b, "_,as,d,t0", group);
   2639     build_vs_index (b, "_,b,ss64,t0", group);
   2640   }
   2641 };
   2642 SHAPE (store_scatter_index_restricted)
   2643 
   2644 /* void svfoo_[s32]offset[_t0](<X>_t *, svint32_t, sv<t0>_t)
   2645    void svfoo_[s64]offset[_t0](<X>_t *, svint64_t, sv<t0>_t)
   2646    void svfoo_[u32]offset[_t0](<X>_t *, svuint32_t, sv<t0>_t)
   2647    void svfoo_[u64]offset[_t0](<X>_t *, svuint64_t, sv<t0>_t)
   2648 
   2649    void svfoo[_u32base_t0](svuint32_t, sv<t0>_t)
   2650    void svfoo[_u64base_t0](svuint64_t, sv<t0>_t)
   2651 
   2652    void svfoo[_u32base]_offset[_t0](svuint32_t, int64_t, sv<t0>_t)
   2653    void svfoo[_u64base]_offset[_t0](svuint64_t, int64_t, sv<t0>_t)
   2654 
   2655    where <X> might be tied to <t0> (for non-truncating stores) or might
   2656    depend on the function base name (for truncating stores).  */
   2657 struct store_scatter_offset_def : public store_scatter_base
   2658 {
   2659   void
   2660   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2661   {
   2662     b.add_overloaded_functions (group, MODE_none);
   2663     b.add_overloaded_functions (group, MODE_offset);
   2664     build_sv_offset (b, "_,as,d,t0", group);
   2665     build_v_base (b, "_,b,t0", group);
   2666     build_vs_offset (b, "_,b,ss64,t0", group);
   2667   }
   2668 };
   2669 SHAPE (store_scatter_offset)
   2670 
   2671 /* void svfoo_[s64]offset[_t0](<X>_t *, svint64_t, sv<t0>_t)
   2672    void svfoo_[u32]offset[_t0](<X>_t *, svuint32_t, sv<t0>_t)
   2673    void svfoo_[u64]offset[_t0](<X>_t *, svuint64_t, sv<t0>_t)
   2674 
   2675    void svfoo[_u32base_t0](svuint32_t, sv<t0>_t)
   2676    void svfoo[_u64base_t0](svuint64_t, sv<t0>_t)
   2677 
   2678    void svfoo[_u32base]_offset[_t0](svuint32_t, int64_t, sv<t0>_t)
   2679    void svfoo[_u64base]_offset[_t0](svuint64_t, int64_t, sv<t0>_t)
   2680 
   2681    i.e. a version of store_scatter_offset that doesn't support svint32_t
   2682    offsets.  */
   2683 struct store_scatter_offset_restricted_def : public store_scatter_base
   2684 {
   2685   void
   2686   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2687   {
   2688     b.add_overloaded_functions (group, MODE_none);
   2689     b.add_overloaded_functions (group, MODE_offset);
   2690     build_sv_uint_offset (b, "_,as,d,t0", group);
   2691     build_v_base (b, "_,b,t0", group);
   2692     build_vs_offset (b, "_,b,ss64,t0", group);
   2693   }
   2694 };
   2695 SHAPE (store_scatter_offset_restricted)
   2696 
   2697 /* sv<t0>_t svfoo[_t0](sv<t0>xN_t, sv<t0:uint>_t).  */
   2698 struct tbl_tuple_def : public overloaded_base<0>
   2699 {
   2700   void
   2701   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2702   {
   2703     b.add_overloaded_functions (group, MODE_none);
   2704     build_all (b, "v0,t0,vu0", group, MODE_none);
   2705   }
   2706 
   2707   tree
   2708   resolve (function_resolver &r) const OVERRIDE
   2709   {
   2710     unsigned int i, nargs;
   2711     type_suffix_index type;
   2712     if (!r.check_gp_argument (2, i, nargs)
   2713 	|| (type = r.infer_tuple_type (i)) == NUM_TYPE_SUFFIXES
   2714 	|| !r.require_derived_vector_type (i + 1, i, type, TYPE_unsigned))
   2715       return error_mark_node;
   2716 
   2717     return r.resolve_to (r.mode_suffix_id, type);
   2718   }
   2719 };
   2720 SHAPE (tbl_tuple)
   2721 
   2722 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbfloatt16_t, svbfloat16_t).  */
   2723 struct ternary_bfloat_def
   2724   : public ternary_resize2_base<16, TYPE_bfloat, TYPE_bfloat>
   2725 {
   2726   void
   2727   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2728   {
   2729     b.add_overloaded_functions (group, MODE_none);
   2730     build_all (b, "v0,v0,vB,vB", group, MODE_none);
   2731   }
   2732 };
   2733 SHAPE (ternary_bfloat)
   2734 
   2735 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbfloat16_t, svbfloat16_t, uint64_t)
   2736 
   2737    where the final argument is an integer constant expression in the range
   2738    [0, 7].  */
   2739 typedef ternary_bfloat_lane_base<1> ternary_bfloat_lane_def;
   2740 SHAPE (ternary_bfloat_lane)
   2741 
   2742 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbfloat16_t, svbfloat16_t, uint64_t)
   2743 
   2744    where the final argument is an integer constant expression in the range
   2745    [0, 3].  */
   2746 typedef ternary_bfloat_lane_base<2> ternary_bfloat_lanex2_def;
   2747 SHAPE (ternary_bfloat_lanex2)
   2748 
   2749 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svbfloatt16_t, svbfloat16_t)
   2750    sv<t0>_t svfoo[_n_t0](sv<t0>_t, svbfloat16_t, bfloat16_t).  */
   2751 struct ternary_bfloat_opt_n_def
   2752   : public ternary_resize2_opt_n_base<16, TYPE_bfloat, TYPE_bfloat>
   2753 {
   2754   void
   2755   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2756   {
   2757     b.add_overloaded_functions (group, MODE_none);
   2758     build_all (b, "v0,v0,vB,vB", group, MODE_none);
   2759     build_all (b, "v0,v0,vB,sB", group, MODE_n);
   2760   }
   2761 };
   2762 SHAPE (ternary_bfloat_opt_n)
   2763 
   2764 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:int:quarter>_t, sv<t0:uint:quarter>_t,
   2765 		       uint64_t)
   2766 
   2767    where the final argument is an integer constant expression in the range
   2768    [0, 16 / sizeof (<t0>_t) - 1].  */
   2769 struct ternary_intq_uintq_lane_def
   2770   : public ternary_qq_lane_base<TYPE_signed, TYPE_unsigned>
   2771 {
   2772   void
   2773   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2774   {
   2775     b.add_overloaded_functions (group, MODE_none);
   2776     build_all (b, "v0,v0,vqs0,vqu0,su64", group, MODE_none);
   2777   }
   2778 };
   2779 SHAPE (ternary_intq_uintq_lane)
   2780 
   2781 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:int:quarter>_t, sv<t0:uint:quarter>_t)
   2782    sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0:int:quarter>_t,
   2783 			 <t0:uint:quarter>_t).  */
   2784 struct ternary_intq_uintq_opt_n_def
   2785   : public ternary_resize2_opt_n_base<function_resolver::QUARTER_SIZE,
   2786 				      TYPE_signed, TYPE_unsigned>
   2787 {
   2788   void
   2789   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2790   {
   2791     b.add_overloaded_functions (group, MODE_none);
   2792     build_all (b, "v0,v0,vqs0,vqu0", group, MODE_none);
   2793     build_all (b, "v0,v0,vqs0,squ0", group, MODE_n);
   2794   }
   2795 };
   2796 SHAPE (ternary_intq_uintq_opt_n)
   2797 
   2798 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, sv<t0>_t, uint64_t)
   2799 
   2800    where the final argument is an integer constant expression in the
   2801    range [0, 16 / sizeof (<t0>_t) - 1].  */
   2802 struct ternary_lane_def : public overloaded_base<0>
   2803 {
   2804   void
   2805   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2806   {
   2807     b.add_overloaded_functions (group, MODE_none);
   2808     build_all (b, "v0,v0,v0,v0,su64", group, MODE_none);
   2809   }
   2810 
   2811   tree
   2812   resolve (function_resolver &r) const OVERRIDE
   2813   {
   2814     return r.resolve_uniform (3, 1);
   2815   }
   2816 
   2817   bool
   2818   check (function_checker &c) const OVERRIDE
   2819   {
   2820     return c.require_immediate_lane_index (3);
   2821   }
   2822 };
   2823 SHAPE (ternary_lane)
   2824 
   2825 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, sv<t0>_t, uint64_t, uint64_t)
   2826 
   2827    where the penultimate argument is an integer constant expression in
   2828    the range [0, 8 / sizeof (<t0>_t) - 1] and where the final argument
   2829    is an integer constant expression in {0, 90, 180, 270}.  */
   2830 struct ternary_lane_rotate_def : public overloaded_base<0>
   2831 {
   2832   void
   2833   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2834   {
   2835     b.add_overloaded_functions (group, MODE_none);
   2836     build_all (b, "v0,v0,v0,v0,su64,su64", group, MODE_none);
   2837   }
   2838 
   2839   tree
   2840   resolve (function_resolver &r) const OVERRIDE
   2841   {
   2842     return r.resolve_uniform (3, 2);
   2843   }
   2844 
   2845   bool
   2846   check (function_checker &c) const OVERRIDE
   2847   {
   2848     return (c.require_immediate_lane_index (3, 2)
   2849 	    && c.require_immediate_one_of (4, 0, 90, 180, 270));
   2850   }
   2851 };
   2852 SHAPE (ternary_lane_rotate)
   2853 
   2854 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:half>_t, sv<t0:half>_t, uint64_t)
   2855 
   2856    where the final argument is an integer constant expression in the range
   2857    [0, 32 / sizeof (<t0>_t) - 1].  */
   2858 struct ternary_long_lane_def
   2859   : public ternary_resize2_lane_base<function_resolver::HALF_SIZE>
   2860 {
   2861   void
   2862   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2863   {
   2864     b.add_overloaded_functions (group, MODE_none);
   2865     build_all (b, "v0,v0,vh0,vh0,su64", group, MODE_none);
   2866   }
   2867 
   2868   bool
   2869   check (function_checker &c) const OVERRIDE
   2870   {
   2871     return c.require_immediate_lane_index (3);
   2872   }
   2873 };
   2874 SHAPE (ternary_long_lane)
   2875 
   2876 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:half>_t, sv<t0:half>_t)
   2877    sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0:half>_t, <t0:half>_t)
   2878 
   2879    i.e. a version of the standard ternary shape ternary_opt_n in which
   2880    the element type of the last two arguments is the half-sized
   2881    equivalent of <t0>.  */
   2882 struct ternary_long_opt_n_def
   2883   : public ternary_resize2_opt_n_base<function_resolver::HALF_SIZE>
   2884 {
   2885   void
   2886   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2887   {
   2888     b.add_overloaded_functions (group, MODE_none);
   2889     build_all (b, "v0,v0,vh0,vh0", group, MODE_none);
   2890     build_all (b, "v0,v0,vh0,sh0", group, MODE_n);
   2891   }
   2892 };
   2893 SHAPE (ternary_long_opt_n)
   2894 
   2895 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t, sv<t0>_t)
   2896    sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0>_t, <t0>_t)
   2897 
   2898    i.e. the standard shape for ternary operations that operate on
   2899    uniform types.  */
   2900 struct ternary_opt_n_def : public overloaded_base<0>
   2901 {
   2902   void
   2903   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2904   {
   2905     b.add_overloaded_functions (group, MODE_none);
   2906     build_all (b, "v0,v0,v0,v0", group, MODE_none);
   2907     build_all (b, "v0,v0,v0,s0", group, MODE_n);
   2908   }
   2909 
   2910   tree
   2911   resolve (function_resolver &r) const OVERRIDE
   2912   {
   2913     return r.resolve_uniform_opt_n (3);
   2914   }
   2915 };
   2916 SHAPE (ternary_opt_n)
   2917 
   2918 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:quarter>_t, sv<t0:quarter>_t, uint64_t)
   2919 
   2920    where the final argument is an integer constant expression in the range
   2921    [0, 16 / sizeof (<t0>_t) - 1].  */
   2922 struct ternary_qq_lane_def : public ternary_qq_lane_base<>
   2923 {
   2924   void
   2925   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2926   {
   2927     b.add_overloaded_functions (group, MODE_none);
   2928     build_all (b, "v0,v0,vq0,vq0,su64", group, MODE_none);
   2929   }
   2930 };
   2931 SHAPE (ternary_qq_lane)
   2932 
   2933 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0:quarter>_t, sv<t0:quarter>_t,
   2934 			 uint64_t)
   2935 
   2936    where the final argument is an integer constant expression in
   2937    {0, 90, 180, 270}.  */
   2938 struct ternary_qq_lane_rotate_def : public overloaded_base<0>
   2939 {
   2940   void
   2941   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2942   {
   2943     b.add_overloaded_functions (group, MODE_none);
   2944     build_all (b, "v0,v0,vq0,vq0,su64,su64", group, MODE_none);
   2945   }
   2946 
   2947   tree
   2948   resolve (function_resolver &r) const OVERRIDE
   2949   {
   2950     unsigned int i, nargs;
   2951     type_suffix_index type;
   2952     if (!r.check_gp_argument (5, i, nargs)
   2953 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
   2954 	|| !r.require_derived_vector_type (i + 1, i, type, r.SAME_TYPE_CLASS,
   2955 					   r.QUARTER_SIZE)
   2956 	|| !r.require_derived_vector_type (i + 2, i, type, r.SAME_TYPE_CLASS,
   2957 					   r.QUARTER_SIZE)
   2958 	|| !r.require_integer_immediate (i + 3)
   2959 	|| !r.require_integer_immediate (i + 4))
   2960       return error_mark_node;
   2961 
   2962     return r.resolve_to (r.mode_suffix_id, type);
   2963   }
   2964 
   2965   bool
   2966   check (function_checker &c) const OVERRIDE
   2967   {
   2968     return (c.require_immediate_lane_index (3, 4)
   2969 	    && c.require_immediate_one_of (4, 0, 90, 180, 270));
   2970   }
   2971 };
   2972 SHAPE (ternary_qq_lane_rotate)
   2973 
   2974 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:quarter>_t, sv<t0:quarter>_t)
   2975    sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0:quarter>_t, <t0:quarter>_t)
   2976 
   2977    i.e. a version of the standard ternary shape ternary_opt_n in which
   2978    the element type of the last two arguments is the quarter-sized
   2979    equivalent of <t0>.  */
   2980 struct ternary_qq_opt_n_def
   2981   : public ternary_resize2_opt_n_base<function_resolver::QUARTER_SIZE>
   2982 {
   2983   void
   2984   build (function_builder &b, const function_group_info &group) const OVERRIDE
   2985   {
   2986     b.add_overloaded_functions (group, MODE_none);
   2987     build_all (b, "v0,v0,vq0,vq0", group, MODE_none);
   2988     build_all (b, "v0,v0,vq0,sq0", group, MODE_n);
   2989   }
   2990 };
   2991 SHAPE (ternary_qq_opt_n)
   2992 
   2993 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0:quarter>_t, sv<t0:quarter>_t,
   2994 			 uint64_t)
   2995 
   2996    where the final argument is an integer constant expression in
   2997    {0, 90, 180, 270}.  */
   2998 struct ternary_qq_rotate_def : public overloaded_base<0>
   2999 {
   3000   void
   3001   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3002   {
   3003     b.add_overloaded_functions (group, MODE_none);
   3004     build_all (b, "v0,v0,vq0,vq0,su64", group, MODE_none);
   3005   }
   3006 
   3007   tree
   3008   resolve (function_resolver &r) const OVERRIDE
   3009   {
   3010     unsigned int i, nargs;
   3011     type_suffix_index type;
   3012     if (!r.check_gp_argument (4, i, nargs)
   3013 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
   3014 	|| !r.require_derived_vector_type (i + 1, i, type, r.SAME_TYPE_CLASS,
   3015 					   r.QUARTER_SIZE)
   3016 	|| !r.require_derived_vector_type (i + 2, i, type, r.SAME_TYPE_CLASS,
   3017 					   r.QUARTER_SIZE)
   3018 	|| !r.require_integer_immediate (i + 3))
   3019       return error_mark_node;
   3020 
   3021     return r.resolve_to (r.mode_suffix_id, type);
   3022   }
   3023 
   3024   bool
   3025   check (function_checker &c) const OVERRIDE
   3026   {
   3027     return c.require_immediate_one_of (3, 0, 90, 180, 270);
   3028   }
   3029 };
   3030 SHAPE (ternary_qq_rotate)
   3031 
   3032 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, sv<t0>_t, uint64_t)
   3033 
   3034    where the final argument is an integer constant expression in
   3035    {0, 90, 180, 270}.  */
   3036 struct ternary_rotate_def : public overloaded_base<0>
   3037 {
   3038   void
   3039   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3040   {
   3041     b.add_overloaded_functions (group, MODE_none);
   3042     build_all (b, "v0,v0,v0,v0,su64", group, MODE_none);
   3043   }
   3044 
   3045   tree
   3046   resolve (function_resolver &r) const OVERRIDE
   3047   {
   3048     return r.resolve_uniform (3, 1);
   3049   }
   3050 
   3051   bool
   3052   check (function_checker &c) const OVERRIDE
   3053   {
   3054     return c.require_immediate_one_of (3, 0, 90, 180, 270);
   3055   }
   3056 };
   3057 SHAPE (ternary_rotate)
   3058 
   3059 /* sv<t0>_t svfoo[_n_t0])(sv<t0>_t, sv<t0>_t, uint64_t)
   3060 
   3061    where the final argument must be an integer constant expression in the
   3062    range [0, sizeof (<t0>_t) * 8 - 1].  */
   3063 struct ternary_shift_left_imm_def : public ternary_shift_imm_base
   3064 {
   3065   bool
   3066   check (function_checker &c) const OVERRIDE
   3067   {
   3068     unsigned int bits = c.type_suffix (0).element_bits;
   3069     return c.require_immediate_range (2, 0, bits - 1);
   3070   }
   3071 };
   3072 SHAPE (ternary_shift_left_imm)
   3073 
   3074 /* sv<t0>_t svfoo[_n_t0])(sv<t0>_t, sv<t0>_t, uint64_t)
   3075 
   3076    where the final argument must be an integer constant expression in the
   3077    range [1, sizeof (<t0>_t) * 8].  */
   3078 struct ternary_shift_right_imm_def : public ternary_shift_imm_base
   3079 {
   3080   bool
   3081   check (function_checker &c) const OVERRIDE
   3082   {
   3083     unsigned int bits = c.type_suffix (0).element_bits;
   3084     return c.require_immediate_range (2, 1, bits);
   3085   }
   3086 };
   3087 SHAPE (ternary_shift_right_imm)
   3088 
   3089 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0>_t, sv<t0:uint>_t).  */
   3090 struct ternary_uint_def : public overloaded_base<0>
   3091 {
   3092   void
   3093   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3094   {
   3095     b.add_overloaded_functions (group, MODE_none);
   3096     build_all (b, "v0,v0,v0,vu0", group, MODE_none);
   3097   }
   3098 
   3099   tree
   3100   resolve (function_resolver &r) const OVERRIDE
   3101   {
   3102     unsigned int i, nargs;
   3103     type_suffix_index type;
   3104     if (!r.check_gp_argument (3, i, nargs)
   3105 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
   3106 	|| !r.require_matching_vector_type (i + 1, type)
   3107 	|| !r.require_derived_vector_type (i + 2, i, type, TYPE_unsigned))
   3108       return error_mark_node;
   3109 
   3110     return r.resolve_to (r.mode_suffix_id, type);
   3111   }
   3112 };
   3113 SHAPE (ternary_uint)
   3114 
   3115 /* sv<t0>_t svfoo[_t0](sv<t0>_t, svu<t0:uint:quarter>_t,
   3116 		       sv<t0:int:quarter>_t).  */
   3117 struct ternary_uintq_intq_def
   3118   : public ternary_resize2_base<function_resolver::QUARTER_SIZE,
   3119 				TYPE_unsigned, TYPE_signed>
   3120 {
   3121   void
   3122   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3123   {
   3124     b.add_overloaded_functions (group, MODE_none);
   3125     build_all (b, "v0,v0,vqu0,vqs0", group, MODE_none);
   3126   }
   3127 };
   3128 SHAPE (ternary_uintq_intq)
   3129 
   3130 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:uint:quarter>_t, sv<t0:int:quarter>_t,
   3131 		       uint64_t)
   3132 
   3133    where the final argument is an integer constant expression in the range
   3134    [0, 16 / sizeof (<t0>_t) - 1].  */
   3135 struct ternary_uintq_intq_lane_def
   3136   : public ternary_qq_lane_base<TYPE_unsigned, TYPE_signed>
   3137 {
   3138   void
   3139   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3140   {
   3141     b.add_overloaded_functions (group, MODE_none);
   3142     build_all (b, "v0,v0,vqu0,vqs0,su64", group, MODE_none);
   3143   }
   3144 };
   3145 SHAPE (ternary_uintq_intq_lane)
   3146 
   3147 /* sv<t0>_t svfoo[_t0](sv<t0>_t, sv<t0:uint:quarter>_t, sv<t0:int:quarter>_t)
   3148    sv<t0>_t svfoo[_n_t0](sv<t0>_t, sv<t0:uint:quarter>_t,
   3149 			 <t0:int:quarter>_t).  */
   3150 struct ternary_uintq_intq_opt_n_def
   3151   : public ternary_resize2_opt_n_base<function_resolver::QUARTER_SIZE,
   3152 				      TYPE_unsigned, TYPE_signed>
   3153 {
   3154   void
   3155   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3156   {
   3157     b.add_overloaded_functions (group, MODE_none);
   3158     build_all (b, "v0,v0,vqu0,vqs0", group, MODE_none);
   3159     build_all (b, "v0,v0,vqu0,sqs0", group, MODE_n);
   3160   }
   3161 };
   3162 SHAPE (ternary_uintq_intq_opt_n)
   3163 
   3164 /* svbool_t svfoo[_<t0>](sv<t0>_t, sv<t0>_t, uint64_t)
   3165 
   3166    where the final argument is an integer constant expression in the
   3167    range [0, 7].  */
   3168 struct tmad_def : public overloaded_base<0>
   3169 {
   3170   void
   3171   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3172   {
   3173     b.add_overloaded_functions (group, MODE_none);
   3174     build_all (b, "v0,v0,v0,su64", group, MODE_none);
   3175   }
   3176 
   3177   tree
   3178   resolve (function_resolver &r) const OVERRIDE
   3179   {
   3180     return r.resolve_uniform (2, 1);
   3181   }
   3182 
   3183   bool
   3184   check (function_checker &c) const OVERRIDE
   3185   {
   3186     return c.require_immediate_range (2, 0, 7);
   3187   }
   3188 };
   3189 SHAPE (tmad)
   3190 
   3191 /* sv<t0>_t svfoo[_t0](sv<t0>_t)
   3192 
   3193    i.e. the standard shape for unary operations that operate on
   3194    uniform types.  */
   3195 struct unary_def : public overloaded_base<0>
   3196 {
   3197   void
   3198   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3199   {
   3200     b.add_overloaded_functions (group, MODE_none);
   3201     build_all (b, "v0,v0", group, MODE_none);
   3202   }
   3203 
   3204   tree
   3205   resolve (function_resolver &r) const OVERRIDE
   3206   {
   3207     return r.resolve_unary ();
   3208   }
   3209 };
   3210 SHAPE (unary)
   3211 
   3212 /* sv<t0>_t svfoo_t0[_t1](sv<t1>_t)
   3213 
   3214    where the target type <t0> must be specified explicitly but the source
   3215    type <t1> can be inferred.  */
   3216 struct unary_convert_def : public overloaded_base<1>
   3217 {
   3218   void
   3219   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3220   {
   3221     b.add_overloaded_functions (group, MODE_none);
   3222     build_all (b, "v0,v1", group, MODE_none);
   3223   }
   3224 
   3225   tree
   3226   resolve (function_resolver &r) const OVERRIDE
   3227   {
   3228     return r.resolve_unary (r.type_suffix (0).tclass,
   3229 			    r.type_suffix (0).element_bits);
   3230   }
   3231 };
   3232 SHAPE (unary_convert)
   3233 
   3234 /* sv<t0>_t svfoo_t0[_t1](sv<t0>_t, sv<t1>_t)
   3235 
   3236    This is a version of unary_convert in which the even-indexed
   3237    elements are passed in as a first parameter, before any governing
   3238    predicate.  */
   3239 struct unary_convert_narrowt_def : public overloaded_base<1>
   3240 {
   3241   void
   3242   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3243   {
   3244     b.add_overloaded_functions (group, MODE_none);
   3245     build_all (b, "v0,v1", group, MODE_none);
   3246   }
   3247 
   3248   tree
   3249   resolve (function_resolver &r) const OVERRIDE
   3250   {
   3251     return r.resolve_unary (r.type_suffix (0).tclass,
   3252 			    r.type_suffix (0).element_bits, true);
   3253   }
   3254 };
   3255 SHAPE (unary_convert_narrowt)
   3256 
   3257 /* sv<t0>_t svfoo[_t0](sv<t0:half>_t).  */
   3258 struct unary_long_def : public overloaded_base<0>
   3259 {
   3260   void
   3261   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3262   {
   3263     b.add_overloaded_functions (group, MODE_none);
   3264     build_all (b, "v0,vh0", group, MODE_none);
   3265   }
   3266 
   3267   tree
   3268   resolve (function_resolver &r) const OVERRIDE
   3269   {
   3270     unsigned int i, nargs;
   3271     type_suffix_index type, result_type;
   3272     if (!r.check_gp_argument (1, i, nargs)
   3273 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES
   3274 	|| (result_type = long_type_suffix (r, type)) == NUM_TYPE_SUFFIXES)
   3275       return error_mark_node;
   3276 
   3277     if (tree res = r.lookup_form (r.mode_suffix_id, result_type))
   3278       return res;
   3279 
   3280     return r.report_no_such_form (type);
   3281   }
   3282 };
   3283 SHAPE (unary_long)
   3284 
   3285 /* sv<t0>_t svfoo[_n]_t0(<t0>_t).  */
   3286 struct unary_n_def : public overloaded_base<1>
   3287 {
   3288   void
   3289   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3290   {
   3291     /* The "_n" suffix is optional; the full name has it, but the short
   3292        name doesn't.  */
   3293     build_all (b, "v0,s0", group, MODE_n, true);
   3294   }
   3295 
   3296   tree
   3297   resolve (function_resolver &) const OVERRIDE
   3298   {
   3299     /* The short forms just make "_n" implicit, so no resolution is needed.  */
   3300     gcc_unreachable ();
   3301   }
   3302 };
   3303 SHAPE (unary_n)
   3304 
   3305 /* sv<t0:half>_t svfoo[_t0](sv<t0>_t).  */
   3306 typedef unary_narrowb_base<> unary_narrowb_def;
   3307 SHAPE (unary_narrowb)
   3308 
   3309 /* sv<t0:half>_t svfoo[_t0](sv<t0:half>_t, sv<t0>_t).  */
   3310 typedef unary_narrowt_base<> unary_narrowt_def;
   3311 SHAPE (unary_narrowt)
   3312 
   3313 /* sv<t0:uint:half>_t svfoo[_t0](sv<t0>_t).  */
   3314 typedef unary_narrowb_base<TYPE_unsigned> unary_narrowb_to_uint_def;
   3315 SHAPE (unary_narrowb_to_uint)
   3316 
   3317 /* sv<t0:uint:half>_t svfoo[_t0](sv<t0:uint:half>_t, sv<t0>_t).  */
   3318 typedef unary_narrowt_base<TYPE_unsigned> unary_narrowt_to_uint_def;
   3319 SHAPE (unary_narrowt_to_uint)
   3320 
   3321 /* svbool_t svfoo(svbool_t).  */
   3322 struct unary_pred_def : public nonoverloaded_base
   3323 {
   3324   void
   3325   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3326   {
   3327     build_all (b, "v0,v0", group, MODE_none);
   3328   }
   3329 };
   3330 SHAPE (unary_pred)
   3331 
   3332 /* sv<t0:int>_t svfoo[_t0](sv<t0>_t)
   3333 
   3334    i.e. a version of "unary" in which the returned vector contains
   3335    signed integers.  */
   3336 struct unary_to_int_def : public overloaded_base<0>
   3337 {
   3338   void
   3339   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3340   {
   3341     b.add_overloaded_functions (group, MODE_none);
   3342     build_all (b, "vs0,v0", group, MODE_none);
   3343   }
   3344 
   3345   tree
   3346   resolve (function_resolver &r) const OVERRIDE
   3347   {
   3348     return r.resolve_unary (TYPE_signed);
   3349   }
   3350 };
   3351 SHAPE (unary_to_int)
   3352 
   3353 /* sv<t0:uint>_t svfoo[_t0](sv<t0>_t)
   3354 
   3355    i.e. a version of "unary" in which the returned vector contains
   3356    unsigned integers.  */
   3357 struct unary_to_uint_def : public overloaded_base<0>
   3358 {
   3359   void
   3360   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3361   {
   3362     b.add_overloaded_functions (group, MODE_none);
   3363     build_all (b, "vu0,v0", group, MODE_none);
   3364   }
   3365 
   3366   tree
   3367   resolve (function_resolver &r) const OVERRIDE
   3368   {
   3369     return r.resolve_unary (TYPE_unsigned);
   3370   }
   3371 };
   3372 SHAPE (unary_to_uint)
   3373 
   3374 /* sv<t0>_t svfoo[_t0](sv<t0:uint>_t)
   3375 
   3376    where <t0> always belongs a certain type class, and where <t0:uint>
   3377    therefore uniquely determines <t0>.  */
   3378 struct unary_uint_def : public overloaded_base<0>
   3379 {
   3380   void
   3381   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3382   {
   3383     b.add_overloaded_functions (group, MODE_none);
   3384     build_all (b, "v0,vu0", group, MODE_none);
   3385   }
   3386 
   3387   tree
   3388   resolve (function_resolver &r) const OVERRIDE
   3389   {
   3390     unsigned int i, nargs;
   3391     type_suffix_index type;
   3392     if (!r.check_gp_argument (1, i, nargs)
   3393 	|| (type = r.infer_unsigned_vector_type (i)) == NUM_TYPE_SUFFIXES)
   3394       return error_mark_node;
   3395 
   3396     /* Search for a valid suffix with the same number of bits as TYPE.  */
   3397     unsigned int element_bits = type_suffixes[type].element_bits;
   3398     if (type_suffixes[type].unsigned_p)
   3399       for (unsigned int j = 0; j < NUM_TYPE_SUFFIXES; ++j)
   3400 	if (type_suffixes[j].element_bits == element_bits)
   3401 	  if (tree res = r.lookup_form (r.mode_suffix_id,
   3402 					type_suffix_index (j)))
   3403 	    return res;
   3404 
   3405     return r.report_no_such_form (type);
   3406   }
   3407 };
   3408 SHAPE (unary_uint)
   3409 
   3410 /* sv<t0>_t svfoo[_<t0>](sv<t0:half>_t)
   3411 
   3412    i.e. a version of "unary" in which the source elements are half the
   3413    size of the destination elements, but have the same type class.  */
   3414 struct unary_widen_def : public overloaded_base<0>
   3415 {
   3416   void
   3417   build (function_builder &b, const function_group_info &group) const OVERRIDE
   3418   {
   3419     b.add_overloaded_functions (group, MODE_none);
   3420     build_all (b, "v0,vh0", group, MODE_none);
   3421   }
   3422 
   3423   tree
   3424   resolve (function_resolver &r) const OVERRIDE
   3425   {
   3426     unsigned int i, nargs;
   3427     type_suffix_index type;
   3428     if (!r.check_gp_argument (1, i, nargs)
   3429 	|| (type = r.infer_vector_type (i)) == NUM_TYPE_SUFFIXES)
   3430       return error_mark_node;
   3431 
   3432     /* There is only a single form for predicates.  */
   3433     if (type == TYPE_SUFFIX_b)
   3434       return r.resolve_to (r.mode_suffix_id, type);
   3435 
   3436     if (type_suffixes[type].integer_p
   3437 	&& type_suffixes[type].element_bits < 64)
   3438       {
   3439 	type_suffix_index wide_suffix
   3440 	  = find_type_suffix (type_suffixes[type].tclass,
   3441 			      type_suffixes[type].element_bits * 2);
   3442 	if (tree res = r.lookup_form (r.mode_suffix_id, wide_suffix))
   3443 	  return res;
   3444       }
   3445 
   3446     return r.report_no_such_form (type);
   3447   }
   3448 };
   3449 SHAPE (unary_widen)
   3450 
   3451 }
   3452