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