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