1 /* ACLE support for AArch64 SVE
2 Copyright (C) 2018-2020 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 #ifndef GCC_AARCH64_SVE_BUILTINS_H
21 #define GCC_AARCH64_SVE_BUILTINS_H
22
23 /* The full name of an SVE ACLE function is the concatenation of:
24
25 - the base name ("svadd", etc.)
26 - the "mode" suffix ("_n", "_index", etc.)
27 - the type suffixes ("_s32", "_b8", etc.)
28 - the predication suffix ("_x", "_z", etc.)
29
30 Each piece of information is individually useful, so we retain this
31 classification throughout:
32
33 - function_base represents the base name
34
35 - mode_suffix_index represents the mode suffix
36
37 - type_suffix_index represents individual type suffixes, while
38 type_suffix_pair represents a pair of them
39
40 - prediction_index extends the predication suffix with an additional
41 alternative: PRED_implicit for implicitly-predicated operations
42
43 In addition to its unique full name, a function may have a shorter
44 overloaded alias. This alias removes pieces of the suffixes that
45 can be inferred from the arguments, such as by shortening the mode
46 suffix or dropping some of the type suffixes. The base name and the
47 predication suffix stay the same.
48
49 The function_shape class describes what arguments a given function
50 takes and what its overloaded alias is called. In broad terms,
51 function_base describes how the underlying instruction behaves while
52 function_shape describes how that instruction has been presented at
53 the language level.
54
55 The static list of functions uses function_group to describe a group
56 of related functions. The function_builder class is responsible for
57 expanding this static description into a list of individual functions
58 and registering the associated built-in functions. function_instance
59 describes one of these individual functions in terms of the properties
60 described above.
61
62 The classes involved in compiling a function call are:
63
64 - function_resolver, which resolves an overloaded function call to a
65 specific function_instance and its associated function decl
66
67 - function_checker, which checks whether the values of the arguments
68 conform to the ACLE specification
69
70 - gimple_folder, which tries to fold a function call at the gimple level
71
72 - function_expander, which expands a function call into rtl instructions
73
74 function_resolver and function_checker operate at the language level
75 and so are associated with the function_shape. gimple_folder and
76 function_expander are concerned with the behavior of the function
77 and so are associated with the function_base.
78
79 Note that we've specifically chosen not to fold calls in the frontend,
80 since SVE intrinsics will hardly ever fold a useful language-level
81 constant. */
82 namespace aarch64_sve
83 {
84 /* The maximum number of vectors in an ACLE tuple type. */
85 const unsigned int MAX_TUPLE_SIZE = 4;
86
87 /* Used to represent the default merge argument index for _m functions.
88 The actual index depends on how many arguments the function takes. */
89 const unsigned int DEFAULT_MERGE_ARGNO = ~0U;
90
91 /* Flags that describe what a function might do, in addition to reading
92 its arguments and returning a result. */
93 const unsigned int CP_READ_FPCR = 1U << 0;
94 const unsigned int CP_RAISE_FP_EXCEPTIONS = 1U << 1;
95 const unsigned int CP_READ_MEMORY = 1U << 2;
96 const unsigned int CP_PREFETCH_MEMORY = 1U << 3;
97 const unsigned int CP_WRITE_MEMORY = 1U << 4;
98 const unsigned int CP_READ_FFR = 1U << 5;
99 const unsigned int CP_WRITE_FFR = 1U << 6;
100
101 /* Enumerates the SVE predicate and (data) vector types, together called
102 "vector types" for brevity. */
103 enum vector_type_index
104 {
105 #define DEF_SVE_TYPE(ACLE_NAME, NCHARS, ABI_NAME, SCALAR_TYPE) \
106 VECTOR_TYPE_ ## ACLE_NAME,
107 #include "aarch64-sve-builtins.def"
108 NUM_VECTOR_TYPES
109 };
110
111 /* Classifies the available measurement units for an address displacement. */
112 enum units_index
113 {
114 UNITS_none,
115 UNITS_bytes,
116 UNITS_elements,
117 UNITS_vectors
118 };
119
120 /* Describes the various uses of a governing predicate. */
121 enum predication_index
122 {
123 /* No governing predicate is present. */
124 PRED_none,
125
126 /* A governing predicate is present but there is no predication suffix
127 associated with it. This is used when the result is neither a vector
128 nor a predicate, since the distinction between "zeroing" and "merging"
129 doesn't apply in that case. It is also used when a suffix would be
130 redundant (such as for loads and comparisons, which are inherently
131 zeroing operations). */
132 PRED_implicit,
133
134 /* Merging predication: copy inactive lanes from the first data argument
135 to the vector result. */
136 PRED_m,
137
138 /* "Don't care" predication: set inactive lanes of the vector result
139 to arbitrary values. */
140 PRED_x,
141
142 /* Zero predication: set inactive lanes of the vector result to zero. */
143 PRED_z,
144
145 NUM_PREDS
146 };
147
148 /* Classifies element types, based on type suffixes with the bit count
149 removed. */
150 enum type_class_index
151 {
152 TYPE_bool,
153 TYPE_bfloat,
154 TYPE_float,
155 TYPE_signed,
156 TYPE_unsigned,
157 NUM_TYPE_CLASSES
158 };
159
160 /* Classifies an operation into "modes"; for example, to distinguish
161 vector-scalar operations from vector-vector operations, or to
162 distinguish between different addressing modes. This classification
163 accounts for the function suffixes that occur between the base name
164 and the first type suffix. */
165 enum mode_suffix_index
166 {
167 #define DEF_SVE_MODE(NAME, BASE, DISPLACEMENT, UNITS) MODE_##NAME,
168 #include "aarch64-sve-builtins.def"
169 MODE_none
170 };
171
172 /* Enumerates the possible type suffixes. Each suffix is associated with
173 a vector type, but for predicates provides extra information about the
174 element size. */
175 enum type_suffix_index
176 {
177 #define DEF_SVE_TYPE_SUFFIX(NAME, ACLE_TYPE, CLASS, BITS, MODE) \
178 TYPE_SUFFIX_ ## NAME,
179 #include "aarch64-sve-builtins.def"
180 NUM_TYPE_SUFFIXES
181 };
182
183 /* Combines two type suffixes. */
184 typedef enum type_suffix_index type_suffix_pair[2];
185
186 class function_base;
187 class function_shape;
188
189 /* Static information about a mode suffix. */
190 struct mode_suffix_info
191 {
192 /* The suffix string itself. */
193 const char *string;
194
195 /* The type of the vector base address, or NUM_VECTOR_TYPES if the
196 mode does not include a vector base address. */
197 vector_type_index base_vector_type;
198
199 /* The type of the vector displacement, or NUM_VECTOR_TYPES if the
200 mode does not include a vector displacement. (Note that scalar
201 displacements are always int64_t.) */
202 vector_type_index displacement_vector_type;
203
204 /* The units in which the vector or scalar displacement is measured,
205 or UNITS_none if the mode doesn't take a displacement. */
206 units_index displacement_units;
207 };
208
209 /* Static information about a type suffix. */
210 struct type_suffix_info
211 {
212 /* The suffix string itself. */
213 const char *string;
214
215 /* The associated ACLE vector or predicate type. */
216 vector_type_index vector_type : 8;
217
218 /* What kind of type the suffix represents. */
219 type_class_index tclass : 8;
220
221 /* The number of bits and bytes in an element. For predicates this
222 measures the associated data elements. */
223 unsigned int element_bits : 8;
224 unsigned int element_bytes : 8;
225
226 /* True if the suffix is for an integer type. */
227 unsigned int integer_p : 1;
228 /* True if the suffix is for an unsigned type. */
229 unsigned int unsigned_p : 1;
230 /* True if the suffix is for a floating-point type. */
231 unsigned int float_p : 1;
232 /* True if the suffix is for a boolean type. */
233 unsigned int bool_p : 1;
234 unsigned int spare : 12;
235
236 /* The associated vector or predicate mode. */
237 machine_mode vector_mode : 16;
238 };
239
240 /* Static information about a set of functions. */
241 struct function_group_info
242 {
243 /* The base name, as a string. */
244 const char *base_name;
245
246 /* Describes the behavior associated with the function base name. */
247 const function_base *const *base;
248
249 /* The shape of the functions, as described above the class definition.
250 It's possible to have entries with the same base name but different
251 shapes. */
252 const function_shape *const *shape;
253
254 /* A list of the available type suffixes, and of the available predication
255 types. The function supports every combination of the two.
256
257 The list of type suffixes is terminated by two NUM_TYPE_SUFFIXES
258 while the list of predication types is terminated by NUM_PREDS.
259 The list of type suffixes is lexicographically ordered based
260 on the index value. */
261 const type_suffix_pair *types;
262 const predication_index *preds;
263
264 /* The architecture extensions that the functions require, as a set of
265 AARCH64_FL_* flags. */
266 uint64_t required_extensions;
267 };
268
269 /* Describes a single fully-resolved function (i.e. one that has a
270 unique full name). */
class(user)271 class GTY((user)) function_instance
272 {
273 public:
274 function_instance (const char *, const function_base *,
275 const function_shape *, mode_suffix_index,
276 const type_suffix_pair &, predication_index);
277
278 bool operator== (const function_instance &) const;
279 bool operator!= (const function_instance &) const;
280 hashval_t hash () const;
281
282 unsigned int call_properties () const;
283 bool reads_global_state_p () const;
284 bool modifies_global_state_p () const;
285 bool could_trap_p () const;
286
287 unsigned int vectors_per_tuple () const;
288 tree memory_scalar_type () const;
289 machine_mode memory_vector_mode () const;
290
291 const mode_suffix_info &mode_suffix () const;
292 tree base_vector_type () const;
293 tree displacement_vector_type () const;
294 units_index displacement_units () const;
295
296 const type_suffix_info &type_suffix (unsigned int) const;
297 tree scalar_type (unsigned int) const;
298 tree vector_type (unsigned int) const;
299 tree tuple_type (unsigned int) const;
300 unsigned int elements_per_vq (unsigned int i) const;
301 machine_mode vector_mode (unsigned int) const;
302 machine_mode gp_mode (unsigned int) const;
303
304 /* The properties of the function. (The explicit "enum"s are required
305 for gengtype.) */
306 const char *base_name;
307 const function_base *base;
308 const function_shape *shape;
309 enum mode_suffix_index mode_suffix_id;
310 type_suffix_pair type_suffix_ids;
311 enum predication_index pred;
312 };
313
314 class registered_function;
315
316 /* A class for building and registering function decls. */
317 class function_builder
318 {
319 public:
320 function_builder ();
321 ~function_builder ();
322
323 void add_unique_function (const function_instance &, tree,
324 vec<tree> &, uint64_t, bool);
325 void add_overloaded_function (const function_instance &, uint64_t);
326 void add_overloaded_functions (const function_group_info &,
327 mode_suffix_index);
328
329 void register_function_group (const function_group_info &);
330
331 private:
332 void append_name (const char *);
333 char *finish_name ();
334
335 char *get_name (const function_instance &, bool);
336
337 tree get_attributes (const function_instance &);
338
339 registered_function &add_function (const function_instance &,
340 const char *, tree, tree, uint64_t, bool);
341
342 /* The function type to use for functions that are resolved by
343 function_resolver. */
344 tree m_overload_type;
345
346 /* True if we should create a separate decl for each instance of an
347 overloaded function, instead of using function_resolver. */
348 bool m_direct_overloads;
349
350 /* Used for building up function names. */
351 obstack m_string_obstack;
352
353 /* Maps all overloaded function names that we've registered so far
354 to their associated function_instances. */
355 hash_map<nofree_string_hash, registered_function *> m_overload_names;
356 };
357
358 /* A base class for handling calls to built-in functions. */
359 class function_call_info : public function_instance
360 {
361 public:
362 function_call_info (location_t, const function_instance &, tree);
363
364 bool function_returns_void_p ();
365
366 /* The location of the call. */
367 location_t location;
368
369 /* The FUNCTION_DECL that is being called. */
370 tree fndecl;
371 };
372
373 /* A class for resolving an overloaded function call. */
374 class function_resolver : public function_call_info
375 {
376 public:
377 enum { SAME_SIZE = 256, HALF_SIZE, QUARTER_SIZE };
378 static const type_class_index SAME_TYPE_CLASS = NUM_TYPE_CLASSES;
379
380 function_resolver (location_t, const function_instance &, tree,
381 vec<tree, va_gc> &);
382
383 tree get_vector_type (type_suffix_index);
384 const char *get_scalar_type_name (type_suffix_index);
385 tree get_argument_type (unsigned int);
386 bool scalar_argument_p (unsigned int);
387
388 tree report_no_such_form (type_suffix_index);
389 tree lookup_form (mode_suffix_index,
390 type_suffix_index = NUM_TYPE_SUFFIXES,
391 type_suffix_index = NUM_TYPE_SUFFIXES);
392 tree resolve_to (mode_suffix_index,
393 type_suffix_index = NUM_TYPE_SUFFIXES,
394 type_suffix_index = NUM_TYPE_SUFFIXES);
395
396 type_suffix_index infer_integer_scalar_type (unsigned int);
397 type_suffix_index infer_pointer_type (unsigned int, bool = false);
398 type_suffix_index infer_vector_or_tuple_type (unsigned int, unsigned int);
399 type_suffix_index infer_vector_type (unsigned int);
400 type_suffix_index infer_integer_vector_type (unsigned int);
401 type_suffix_index infer_unsigned_vector_type (unsigned int);
402 type_suffix_index infer_sd_vector_type (unsigned int);
403 type_suffix_index infer_tuple_type (unsigned int);
404
405 bool require_vector_or_scalar_type (unsigned int);
406
407 bool require_vector_type (unsigned int, vector_type_index);
408 bool require_matching_vector_type (unsigned int, type_suffix_index);
409 bool require_derived_vector_type (unsigned int, unsigned int,
410 type_suffix_index,
411 type_class_index = SAME_TYPE_CLASS,
412 unsigned int = SAME_SIZE);
413
414 bool require_scalar_type (unsigned int, const char *);
415 bool require_pointer_type (unsigned int);
416 bool require_matching_integer_scalar_type (unsigned int, unsigned int,
417 type_suffix_index);
418 bool require_derived_scalar_type (unsigned int, type_class_index,
419 unsigned int = SAME_SIZE);
420 bool require_matching_pointer_type (unsigned int, unsigned int,
421 type_suffix_index);
422 bool require_integer_immediate (unsigned int);
423
424 vector_type_index infer_vector_base_type (unsigned int);
425 vector_type_index infer_vector_displacement_type (unsigned int);
426
427 mode_suffix_index resolve_sv_displacement (unsigned int,
428 type_suffix_index, bool);
429 mode_suffix_index resolve_gather_address (unsigned int,
430 type_suffix_index, bool);
431 mode_suffix_index resolve_adr_address (unsigned int);
432
433 bool check_num_arguments (unsigned int);
434 bool check_gp_argument (unsigned int, unsigned int &, unsigned int &);
435 tree resolve_unary (type_class_index = SAME_TYPE_CLASS,
436 unsigned int = SAME_SIZE, bool = false);
437 tree resolve_uniform (unsigned int, unsigned int = 0);
438 tree resolve_uniform_opt_n (unsigned int);
439 tree finish_opt_n_resolution (unsigned int, unsigned int, type_suffix_index,
440 type_class_index = SAME_TYPE_CLASS,
441 unsigned int = SAME_SIZE,
442 type_suffix_index = NUM_TYPE_SUFFIXES);
443
444 tree resolve ();
445
446 private:
447 /* The arguments to the overloaded function. */
448 vec<tree, va_gc> &m_arglist;
449 };
450
451 /* A class for checking that the semantic constraints on a function call are
452 satisfied, such as arguments being integer constant expressions with
453 a particular range. The parent class's FNDECL is the decl that was
454 called in the original source, before overload resolution. */
455 class function_checker : public function_call_info
456 {
457 public:
458 function_checker (location_t, const function_instance &, tree,
459 tree, unsigned int, tree *);
460
461 bool require_immediate_either_or (unsigned int, HOST_WIDE_INT,
462 HOST_WIDE_INT);
463 bool require_immediate_enum (unsigned int, tree);
464 bool require_immediate_lane_index (unsigned int, unsigned int = 1);
465 bool require_immediate_one_of (unsigned int, HOST_WIDE_INT, HOST_WIDE_INT,
466 HOST_WIDE_INT, HOST_WIDE_INT);
467 bool require_immediate_range (unsigned int, HOST_WIDE_INT, HOST_WIDE_INT);
468
469 bool check ();
470
471 private:
472 bool argument_exists_p (unsigned int);
473
474 bool require_immediate (unsigned int, HOST_WIDE_INT &);
475
476 /* The type of the resolved function. */
477 tree m_fntype;
478
479 /* The arguments to the function. */
480 unsigned int m_nargs;
481 tree *m_args;
482
483 /* The first argument not associated with the function's predication
484 type. */
485 unsigned int m_base_arg;
486 };
487
488 /* A class for folding a gimple function call. */
489 class gimple_folder : public function_call_info
490 {
491 public:
492 gimple_folder (const function_instance &, tree,
493 gimple_stmt_iterator *, gcall *);
494
495 tree force_vector (gimple_seq &, tree, tree);
496 tree convert_pred (gimple_seq &, tree, unsigned int);
497 tree fold_contiguous_base (gimple_seq &, tree);
498 tree load_store_cookie (tree);
499
500 gimple *redirect_call (const function_instance &);
501 gimple *fold_to_pfalse ();
502 gimple *fold_to_ptrue ();
503 gimple *fold_to_vl_pred (unsigned int);
504
505 gimple *fold ();
506
507 /* Where to insert extra statements that feed the final replacement. */
508 gimple_stmt_iterator *gsi;
509
510 /* The call we're folding. */
511 gcall *call;
512
513 /* The result of the call, or null if none. */
514 tree lhs;
515 };
516
517 /* A class for expanding a function call into RTL. */
518 class function_expander : public function_call_info
519 {
520 public:
521 function_expander (const function_instance &, tree, tree, rtx);
522 rtx expand ();
523
524 insn_code direct_optab_handler (optab, unsigned int = 0);
525 insn_code direct_optab_handler_for_sign (optab, optab, unsigned int = 0,
526 machine_mode = E_VOIDmode);
527
528 bool overlaps_input_p (rtx);
529
530 rtx convert_to_pmode (rtx);
531 rtx get_contiguous_base (machine_mode);
532 rtx get_fallback_value (machine_mode, unsigned int,
533 unsigned int, unsigned int &);
534 rtx get_reg_target ();
535 rtx get_nonoverlapping_reg_target ();
536
537 void add_output_operand (insn_code);
538 void add_input_operand (insn_code, rtx);
539 void add_integer_operand (HOST_WIDE_INT);
540 void add_mem_operand (machine_mode, rtx);
541 void add_address_operand (rtx);
542 void add_fixed_operand (rtx);
543 rtx generate_insn (insn_code);
544
545 void prepare_gather_address_operands (unsigned int, bool = true);
546 void prepare_prefetch_operands ();
547 void add_ptrue_hint (unsigned int, machine_mode);
548 void rotate_inputs_left (unsigned int, unsigned int);
549 bool try_negating_argument (unsigned int, machine_mode);
550
551 rtx use_exact_insn (insn_code);
552 rtx use_unpred_insn (insn_code);
553 rtx use_pred_x_insn (insn_code);
554 rtx use_cond_insn (insn_code, unsigned int = DEFAULT_MERGE_ARGNO);
555 rtx use_vcond_mask_insn (insn_code, unsigned int = DEFAULT_MERGE_ARGNO);
556 rtx use_contiguous_load_insn (insn_code);
557 rtx use_contiguous_prefetch_insn (insn_code);
558 rtx use_contiguous_store_insn (insn_code);
559
560 rtx map_to_rtx_codes (rtx_code, rtx_code, int,
561 unsigned int = DEFAULT_MERGE_ARGNO);
562 rtx map_to_unspecs (int, int, int, unsigned int = DEFAULT_MERGE_ARGNO);
563
564 /* The function call expression. */
565 tree call_expr;
566
567 /* For functions that return a value, this is the preferred location
568 of that value. It could be null or could have a different mode
569 from the function return type. */
570 rtx possible_target;
571
572 /* The expanded arguments. */
573 auto_vec<rtx, 16> args;
574
575 private:
576 /* Used to build up the operands to an instruction. */
577 auto_vec<expand_operand, 8> m_ops;
578 };
579
580 /* Provides information about a particular function base name, and handles
581 tasks related to the base name. */
582 class function_base
583 {
584 public:
585 /* Return a set of CP_* flags that describe what the function might do,
586 in addition to reading its arguments and returning a result. */
587 virtual unsigned int call_properties (const function_instance &) const;
588
589 /* If the function operates on tuples of vectors, return the number
590 of vectors in the tuples, otherwise return 1. */
vectors_per_tuple()591 virtual unsigned int vectors_per_tuple () const { return 1; }
592
593 /* If the function addresses memory, return the type of a single
594 scalar memory element. */
595 virtual tree
memory_scalar_type(const function_instance &)596 memory_scalar_type (const function_instance &) const
597 {
598 gcc_unreachable ();
599 }
600
601 /* If the function addresses memory, return a vector mode whose
602 GET_MODE_NUNITS is the number of elements addressed and whose
603 GET_MODE_INNER is the mode of a single scalar memory element. */
604 virtual machine_mode
memory_vector_mode(const function_instance &)605 memory_vector_mode (const function_instance &) const
606 {
607 gcc_unreachable ();
608 }
609
610 /* Try to fold the given gimple call. Return the new gimple statement
611 on success, otherwise return null. */
fold(gimple_folder &)612 virtual gimple *fold (gimple_folder &) const { return NULL; }
613
614 /* Expand the given call into rtl. Return the result of the function,
615 or an arbitrary value if the function doesn't return a result. */
616 virtual rtx expand (function_expander &) const = 0;
617 };
618
619 /* Classifies functions into "shapes". The idea is to take all the
620 type signatures for a set of functions, remove the governing predicate
621 (if any), and classify what's left based on:
622
623 - the number of arguments
624
625 - the process of determining the types in the signature from the mode
626 and type suffixes in the function name (including types that are not
627 affected by the suffixes)
628
629 - which arguments must be integer constant expressions, and what range
630 those arguments have
631
632 - the process for mapping overloaded names to "full" names. */
633 class function_shape
634 {
635 public:
636 virtual bool explicit_type_suffix_p (unsigned int) const = 0;
637
638 /* Define all functions associated with the given group. */
639 virtual void build (function_builder &,
640 const function_group_info &) const = 0;
641
642 /* Try to resolve the overloaded call. Return the non-overloaded
643 function decl on success and error_mark_node on failure. */
644 virtual tree resolve (function_resolver &) const = 0;
645
646 /* Check whether the given call is semantically valid. Return true
647 if it is, otherwise report an error and return false. */
check(function_checker &)648 virtual bool check (function_checker &) const { return true; }
649 };
650
651 /* RAII class for enabling enough SVE features to define the built-in
652 types and implement the arm_sve.h pragma. */
653 class sve_switcher
654 {
655 public:
656 sve_switcher ();
657 ~sve_switcher ();
658
659 private:
660 unsigned long m_old_isa_flags;
661 bool m_old_general_regs_only;
662 bool m_old_have_regs_of_mode[MAX_MACHINE_MODE];
663 };
664
665 extern const type_suffix_info type_suffixes[NUM_TYPE_SUFFIXES + 1];
666 extern const mode_suffix_info mode_suffixes[MODE_none + 1];
667
668 extern tree scalar_types[NUM_VECTOR_TYPES];
669 extern tree acle_vector_types[MAX_TUPLE_SIZE][NUM_VECTOR_TYPES + 1];
670 extern tree acle_svpattern;
671 extern tree acle_svprfop;
672
673 /* Return the ACLE type svbool_t. */
674 inline tree
get_svbool_t(void)675 get_svbool_t (void)
676 {
677 return acle_vector_types[0][VECTOR_TYPE_svbool_t];
678 }
679
680 /* Try to find a mode with the given mode_suffix_info fields. Return the
681 mode on success or MODE_none on failure. */
682 inline mode_suffix_index
find_mode_suffix(vector_type_index base_vector_type,vector_type_index displacement_vector_type,units_index displacement_units)683 find_mode_suffix (vector_type_index base_vector_type,
684 vector_type_index displacement_vector_type,
685 units_index displacement_units)
686 {
687 for (unsigned int mode_i = 0; mode_i < ARRAY_SIZE (mode_suffixes); ++mode_i)
688 {
689 const mode_suffix_info &mode = mode_suffixes[mode_i];
690 if (mode.base_vector_type == base_vector_type
691 && mode.displacement_vector_type == displacement_vector_type
692 && mode.displacement_units == displacement_units)
693 return mode_suffix_index (mode_i);
694 }
695 return MODE_none;
696 }
697
698 /* Return the type suffix associated with ELEMENT_BITS-bit elements of type
699 class TCLASS. */
700 inline type_suffix_index
find_type_suffix(type_class_index tclass,unsigned int element_bits)701 find_type_suffix (type_class_index tclass, unsigned int element_bits)
702 {
703 for (unsigned int i = 0; i < NUM_TYPE_SUFFIXES; ++i)
704 if (type_suffixes[i].tclass == tclass
705 && type_suffixes[i].element_bits == element_bits)
706 return type_suffix_index (i);
707 gcc_unreachable ();
708 }
709
710 /* Return the single field in tuple type TYPE. */
711 inline tree
tuple_type_field(tree type)712 tuple_type_field (tree type)
713 {
714 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
715 if (TREE_CODE (field) == FIELD_DECL)
716 return field;
717 gcc_unreachable ();
718 }
719
720 inline function_instance::
function_instance(const char * base_name_in,const function_base * base_in,const function_shape * shape_in,mode_suffix_index mode_suffix_id_in,const type_suffix_pair & type_suffix_ids_in,predication_index pred_in)721 function_instance (const char *base_name_in,
722 const function_base *base_in,
723 const function_shape *shape_in,
724 mode_suffix_index mode_suffix_id_in,
725 const type_suffix_pair &type_suffix_ids_in,
726 predication_index pred_in)
727 : base_name (base_name_in), base (base_in), shape (shape_in),
728 mode_suffix_id (mode_suffix_id_in), pred (pred_in)
729 {
730 memcpy (type_suffix_ids, type_suffix_ids_in, sizeof (type_suffix_ids));
731 }
732
733 inline bool
734 function_instance::operator== (const function_instance &other) const
735 {
736 return (base == other.base
737 && shape == other.shape
738 && mode_suffix_id == other.mode_suffix_id
739 && pred == other.pred
740 && type_suffix_ids[0] == other.type_suffix_ids[0]
741 && type_suffix_ids[1] == other.type_suffix_ids[1]);
742 }
743
744 inline bool
745 function_instance::operator!= (const function_instance &other) const
746 {
747 return !operator== (other);
748 }
749
750 /* If the function operates on tuples of vectors, return the number
751 of vectors in the tuples, otherwise return 1. */
752 inline unsigned int
vectors_per_tuple()753 function_instance::vectors_per_tuple () const
754 {
755 return base->vectors_per_tuple ();
756 }
757
758 /* If the function addresses memory, return the type of a single
759 scalar memory element. */
760 inline tree
memory_scalar_type()761 function_instance::memory_scalar_type () const
762 {
763 return base->memory_scalar_type (*this);
764 }
765
766 /* If the function addresses memory, return a vector mode whose
767 GET_MODE_NUNITS is the number of elements addressed and whose
768 GET_MODE_INNER is the mode of a single scalar memory element. */
769 inline machine_mode
memory_vector_mode()770 function_instance::memory_vector_mode () const
771 {
772 return base->memory_vector_mode (*this);
773 }
774
775 /* Return information about the function's mode suffix. */
776 inline const mode_suffix_info &
mode_suffix()777 function_instance::mode_suffix () const
778 {
779 return mode_suffixes[mode_suffix_id];
780 }
781
782 /* Return the type of the function's vector base address argument,
783 or null it doesn't have a vector base address. */
784 inline tree
base_vector_type()785 function_instance::base_vector_type () const
786 {
787 return acle_vector_types[0][mode_suffix ().base_vector_type];
788 }
789
790 /* Return the type of the function's vector index or offset argument,
791 or null if doesn't have a vector index or offset argument. */
792 inline tree
displacement_vector_type()793 function_instance::displacement_vector_type () const
794 {
795 return acle_vector_types[0][mode_suffix ().displacement_vector_type];
796 }
797
798 /* If the function takes a vector or scalar displacement, return the units
799 in which the displacement is measured, otherwise return UNITS_none. */
800 inline units_index
displacement_units()801 function_instance::displacement_units () const
802 {
803 return mode_suffix ().displacement_units;
804 }
805
806 /* Return information about type suffix I. */
807 inline const type_suffix_info &
type_suffix(unsigned int i)808 function_instance::type_suffix (unsigned int i) const
809 {
810 return type_suffixes[type_suffix_ids[i]];
811 }
812
813 /* Return the scalar type associated with type suffix I. */
814 inline tree
scalar_type(unsigned int i)815 function_instance::scalar_type (unsigned int i) const
816 {
817 return scalar_types[type_suffix (i).vector_type];
818 }
819
820 /* Return the vector type associated with type suffix I. */
821 inline tree
vector_type(unsigned int i)822 function_instance::vector_type (unsigned int i) const
823 {
824 return acle_vector_types[0][type_suffix (i).vector_type];
825 }
826
827 /* If the function operates on tuples of vectors, return the tuple type
828 associated with type suffix I, otherwise return the vector type associated
829 with type suffix I. */
830 inline tree
tuple_type(unsigned int i)831 function_instance::tuple_type (unsigned int i) const
832 {
833 unsigned int num_vectors = vectors_per_tuple ();
834 return acle_vector_types[num_vectors - 1][type_suffix (i).vector_type];
835 }
836
837 /* Return the number of elements of type suffix I that fit within a
838 128-bit block. */
839 inline unsigned int
elements_per_vq(unsigned int i)840 function_instance::elements_per_vq (unsigned int i) const
841 {
842 return 128 / type_suffix (i).element_bits;
843 }
844
845 /* Return the vector or predicate mode associated with type suffix I. */
846 inline machine_mode
vector_mode(unsigned int i)847 function_instance::vector_mode (unsigned int i) const
848 {
849 return type_suffix (i).vector_mode;
850 }
851
852 /* Return the mode of the governing predicate to use when operating on
853 type suffix I. */
854 inline machine_mode
gp_mode(unsigned int i)855 function_instance::gp_mode (unsigned int i) const
856 {
857 return aarch64_sve_pred_mode (type_suffix (i).element_bytes).require ();
858 }
859
860 /* Return true if the function has no return value. */
861 inline bool
function_returns_void_p()862 function_call_info::function_returns_void_p ()
863 {
864 return TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node;
865 }
866
867 /* Default implementation of function::call_properties, with conservatively
868 correct behavior for floating-point instructions. */
869 inline unsigned int
call_properties(const function_instance & instance)870 function_base::call_properties (const function_instance &instance) const
871 {
872 unsigned int flags = 0;
873 if (instance.type_suffix (0).float_p || instance.type_suffix (1).float_p)
874 flags |= CP_READ_FPCR | CP_RAISE_FP_EXCEPTIONS;
875 return flags;
876 }
877
878 }
879
880 #endif
881