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