1 /* ACLE support for AArch64 SVE
2 Copyright (C) 2018-2020 Free Software Foundation, Inc.
4 This file is part of GCC.
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)
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.
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/>. */
20 #ifndef GCC_AARCH64_SVE_BUILTINS_H
21 #define GCC_AARCH64_SVE_BUILTINS_H
23 /* The full name of an SVE ACLE function is the concatenation of:
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.)
30 Each piece of information is individually useful, so we retain this
31 classification throughout:
33 - function_base represents the base name
35 - mode_suffix_index represents the mode suffix
37 - type_suffix_index represents individual type suffixes, while
38 type_suffix_pair represents a pair of them
40 - prediction_index extends the predication suffix with an additional
41 alternative: PRED_implicit for implicitly-predicated operations
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.
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
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
62 The classes involved in compiling a function call are:
64 - function_resolver, which resolves an overloaded function call to a
65 specific function_instance and its associated function decl
67 - function_checker, which checks whether the values of the arguments
68 conform to the ACLE specification
70 - gimple_folder, which tries to fold a function call at the gimple level
72 - function_expander, which expands a function call into rtl instructions
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.
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
84 /* The maximum number of vectors in an ACLE tuple type. */
85 const unsigned int MAX_TUPLE_SIZE
= 4;
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;
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;
101 /* Enumerates the SVE predicate and (data) vector types, together called
102 "vector types" for brevity. */
103 enum vector_type_index
105 #define DEF_SVE_TYPE(ACLE_NAME, NCHARS, ABI_NAME, SCALAR_TYPE) \
106 VECTOR_TYPE_ ## ACLE_NAME,
107 #include "aarch64-sve-builtins.def"
111 /* Classifies the available measurement units for an address displacement. */
120 /* Describes the various uses of a governing predicate. */
121 enum predication_index
123 /* No governing predicate is present. */
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). */
134 /* Merging predication: copy inactive lanes from the first data argument
135 to the vector result. */
138 /* "Don't care" predication: set inactive lanes of the vector result
139 to arbitrary values. */
142 /* Zero predication: set inactive lanes of the vector result to zero. */
148 /* Classifies element types, based on type suffixes with the bit count
150 enum type_class_index
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. */
164 enum mode_suffix_index
166 #define DEF_SVE_MODE(NAME, BASE, DISPLACEMENT, UNITS) MODE_##NAME,
167 #include "aarch64-sve-builtins.def"
171 /* Enumerates the possible type suffixes. Each suffix is associated with
172 a vector type, but for predicates provides extra information about the
174 enum type_suffix_index
176 #define DEF_SVE_TYPE_SUFFIX(NAME, ACLE_TYPE, CLASS, BITS, MODE) \
177 TYPE_SUFFIX_ ## NAME,
178 #include "aarch64-sve-builtins.def"
182 /* Combines two type suffixes. */
183 typedef enum type_suffix_index type_suffix_pair
[2];
186 class function_shape
;
188 /* Static information about a mode suffix. */
189 struct mode_suffix_info
191 /* The suffix string itself. */
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
;
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
;
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
;
208 /* Static information about a type suffix. */
209 struct type_suffix_info
211 /* The suffix string itself. */
214 /* The associated ACLE vector or predicate type. */
215 vector_type_index vector_type
: 8;
217 /* What kind of type the suffix represents. */
218 type_class_index tclass
: 8;
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;
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;
235 /* The associated vector or predicate mode. */
236 machine_mode vector_mode
: 16;
239 /* Static information about a set of functions. */
240 struct function_group_info
242 /* The base name, as a string. */
243 const char *base_name
;
245 /* Describes the behavior associated with the function base name. */
246 const function_base
*const *base
;
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
251 const function_shape
*const *shape
;
253 /* A list of the available type suffixes, and of the available predication
254 types. The function supports every combination of the two.
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
;
263 /* The architecture extensions that the functions require, as a set of
264 AARCH64_FL_* flags. */
265 uint64_t required_extensions
;
268 /* Describes a single fully-resolved function (i.e. one that has a
269 unique full name). */
270 class GTY((user
)) function_instance
273 function_instance (const char *, const function_base
*,
274 const function_shape
*, mode_suffix_index
,
275 const type_suffix_pair
&, predication_index
);
277 bool operator== (const function_instance
&) const;
278 bool operator!= (const function_instance
&) const;
279 hashval_t
hash () const;
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;
286 unsigned int vectors_per_tuple () const;
287 tree
memory_scalar_type () const;
288 machine_mode
memory_vector_mode () const;
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;
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;
303 /* The properties of the function. (The explicit "enum"s are required
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
;
313 class registered_function
;
315 /* A class for building and registering function decls. */
316 class function_builder
320 ~function_builder ();
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
&,
328 void register_function_group (const function_group_info
&);
331 void append_name (const char *);
332 char *finish_name ();
334 char *get_name (const function_instance
&, bool);
336 tree
get_attributes (const function_instance
&);
338 registered_function
&add_function (const function_instance
&,
339 const char *, tree
, tree
, uint64_t, bool);
341 /* The function type to use for functions that are resolved by
342 function_resolver. */
343 tree m_overload_type
;
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
;
349 /* Used for building up function names. */
350 obstack m_string_obstack
;
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
;
357 /* A base class for handling calls to built-in functions. */
358 class function_call_info
: public function_instance
361 function_call_info (location_t
, const function_instance
&, tree
);
363 bool function_returns_void_p ();
365 /* The location of the call. */
368 /* The FUNCTION_DECL that is being called. */
372 /* A class for resolving an overloaded function call. */
373 class function_resolver
: public function_call_info
376 enum { SAME_SIZE
= 256, HALF_SIZE
, QUARTER_SIZE
};
377 static const type_class_index SAME_TYPE_CLASS
= NUM_TYPE_CLASSES
;
379 function_resolver (location_t
, const function_instance
&, tree
,
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);
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
);
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);
404 bool require_vector_or_scalar_type (unsigned int);
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,
410 type_class_index
= SAME_TYPE_CLASS
,
411 unsigned int = SAME_SIZE
);
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,
417 bool require_derived_scalar_type (unsigned int, type_class_index
,
418 unsigned int = SAME_SIZE
);
419 bool require_integer_immediate (unsigned int);
421 vector_type_index
infer_vector_base_type (unsigned int);
422 vector_type_index
infer_vector_displacement_type (unsigned int);
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);
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
);
443 /* The arguments to the overloaded function. */
444 vec
<tree
, va_gc
> &m_arglist
;
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. */
451 class function_checker
: public function_call_info
454 function_checker (location_t
, const function_instance
&, tree
,
455 tree
, unsigned int, tree
*);
457 bool require_immediate_either_or (unsigned int, 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
);
468 bool argument_exists_p (unsigned int);
470 bool require_immediate (unsigned int, HOST_WIDE_INT
&);
472 /* The type of the resolved function. */
475 /* The arguments to the function. */
476 unsigned int m_nargs
;
479 /* The first argument not associated with the function's predication
481 unsigned int m_base_arg
;
484 /* A class for folding a gimple function call. */
485 class gimple_folder
: public function_call_info
488 gimple_folder (const function_instance
&, tree
,
489 gimple_stmt_iterator
*, gcall
*);
491 tree
force_vector (gimple_seq
&, tree
, tree
);
492 tree
convert_pred (gimple_seq
&, tree
, unsigned int);
493 tree
fold_contiguous_base (gimple_seq
&, tree
);
494 tree
load_store_cookie (tree
);
496 gimple
*fold_to_pfalse ();
497 gimple
*fold_to_ptrue ();
498 gimple
*fold_to_vl_pred (unsigned int);
502 /* Where to insert extra statements that feed the final replacement. */
503 gimple_stmt_iterator
*gsi
;
505 /* The call we're folding. */
508 /* The result of the call, or null if none. */
512 /* A class for expanding a function call into RTL. */
513 class function_expander
: public function_call_info
516 function_expander (const function_instance
&, tree
, tree
, rtx
);
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
);
523 bool overlaps_input_p (rtx
);
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 ();
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
);
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
);
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
);
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
);
559 /* The function call expression. */
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. */
567 /* The expanded arguments. */
568 auto_vec
<rtx
, 16> args
;
571 /* Used to build up the operands to an instruction. */
572 auto_vec
<expand_operand
, 8> m_ops
;
575 /* Provides information about a particular function base name, and handles
576 tasks related to the base name. */
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;
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; }
588 /* If the function addresses memory, return the type of a single
589 scalar memory element. */
591 memory_scalar_type (const function_instance
&) const
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. */
600 memory_vector_mode (const function_instance
&) const
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
; }
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;
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:
618 - the number of arguments
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)
624 - which arguments must be integer constant expressions, and what range
627 - the process for mapping overloaded names to "full" names. */
631 virtual bool explicit_type_suffix_p (unsigned int) const = 0;
633 /* Define all functions associated with the given group. */
634 virtual void build (function_builder
&,
635 const function_group_info
&) const = 0;
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;
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; }
646 /* RAII class for enabling enough SVE features to define the built-in
647 types and implement the arm_sve.h pragma. */
655 unsigned long m_old_isa_flags
;
656 bool m_old_have_regs_of_mode
[MAX_MACHINE_MODE
];
659 extern const type_suffix_info type_suffixes
[NUM_TYPE_SUFFIXES
+ 1];
660 extern const mode_suffix_info mode_suffixes
[MODE_none
+ 1];
662 extern tree scalar_types
[NUM_VECTOR_TYPES
];
663 extern tree acle_vector_types
[MAX_TUPLE_SIZE
][NUM_VECTOR_TYPES
+ 1];
664 extern tree acle_svpattern
;
665 extern tree acle_svprfop
;
667 /* Return the ACLE type svbool_t. */
671 return acle_vector_types
[0][VECTOR_TYPE_svbool_t
];
674 /* Try to find a mode with the given mode_suffix_info fields. Return the
675 mode on success or MODE_none on failure. */
676 inline mode_suffix_index
677 find_mode_suffix (vector_type_index base_vector_type
,
678 vector_type_index displacement_vector_type
,
679 units_index displacement_units
)
681 for (unsigned int mode_i
= 0; mode_i
< ARRAY_SIZE (mode_suffixes
); ++mode_i
)
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
);
692 /* Return the type suffix associated with ELEMENT_BITS-bit elements of type
694 inline type_suffix_index
695 find_type_suffix (type_class_index tclass
, unsigned int element_bits
)
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
);
704 /* Return the single field in tuple type TYPE. */
706 tuple_type_field (tree type
)
708 for (tree field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
709 if (TREE_CODE (field
) == FIELD_DECL
)
714 inline function_instance::
715 function_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
)
724 memcpy (type_suffix_ids
, type_suffix_ids_in
, sizeof (type_suffix_ids
));
728 function_instance::operator== (const function_instance
&other
) const
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]);
739 function_instance::operator!= (const function_instance
&other
) const
741 return !operator== (other
);
744 /* If the function operates on tuples of vectors, return the number
745 of vectors in the tuples, otherwise return 1. */
747 function_instance::vectors_per_tuple () const
749 return base
->vectors_per_tuple ();
752 /* If the function addresses memory, return the type of a single
753 scalar memory element. */
755 function_instance::memory_scalar_type () const
757 return base
->memory_scalar_type (*this);
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. */
764 function_instance::memory_vector_mode () const
766 return base
->memory_vector_mode (*this);
769 /* Return information about the function's mode suffix. */
770 inline const mode_suffix_info
&
771 function_instance::mode_suffix () const
773 return mode_suffixes
[mode_suffix_id
];
776 /* Return the type of the function's vector base address argument,
777 or null it doesn't have a vector base address. */
779 function_instance::base_vector_type () const
781 return acle_vector_types
[0][mode_suffix ().base_vector_type
];
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. */
787 function_instance::displacement_vector_type () const
789 return acle_vector_types
[0][mode_suffix ().displacement_vector_type
];
792 /* If the function takes a vector or scalar displacement, return the units
793 in which the displacement is measured, otherwise return UNITS_none. */
795 function_instance::displacement_units () const
797 return mode_suffix ().displacement_units
;
800 /* Return information about type suffix I. */
801 inline const type_suffix_info
&
802 function_instance::type_suffix (unsigned int i
) const
804 return type_suffixes
[type_suffix_ids
[i
]];
807 /* Return the scalar type associated with type suffix I. */
809 function_instance::scalar_type (unsigned int i
) const
811 return scalar_types
[type_suffix (i
).vector_type
];
814 /* Return the vector type associated with type suffix I. */
816 function_instance::vector_type (unsigned int i
) const
818 return acle_vector_types
[0][type_suffix (i
).vector_type
];
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. */
825 function_instance::tuple_type (unsigned int i
) const
827 unsigned int num_vectors
= vectors_per_tuple ();
828 return acle_vector_types
[num_vectors
- 1][type_suffix (i
).vector_type
];
831 /* Return the number of elements of type suffix I that fit within a
834 function_instance::elements_per_vq (unsigned int i
) const
836 return 128 / type_suffix (i
).element_bits
;
839 /* Return the vector or predicate mode associated with type suffix I. */
841 function_instance::vector_mode (unsigned int i
) const
843 return type_suffix (i
).vector_mode
;
846 /* Return the mode of the governing predicate to use when operating on
849 function_instance::gp_mode (unsigned int i
) const
851 return aarch64_sve_pred_mode (type_suffix (i
).element_bytes
).require ();
854 /* Return true if the function has no return value. */
856 function_call_info::function_returns_void_p ()
858 return TREE_TYPE (TREE_TYPE (fndecl
)) == void_type_node
;
861 /* Default implementation of function::call_properties, with conservatively
862 correct behavior for floating-point instructions. */
864 function_base::call_properties (const function_instance
&instance
) const
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
;