]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm-mve-builtins.cc
arm: [MVE intrinsics] Add support for contiguous loads and stores
[thirdparty/gcc.git] / gcc / config / arm / arm-mve-builtins.cc
1 /* ACLE support for Arm MVE
2 Copyright (C) 2021-2023 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 #define IN_TARGET_CODE 1
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "tm_p.h"
29 #include "memmodel.h"
30 #include "insn-codes.h"
31 #include "optabs.h"
32 #include "recog.h"
33 #include "expr.h"
34 #include "basic-block.h"
35 #include "function.h"
36 #include "fold-const.h"
37 #include "gimple.h"
38 #include "gimple-iterator.h"
39 #include "explow.h"
40 #include "emit-rtl.h"
41 #include "langhooks.h"
42 #include "stringpool.h"
43 #include "attribs.h"
44 #include "diagnostic.h"
45 #include "arm-protos.h"
46 #include "arm-builtins.h"
47 #include "arm-mve-builtins.h"
48 #include "arm-mve-builtins-base.h"
49 #include "arm-mve-builtins-shapes.h"
50
51 namespace arm_mve {
52
53 /* Static information about each single-predicate or single-vector
54 ACLE type. */
55 struct vector_type_info
56 {
57 /* The name of the type as declared by arm_mve.h. */
58 const char *acle_name;
59
60 /* Whether the type requires a floating point abi. */
61 const bool requires_float;
62 };
63
64 /* Describes a function decl. */
65 class GTY(()) registered_function
66 {
67 public:
68 /* The ACLE function that the decl represents. */
69 function_instance instance GTY ((skip));
70
71 /* The decl itself. */
72 tree decl;
73
74 /* Whether the function requires a floating point abi. */
75 bool requires_float;
76
77 /* True if the decl represents an overloaded function that needs to be
78 resolved by function_resolver. */
79 bool overloaded_p;
80 };
81
82 /* Hash traits for registered_function. */
83 struct registered_function_hasher : nofree_ptr_hash <registered_function>
84 {
85 typedef function_instance compare_type;
86
87 static hashval_t hash (value_type);
88 static bool equal (value_type, const compare_type &);
89 };
90
91 /* Flag indicating whether the arm MVE types have been handled. */
92 static bool handle_arm_mve_types_p;
93
94 /* Information about each single-predicate or single-vector type. */
95 static CONSTEXPR const vector_type_info vector_types[] = {
96 #define DEF_MVE_TYPE(ACLE_NAME, SCALAR_TYPE) \
97 { #ACLE_NAME, REQUIRES_FLOAT },
98 #include "arm-mve-builtins.def"
99 };
100
101 /* The function name suffix associated with each predication type. */
102 static const char *const pred_suffixes[NUM_PREDS + 1] = {
103 "",
104 "_m",
105 "_p",
106 "_x",
107 "_z",
108 ""
109 };
110
111 /* Static information about each mode_suffix_index. */
112 CONSTEXPR const mode_suffix_info mode_suffixes[] = {
113 #define VECTOR_TYPE_none NUM_VECTOR_TYPES
114 #define DEF_MVE_MODE(NAME, BASE, DISPLACEMENT, UNITS) \
115 { "_" #NAME, VECTOR_TYPE_##BASE, VECTOR_TYPE_##DISPLACEMENT, UNITS_##UNITS },
116 #include "arm-mve-builtins.def"
117 #undef VECTOR_TYPE_none
118 { "", NUM_VECTOR_TYPES, NUM_VECTOR_TYPES, UNITS_none }
119 };
120
121 /* Static information about each type_suffix_index. */
122 CONSTEXPR const type_suffix_info type_suffixes[NUM_TYPE_SUFFIXES + 1] = {
123 #define DEF_MVE_TYPE_SUFFIX(NAME, ACLE_TYPE, CLASS, BITS, MODE) \
124 { "_" #NAME, \
125 VECTOR_TYPE_##ACLE_TYPE, \
126 TYPE_##CLASS, \
127 BITS, \
128 BITS / BITS_PER_UNIT, \
129 TYPE_##CLASS == TYPE_signed || TYPE_##CLASS == TYPE_unsigned, \
130 TYPE_##CLASS == TYPE_unsigned, \
131 TYPE_##CLASS == TYPE_float, \
132 TYPE_##CLASS == TYPE_poly, \
133 0, \
134 MODE },
135 #include "arm-mve-builtins.def"
136 { "", NUM_VECTOR_TYPES, TYPE_bool, 0, 0, false, false, false, false,
137 0, VOIDmode }
138 };
139
140 /* Define a TYPES_<combination> macro for each combination of type
141 suffixes that an ACLE function can have, where <combination> is the
142 name used in DEF_MVE_FUNCTION entries.
143
144 Use S (T) for single type suffix T and D (T1, T2) for a pair of type
145 suffixes T1 and T2. Use commas to separate the suffixes.
146
147 Although the order shouldn't matter, the convention is to sort the
148 suffixes lexicographically after dividing suffixes into a type
149 class ("b", "f", etc.) and a numerical bit count. */
150
151 /* _f16. */
152 #define TYPES_float16(S, D) \
153 S (f16)
154
155 /* _f16 _f32. */
156 #define TYPES_all_float(S, D) \
157 S (f16), S (f32)
158
159 /* _s8 _u8 . */
160 #define TYPES_integer_8(S, D) \
161 S (s8), S (u8)
162
163 /* _s8 _s16
164 _u8 _u16. */
165 #define TYPES_integer_8_16(S, D) \
166 S (s8), S (s16), S (u8), S(u16)
167
168 /* _s16 _s32
169 _u16 _u32. */
170 #define TYPES_integer_16_32(S, D) \
171 S (s16), S (s32), \
172 S (u16), S (u32)
173
174 /* _s16 _s32. */
175 #define TYPES_signed_16_32(S, D) \
176 S (s16), S (s32)
177
178 /* _s8 _s16 _s32. */
179 #define TYPES_all_signed(S, D) \
180 S (s8), S (s16), S (s32)
181
182 /* _p8 _p16. */
183 #define TYPES_poly_8_16(S, D) \
184 S (p8), S (p16)
185
186 /* _u8 _u16 _u32. */
187 #define TYPES_all_unsigned(S, D) \
188 S (u8), S (u16), S (u32)
189
190 /* _s8 _s16 _s32
191 _u8 _u16 _u32. */
192 #define TYPES_all_integer(S, D) \
193 TYPES_all_signed (S, D), TYPES_all_unsigned (S, D)
194
195 /* _s8 _s16 _s32 _s64
196 _u8 _u16 _u32 _u64. */
197 #define TYPES_all_integer_with_64(S, D) \
198 TYPES_all_signed (S, D), S (s64), TYPES_all_unsigned (S, D), S (u64)
199
200 /* s32 _u32. */
201 #define TYPES_integer_32(S, D) \
202 S (s32), S (u32)
203
204 /* s32 . */
205 #define TYPES_signed_32(S, D) \
206 S (s32)
207
208 #define TYPES_reinterpret_signed1(D, A) \
209 D (A, s8), D (A, s16), D (A, s32), D (A, s64)
210
211 #define TYPES_reinterpret_unsigned1(D, A) \
212 D (A, u8), D (A, u16), D (A, u32), D (A, u64)
213
214 #define TYPES_reinterpret_integer(S, D) \
215 TYPES_reinterpret_unsigned1 (D, s8), \
216 D (s8, s16), D (s8, s32), D (s8, s64), \
217 TYPES_reinterpret_unsigned1 (D, s16), \
218 D (s16, s8), D (s16, s32), D (s16, s64), \
219 TYPES_reinterpret_unsigned1 (D, s32), \
220 D (s32, s8), D (s32, s16), D (s32, s64), \
221 TYPES_reinterpret_unsigned1 (D, s64), \
222 D (s64, s8), D (s64, s16), D (s64, s32), \
223 TYPES_reinterpret_signed1 (D, u8), \
224 D (u8, u16), D (u8, u32), D (u8, u64), \
225 TYPES_reinterpret_signed1 (D, u16), \
226 D (u16, u8), D (u16, u32), D (u16, u64), \
227 TYPES_reinterpret_signed1 (D, u32), \
228 D (u32, u8), D (u32, u16), D (u32, u64), \
229 TYPES_reinterpret_signed1 (D, u64), \
230 D (u64, u8), D (u64, u16), D (u64, u32)
231
232 /* { _s8 _s16 _s32 _s64 } x { _s8 _s16 _s32 _s64 }
233 { _u8 _u16 _u32 _u64 } { _u8 _u16 _u32 _u64 }. */
234 #define TYPES_reinterpret_integer1(D, A) \
235 TYPES_reinterpret_signed1 (D, A), \
236 TYPES_reinterpret_unsigned1 (D, A)
237
238 #define TYPES_reinterpret_float1(D, A) \
239 D (A, f16), D (A, f32)
240
241 #define TYPES_reinterpret_float(S, D) \
242 TYPES_reinterpret_float1 (D, s8), \
243 TYPES_reinterpret_float1 (D, s16), \
244 TYPES_reinterpret_float1 (D, s32), \
245 TYPES_reinterpret_float1 (D, s64), \
246 TYPES_reinterpret_float1 (D, u8), \
247 TYPES_reinterpret_float1 (D, u16), \
248 TYPES_reinterpret_float1 (D, u32), \
249 TYPES_reinterpret_float1 (D, u64), \
250 TYPES_reinterpret_integer1 (D, f16), \
251 TYPES_reinterpret_integer1 (D, f32), \
252 D (f16, f32), D (f32, f16)
253
254 /* Describe a pair of type suffixes in which only the first is used. */
255 #define DEF_VECTOR_TYPE(X) { TYPE_SUFFIX_ ## X, NUM_TYPE_SUFFIXES }
256
257 /* Describe a pair of type suffixes in which both are used. */
258 #define DEF_DOUBLE_TYPE(X, Y) { TYPE_SUFFIX_ ## X, TYPE_SUFFIX_ ## Y }
259
260 /* Create an array that can be used in arm-mve-builtins.def to
261 select the type suffixes in TYPES_<NAME>. */
262 #define DEF_MVE_TYPES_ARRAY(NAME) \
263 static const type_suffix_pair types_##NAME[] = { \
264 TYPES_##NAME (DEF_VECTOR_TYPE, DEF_DOUBLE_TYPE), \
265 { NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES } \
266 }
267
268 /* For functions that don't take any type suffixes. */
269 static const type_suffix_pair types_none[] = {
270 { NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES },
271 { NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES }
272 };
273
274 DEF_MVE_TYPES_ARRAY (all_integer);
275 DEF_MVE_TYPES_ARRAY (all_integer_with_64);
276 DEF_MVE_TYPES_ARRAY (float16);
277 DEF_MVE_TYPES_ARRAY (all_float);
278 DEF_MVE_TYPES_ARRAY (all_signed);
279 DEF_MVE_TYPES_ARRAY (all_unsigned);
280 DEF_MVE_TYPES_ARRAY (integer_8);
281 DEF_MVE_TYPES_ARRAY (integer_8_16);
282 DEF_MVE_TYPES_ARRAY (integer_16_32);
283 DEF_MVE_TYPES_ARRAY (integer_32);
284 DEF_MVE_TYPES_ARRAY (poly_8_16);
285 DEF_MVE_TYPES_ARRAY (signed_16_32);
286 DEF_MVE_TYPES_ARRAY (signed_32);
287 DEF_MVE_TYPES_ARRAY (reinterpret_integer);
288 DEF_MVE_TYPES_ARRAY (reinterpret_float);
289
290 /* Used by functions that have no governing predicate. */
291 static const predication_index preds_none[] = { PRED_none, NUM_PREDS };
292
293 /* Used by functions that have the m (merging) predicated form, and in
294 addition have an unpredicated form. */
295 const predication_index preds_m_or_none[] = {
296 PRED_m, PRED_none, NUM_PREDS
297 };
298
299 /* Used by functions that have the mx (merging and "don't care"
300 predicated forms, and in addition have an unpredicated form. */
301 static const predication_index preds_mx_or_none[] = {
302 PRED_m, PRED_x, PRED_none, NUM_PREDS
303 };
304
305 /* Used by functions that have the p predicated form, in addition to
306 an unpredicated form. */
307 static const predication_index preds_p_or_none[] = {
308 PRED_p, PRED_none, NUM_PREDS
309 };
310
311 /* A list of all MVE ACLE functions. */
312 static CONSTEXPR const function_group_info function_groups[] = {
313 #define DEF_MVE_FUNCTION(NAME, SHAPE, TYPES, PREDS) \
314 { #NAME, &functions::NAME, &shapes::SHAPE, types_##TYPES, preds_##PREDS, \
315 REQUIRES_FLOAT },
316 #include "arm-mve-builtins.def"
317 };
318
319 /* The scalar type associated with each vector type. */
320 extern GTY(()) tree scalar_types[NUM_VECTOR_TYPES];
321 tree scalar_types[NUM_VECTOR_TYPES];
322
323 /* The single-predicate and single-vector types, with their built-in
324 "__simd128_..._t" name. Allow an index of NUM_VECTOR_TYPES, which always
325 yields a null tree. */
326 static GTY(()) tree abi_vector_types[NUM_VECTOR_TYPES + 1];
327
328 /* Same, but with the arm_mve.h names. */
329 extern GTY(()) tree acle_vector_types[MAX_TUPLE_SIZE][NUM_VECTOR_TYPES + 1];
330 tree acle_vector_types[MAX_TUPLE_SIZE][NUM_VECTOR_TYPES + 1];
331
332 /* The list of all registered function decls, indexed by code. */
333 static GTY(()) vec<registered_function *, va_gc> *registered_functions;
334
335 /* All registered function decls, hashed on the function_instance
336 that they implement. This is used for looking up implementations of
337 overloaded functions. */
338 static hash_table<registered_function_hasher> *function_table;
339
340 /* True if we've already complained about attempts to use functions
341 when the required extension is disabled. */
342 static bool reported_missing_float_p;
343
344 /* Return the MVE abi type with element of type TYPE. */
345 static tree
346 arm_mve_type_for_scalar_type (tree eltype)
347 {
348 for (unsigned int i = 0; i < __TYPE_FINAL; ++i)
349 if (arm_simd_types[i].eltype == eltype
350 && GET_MODE_SIZE (arm_simd_types[i].mode) == 16)
351 return arm_simd_types[i].itype;
352
353 gcc_unreachable ();
354 }
355
356 /* Register the built-in MVE ABI vector types, such as uint32x4_t. */
357 static void
358 register_builtin_types ()
359 {
360 #define DEF_MVE_TYPE(ACLE_NAME, SCALAR_TYPE) \
361 scalar_types[VECTOR_TYPE_ ## ACLE_NAME] = SCALAR_TYPE;
362 #include "arm-mve-builtins.def"
363 for (unsigned int i = 0; i < NUM_VECTOR_TYPES; ++i)
364 {
365 if (vector_types[i].requires_float && !TARGET_HAVE_MVE_FLOAT)
366 continue;
367 tree eltype = scalar_types[i];
368 tree vectype;
369 if (eltype == boolean_type_node)
370 {
371 vectype = get_typenode_from_name (UINT16_TYPE);
372 gcc_assert (GET_MODE_SIZE (TYPE_MODE (vectype)) == 2);
373 }
374 else
375 {
376 vectype = arm_mve_type_for_scalar_type (eltype);
377 gcc_assert (VECTOR_MODE_P (TYPE_MODE (vectype))
378 && GET_MODE_SIZE (TYPE_MODE (vectype)) == 16);
379 }
380 abi_vector_types[i] = vectype;
381 }
382 }
383
384 /* Register vector type TYPE under its arm_mve.h name. */
385 static void
386 register_vector_type (vector_type_index type)
387 {
388
389 /* If the target does not have the mve.fp extension, but the type requires
390 it, then it needs to be assigned a non-dummy type so that functions
391 with those types in their signature can be registered. This allows for
392 diagnostics about the missing extension, rather than about a missing
393 function definition. */
394 if (vector_types[type].requires_float && !TARGET_HAVE_MVE_FLOAT)
395 {
396 acle_vector_types[0][type] = void_type_node;
397 return;
398 }
399
400 tree vectype = abi_vector_types[type];
401 tree id = get_identifier (vector_types[type].acle_name);
402 tree decl = build_decl (input_location, TYPE_DECL, id, vectype);
403 decl = lang_hooks.decls.pushdecl (decl);
404
405 /* Record the new ACLE type if pushdecl succeeded without error. Use
406 the ABI type otherwise, so that the type we record at least has the
407 right form, even if it doesn't have the right name. This should give
408 better error recovery behavior than installing error_mark_node or
409 installing an incorrect type. */
410 if (decl
411 && TREE_CODE (decl) == TYPE_DECL
412 && TREE_TYPE (decl) != error_mark_node
413 && TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == vectype)
414 vectype = TREE_TYPE (decl);
415 acle_vector_types[0][type] = vectype;
416 }
417
418 /* Register tuple types of element type TYPE under their arm_mve_types.h
419 names. */
420 static void
421 register_builtin_tuple_types (vector_type_index type)
422 {
423 const vector_type_info* info = &vector_types[type];
424
425 /* If the target does not have the mve.fp extension, but the type requires
426 it, then it needs to be assigned a non-dummy type so that functions
427 with those types in their signature can be registered. This allows for
428 diagnostics about the missing extension, rather than about a missing
429 function definition. */
430 if (scalar_types[type] == boolean_type_node
431 || (info->requires_float && !TARGET_HAVE_MVE_FLOAT))
432 {
433 for (unsigned int num_vectors = 2; num_vectors <= 4; num_vectors += 2)
434 acle_vector_types[num_vectors >> 1][type] = void_type_node;
435 return;
436 }
437
438 const char *vector_type_name = info->acle_name;
439 char buffer[sizeof ("float32x4x2_t")];
440 for (unsigned int num_vectors = 2; num_vectors <= 4; num_vectors += 2)
441 {
442 snprintf (buffer, sizeof (buffer), "%.*sx%d_t",
443 (int) strlen (vector_type_name) - 2, vector_type_name,
444 num_vectors);
445
446 tree vectype = acle_vector_types[0][type];
447 tree arrtype = build_array_type_nelts (vectype, num_vectors);
448 gcc_assert (TYPE_MODE_RAW (arrtype) == TYPE_MODE (arrtype));
449 tree field = build_decl (input_location, FIELD_DECL,
450 get_identifier ("val"), arrtype);
451
452 tree t = lang_hooks.types.simulate_record_decl (input_location, buffer,
453 make_array_slice (&field,
454 1));
455 gcc_assert (TYPE_MODE_RAW (t) == TYPE_MODE (t));
456 acle_vector_types[num_vectors >> 1][type] = TREE_TYPE (t);
457 }
458 }
459
460 /* Implement #pragma GCC arm "arm_mve_types.h". */
461 void
462 handle_arm_mve_types_h ()
463 {
464 if (handle_arm_mve_types_p)
465 {
466 error ("duplicate definition of %qs", "arm_mve_types.h");
467 return;
468 }
469 handle_arm_mve_types_p = true;
470 if (!TARGET_HAVE_MVE)
471 {
472 error ("this definition requires the MVE ISA extension");
473 return;
474 }
475 register_builtin_types ();
476 for (unsigned int type_i = 0; type_i < NUM_VECTOR_TYPES; ++type_i)
477 {
478 vector_type_index type = vector_type_index (type_i);
479 register_vector_type (type);
480 if (type_i != VECTOR_TYPE_mve_pred16_t)
481 register_builtin_tuple_types (type);
482 }
483 }
484
485 /* Implement #pragma GCC arm "arm_mve.h" <bool>. */
486 void
487 handle_arm_mve_h (bool preserve_user_namespace)
488 {
489 if (function_table)
490 {
491 error ("duplicate definition of %qs", "arm_mve.h");
492 return;
493 }
494
495 /* Define MVE functions. */
496 function_table = new hash_table<registered_function_hasher> (1023);
497 function_builder builder;
498 for (unsigned int i = 0; i < ARRAY_SIZE (function_groups); ++i)
499 builder.register_function_group (function_groups[i],
500 preserve_user_namespace);
501 }
502
503 /* Return the function decl with MVE function subcode CODE, or error_mark_node
504 if no such function exists. */
505 tree
506 builtin_decl (unsigned int code)
507 {
508 if (code >= vec_safe_length (registered_functions))
509 return error_mark_node;
510 return (*registered_functions)[code]->decl;
511 }
512
513 /* Return true if CANDIDATE is equivalent to MODEL_TYPE for overloading
514 purposes. */
515 static bool
516 matches_type_p (const_tree model_type, const_tree candidate)
517 {
518 if (VECTOR_TYPE_P (model_type))
519 {
520 if (!VECTOR_TYPE_P (candidate)
521 || maybe_ne (TYPE_VECTOR_SUBPARTS (model_type),
522 TYPE_VECTOR_SUBPARTS (candidate))
523 || TYPE_MODE (model_type) != TYPE_MODE (candidate))
524 return false;
525
526 model_type = TREE_TYPE (model_type);
527 candidate = TREE_TYPE (candidate);
528 }
529 return (candidate != error_mark_node
530 && TYPE_MAIN_VARIANT (model_type) == TYPE_MAIN_VARIANT (candidate));
531 }
532
533 /* If TYPE is a valid MVE element type, return the corresponding type
534 suffix, otherwise return NUM_TYPE_SUFFIXES. */
535 static type_suffix_index
536 find_type_suffix_for_scalar_type (const_tree type)
537 {
538 /* A linear search should be OK here, since the code isn't hot and
539 the number of types is only small. */
540 for (unsigned int suffix_i = 0; suffix_i < NUM_TYPE_SUFFIXES; ++suffix_i)
541 {
542 vector_type_index vector_i = type_suffixes[suffix_i].vector_type;
543 if (matches_type_p (scalar_types[vector_i], type))
544 return type_suffix_index (suffix_i);
545 }
546 return NUM_TYPE_SUFFIXES;
547 }
548
549 /* Report an error against LOCATION that the user has tried to use
550 a floating point function when the mve.fp extension is disabled. */
551 static void
552 report_missing_float (location_t location, tree fndecl)
553 {
554 /* Avoid reporting a slew of messages for a single oversight. */
555 if (reported_missing_float_p)
556 return;
557
558 error_at (location, "ACLE function %qD requires ISA extension %qs",
559 fndecl, "mve.fp");
560 inform (location, "you can enable mve.fp by using the command-line"
561 " option %<-march%>, or by using the %<target%>"
562 " attribute or pragma");
563 reported_missing_float_p = true;
564 }
565
566 /* Report that LOCATION has a call to FNDECL in which argument ARGNO
567 was not an integer constant expression. ARGNO counts from zero. */
568 static void
569 report_non_ice (location_t location, tree fndecl, unsigned int argno)
570 {
571 error_at (location, "argument %d of %qE must be an integer constant"
572 " expression", argno + 1, fndecl);
573 }
574
575 /* Report that LOCATION has a call to FNDECL in which argument ARGNO has
576 the value ACTUAL, whereas the function requires a value in the range
577 [MIN, MAX]. ARGNO counts from zero. */
578 static void
579 report_out_of_range (location_t location, tree fndecl, unsigned int argno,
580 HOST_WIDE_INT actual, HOST_WIDE_INT min,
581 HOST_WIDE_INT max)
582 {
583 error_at (location, "passing %wd to argument %d of %qE, which expects"
584 " a value in the range [%wd, %wd]", actual, argno + 1, fndecl,
585 min, max);
586 }
587
588 /* Report that LOCATION has a call to FNDECL in which argument ARGNO has
589 the value ACTUAL, whereas the function requires a valid value of
590 enum type ENUMTYPE. ARGNO counts from zero. */
591 static void
592 report_not_enum (location_t location, tree fndecl, unsigned int argno,
593 HOST_WIDE_INT actual, tree enumtype)
594 {
595 error_at (location, "passing %wd to argument %d of %qE, which expects"
596 " a valid %qT value", actual, argno + 1, fndecl, enumtype);
597 }
598
599 /* Checks that the mve.fp extension is enabled, given that REQUIRES_FLOAT
600 indicates whether it is required or not for function FNDECL.
601 Report an error against LOCATION if not. */
602 static bool
603 check_requires_float (location_t location, tree fndecl,
604 bool requires_float)
605 {
606 if (requires_float && !TARGET_HAVE_MVE_FLOAT)
607 {
608 report_missing_float (location, fndecl);
609 return false;
610 }
611
612 return true;
613 }
614
615 /* Return a hash code for a function_instance. */
616 hashval_t
617 function_instance::hash () const
618 {
619 inchash::hash h;
620 /* BASE uniquely determines BASE_NAME, so we don't need to hash both. */
621 h.add_ptr (base);
622 h.add_ptr (shape);
623 h.add_int (mode_suffix_id);
624 h.add_int (type_suffix_ids[0]);
625 h.add_int (type_suffix_ids[1]);
626 h.add_int (pred);
627 return h.end ();
628 }
629
630 /* Return a set of CP_* flags that describe what the function could do,
631 taking the command-line flags into account. */
632 unsigned int
633 function_instance::call_properties () const
634 {
635 unsigned int flags = base->call_properties (*this);
636
637 /* -fno-trapping-math means that we can assume any FP exceptions
638 are not user-visible. */
639 if (!flag_trapping_math)
640 flags &= ~CP_RAISE_FP_EXCEPTIONS;
641
642 return flags;
643 }
644
645 /* Return true if calls to the function could read some form of
646 global state. */
647 bool
648 function_instance::reads_global_state_p () const
649 {
650 unsigned int flags = call_properties ();
651
652 /* Preserve any dependence on rounding mode, flush to zero mode, etc.
653 There is currently no way of turning this off; in particular,
654 -fno-rounding-math (which is the default) means that we should make
655 the usual assumptions about rounding mode, which for intrinsics means
656 acting as the instructions do. */
657 if (flags & CP_READ_FPCR)
658 return true;
659
660 return false;
661 }
662
663 /* Return true if calls to the function could modify some form of
664 global state. */
665 bool
666 function_instance::modifies_global_state_p () const
667 {
668 unsigned int flags = call_properties ();
669
670 /* Preserve any exception state written back to the FPCR,
671 unless -fno-trapping-math says this is unnecessary. */
672 if (flags & CP_RAISE_FP_EXCEPTIONS)
673 return true;
674
675 /* Handle direct modifications of global state. */
676 return flags & CP_WRITE_MEMORY;
677 }
678
679 /* Return true if calls to the function could raise a signal. */
680 bool
681 function_instance::could_trap_p () const
682 {
683 unsigned int flags = call_properties ();
684
685 /* Handle functions that could raise SIGFPE. */
686 if (flags & CP_RAISE_FP_EXCEPTIONS)
687 return true;
688
689 /* Handle functions that could raise SIGBUS or SIGSEGV. */
690 if (flags & (CP_READ_MEMORY | CP_WRITE_MEMORY))
691 return true;
692
693 return false;
694 }
695
696 /* Return true if the function has an implicit "inactive" argument.
697 This is the case of most _m predicated functions, but not all.
698 The list will be updated as needed. */
699 bool
700 function_instance::has_inactive_argument () const
701 {
702 if (pred != PRED_m)
703 return false;
704
705 if (mode_suffix_id == MODE_r
706 || base == functions::vcmlaq
707 || base == functions::vcmlaq_rot90
708 || base == functions::vcmlaq_rot180
709 || base == functions::vcmlaq_rot270
710 || base == functions::vcmpeqq
711 || base == functions::vcmpneq
712 || base == functions::vcmpgeq
713 || base == functions::vcmpgtq
714 || base == functions::vcmpleq
715 || base == functions::vcmpltq
716 || base == functions::vcmpcsq
717 || base == functions::vcmphiq
718 || base == functions::vfmaq
719 || base == functions::vfmasq
720 || base == functions::vfmsq
721 || base == functions::vmaxaq
722 || base == functions::vmaxnmaq
723 || base == functions::vminaq
724 || base == functions::vminnmaq
725 || base == functions::vmlaq
726 || base == functions::vmlasq
727 || base == functions::vmovnbq
728 || base == functions::vmovntq
729 || base == functions::vqmovnbq
730 || base == functions::vqmovntq
731 || base == functions::vqmovunbq
732 || base == functions::vqmovuntq
733 || (base == functions::vorrq && mode_suffix_id == MODE_n)
734 || base == functions::vqdmladhq
735 || base == functions::vqdmladhxq
736 || base == functions::vqdmlahq
737 || base == functions::vqdmlashq
738 || base == functions::vqdmlsdhq
739 || base == functions::vqdmlsdhxq
740 || base == functions::vqrdmladhq
741 || base == functions::vqrdmladhxq
742 || base == functions::vqrdmlahq
743 || base == functions::vqrdmlashq
744 || base == functions::vqrdmlsdhq
745 || base == functions::vqrdmlsdhxq
746 || (base == functions::vqrshlq && mode_suffix_id == MODE_n)
747 || base == functions::vqrshrnbq
748 || base == functions::vqrshrntq
749 || base == functions::vqrshrunbq
750 || base == functions::vqrshruntq
751 || base == functions::vqshrnbq
752 || base == functions::vqshrntq
753 || base == functions::vqshrunbq
754 || base == functions::vqshruntq
755 || (base == functions::vrshlq && mode_suffix_id == MODE_n)
756 || base == functions::vrshrnbq
757 || base == functions::vrshrntq
758 || base == functions::vshrnbq
759 || base == functions::vshrntq
760 || base == functions::vsliq
761 || base == functions::vsriq)
762 return false;
763
764 return true;
765 }
766
767 inline hashval_t
768 registered_function_hasher::hash (value_type value)
769 {
770 return value->instance.hash ();
771 }
772
773 inline bool
774 registered_function_hasher::equal (value_type value, const compare_type &key)
775 {
776 return value->instance == key;
777 }
778
779 function_builder::function_builder ()
780 {
781 m_overload_type = build_function_type (void_type_node, void_list_node);
782 m_direct_overloads = lang_GNU_CXX ();
783 gcc_obstack_init (&m_string_obstack);
784 }
785
786 function_builder::~function_builder ()
787 {
788 obstack_free (&m_string_obstack, NULL);
789 }
790
791 /* Add NAME to the end of the function name being built. */
792 void
793 function_builder::append_name (const char *name)
794 {
795 obstack_grow (&m_string_obstack, name, strlen (name));
796 }
797
798 /* Zero-terminate and complete the function name being built. */
799 char *
800 function_builder::finish_name ()
801 {
802 obstack_1grow (&m_string_obstack, 0);
803 return (char *) obstack_finish (&m_string_obstack);
804 }
805
806 /* Return the overloaded or full function name for INSTANCE, with optional
807 prefix; PRESERVE_USER_NAMESPACE selects the prefix, and OVERLOADED_P
808 selects which the overloaded or full function name. Allocate the string on
809 m_string_obstack; the caller must use obstack_free to free it after use. */
810 char *
811 function_builder::get_name (const function_instance &instance,
812 bool preserve_user_namespace,
813 bool overloaded_p)
814 {
815 if (preserve_user_namespace)
816 append_name ("__arm_");
817 append_name (instance.base_name);
818 append_name (pred_suffixes[instance.pred]);
819 if (!overloaded_p
820 || instance.shape->explicit_mode_suffix_p (instance.pred,
821 instance.mode_suffix_id))
822 append_name (instance.mode_suffix ().string);
823 for (unsigned int i = 0; i < 2; ++i)
824 if (!overloaded_p
825 || instance.shape->explicit_type_suffix_p (i, instance.pred,
826 instance.mode_suffix_id))
827 append_name (instance.type_suffix (i).string);
828 return finish_name ();
829 }
830
831 /* Add attribute NAME to ATTRS. */
832 static tree
833 add_attribute (const char *name, tree attrs)
834 {
835 return tree_cons (get_identifier (name), NULL_TREE, attrs);
836 }
837
838 /* Return the appropriate function attributes for INSTANCE. */
839 tree
840 function_builder::get_attributes (const function_instance &instance)
841 {
842 tree attrs = NULL_TREE;
843
844 if (!instance.modifies_global_state_p ())
845 {
846 if (instance.reads_global_state_p ())
847 attrs = add_attribute ("pure", attrs);
848 else
849 attrs = add_attribute ("const", attrs);
850 }
851
852 if (!flag_non_call_exceptions || !instance.could_trap_p ())
853 attrs = add_attribute ("nothrow", attrs);
854
855 return add_attribute ("leaf", attrs);
856 }
857
858 /* Add a function called NAME with type FNTYPE and attributes ATTRS.
859 INSTANCE describes what the function does and OVERLOADED_P indicates
860 whether it is overloaded. REQUIRES_FLOAT indicates whether the function
861 requires the mve.fp extension. */
862 registered_function &
863 function_builder::add_function (const function_instance &instance,
864 const char *name, tree fntype, tree attrs,
865 bool requires_float,
866 bool overloaded_p,
867 bool placeholder_p)
868 {
869 unsigned int code = vec_safe_length (registered_functions);
870 code = (code << ARM_BUILTIN_SHIFT) | ARM_BUILTIN_MVE;
871
872 /* We need to be able to generate placeholders to ensure that we have a
873 consistent numbering scheme for function codes between the C and C++
874 frontends, so that everything ties up in LTO.
875
876 Currently, tree-streamer-in.cc:unpack_ts_function_decl_value_fields
877 validates that tree nodes returned by TARGET_BUILTIN_DECL are non-NULL and
878 some node other than error_mark_node. This is a holdover from when builtin
879 decls were streamed by code rather than by value.
880
881 Ultimately, we should be able to remove this validation of BUILT_IN_MD
882 nodes and remove the target hook. For now, however, we need to appease the
883 validation and return a non-NULL, non-error_mark_node node, so we
884 arbitrarily choose integer_zero_node. */
885 tree decl = placeholder_p
886 ? integer_zero_node
887 : simulate_builtin_function_decl (input_location, name, fntype,
888 code, NULL, attrs);
889 registered_function &rfn = *ggc_alloc <registered_function> ();
890 rfn.instance = instance;
891 rfn.decl = decl;
892 rfn.requires_float = requires_float;
893 rfn.overloaded_p = overloaded_p;
894 vec_safe_push (registered_functions, &rfn);
895
896 return rfn;
897 }
898
899 /* Add a built-in function for INSTANCE, with the argument types given
900 by ARGUMENT_TYPES and the return type given by RETURN_TYPE.
901 REQUIRES_FLOAT indicates whether the function requires the mve.fp extension,
902 and PRESERVE_USER_NAMESPACE indicates whether the function should also be
903 registered under its non-prefixed name. */
904 void
905 function_builder::add_unique_function (const function_instance &instance,
906 tree return_type,
907 vec<tree> &argument_types,
908 bool preserve_user_namespace,
909 bool requires_float,
910 bool force_direct_overloads)
911 {
912 /* Add the function under its full (unique) name with prefix. */
913 char *name = get_name (instance, true, false);
914 tree fntype = build_function_type_array (return_type,
915 argument_types.length (),
916 argument_types.address ());
917 tree attrs = get_attributes (instance);
918 registered_function &rfn = add_function (instance, name, fntype, attrs,
919 requires_float, false, false);
920
921 /* Enter the function into the hash table. */
922 hashval_t hash = instance.hash ();
923 registered_function **rfn_slot
924 = function_table->find_slot_with_hash (instance, hash, INSERT);
925 gcc_assert (!*rfn_slot);
926 *rfn_slot = &rfn;
927
928 /* Also add the non-prefixed non-overloaded function, as placeholder
929 if the user namespace does not need to be preserved. */
930 char *noprefix_name = get_name (instance, false, false);
931 attrs = get_attributes (instance);
932 add_function (instance, noprefix_name, fntype, attrs, requires_float,
933 false, preserve_user_namespace);
934
935 /* Also add the function under its overloaded alias, if we want
936 a separate decl for each instance of an overloaded function. */
937 char *overload_name = get_name (instance, true, true);
938 if (strcmp (name, overload_name) != 0)
939 {
940 /* Attribute lists shouldn't be shared. */
941 attrs = get_attributes (instance);
942 bool placeholder_p = !(m_direct_overloads || force_direct_overloads);
943 add_function (instance, overload_name, fntype, attrs,
944 requires_float, false, placeholder_p);
945
946 /* Also add the non-prefixed overloaded function, as placeholder
947 if the user namespace does not need to be preserved. */
948 char *noprefix_overload_name = get_name (instance, false, true);
949 attrs = get_attributes (instance);
950 add_function (instance, noprefix_overload_name, fntype, attrs,
951 requires_float, false, preserve_user_namespace || placeholder_p);
952 }
953
954 obstack_free (&m_string_obstack, name);
955 }
956
957 /* Add one function decl for INSTANCE, to be used with manual overload
958 resolution. REQUIRES_FLOAT indicates whether the function requires the
959 mve.fp extension.
960
961 For simplicity, partition functions by instance and required extensions,
962 and check whether the required extensions are available as part of resolving
963 the function to the relevant unique function. */
964 void
965 function_builder::add_overloaded_function (const function_instance &instance,
966 bool preserve_user_namespace,
967 bool requires_float)
968 {
969 char *name = get_name (instance, true, true);
970 if (registered_function **map_value = m_overload_names.get (name))
971 {
972 gcc_assert ((*map_value)->instance == instance);
973 obstack_free (&m_string_obstack, name);
974 }
975 else
976 {
977 registered_function &rfn
978 = add_function (instance, name, m_overload_type, NULL_TREE,
979 requires_float, true, m_direct_overloads);
980 m_overload_names.put (name, &rfn);
981
982 /* Also add the non-prefixed function, as placeholder if the
983 user namespace does not need to be preserved. */
984 char *noprefix_name = get_name (instance, false, true);
985 registered_function &noprefix_rfn
986 = add_function (instance, noprefix_name, m_overload_type,
987 NULL_TREE, requires_float, true,
988 preserve_user_namespace || m_direct_overloads);
989 m_overload_names.put (noprefix_name, &noprefix_rfn);
990 }
991 }
992
993 /* If we are using manual overload resolution, add one function decl
994 for each overloaded function in GROUP. Take the function base name
995 from GROUP and the mode from MODE. */
996 void
997 function_builder::add_overloaded_functions (const function_group_info &group,
998 mode_suffix_index mode,
999 bool preserve_user_namespace)
1000 {
1001 for (unsigned int pi = 0; group.preds[pi] != NUM_PREDS; ++pi)
1002 {
1003 unsigned int explicit_type0
1004 = (*group.shape)->explicit_type_suffix_p (0, group.preds[pi], mode);
1005 unsigned int explicit_type1
1006 = (*group.shape)->explicit_type_suffix_p (1, group.preds[pi], mode);
1007
1008 if ((*group.shape)->skip_overload_p (group.preds[pi], mode))
1009 continue;
1010
1011 if (!explicit_type0 && !explicit_type1)
1012 {
1013 /* Deal with the common case in which there is one overloaded
1014 function for all type combinations. */
1015 function_instance instance (group.base_name, *group.base,
1016 *group.shape, mode, types_none[0],
1017 group.preds[pi]);
1018 add_overloaded_function (instance, preserve_user_namespace,
1019 group.requires_float);
1020 }
1021 else
1022 for (unsigned int ti = 0; group.types[ti][0] != NUM_TYPE_SUFFIXES;
1023 ++ti)
1024 {
1025 /* Stub out the types that are determined by overload
1026 resolution. */
1027 type_suffix_pair types = {
1028 explicit_type0 ? group.types[ti][0] : NUM_TYPE_SUFFIXES,
1029 explicit_type1 ? group.types[ti][1] : NUM_TYPE_SUFFIXES
1030 };
1031 function_instance instance (group.base_name, *group.base,
1032 *group.shape, mode, types,
1033 group.preds[pi]);
1034 add_overloaded_function (instance, preserve_user_namespace,
1035 group.requires_float);
1036 }
1037 }
1038 }
1039
1040 /* Register all the functions in GROUP. */
1041 void
1042 function_builder::register_function_group (const function_group_info &group,
1043 bool preserve_user_namespace)
1044 {
1045 (*group.shape)->build (*this, group, preserve_user_namespace);
1046 }
1047
1048 function_call_info::function_call_info (location_t location_in,
1049 const function_instance &instance_in,
1050 tree fndecl_in)
1051 : function_instance (instance_in), location (location_in), fndecl (fndecl_in)
1052 {
1053 }
1054
1055 function_resolver::function_resolver (location_t location,
1056 const function_instance &instance,
1057 tree fndecl, vec<tree, va_gc> &arglist)
1058 : function_call_info (location, instance, fndecl), m_arglist (arglist)
1059 {
1060 }
1061
1062 /* Return the vector type associated with type suffix TYPE. */
1063 tree
1064 function_resolver::get_vector_type (type_suffix_index type)
1065 {
1066 return acle_vector_types[0][type_suffixes[type].vector_type];
1067 }
1068
1069 /* Return the <stdint.h> name associated with TYPE. Using the <stdint.h>
1070 name should be more user-friendly than the underlying canonical type,
1071 since it makes the signedness and bitwidth explicit. */
1072 const char *
1073 function_resolver::get_scalar_type_name (type_suffix_index type)
1074 {
1075 return vector_types[type_suffixes[type].vector_type].acle_name + 2;
1076 }
1077
1078 /* Return the type of argument I, or error_mark_node if it isn't
1079 well-formed. */
1080 tree
1081 function_resolver::get_argument_type (unsigned int i)
1082 {
1083 tree arg = m_arglist[i];
1084 return arg == error_mark_node ? arg : TREE_TYPE (arg);
1085 }
1086
1087 /* Return true if argument I is some form of scalar value. */
1088 bool
1089 function_resolver::scalar_argument_p (unsigned int i)
1090 {
1091 tree type = get_argument_type (i);
1092 return (INTEGRAL_TYPE_P (type)
1093 /* Allow pointer types, leaving the frontend to warn where
1094 necessary. */
1095 || POINTER_TYPE_P (type)
1096 || SCALAR_FLOAT_TYPE_P (type));
1097 }
1098
1099 /* Report that the function has no form that takes type suffix TYPE.
1100 Return error_mark_node. */
1101 tree
1102 function_resolver::report_no_such_form (type_suffix_index type)
1103 {
1104 error_at (location, "%qE has no form that takes %qT arguments",
1105 fndecl, get_vector_type (type));
1106 return error_mark_node;
1107 }
1108
1109 /* Silently check whether there is an instance of the function with the
1110 mode suffix given by MODE and the type suffixes given by TYPE0 and TYPE1.
1111 Return its function decl if so, otherwise return null. */
1112 tree
1113 function_resolver::lookup_form (mode_suffix_index mode,
1114 type_suffix_index type0,
1115 type_suffix_index type1)
1116 {
1117 type_suffix_pair types = { type0, type1 };
1118 function_instance instance (base_name, base, shape, mode, types, pred);
1119 registered_function *rfn
1120 = function_table->find_with_hash (instance, instance.hash ());
1121 return rfn ? rfn->decl : NULL_TREE;
1122 }
1123
1124 /* Resolve the function to one with the mode suffix given by MODE and the
1125 type suffixes given by TYPE0 and TYPE1. Return its function decl on
1126 success, otherwise report an error and return error_mark_node. */
1127 tree
1128 function_resolver::resolve_to (mode_suffix_index mode,
1129 type_suffix_index type0,
1130 type_suffix_index type1)
1131 {
1132 tree res = lookup_form (mode, type0, type1);
1133 if (!res)
1134 {
1135 if (type1 == NUM_TYPE_SUFFIXES)
1136 return report_no_such_form (type0);
1137 if (type0 == type_suffix_ids[0])
1138 return report_no_such_form (type1);
1139 /* To be filled in when we have other cases. */
1140 gcc_unreachable ();
1141 }
1142 return res;
1143 }
1144
1145 /* Require argument ARGNO to be a pointer to a scalar type that has a
1146 corresponding type suffix. Return that type suffix on success,
1147 otherwise report an error and return NUM_TYPE_SUFFIXES. */
1148 type_suffix_index
1149 function_resolver::infer_pointer_type (unsigned int argno)
1150 {
1151 tree actual = get_argument_type (argno);
1152 if (actual == error_mark_node)
1153 return NUM_TYPE_SUFFIXES;
1154
1155 if (TREE_CODE (actual) != POINTER_TYPE)
1156 {
1157 error_at (location, "passing %qT to argument %d of %qE, which"
1158 " expects a pointer type", actual, argno + 1, fndecl);
1159 return NUM_TYPE_SUFFIXES;
1160 }
1161
1162 tree target = TREE_TYPE (actual);
1163 type_suffix_index type = find_type_suffix_for_scalar_type (target);
1164 if (type == NUM_TYPE_SUFFIXES)
1165 {
1166 error_at (location, "passing %qT to argument %d of %qE, but %qT is not"
1167 " a valid MVE element type", actual, argno + 1, fndecl,
1168 build_qualified_type (target, 0));
1169 return NUM_TYPE_SUFFIXES;
1170 }
1171 unsigned int bits = type_suffixes[type].element_bits;
1172
1173 return type;
1174 }
1175
1176 /* Require argument ARGNO to be a single vector or a tuple of NUM_VECTORS
1177 vectors; NUM_VECTORS is 1 for the former. Return the associated type
1178 suffix on success, using TYPE_SUFFIX_b for predicates. Report an error
1179 and return NUM_TYPE_SUFFIXES on failure. */
1180 type_suffix_index
1181 function_resolver::infer_vector_or_tuple_type (unsigned int argno,
1182 unsigned int num_vectors)
1183 {
1184 tree actual = get_argument_type (argno);
1185 if (actual == error_mark_node)
1186 return NUM_TYPE_SUFFIXES;
1187
1188 /* A linear search should be OK here, since the code isn't hot and
1189 the number of types is only small. */
1190 for (unsigned int size_i = 0; size_i < MAX_TUPLE_SIZE; ++size_i)
1191 for (unsigned int suffix_i = 0; suffix_i < NUM_TYPE_SUFFIXES; ++suffix_i)
1192 {
1193 vector_type_index type_i = type_suffixes[suffix_i].vector_type;
1194 tree type = acle_vector_types[size_i][type_i];
1195 if (type && matches_type_p (type, actual))
1196 {
1197 if (size_i + 1 == num_vectors)
1198 return type_suffix_index (suffix_i);
1199
1200 if (num_vectors == 1)
1201 error_at (location, "passing %qT to argument %d of %qE, which"
1202 " expects a single MVE vector rather than a tuple",
1203 actual, argno + 1, fndecl);
1204 else if (size_i == 0 && type_i != VECTOR_TYPE_mve_pred16_t)
1205 /* num_vectors is always != 1, so the singular isn't needed. */
1206 error_n (location, num_vectors, "%qT%d%qE%d",
1207 "passing single vector %qT to argument %d"
1208 " of %qE, which expects a tuple of %d vectors",
1209 actual, argno + 1, fndecl, num_vectors);
1210 else
1211 /* num_vectors is always != 1, so the singular isn't needed. */
1212 error_n (location, num_vectors, "%qT%d%qE%d",
1213 "passing %qT to argument %d of %qE, which"
1214 " expects a tuple of %d vectors", actual, argno + 1,
1215 fndecl, num_vectors);
1216 return NUM_TYPE_SUFFIXES;
1217 }
1218 }
1219
1220 if (num_vectors == 1)
1221 error_at (location, "passing %qT to argument %d of %qE, which"
1222 " expects an MVE vector type", actual, argno + 1, fndecl);
1223 else
1224 error_at (location, "passing %qT to argument %d of %qE, which"
1225 " expects an MVE tuple type", actual, argno + 1, fndecl);
1226 return NUM_TYPE_SUFFIXES;
1227 }
1228
1229 /* Require argument ARGNO to have some form of vector type. Return the
1230 associated type suffix on success, using TYPE_SUFFIX_b for predicates.
1231 Report an error and return NUM_TYPE_SUFFIXES on failure. */
1232 type_suffix_index
1233 function_resolver::infer_vector_type (unsigned int argno)
1234 {
1235 return infer_vector_or_tuple_type (argno, 1);
1236 }
1237
1238 /* Require argument ARGNO to be a vector or scalar argument. Return true
1239 if it is, otherwise report an appropriate error. */
1240 bool
1241 function_resolver::require_vector_or_scalar_type (unsigned int argno)
1242 {
1243 tree actual = get_argument_type (argno);
1244 if (actual == error_mark_node)
1245 return false;
1246
1247 if (!scalar_argument_p (argno) && !VECTOR_TYPE_P (actual))
1248 {
1249 error_at (location, "passing %qT to argument %d of %qE, which"
1250 " expects a vector or scalar type", actual, argno + 1, fndecl);
1251 return false;
1252 }
1253
1254 return true;
1255 }
1256
1257 /* Require argument ARGNO to have vector type TYPE, in cases where this
1258 requirement holds for all uses of the function. Return true if the
1259 argument has the right form, otherwise report an appropriate error. */
1260 bool
1261 function_resolver::require_vector_type (unsigned int argno,
1262 vector_type_index type)
1263 {
1264 tree expected = acle_vector_types[0][type];
1265 tree actual = get_argument_type (argno);
1266 if (actual == error_mark_node)
1267 return false;
1268
1269 if (!matches_type_p (expected, actual))
1270 {
1271 error_at (location, "passing %qT to argument %d of %qE, which"
1272 " expects %qT", actual, argno + 1, fndecl, expected);
1273 return false;
1274 }
1275 return true;
1276 }
1277
1278 /* Like require_vector_type, but TYPE is inferred from previous arguments
1279 rather than being a fixed part of the function signature. This changes
1280 the nature of the error messages. */
1281 bool
1282 function_resolver::require_matching_vector_type (unsigned int argno,
1283 type_suffix_index type)
1284 {
1285 type_suffix_index new_type = infer_vector_type (argno);
1286 if (new_type == NUM_TYPE_SUFFIXES)
1287 return false;
1288
1289 if (type != new_type)
1290 {
1291 error_at (location, "passing %qT to argument %d of %qE, but"
1292 " previous arguments had type %qT",
1293 get_vector_type (new_type), argno + 1, fndecl,
1294 get_vector_type (type));
1295 return false;
1296 }
1297 return true;
1298 }
1299
1300 /* Require argument ARGNO to be a vector type with the following properties:
1301
1302 - the type class must be the same as FIRST_TYPE's if EXPECTED_TCLASS
1303 is SAME_TYPE_CLASS, otherwise it must be EXPECTED_TCLASS itself.
1304
1305 - the element size must be:
1306
1307 - the same as FIRST_TYPE's if EXPECTED_BITS == SAME_SIZE
1308 - half of FIRST_TYPE's if EXPECTED_BITS == HALF_SIZE
1309 - a quarter of FIRST_TYPE's if EXPECTED_BITS == QUARTER_SIZE
1310 - EXPECTED_BITS itself otherwise
1311
1312 Return true if the argument has the required type, otherwise report
1313 an appropriate error.
1314
1315 FIRST_ARGNO is the first argument that is known to have type FIRST_TYPE.
1316 Usually it comes before ARGNO, but sometimes it is more natural to resolve
1317 arguments out of order.
1318
1319 If the required properties depend on FIRST_TYPE then both FIRST_ARGNO and
1320 ARGNO contribute to the resolution process. If the required properties
1321 are fixed, only FIRST_ARGNO contributes to the resolution process.
1322
1323 This function is a bit of a Swiss army knife. The complication comes
1324 from trying to give good error messages when FIRST_ARGNO and ARGNO are
1325 inconsistent, since either of them might be wrong. */
1326 bool function_resolver::
1327 require_derived_vector_type (unsigned int argno,
1328 unsigned int first_argno,
1329 type_suffix_index first_type,
1330 type_class_index expected_tclass,
1331 unsigned int expected_bits)
1332 {
1333 /* If the type needs to match FIRST_ARGNO exactly, use the preferred
1334 error message for that case. The VECTOR_TYPE_P test excludes tuple
1335 types, which we handle below instead. */
1336 bool both_vectors_p = VECTOR_TYPE_P (get_argument_type (first_argno));
1337 if (both_vectors_p
1338 && expected_tclass == SAME_TYPE_CLASS
1339 && expected_bits == SAME_SIZE)
1340 {
1341 /* There's no need to resolve this case out of order. */
1342 gcc_assert (argno > first_argno);
1343 return require_matching_vector_type (argno, first_type);
1344 }
1345
1346 /* Use FIRST_TYPE to get the expected type class and element size. */
1347 type_class_index orig_expected_tclass = expected_tclass;
1348 if (expected_tclass == NUM_TYPE_CLASSES)
1349 expected_tclass = type_suffixes[first_type].tclass;
1350
1351 unsigned int orig_expected_bits = expected_bits;
1352 if (expected_bits == SAME_SIZE)
1353 expected_bits = type_suffixes[first_type].element_bits;
1354 else if (expected_bits == HALF_SIZE)
1355 expected_bits = type_suffixes[first_type].element_bits / 2;
1356 else if (expected_bits == QUARTER_SIZE)
1357 expected_bits = type_suffixes[first_type].element_bits / 4;
1358
1359 /* If the expected type doesn't depend on FIRST_TYPE at all,
1360 just check for the fixed choice of vector type. */
1361 if (expected_tclass == orig_expected_tclass
1362 && expected_bits == orig_expected_bits)
1363 {
1364 const type_suffix_info &expected_suffix
1365 = type_suffixes[find_type_suffix (expected_tclass, expected_bits)];
1366 return require_vector_type (argno, expected_suffix.vector_type);
1367 }
1368
1369 /* Require the argument to be some form of MVE vector type,
1370 without being specific about the type of vector we want. */
1371 type_suffix_index actual_type = infer_vector_type (argno);
1372 if (actual_type == NUM_TYPE_SUFFIXES)
1373 return false;
1374
1375 /* Exit now if we got the right type. */
1376 bool tclass_ok_p = (type_suffixes[actual_type].tclass == expected_tclass);
1377 bool size_ok_p = (type_suffixes[actual_type].element_bits == expected_bits);
1378 if (tclass_ok_p && size_ok_p)
1379 return true;
1380
1381 /* First look for cases in which the actual type contravenes a fixed
1382 size requirement, without having to refer to FIRST_TYPE. */
1383 if (!size_ok_p && expected_bits == orig_expected_bits)
1384 {
1385 error_at (location, "passing %qT to argument %d of %qE, which"
1386 " expects a vector of %d-bit elements",
1387 get_vector_type (actual_type), argno + 1, fndecl,
1388 expected_bits);
1389 return false;
1390 }
1391
1392 /* Likewise for a fixed type class requirement. This is only ever
1393 needed for signed and unsigned types, so don't create unnecessary
1394 translation work for other type classes. */
1395 if (!tclass_ok_p && orig_expected_tclass == TYPE_signed)
1396 {
1397 error_at (location, "passing %qT to argument %d of %qE, which"
1398 " expects a vector of signed integers",
1399 get_vector_type (actual_type), argno + 1, fndecl);
1400 return false;
1401 }
1402 if (!tclass_ok_p && orig_expected_tclass == TYPE_unsigned)
1403 {
1404 error_at (location, "passing %qT to argument %d of %qE, which"
1405 " expects a vector of unsigned integers",
1406 get_vector_type (actual_type), argno + 1, fndecl);
1407 return false;
1408 }
1409
1410 /* Make sure that FIRST_TYPE itself is sensible before using it
1411 as a basis for an error message. */
1412 if (resolve_to (mode_suffix_id, first_type) == error_mark_node)
1413 return false;
1414
1415 /* If the arguments have consistent type classes, but a link between
1416 the sizes has been broken, try to describe the error in those terms. */
1417 if (both_vectors_p && tclass_ok_p && orig_expected_bits == SAME_SIZE)
1418 {
1419 if (argno < first_argno)
1420 {
1421 std::swap (argno, first_argno);
1422 std::swap (actual_type, first_type);
1423 }
1424 error_at (location, "arguments %d and %d of %qE must have the"
1425 " same element size, but the values passed here have type"
1426 " %qT and %qT respectively", first_argno + 1, argno + 1,
1427 fndecl, get_vector_type (first_type),
1428 get_vector_type (actual_type));
1429 return false;
1430 }
1431
1432 /* Likewise in reverse: look for cases in which the sizes are consistent
1433 but a link between the type classes has been broken. */
1434 if (both_vectors_p
1435 && size_ok_p
1436 && orig_expected_tclass == SAME_TYPE_CLASS
1437 && type_suffixes[first_type].integer_p
1438 && type_suffixes[actual_type].integer_p)
1439 {
1440 if (argno < first_argno)
1441 {
1442 std::swap (argno, first_argno);
1443 std::swap (actual_type, first_type);
1444 }
1445 error_at (location, "arguments %d and %d of %qE must have the"
1446 " same signedness, but the values passed here have type"
1447 " %qT and %qT respectively", first_argno + 1, argno + 1,
1448 fndecl, get_vector_type (first_type),
1449 get_vector_type (actual_type));
1450 return false;
1451 }
1452
1453 /* The two arguments are wildly inconsistent. */
1454 type_suffix_index expected_type
1455 = find_type_suffix (expected_tclass, expected_bits);
1456 error_at (location, "passing %qT instead of the expected %qT to argument"
1457 " %d of %qE, after passing %qT to argument %d",
1458 get_vector_type (actual_type), get_vector_type (expected_type),
1459 argno + 1, fndecl, get_argument_type (first_argno),
1460 first_argno + 1);
1461 return false;
1462 }
1463
1464 /* Require argument ARGNO to be a (possibly variable) scalar, expecting it
1465 to have the following properties:
1466
1467 - the type class must be the same as for type suffix 0 if EXPECTED_TCLASS
1468 is SAME_TYPE_CLASS, otherwise it must be EXPECTED_TCLASS itself.
1469
1470 - the element size must be the same as for type suffix 0 if EXPECTED_BITS
1471 is SAME_TYPE_SIZE, otherwise it must be EXPECTED_BITS itself.
1472
1473 Return true if the argument is valid, otherwise report an appropriate error.
1474
1475 Note that we don't check whether the scalar type actually has the required
1476 properties, since that's subject to implicit promotions and conversions.
1477 Instead we just use the expected properties to tune the error message. */
1478 bool function_resolver::
1479 require_derived_scalar_type (unsigned int argno,
1480 type_class_index expected_tclass,
1481 unsigned int expected_bits)
1482 {
1483 gcc_assert (expected_tclass == SAME_TYPE_CLASS
1484 || expected_tclass == TYPE_signed
1485 || expected_tclass == TYPE_unsigned);
1486
1487 /* If the expected type doesn't depend on the type suffix at all,
1488 just check for the fixed choice of scalar type. */
1489 if (expected_tclass != SAME_TYPE_CLASS && expected_bits != SAME_SIZE)
1490 {
1491 type_suffix_index expected_type
1492 = find_type_suffix (expected_tclass, expected_bits);
1493 return require_scalar_type (argno, get_scalar_type_name (expected_type));
1494 }
1495
1496 if (scalar_argument_p (argno))
1497 return true;
1498
1499 if (expected_tclass == SAME_TYPE_CLASS)
1500 /* It doesn't really matter whether the element is expected to be
1501 the same size as type suffix 0. */
1502 error_at (location, "passing %qT to argument %d of %qE, which"
1503 " expects a scalar element", get_argument_type (argno),
1504 argno + 1, fndecl);
1505 else
1506 /* It doesn't seem useful to distinguish between signed and unsigned
1507 scalars here. */
1508 error_at (location, "passing %qT to argument %d of %qE, which"
1509 " expects a scalar integer", get_argument_type (argno),
1510 argno + 1, fndecl);
1511 return false;
1512 }
1513
1514 /* Require argument ARGNO to be suitable for an integer constant expression.
1515 Return true if it is, otherwise report an appropriate error.
1516
1517 function_checker checks whether the argument is actually constant and
1518 has a suitable range. The reason for distinguishing immediate arguments
1519 here is because it provides more consistent error messages than
1520 require_scalar_type would. */
1521 bool
1522 function_resolver::require_integer_immediate (unsigned int argno)
1523 {
1524 if (!scalar_argument_p (argno))
1525 {
1526 report_non_ice (location, fndecl, argno);
1527 return false;
1528 }
1529 return true;
1530 }
1531
1532 /* Require argument ARGNO to be a (possibly variable) scalar, using EXPECTED
1533 as the name of its expected type. Return true if the argument has the
1534 right form, otherwise report an appropriate error. */
1535 bool
1536 function_resolver::require_scalar_type (unsigned int argno,
1537 const char *expected)
1538 {
1539 if (!scalar_argument_p (argno))
1540 {
1541 error_at (location, "passing %qT to argument %d of %qE, which"
1542 " expects %qs", get_argument_type (argno), argno + 1,
1543 fndecl, expected);
1544 return false;
1545 }
1546 return true;
1547 }
1548
1549 /* Require argument ARGNO to be some form of pointer, without being specific
1550 about its target type. Return true if the argument has the right form,
1551 otherwise report an appropriate error. */
1552 bool
1553 function_resolver::require_pointer_type (unsigned int argno)
1554 {
1555 if (!scalar_argument_p (argno))
1556 {
1557 error_at (location, "passing %qT to argument %d of %qE, which"
1558 " expects a scalar pointer", get_argument_type (argno),
1559 argno + 1, fndecl);
1560 return false;
1561 }
1562 return true;
1563 }
1564
1565 /* Require the function to have exactly EXPECTED arguments. Return true
1566 if it does, otherwise report an appropriate error. */
1567 bool
1568 function_resolver::check_num_arguments (unsigned int expected)
1569 {
1570 if (m_arglist.length () < expected)
1571 error_at (location, "too few arguments to function %qE", fndecl);
1572 else if (m_arglist.length () > expected)
1573 error_at (location, "too many arguments to function %qE", fndecl);
1574 return m_arglist.length () == expected;
1575 }
1576
1577 /* If the function is predicated, check that the last argument is a
1578 suitable predicate. Also check that there are NOPS further
1579 arguments before any predicate, but don't check what they are.
1580
1581 Return true on success, otherwise report a suitable error.
1582 When returning true:
1583
1584 - set I to the number of the last unchecked argument.
1585 - set NARGS to the total number of arguments. */
1586 bool
1587 function_resolver::check_gp_argument (unsigned int nops,
1588 unsigned int &i, unsigned int &nargs)
1589 {
1590 i = nops - 1;
1591 if (pred != PRED_none)
1592 {
1593 switch (pred)
1594 {
1595 case PRED_m:
1596 /* Add first inactive argument if needed, and final predicate. */
1597 if (has_inactive_argument ())
1598 nargs = nops + 2;
1599 else
1600 nargs = nops + 1;
1601 break;
1602
1603 case PRED_p:
1604 case PRED_x:
1605 /* Add final predicate. */
1606 nargs = nops + 1;
1607 break;
1608
1609 default:
1610 gcc_unreachable ();
1611 }
1612
1613 if (!check_num_arguments (nargs)
1614 || !require_vector_type (nargs - 1, VECTOR_TYPE_mve_pred16_t))
1615 return false;
1616
1617 i = nargs - 2;
1618 }
1619 else
1620 {
1621 nargs = nops;
1622 if (!check_num_arguments (nargs))
1623 return false;
1624 }
1625
1626 return true;
1627 }
1628
1629 /* Finish resolving a function whose final argument can be a vector
1630 or a scalar, with the function having an implicit "_n" suffix
1631 in the latter case. This "_n" form might only exist for certain
1632 type suffixes.
1633
1634 ARGNO is the index of the final argument. The inferred type suffix
1635 was obtained from argument FIRST_ARGNO, which has type FIRST_TYPE.
1636 EXPECTED_TCLASS and EXPECTED_BITS describe the expected properties
1637 of the final vector or scalar argument, in the same way as for
1638 require_derived_vector_type. INFERRED_TYPE is the inferred type
1639 suffix itself, or NUM_TYPE_SUFFIXES if it's the same as FIRST_TYPE.
1640
1641 Return the function decl of the resolved function on success,
1642 otherwise report a suitable error and return error_mark_node. */
1643 tree function_resolver::
1644 finish_opt_n_resolution (unsigned int argno, unsigned int first_argno,
1645 type_suffix_index first_type,
1646 type_class_index expected_tclass,
1647 unsigned int expected_bits,
1648 type_suffix_index inferred_type)
1649 {
1650 if (inferred_type == NUM_TYPE_SUFFIXES)
1651 inferred_type = first_type;
1652 mode_suffix_index scalar_mode = MODE_n;
1653 if (mode_suffix_id == MODE_r)
1654 scalar_mode = MODE_r;
1655 tree scalar_form = lookup_form (scalar_mode, inferred_type);
1656
1657 /* Allow the final argument to be scalar, if an _n form exists. */
1658 if (scalar_argument_p (argno))
1659 {
1660 if (scalar_form)
1661 return scalar_form;
1662
1663 /* Check the vector form normally. If that succeeds, raise an
1664 error about having no corresponding _n form. */
1665 tree res = resolve_to (mode_suffix_id, inferred_type);
1666 if (res != error_mark_node)
1667 error_at (location, "passing %qT to argument %d of %qE, but its"
1668 " %qT form does not accept scalars",
1669 get_argument_type (argno), argno + 1, fndecl,
1670 get_vector_type (first_type));
1671 return error_mark_node;
1672 }
1673
1674 /* If an _n form does exist, provide a more accurate message than
1675 require_derived_vector_type would for arguments that are neither
1676 vectors nor scalars. */
1677 if (scalar_form && !require_vector_or_scalar_type (argno))
1678 return error_mark_node;
1679
1680 /* Check for the correct vector type. */
1681 if (!require_derived_vector_type (argno, first_argno, first_type,
1682 expected_tclass, expected_bits))
1683 return error_mark_node;
1684
1685 return resolve_to (mode_suffix_id, inferred_type);
1686 }
1687
1688 /* Resolve a (possibly predicated) unary function. If the function uses
1689 merge predication or if TREAT_AS_MERGE_P is true, there is an extra
1690 vector argument before the governing predicate that specifies the
1691 values of inactive elements. This argument has the following
1692 properties:
1693
1694 - the type class must be the same as for active elements if MERGE_TCLASS
1695 is SAME_TYPE_CLASS, otherwise it must be MERGE_TCLASS itself.
1696
1697 - the element size must be the same as for active elements if MERGE_BITS
1698 is SAME_TYPE_SIZE, otherwise it must be MERGE_BITS itself.
1699
1700 Return the function decl of the resolved function on success,
1701 otherwise report a suitable error and return error_mark_node. */
1702 tree
1703 function_resolver::resolve_unary (type_class_index merge_tclass,
1704 unsigned int merge_bits,
1705 bool treat_as_merge_p)
1706 {
1707 type_suffix_index type;
1708 if (pred == PRED_m || treat_as_merge_p)
1709 {
1710 if (!check_num_arguments (3))
1711 return error_mark_node;
1712 if (merge_tclass == SAME_TYPE_CLASS && merge_bits == SAME_SIZE)
1713 {
1714 /* The inactive elements are the same as the active elements,
1715 so we can use normal left-to-right resolution. */
1716 if ((type = infer_vector_type (0)) == NUM_TYPE_SUFFIXES
1717 /* Predicates are the last argument. */
1718 || !require_vector_type (2 , VECTOR_TYPE_mve_pred16_t)
1719 || !require_matching_vector_type (1 , type))
1720 return error_mark_node;
1721 }
1722 else
1723 {
1724 /* The inactive element type is a function of the active one,
1725 so resolve the active one first. */
1726 if (!require_vector_type (1, VECTOR_TYPE_mve_pred16_t)
1727 || (type = infer_vector_type (2)) == NUM_TYPE_SUFFIXES
1728 || !require_derived_vector_type (0, 2, type, merge_tclass,
1729 merge_bits))
1730 return error_mark_node;
1731 }
1732 }
1733 else
1734 {
1735 /* We just need to check the predicate (if any) and the single
1736 vector argument. */
1737 unsigned int i, nargs;
1738 if (!check_gp_argument (1, i, nargs)
1739 || (type = infer_vector_type (i)) == NUM_TYPE_SUFFIXES)
1740 return error_mark_node;
1741 }
1742
1743 /* Handle convert-like functions in which the first type suffix is
1744 explicit. */
1745 if (type_suffix_ids[0] != NUM_TYPE_SUFFIXES)
1746 return resolve_to (mode_suffix_id, type_suffix_ids[0], type);
1747
1748 return resolve_to (mode_suffix_id, type);
1749 }
1750
1751 /* Resolve a (possibly predicated) unary function taking a scalar
1752 argument (_n suffix). If the function uses merge predication,
1753 there is an extra vector argument in the first position, and the
1754 final governing predicate that specifies the values of inactive
1755 elements.
1756
1757 Return the function decl of the resolved function on success,
1758 otherwise report a suitable error and return error_mark_node. */
1759 tree
1760 function_resolver::resolve_unary_n ()
1761 {
1762 type_suffix_index type;
1763
1764 /* Currently only support overrides for _m (vdupq). */
1765 if (pred != PRED_m)
1766 return error_mark_node;
1767
1768 if (pred == PRED_m)
1769 {
1770 if (!check_num_arguments (3))
1771 return error_mark_node;
1772
1773 /* The inactive elements are the same as the active elements,
1774 so we can use normal left-to-right resolution. */
1775 if ((type = infer_vector_type (0)) == NUM_TYPE_SUFFIXES
1776 /* Predicates are the last argument. */
1777 || !require_vector_type (2 , VECTOR_TYPE_mve_pred16_t))
1778 return error_mark_node;
1779 }
1780
1781 /* Make sure the argument is scalar. */
1782 tree scalar_form = lookup_form (MODE_n, type);
1783
1784 if (scalar_argument_p (1) && scalar_form)
1785 return scalar_form;
1786
1787 return error_mark_node;
1788 }
1789
1790 /* Resolve a (possibly predicated) function that takes NOPS like-typed
1791 vector arguments followed by NIMM integer immediates. Return the
1792 function decl of the resolved function on success, otherwise report
1793 a suitable error and return error_mark_node. */
1794 tree
1795 function_resolver::resolve_uniform (unsigned int nops, unsigned int nimm)
1796 {
1797 unsigned int i, nargs;
1798 type_suffix_index type;
1799 if (!check_gp_argument (nops + nimm, i, nargs)
1800 || (type = infer_vector_type (0 )) == NUM_TYPE_SUFFIXES)
1801 return error_mark_node;
1802
1803 unsigned int last_arg = i + 1 - nimm;
1804 for (i = 0; i < last_arg; i++)
1805 if (!require_matching_vector_type (i, type))
1806 return error_mark_node;
1807
1808 for (i = last_arg; i < nargs; ++i)
1809 if (!require_integer_immediate (i))
1810 return error_mark_node;
1811
1812 return resolve_to (mode_suffix_id, type);
1813 }
1814
1815 /* Resolve a (possibly predicated) function that offers a choice between
1816 taking:
1817
1818 - NOPS like-typed vector arguments or
1819 - NOPS - 1 like-typed vector arguments followed by a scalar argument
1820
1821 Return the function decl of the resolved function on success,
1822 otherwise report a suitable error and return error_mark_node. */
1823 tree
1824 function_resolver::resolve_uniform_opt_n (unsigned int nops)
1825 {
1826 unsigned int i, nargs;
1827 type_suffix_index type;
1828 if (!check_gp_argument (nops, i, nargs)
1829 /* Unary operators should use resolve_unary, so using i - 1 is
1830 safe. */
1831 || (type = infer_vector_type (i - 1)) == NUM_TYPE_SUFFIXES)
1832 return error_mark_node;
1833
1834 /* Skip last argument, may be scalar. */
1835 unsigned int last_arg = i;
1836 for (i = 0; i < last_arg; i++)
1837 if (!require_matching_vector_type (i, type))
1838 return error_mark_node;
1839
1840 return finish_opt_n_resolution (last_arg, 0, type);
1841 }
1842
1843 /* If the call is erroneous, report an appropriate error and return
1844 error_mark_node. Otherwise, if the function is overloaded, return
1845 the decl of the non-overloaded function. Return NULL_TREE otherwise,
1846 indicating that the call should be processed in the normal way. */
1847 tree
1848 function_resolver::resolve ()
1849 {
1850 return shape->resolve (*this);
1851 }
1852
1853 function_checker::function_checker (location_t location,
1854 const function_instance &instance,
1855 tree fndecl, tree fntype,
1856 unsigned int nargs, tree *args)
1857 : function_call_info (location, instance, fndecl),
1858 m_fntype (fntype), m_nargs (nargs), m_args (args)
1859 {
1860 if (instance.has_inactive_argument ())
1861 m_base_arg = 1;
1862 else
1863 m_base_arg = 0;
1864 }
1865
1866 /* Return true if argument ARGNO exists. which it might not for
1867 erroneous calls. It is safe to wave through checks if this
1868 function returns false. */
1869 bool
1870 function_checker::argument_exists_p (unsigned int argno)
1871 {
1872 gcc_assert (argno < (unsigned int) type_num_arguments (m_fntype));
1873 return argno < m_nargs;
1874 }
1875
1876 /* Check that argument ARGNO is an integer constant expression and
1877 store its value in VALUE_OUT if so. The caller should first
1878 check that argument ARGNO exists. */
1879 bool
1880 function_checker::require_immediate (unsigned int argno,
1881 HOST_WIDE_INT &value_out)
1882 {
1883 gcc_assert (argno < m_nargs);
1884 tree arg = m_args[argno];
1885
1886 /* The type and range are unsigned, so read the argument as an
1887 unsigned rather than signed HWI. */
1888 if (!tree_fits_uhwi_p (arg))
1889 {
1890 report_non_ice (location, fndecl, argno);
1891 return false;
1892 }
1893
1894 /* ...but treat VALUE_OUT as signed for error reporting, since printing
1895 -1 is more user-friendly than the maximum uint64_t value. */
1896 value_out = tree_to_uhwi (arg);
1897 return true;
1898 }
1899
1900 /* Check that argument REL_ARGNO is an integer constant expression that has
1901 a valid value for enumeration type TYPE. REL_ARGNO counts from the end
1902 of the predication arguments. */
1903 bool
1904 function_checker::require_immediate_enum (unsigned int rel_argno, tree type)
1905 {
1906 unsigned int argno = m_base_arg + rel_argno;
1907 if (!argument_exists_p (argno))
1908 return true;
1909
1910 HOST_WIDE_INT actual;
1911 if (!require_immediate (argno, actual))
1912 return false;
1913
1914 for (tree entry = TYPE_VALUES (type); entry; entry = TREE_CHAIN (entry))
1915 {
1916 /* The value is an INTEGER_CST for C and a CONST_DECL wrapper
1917 around an INTEGER_CST for C++. */
1918 tree value = TREE_VALUE (entry);
1919 if (TREE_CODE (value) == CONST_DECL)
1920 value = DECL_INITIAL (value);
1921 if (wi::to_widest (value) == actual)
1922 return true;
1923 }
1924
1925 report_not_enum (location, fndecl, argno, actual, type);
1926 return false;
1927 }
1928
1929 /* Check that argument REL_ARGNO is an integer constant expression in the
1930 range [MIN, MAX]. REL_ARGNO counts from the end of the predication
1931 arguments. */
1932 bool
1933 function_checker::require_immediate_range (unsigned int rel_argno,
1934 HOST_WIDE_INT min,
1935 HOST_WIDE_INT max)
1936 {
1937 unsigned int argno = m_base_arg + rel_argno;
1938 if (!argument_exists_p (argno))
1939 return true;
1940
1941 /* Required because of the tree_to_uhwi -> HOST_WIDE_INT conversion
1942 in require_immediate. */
1943 gcc_assert (min >= 0 && min <= max);
1944 HOST_WIDE_INT actual;
1945 if (!require_immediate (argno, actual))
1946 return false;
1947
1948 if (!IN_RANGE (actual, min, max))
1949 {
1950 report_out_of_range (location, fndecl, argno, actual, min, max);
1951 return false;
1952 }
1953
1954 return true;
1955 }
1956
1957 /* Perform semantic checks on the call. Return true if the call is valid,
1958 otherwise report a suitable error. */
1959 bool
1960 function_checker::check ()
1961 {
1962 function_args_iterator iter;
1963 tree type;
1964 unsigned int i = 0;
1965 FOREACH_FUNCTION_ARGS (m_fntype, type, iter)
1966 {
1967 if (type == void_type_node || i >= m_nargs)
1968 break;
1969
1970 if (i >= m_base_arg
1971 && TREE_CODE (type) == ENUMERAL_TYPE
1972 && !require_immediate_enum (i - m_base_arg, type))
1973 return false;
1974
1975 i += 1;
1976 }
1977
1978 return shape->check (*this);
1979 }
1980
1981 gimple_folder::gimple_folder (const function_instance &instance, tree fndecl,
1982 gcall *call_in)
1983 : function_call_info (gimple_location (call_in), instance, fndecl),
1984 call (call_in), lhs (gimple_call_lhs (call_in))
1985 {
1986 }
1987
1988 /* Try to fold the call. Return the new statement on success and null
1989 on failure. */
1990 gimple *
1991 gimple_folder::fold ()
1992 {
1993 /* Don't fold anything when MVE is disabled; emit an error during
1994 expansion instead. */
1995 if (!TARGET_HAVE_MVE)
1996 return NULL;
1997
1998 /* Punt if the function has a return type and no result location is
1999 provided. The attributes should allow target-independent code to
2000 remove the calls if appropriate. */
2001 if (!lhs && TREE_TYPE (gimple_call_fntype (call)) != void_type_node)
2002 return NULL;
2003
2004 return base->fold (*this);
2005 }
2006
2007 function_expander::function_expander (const function_instance &instance,
2008 tree fndecl, tree call_expr_in,
2009 rtx possible_target_in)
2010 : function_call_info (EXPR_LOCATION (call_expr_in), instance, fndecl),
2011 call_expr (call_expr_in), possible_target (possible_target_in)
2012 {
2013 }
2014
2015 /* Return the handler of direct optab OP for type suffix SUFFIX_I. */
2016 insn_code
2017 function_expander::direct_optab_handler (optab op, unsigned int suffix_i)
2018 {
2019 return ::direct_optab_handler (op, vector_mode (suffix_i));
2020 }
2021
2022 /* Return the base address for a contiguous load or store
2023 function. */
2024 rtx
2025 function_expander::get_contiguous_base ()
2026 {
2027 return args[0];
2028 }
2029
2030 /* For a function that does the equivalent of:
2031
2032 OUTPUT = COND ? FN (INPUTS) : FALLBACK;
2033
2034 return the value of FALLBACK.
2035
2036 MODE is the mode of OUTPUT.
2037 MERGE_ARGNO is the argument that provides FALLBACK for _m functions,
2038 or DEFAULT_MERGE_ARGNO if we should apply the usual rules.
2039
2040 ARGNO is the caller's index into args. If the returned value is
2041 argument 0 (as for unary _m operations), increment ARGNO past the
2042 returned argument. */
2043 rtx
2044 function_expander::get_fallback_value (machine_mode mode,
2045 unsigned int merge_argno,
2046 unsigned int &argno)
2047 {
2048 if (pred == PRED_z)
2049 return CONST0_RTX (mode);
2050
2051 gcc_assert (pred == PRED_m || pred == PRED_x);
2052
2053 if (merge_argno == 0)
2054 return args[argno++];
2055
2056 return args[merge_argno];
2057 }
2058
2059 /* Return a REG rtx that can be used for the result of the function,
2060 using the preferred target if suitable. */
2061 rtx
2062 function_expander::get_reg_target ()
2063 {
2064 machine_mode target_mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl)));
2065 if (!possible_target || GET_MODE (possible_target) != target_mode)
2066 possible_target = gen_reg_rtx (target_mode);
2067 return possible_target;
2068 }
2069
2070 /* Add an output operand to the instruction we're building, which has
2071 code ICODE. Bind the output to the preferred target rtx if possible. */
2072 void
2073 function_expander::add_output_operand (insn_code icode)
2074 {
2075 unsigned int opno = m_ops.length ();
2076 machine_mode mode = insn_data[icode].operand[opno].mode;
2077 m_ops.safe_grow (opno + 1, true);
2078 create_output_operand (&m_ops.last (), possible_target, mode);
2079 }
2080
2081 /* Add an input operand to the instruction we're building, which has
2082 code ICODE. Calculate the value of the operand as follows:
2083
2084 - If the operand is a predicate, coerce X to have the
2085 mode that the instruction expects.
2086
2087 - Otherwise use X directly. The expand machinery checks that X has
2088 the right mode for the instruction. */
2089 void
2090 function_expander::add_input_operand (insn_code icode, rtx x)
2091 {
2092 unsigned int opno = m_ops.length ();
2093 const insn_operand_data &operand = insn_data[icode].operand[opno];
2094 machine_mode mode = operand.mode;
2095 if (mode == VOIDmode)
2096 {
2097 /* The only allowable use of VOIDmode is the wildcard
2098 arm_any_register_operand, which is used to avoid
2099 combinatorial explosion in the reinterpret patterns. */
2100 gcc_assert (operand.predicate == arm_any_register_operand);
2101 mode = GET_MODE (x);
2102 }
2103 else if (VALID_MVE_PRED_MODE (mode))
2104 x = gen_lowpart (mode, x);
2105
2106 m_ops.safe_grow (m_ops.length () + 1, true);
2107 create_input_operand (&m_ops.last (), x, mode);
2108 }
2109
2110 /* Add an integer operand with value X to the instruction. */
2111 void
2112 function_expander::add_integer_operand (HOST_WIDE_INT x)
2113 {
2114 m_ops.safe_grow (m_ops.length () + 1, true);
2115 create_integer_operand (&m_ops.last (), x);
2116 }
2117
2118 /* Add a memory operand with mode MODE and address ADDR. */
2119 void
2120 function_expander::add_mem_operand (machine_mode mode, rtx addr)
2121 {
2122 gcc_assert (VECTOR_MODE_P (mode));
2123 rtx mem = gen_rtx_MEM (mode, memory_address (mode, addr));
2124 /* The memory is only guaranteed to be element-aligned. */
2125 set_mem_align (mem, GET_MODE_ALIGNMENT (GET_MODE_INNER (mode)));
2126 add_fixed_operand (mem);
2127 }
2128
2129 /* Add an operand that must be X. The only way of legitimizing an
2130 invalid X is to reload the address of a MEM. */
2131 void
2132 function_expander::add_fixed_operand (rtx x)
2133 {
2134 m_ops.safe_grow (m_ops.length () + 1, true);
2135 create_fixed_operand (&m_ops.last (), x);
2136 }
2137
2138 /* Generate instruction ICODE, given that its operands have already
2139 been added to M_OPS. Return the value of the first operand. */
2140 rtx
2141 function_expander::generate_insn (insn_code icode)
2142 {
2143 expand_insn (icode, m_ops.length (), m_ops.address ());
2144 return function_returns_void_p () ? const0_rtx : m_ops[0].value;
2145 }
2146
2147 /* Implement the call using instruction ICODE, with a 1:1 mapping between
2148 arguments and input operands. */
2149 rtx
2150 function_expander::use_exact_insn (insn_code icode)
2151 {
2152 unsigned int nops = insn_data[icode].n_operands;
2153 if (!function_returns_void_p ())
2154 {
2155 add_output_operand (icode);
2156 nops -= 1;
2157 }
2158 for (unsigned int i = 0; i < nops; ++i)
2159 add_input_operand (icode, args[i]);
2160 return generate_insn (icode);
2161 }
2162
2163 /* Implement the call using instruction ICODE, which does not use a
2164 predicate. */
2165 rtx
2166 function_expander::use_unpred_insn (insn_code icode)
2167 {
2168 gcc_assert (pred == PRED_none);
2169 /* Discount the output operand. */
2170 unsigned int nops = insn_data[icode].n_operands - 1;
2171 unsigned int i = 0;
2172
2173 add_output_operand (icode);
2174 for (; i < nops; ++i)
2175 add_input_operand (icode, args[i]);
2176
2177 return generate_insn (icode);
2178 }
2179
2180 /* Implement the call using instruction ICODE, which is a predicated
2181 operation that returns arbitrary values for inactive lanes. */
2182 rtx
2183 function_expander::use_pred_x_insn (insn_code icode)
2184 {
2185 gcc_assert (pred == PRED_x);
2186 unsigned int nops = args.length ();
2187
2188 add_output_operand (icode);
2189 /* Use first operand as arbitrary inactive input. */
2190 add_input_operand (icode, possible_target);
2191 emit_clobber (possible_target);
2192 /* Copy remaining arguments, including the final predicate. */
2193 for (unsigned int i = 0; i < nops; ++i)
2194 add_input_operand (icode, args[i]);
2195
2196 return generate_insn (icode);
2197 }
2198
2199 /* Implement the call using instruction ICODE, which does the equivalent of:
2200
2201 OUTPUT = COND ? FN (INPUTS) : FALLBACK;
2202
2203 The instruction operands are in the order above: OUTPUT, COND, INPUTS
2204 and FALLBACK. MERGE_ARGNO is the argument that provides FALLBACK for _m
2205 functions, or DEFAULT_MERGE_ARGNO if we should apply the usual rules. */
2206 rtx
2207 function_expander::use_cond_insn (insn_code icode, unsigned int merge_argno)
2208 {
2209 /* At present we never need to handle PRED_none, which would involve
2210 creating a new predicate rather than using one supplied by the user. */
2211 gcc_assert (pred != PRED_none);
2212 /* For MVE, we only handle PRED_m at present. */
2213 gcc_assert (pred == PRED_m);
2214
2215 /* Discount the output, predicate and fallback value. */
2216 unsigned int nops = insn_data[icode].n_operands - 3;
2217 machine_mode mode = insn_data[icode].operand[0].mode;
2218
2219 unsigned int opno = 0;
2220 rtx fallback_arg = NULL_RTX;
2221 fallback_arg = get_fallback_value (mode, merge_argno, opno);
2222 rtx pred_arg = args[nops + 1];
2223
2224 add_output_operand (icode);
2225 add_input_operand (icode, fallback_arg);
2226 for (unsigned int i = 0; i < nops; ++i)
2227 add_input_operand (icode, args[opno + i]);
2228 add_input_operand (icode, pred_arg);
2229 return generate_insn (icode);
2230 }
2231
2232 /* Implement the call using instruction ICODE, which loads memory operand 1
2233 into register operand 0. */
2234 rtx
2235 function_expander::use_contiguous_load_insn (insn_code icode)
2236 {
2237 machine_mode mem_mode = memory_vector_mode ();
2238
2239 add_output_operand (icode);
2240 add_mem_operand (mem_mode, get_contiguous_base ());
2241 return generate_insn (icode);
2242 }
2243
2244 /* Implement the call using instruction ICODE, which stores register operand 1
2245 into memory operand 0. */
2246 rtx
2247 function_expander::use_contiguous_store_insn (insn_code icode)
2248 {
2249 machine_mode mem_mode = memory_vector_mode ();
2250
2251 add_mem_operand (mem_mode, get_contiguous_base ());
2252 add_input_operand (icode, args[1]);
2253 return generate_insn (icode);
2254 }
2255
2256 /* Implement the call using a normal unpredicated optab for PRED_none.
2257
2258 <optab> corresponds to:
2259
2260 - CODE_FOR_SINT for signed integers
2261 - CODE_FOR_UINT for unsigned integers
2262 - CODE_FOR_FP for floating-point values */
2263 rtx
2264 function_expander::map_to_rtx_codes (rtx_code code_for_sint,
2265 rtx_code code_for_uint,
2266 rtx_code code_for_fp)
2267 {
2268 gcc_assert (pred == PRED_none);
2269 rtx_code code = type_suffix (0).integer_p ?
2270 (type_suffix (0).unsigned_p ? code_for_uint : code_for_sint)
2271 : code_for_fp;
2272 insn_code icode = direct_optab_handler (code_to_optab (code), 0);
2273 if (icode == CODE_FOR_nothing)
2274 gcc_unreachable ();
2275
2276 return use_unpred_insn (icode);
2277 }
2278
2279 /* Expand the call and return its lhs. */
2280 rtx
2281 function_expander::expand ()
2282 {
2283 unsigned int nargs = call_expr_nargs (call_expr);
2284 args.reserve (nargs);
2285 for (unsigned int i = 0; i < nargs; ++i)
2286 args.quick_push (expand_normal (CALL_EXPR_ARG (call_expr, i)));
2287
2288 return base->expand (*this);
2289 }
2290
2291 /* If we're implementing manual overloading, check whether the MVE
2292 function with subcode CODE is overloaded, and if so attempt to
2293 determine the corresponding non-overloaded function. The call
2294 occurs at location LOCATION and has the arguments given by ARGLIST.
2295
2296 If the call is erroneous, report an appropriate error and return
2297 error_mark_node. Otherwise, if the function is overloaded, return
2298 the decl of the non-overloaded function. Return NULL_TREE otherwise,
2299 indicating that the call should be processed in the normal way. */
2300 tree
2301 resolve_overloaded_builtin (location_t location, unsigned int code,
2302 vec<tree, va_gc> *arglist)
2303 {
2304 if (code >= vec_safe_length (registered_functions))
2305 return NULL_TREE;
2306
2307 registered_function &rfn = *(*registered_functions)[code];
2308 if (rfn.overloaded_p)
2309 return function_resolver (location, rfn.instance, rfn.decl,
2310 *arglist).resolve ();
2311 return NULL_TREE;
2312 }
2313
2314 /* Perform any semantic checks needed for a call to the MVE function
2315 with subcode CODE, such as testing for integer constant expressions.
2316 The call occurs at location LOCATION and has NARGS arguments,
2317 given by ARGS. FNDECL is the original function decl, before
2318 overload resolution.
2319
2320 Return true if the call is valid, otherwise report a suitable error. */
2321 bool
2322 check_builtin_call (location_t location, vec<location_t>, unsigned int code,
2323 tree fndecl, unsigned int nargs, tree *args)
2324 {
2325 const registered_function &rfn = *(*registered_functions)[code];
2326 if (!check_requires_float (location, rfn.decl, rfn.requires_float))
2327 return false;
2328
2329 return function_checker (location, rfn.instance, fndecl,
2330 TREE_TYPE (rfn.decl), nargs, args).check ();
2331 }
2332
2333 /* Attempt to fold STMT, given that it's a call to the MVE function
2334 with subcode CODE. Return the new statement on success and null
2335 on failure. Insert any other new statements at GSI. */
2336 gimple *
2337 gimple_fold_builtin (unsigned int code, gcall *stmt)
2338 {
2339 registered_function &rfn = *(*registered_functions)[code];
2340 return gimple_folder (rfn.instance, rfn.decl, stmt).fold ();
2341 }
2342
2343 /* Expand a call to the MVE function with subcode CODE. EXP is the call
2344 expression and TARGET is the preferred location for the result.
2345 Return the value of the lhs. */
2346 rtx
2347 expand_builtin (unsigned int code, tree exp, rtx target)
2348 {
2349 registered_function &rfn = *(*registered_functions)[code];
2350 if (!check_requires_float (EXPR_LOCATION (exp), rfn.decl,
2351 rfn.requires_float))
2352 return target;
2353 return function_expander (rfn.instance, rfn.decl, exp, target).expand ();
2354 }
2355
2356 } /* end namespace arm_mve */
2357
2358 using namespace arm_mve;
2359
2360 inline void
2361 gt_ggc_mx (function_instance *)
2362 {
2363 }
2364
2365 inline void
2366 gt_pch_nx (function_instance *)
2367 {
2368 }
2369
2370 inline void
2371 gt_pch_nx (function_instance *, gt_pointer_operator, void *)
2372 {
2373 }
2374
2375 #include "gt-arm-mve-builtins.h"