[PR testsuite/116860] Testsuite adjustment for recently added tests
[official-gcc.git] / gcc / config / arm / arm-mve-builtins.h
blob3a0d50dc64cedf9534bfb17c398a385bd4bcc4f5
1 /* ACLE support for Arm MVE
2 Copyright (C) 2021-2025 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)
9 any later version.
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_ARM_MVE_BUILTINS_H
21 #define GCC_ARM_MVE_BUILTINS_H
23 /* The full name of an MVE ACLE function is the concatenation of:
25 - the base name ("vadd", 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
53 the language level.
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.
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 MVE intrinsics will hardly ever fold a useful language-level
81 constant. */
82 namespace arm_mve {
83 /* The maximum number of vectors in an ACLE tuple type. */
84 const unsigned int MAX_TUPLE_SIZE = 3;
86 /* Used to represent the default merge argument index for _m functions.
87 The actual index depends on how many arguments the function takes. */
88 const unsigned int DEFAULT_MERGE_ARGNO = 0;
90 /* Flags that describe what a function might do, in addition to reading
91 its arguments and returning a result. */
92 const unsigned int CP_READ_FPCR = 1U << 0;
93 const unsigned int CP_RAISE_FP_EXCEPTIONS = 1U << 1;
94 const unsigned int CP_READ_MEMORY = 1U << 2;
95 const unsigned int CP_WRITE_MEMORY = 1U << 3;
97 /* Enumerates the MVE predicate and (data) vector types, together called
98 "vector types" for brevity. */
99 enum vector_type_index
101 #define DEF_MVE_TYPE(ACLE_NAME, SCALAR_TYPE) \
102 VECTOR_TYPE_ ## ACLE_NAME,
103 #include "arm-mve-builtins.def"
104 NUM_VECTOR_TYPES
107 /* Classifies the available measurement units for an address displacement. */
108 enum units_index
110 UNITS_none,
111 UNITS_bytes
114 /* Describes the various uses of a governing predicate. */
115 enum predication_index
117 /* No governing predicate is present. */
118 PRED_none,
120 /* Merging predication: copy inactive lanes from the first data argument
121 to the vector result. */
122 PRED_m,
124 /* Plain predication: inactive lanes are not used to compute the
125 scalar result. */
126 PRED_p,
128 /* "Don't care" predication: set inactive lanes of the vector result
129 to arbitrary values. */
130 PRED_x,
132 /* Zero predication: set inactive lanes of the vector result to zero. */
133 PRED_z,
135 NUM_PREDS
138 /* Some shapes need access to some predicate sets. */
139 extern const predication_index preds_m_or_none[];
141 /* Classifies element types, based on type suffixes with the bit count
142 removed. */
143 enum type_class_index
145 TYPE_bool,
146 TYPE_float,
147 TYPE_signed,
148 TYPE_unsigned,
149 TYPE_poly,
150 NUM_TYPE_CLASSES
153 /* Classifies an operation into "modes"; for example, to distinguish
154 vector-scalar operations from vector-vector operations, or to
155 distinguish between different addressing modes. This classification
156 accounts for the function suffixes that occur between the base name
157 and the first type suffix. */
158 enum mode_suffix_index
160 #define DEF_MVE_MODE(NAME, BASE, DISPLACEMENT, UNITS) MODE_##NAME,
161 #include "arm-mve-builtins.def"
162 MODE_none
165 /* Enumerates the possible type suffixes. Each suffix is associated with
166 a vector type, but for predicates provides extra information about the
167 element size. */
168 enum type_suffix_index
170 #define DEF_MVE_TYPE_SUFFIX(NAME, ACLE_TYPE, CLASS, BITS, MODE) \
171 TYPE_SUFFIX_ ## NAME,
172 #include "arm-mve-builtins.def"
173 NUM_TYPE_SUFFIXES
176 /* Combines two type suffixes. */
177 typedef enum type_suffix_index type_suffix_pair[2];
179 class function_base;
180 class function_shape;
182 /* Static information about a mode suffix. */
183 struct mode_suffix_info
185 /* The suffix string itself. */
186 const char *string;
188 /* The type of the vector base address, or NUM_VECTOR_TYPES if the
189 mode does not include a vector base address. */
190 vector_type_index base_vector_type;
192 /* The type of the vector displacement, or NUM_VECTOR_TYPES if the
193 mode does not include a vector displacement. (Note that scalar
194 displacements are always int64_t.) */
195 vector_type_index displacement_vector_type;
197 /* The units in which the vector or scalar displacement is measured,
198 or UNITS_none if the mode doesn't take a displacement. */
199 units_index displacement_units;
202 /* Static information about a type suffix. */
203 struct type_suffix_info
205 /* The suffix string itself. */
206 const char *string;
208 /* The associated ACLE vector or predicate type. */
209 vector_type_index vector_type : 8;
211 /* What kind of type the suffix represents. */
212 type_class_index tclass : 8;
214 /* The number of bits and bytes in an element. For predicates this
215 measures the associated data elements. */
216 unsigned int element_bits : 8;
217 unsigned int element_bytes : 8;
219 /* True if the suffix is for an integer type. */
220 unsigned int integer_p : 1;
221 /* True if the suffix is for an unsigned type. */
222 unsigned int unsigned_p : 1;
223 /* True if the suffix is for a floating-point type. */
224 unsigned int float_p : 1;
225 /* True if the suffix is for a polynomial type. */
226 unsigned int poly_p : 1;
227 unsigned int spare : 12;
229 /* The associated vector or predicate mode. */
230 machine_mode vector_mode : 16;
233 /* Static information about a set of functions. */
234 struct function_group_info
236 /* The base name, as a string. */
237 const char *base_name;
239 /* Describes the behavior associated with the function base name. */
240 const function_base *const *base;
242 /* The shape of the functions, as described above the class definition.
243 It's possible to have entries with the same base name but different
244 shapes. */
245 const function_shape *const *shape;
247 /* A list of the available type suffixes, and of the available predication
248 types. The function supports every combination of the two.
250 The list of type suffixes is terminated by two NUM_TYPE_SUFFIXES
251 while the list of predication types is terminated by NUM_PREDS.
252 The list of type suffixes is lexicographically ordered based
253 on the index value. */
254 const type_suffix_pair *types;
255 const predication_index *preds;
257 /* Whether the function group requires a floating point abi. */
258 bool requires_float;
261 /* Describes a single fully-resolved function (i.e. one that has a
262 unique full name). */
263 class GTY((user)) function_instance
265 public:
266 function_instance (const char *, const function_base *,
267 const function_shape *, mode_suffix_index,
268 const type_suffix_pair &, predication_index);
270 bool operator== (const function_instance &) const;
271 bool operator!= (const function_instance &) const;
272 hashval_t hash () const;
274 unsigned int call_properties () const;
275 bool reads_global_state_p () const;
276 bool modifies_global_state_p () const;
277 bool could_trap_p () const;
279 unsigned int vectors_per_tuple () const;
280 tree memory_scalar_type () const;
281 machine_mode memory_vector_mode () const;
283 const mode_suffix_info &mode_suffix () const;
285 const type_suffix_info &type_suffix (unsigned int) const;
286 tree scalar_type (unsigned int) const;
287 tree vector_type (unsigned int) const;
288 tree tuple_type (unsigned int) const;
289 machine_mode vector_mode (unsigned int) const;
290 machine_mode gp_mode (unsigned int) const;
292 bool has_inactive_argument () const;
294 /* The properties of the function. (The explicit "enum"s are required
295 for gengtype.) */
296 const char *base_name;
297 const function_base *base;
298 const function_shape *shape;
299 enum mode_suffix_index mode_suffix_id;
300 type_suffix_pair type_suffix_ids;
301 enum predication_index pred;
304 class registered_function;
306 /* A class for building and registering function decls. */
307 class function_builder
309 public:
310 function_builder ();
311 ~function_builder ();
313 void add_unique_function (const function_instance &, tree,
314 vec<tree> &, bool, bool, bool);
315 void add_overloaded_function (const function_instance &, bool, bool);
316 void add_overloaded_functions (const function_group_info &,
317 mode_suffix_index, bool);
319 void register_function_group (const function_group_info &, bool);
321 private:
322 void append_name (const char *);
323 char *finish_name ();
325 char *get_name (const function_instance &, bool, bool);
327 tree get_attributes (const function_instance &);
329 registered_function &add_function (const function_instance &,
330 const char *, tree, tree,
331 bool, bool, bool);
333 /* The function type to use for functions that are resolved by
334 function_resolver. */
335 tree m_overload_type;
337 /* True if we should create a separate decl for each instance of an
338 overloaded function, instead of using function_resolver. */
339 bool m_direct_overloads;
341 /* Used for building up function names. */
342 obstack m_string_obstack;
344 /* Maps all overloaded function names that we've registered so far
345 to their associated function_instances. */
346 hash_map<nofree_string_hash, registered_function *> m_overload_names;
349 /* A base class for handling calls to built-in functions. */
350 class function_call_info : public function_instance
352 public:
353 function_call_info (location_t, const function_instance &, tree);
355 bool function_returns_void_p ();
357 /* The location of the call. */
358 location_t location;
360 /* The FUNCTION_DECL that is being called. */
361 tree fndecl;
364 /* A class for resolving an overloaded function call. */
365 class function_resolver : public function_call_info
367 public:
368 enum { SAME_SIZE = 256, HALF_SIZE, QUARTER_SIZE };
369 static const type_class_index SAME_TYPE_CLASS = NUM_TYPE_CLASSES;
371 function_resolver (location_t, const function_instance &, tree,
372 vec<tree, va_gc> &);
374 tree get_vector_type (type_suffix_index);
375 const char *get_scalar_type_name (type_suffix_index);
376 tree get_argument_type (unsigned int);
377 bool scalar_argument_p (unsigned int);
379 tree report_no_such_form (type_suffix_index);
380 tree lookup_form (mode_suffix_index,
381 type_suffix_index = NUM_TYPE_SUFFIXES,
382 type_suffix_index = NUM_TYPE_SUFFIXES);
383 tree resolve_to (mode_suffix_index,
384 type_suffix_index = NUM_TYPE_SUFFIXES,
385 type_suffix_index = NUM_TYPE_SUFFIXES);
387 type_suffix_index infer_pointer_type (unsigned int);
388 type_suffix_index infer_vector_or_tuple_type (unsigned int, unsigned int);
389 type_suffix_index infer_vector_type (unsigned int);
390 type_suffix_index infer_tuple_type (unsigned int);
392 bool require_vector_or_scalar_type (unsigned int);
394 bool require_vector_type (unsigned int, vector_type_index);
395 bool require_matching_vector_type (unsigned int, type_suffix_index);
396 bool require_derived_vector_type (unsigned int, unsigned int,
397 type_suffix_index,
398 type_class_index = SAME_TYPE_CLASS,
399 unsigned int = SAME_SIZE);
400 bool require_scalar_type (unsigned int, const char *);
401 bool require_pointer_type (unsigned int);
402 bool require_pointer_to_type (unsigned int, tree);
403 bool require_integer_immediate (unsigned int);
404 bool require_derived_scalar_type (unsigned int, type_class_index,
405 unsigned int = SAME_SIZE);
407 bool check_num_arguments (unsigned int);
408 bool check_gp_argument (unsigned int, unsigned int &, unsigned int &);
409 tree resolve_unary (type_class_index = SAME_TYPE_CLASS,
410 unsigned int = SAME_SIZE, bool = false);
411 tree resolve_unary_n ();
412 tree resolve_uniform (unsigned int, unsigned int = 0);
413 tree resolve_uniform_opt_n (unsigned int);
414 tree finish_opt_n_resolution (unsigned int, unsigned int, type_suffix_index,
415 type_class_index = SAME_TYPE_CLASS,
416 unsigned int = SAME_SIZE,
417 type_suffix_index = NUM_TYPE_SUFFIXES);
419 tree resolve ();
421 private:
422 /* The arguments to the overloaded function. */
423 vec<tree, va_gc> &m_arglist;
426 /* A class for checking that the semantic constraints on a function call are
427 satisfied, such as arguments being integer constant expressions with
428 a particular range. The parent class's FNDECL is the decl that was
429 called in the original source, before overload resolution. */
430 class function_checker : public function_call_info
432 public:
433 function_checker (location_t, const function_instance &, tree,
434 tree, unsigned int, tree *);
436 bool require_immediate_enum (unsigned int, tree);
437 bool require_immediate_lane_index (unsigned int, unsigned int = 1);
438 bool require_immediate_one_of (unsigned int, HOST_WIDE_INT, HOST_WIDE_INT,
439 HOST_WIDE_INT, HOST_WIDE_INT);
440 bool require_immediate_range (unsigned int, HOST_WIDE_INT, HOST_WIDE_INT);
441 bool require_immediate_range_multiple (unsigned int, HOST_WIDE_INT,
442 HOST_WIDE_INT, HOST_WIDE_INT);
444 bool check ();
446 private:
447 bool argument_exists_p (unsigned int);
449 bool require_immediate (unsigned int, HOST_WIDE_INT &);
450 bool require_signed_immediate (unsigned int, HOST_WIDE_INT &);
452 /* The type of the resolved function. */
453 tree m_fntype;
455 /* The arguments to the function. */
456 unsigned int m_nargs;
457 tree *m_args;
459 /* The first argument not associated with the function's predication
460 type. */
461 unsigned int m_base_arg;
464 /* A class for folding a gimple function call. */
465 class gimple_folder : public function_call_info
467 public:
468 gimple_folder (const function_instance &, tree,
469 gcall *);
471 gimple *fold ();
473 /* The call we're folding. */
474 gcall *call;
476 /* The result of the call, or null if none. */
477 tree lhs;
480 /* A class for expanding a function call into RTL. */
481 class function_expander : public function_call_info
483 public:
484 function_expander (const function_instance &, tree, tree, rtx);
485 rtx expand ();
487 insn_code direct_optab_handler (optab, unsigned int = 0);
489 rtx get_contiguous_base ();
490 rtx get_fallback_value (machine_mode, unsigned int, unsigned int &);
491 rtx get_reg_target ();
493 void add_output_operand (insn_code);
494 void add_input_operand (insn_code, rtx);
495 void add_integer_operand (HOST_WIDE_INT);
496 void add_mem_operand (machine_mode, rtx);
497 void add_fixed_operand (rtx);
498 rtx generate_insn (insn_code);
500 rtx use_exact_insn (insn_code);
501 rtx use_unpred_insn (insn_code);
502 rtx use_pred_x_insn (insn_code);
503 rtx use_cond_insn (insn_code, unsigned int = DEFAULT_MERGE_ARGNO);
504 rtx use_contiguous_load_insn (insn_code);
505 rtx use_contiguous_store_insn (insn_code);
507 rtx map_to_rtx_codes (rtx_code, rtx_code, rtx_code);
509 /* The function call expression. */
510 tree call_expr;
512 /* For functions that return a value, this is the preferred location
513 of that value. It could be null or could have a different mode
514 from the function return type. */
515 rtx possible_target;
517 /* The expanded arguments. */
518 auto_vec<rtx, 16> args;
520 private:
521 /* Used to build up the operands to an instruction. */
522 auto_vec<expand_operand, 8> m_ops;
525 /* Provides information about a particular function base name, and handles
526 tasks related to the base name. */
527 class function_base
529 public:
530 /* Return a set of CP_* flags that describe what the function might do,
531 in addition to reading its arguments and returning a result. */
532 virtual unsigned int call_properties (const function_instance &) const;
534 /* If the function operates on tuples of vectors, return the number
535 of vectors in the tuples, otherwise return 1. */
536 virtual unsigned int vectors_per_tuple () const { return 1; }
538 /* If the function addresses memory, return the type of a single
539 scalar memory element. */
540 virtual tree
541 memory_scalar_type (const function_instance &) const
543 gcc_unreachable ();
546 /* If the function addresses memory, return a vector mode whose
547 GET_MODE_NUNITS is the number of elements addressed and whose
548 GET_MODE_INNER is the mode of a single scalar memory element. */
549 virtual machine_mode
550 memory_vector_mode (const function_instance &) const
552 gcc_unreachable ();
555 /* Try to fold the given gimple call. Return the new gimple statement
556 on success, otherwise return null. */
557 virtual gimple *fold (gimple_folder &) const { return NULL; }
559 /* Expand the given call into rtl. Return the result of the function,
560 or an arbitrary value if the function doesn't return a result. */
561 virtual rtx expand (function_expander &) const = 0;
564 /* Classifies functions into "shapes". The idea is to take all the
565 type signatures for a set of functions, and classify what's left
566 based on:
568 - the number of arguments
570 - the process of determining the types in the signature from the mode
571 and type suffixes in the function name (including types that are not
572 affected by the suffixes)
574 - which arguments must be integer constant expressions, and what range
575 those arguments have
577 - the process for mapping overloaded names to "full" names. */
578 class function_shape
580 public:
581 virtual bool explicit_type_suffix_p (unsigned int, enum predication_index,
582 enum mode_suffix_index,
583 type_suffix_info) const = 0;
584 virtual bool explicit_mode_suffix_p (enum predication_index,
585 enum mode_suffix_index) const = 0;
586 virtual bool skip_overload_p (enum predication_index,
587 enum mode_suffix_index) const = 0;
588 virtual bool mode_after_pred () const = 0;
590 /* Define all functions associated with the given group. */
591 virtual void build (function_builder &,
592 const function_group_info &,
593 bool) const = 0;
595 /* Try to resolve the overloaded call. Return the non-overloaded
596 function decl on success and error_mark_node on failure. */
597 virtual tree resolve (function_resolver &) const = 0;
599 /* Check whether the given call is semantically valid. Return true
600 if it is, otherwise report an error and return false. */
601 virtual bool check (function_checker &) const { return true; }
604 extern const type_suffix_info type_suffixes[NUM_TYPE_SUFFIXES + 1];
605 extern const mode_suffix_info mode_suffixes[MODE_none + 1];
607 extern tree scalar_types[NUM_VECTOR_TYPES];
608 extern tree acle_vector_types[MAX_TUPLE_SIZE][NUM_VECTOR_TYPES + 1];
610 /* Return the ACLE type mve_pred16_t. */
611 inline tree
612 get_mve_pred16_t (void)
614 return acle_vector_types[0][VECTOR_TYPE_mve_pred16_t];
617 /* Try to find a mode with the given mode_suffix_info fields. Return the
618 mode on success or MODE_none on failure. */
619 inline mode_suffix_index
620 find_mode_suffix (vector_type_index base_vector_type,
621 vector_type_index displacement_vector_type,
622 units_index displacement_units)
624 for (unsigned int mode_i = 0; mode_i < ARRAY_SIZE (mode_suffixes); ++mode_i)
626 const mode_suffix_info &mode = mode_suffixes[mode_i];
627 if (mode.base_vector_type == base_vector_type
628 && mode.displacement_vector_type == displacement_vector_type
629 && mode.displacement_units == displacement_units)
630 return mode_suffix_index (mode_i);
632 return MODE_none;
635 /* Return the type suffix associated with ELEMENT_BITS-bit elements of type
636 class TCLASS. */
637 inline type_suffix_index
638 find_type_suffix (type_class_index tclass, unsigned int element_bits)
640 for (unsigned int i = 0; i < NUM_TYPE_SUFFIXES; ++i)
641 if (type_suffixes[i].tclass == tclass
642 && type_suffixes[i].element_bits == element_bits)
643 return type_suffix_index (i);
644 gcc_unreachable ();
647 inline function_instance::
648 function_instance (const char *base_name_in,
649 const function_base *base_in,
650 const function_shape *shape_in,
651 mode_suffix_index mode_suffix_id_in,
652 const type_suffix_pair &type_suffix_ids_in,
653 predication_index pred_in)
654 : base_name (base_name_in), base (base_in), shape (shape_in),
655 mode_suffix_id (mode_suffix_id_in), pred (pred_in)
657 memcpy (type_suffix_ids, type_suffix_ids_in, sizeof (type_suffix_ids));
660 inline bool
661 function_instance::operator== (const function_instance &other) const
663 return (base == other.base
664 && shape == other.shape
665 && mode_suffix_id == other.mode_suffix_id
666 && pred == other.pred
667 && type_suffix_ids[0] == other.type_suffix_ids[0]
668 && type_suffix_ids[1] == other.type_suffix_ids[1]);
671 inline bool
672 function_instance::operator!= (const function_instance &other) const
674 return !operator== (other);
677 /* If the function operates on tuples of vectors, return the number
678 of vectors in the tuples, otherwise return 1. */
679 inline unsigned int
680 function_instance::vectors_per_tuple () const
682 return base->vectors_per_tuple ();
685 /* If the function addresses memory, return the type of a single
686 scalar memory element. */
687 inline tree
688 function_instance::memory_scalar_type () const
690 return base->memory_scalar_type (*this);
693 /* If the function addresses memory, return a vector mode whose
694 GET_MODE_NUNITS is the number of elements addressed and whose
695 GET_MODE_INNER is the mode of a single scalar memory element. */
696 inline machine_mode
697 function_instance::memory_vector_mode () const
699 return base->memory_vector_mode (*this);
702 /* Return information about the function's mode suffix. */
703 inline const mode_suffix_info &
704 function_instance::mode_suffix () const
706 return mode_suffixes[mode_suffix_id];
709 /* Return information about type suffix I. */
710 inline const type_suffix_info &
711 function_instance::type_suffix (unsigned int i) const
713 return type_suffixes[type_suffix_ids[i]];
716 /* Return the scalar type associated with type suffix I. */
717 inline tree
718 function_instance::scalar_type (unsigned int i) const
720 return scalar_types[type_suffix (i).vector_type];
723 /* Return the vector type associated with type suffix I. */
724 inline tree
725 function_instance::vector_type (unsigned int i) const
727 return acle_vector_types[0][type_suffix (i).vector_type];
730 /* If the function operates on tuples of vectors, return the tuple type
731 associated with type suffix I, otherwise return the vector type associated
732 with type suffix I. */
733 inline tree
734 function_instance::tuple_type (unsigned int i) const
736 unsigned int num_vectors = vectors_per_tuple ();
737 return acle_vector_types[num_vectors >> 1][type_suffix (i).vector_type];
740 /* Return the vector or predicate mode associated with type suffix I. */
741 inline machine_mode
742 function_instance::vector_mode (unsigned int i) const
744 return type_suffix (i).vector_mode;
747 /* Return true if the function has no return value. */
748 inline bool
749 function_call_info::function_returns_void_p ()
751 return TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node;
754 /* Default implementation of function::call_properties, with conservatively
755 correct behavior for floating-point instructions. */
756 inline unsigned int
757 function_base::call_properties (const function_instance &instance) const
759 unsigned int flags = 0;
760 if (instance.type_suffix (0).float_p || instance.type_suffix (1).float_p)
761 flags |= CP_READ_FPCR | CP_RAISE_FP_EXCEPTIONS;
762 return flags;
765 } /* end namespace arm_mve */
767 #endif /* GCC_ARM_MVE_BUILTINS_H */