1239281Sgonzo/* ACLE support for AArch64 SVE
2239281Sgonzo   Copyright (C) 2018-2020 Free Software Foundation, Inc.
3239281Sgonzo
4239281Sgonzo   This file is part of GCC.
5239281Sgonzo
6239281Sgonzo   GCC is free software; you can redistribute it and/or modify it
7239281Sgonzo   under the terms of the GNU General Public License as published by
8239281Sgonzo   the Free Software Foundation; either version 3, or (at your option)
9239281Sgonzo   any later version.
10239281Sgonzo
11239281Sgonzo   GCC is distributed in the hope that it will be useful, but
12239281Sgonzo   WITHOUT ANY WARRANTY; without even the implied warranty of
13239281Sgonzo   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14239281Sgonzo   General Public License for more details.
15239281Sgonzo
16239281Sgonzo   You should have received a copy of the GNU General Public License
17239281Sgonzo   along with GCC; see the file COPYING3.  If not see
18239281Sgonzo   <http://www.gnu.org/licenses/>.  */
19239281Sgonzo
20239281Sgonzo#ifndef GCC_AARCH64_SVE_BUILTINS_H
21239281Sgonzo#define GCC_AARCH64_SVE_BUILTINS_H
22239281Sgonzo
23239281Sgonzo/* The full name of an SVE ACLE function is the concatenation of:
24239281Sgonzo
25239281Sgonzo   - the base name ("svadd", etc.)
26239281Sgonzo   - the "mode" suffix ("_n", "_index", etc.)
27239281Sgonzo   - the type suffixes ("_s32", "_b8", etc.)
28239281Sgonzo   - the predication suffix ("_x", "_z", etc.)
29239281Sgonzo
30239281Sgonzo   Each piece of information is individually useful, so we retain this
31239281Sgonzo   classification throughout:
32239281Sgonzo
33239281Sgonzo   - function_base represents the base name
34239281Sgonzo
35239281Sgonzo   - mode_suffix_index represents the mode suffix
36239281Sgonzo
37239281Sgonzo   - type_suffix_index represents individual type suffixes, while
38239281Sgonzo     type_suffix_pair represents a pair of them
39239281Sgonzo
40239281Sgonzo   - prediction_index extends the predication suffix with an additional
41239281Sgonzo     alternative: PRED_implicit for implicitly-predicated operations
42239281Sgonzo
43239281Sgonzo   In addition to its unique full name, a function may have a shorter
44239281Sgonzo   overloaded alias.  This alias removes pieces of the suffixes that
45239281Sgonzo   can be inferred from the arguments, such as by shortening the mode
46239281Sgonzo   suffix or dropping some of the type suffixes.  The base name and the
47239281Sgonzo   predication suffix stay the same.
48239281Sgonzo
49239281Sgonzo   The function_shape class describes what arguments a given function
50239281Sgonzo   takes and what its overloaded alias is called.  In broad terms,
51239281Sgonzo   function_base describes how the underlying instruction behaves while
52239281Sgonzo   function_shape describes how that instruction has been presented at
53239281Sgonzo   the language level.
54239281Sgonzo
55239281Sgonzo   The static list of functions uses function_group to describe a group
56239281Sgonzo   of related functions.  The function_builder class is responsible for
57239281Sgonzo   expanding this static description into a list of individual functions
58239281Sgonzo   and registering the associated built-in functions.  function_instance
59239281Sgonzo   describes one of these individual functions in terms of the properties
60239281Sgonzo   described above.
61239281Sgonzo
62239281Sgonzo   The classes involved in compiling a function call are:
63239281Sgonzo
64239281Sgonzo   - function_resolver, which resolves an overloaded function call to a
65239281Sgonzo     specific function_instance and its associated function decl
66239281Sgonzo
67239281Sgonzo   - function_checker, which checks whether the values of the arguments
68239281Sgonzo     conform to the ACLE specification
69239281Sgonzo
70239281Sgonzo   - gimple_folder, which tries to fold a function call at the gimple level
71239281Sgonzo
72239281Sgonzo   - function_expander, which expands a function call into rtl instructions
73239281Sgonzo
74239281Sgonzo   function_resolver and function_checker operate at the language level
75239281Sgonzo   and so are associated with the function_shape.  gimple_folder and
76239281Sgonzo   function_expander are concerned with the behavior of the function
77239281Sgonzo   and so are associated with the function_base.
78239281Sgonzo
79239281Sgonzo   Note that we've specifically chosen not to fold calls in the frontend,
80239281Sgonzo   since SVE intrinsics will hardly ever fold a useful language-level
81239281Sgonzo   constant.  */
82239281Sgonzonamespace aarch64_sve
83239281Sgonzo{
84239281Sgonzo/* The maximum number of vectors in an ACLE tuple type.  */
85239281Sgonzoconst unsigned int MAX_TUPLE_SIZE = 4;
86239281Sgonzo
87239281Sgonzo/* Used to represent the default merge argument index for _m functions.
88239281Sgonzo   The actual index depends on how many arguments the function takes.  */
89239281Sgonzoconst unsigned int DEFAULT_MERGE_ARGNO = ~0U;
90239281Sgonzo
91239281Sgonzo/* Flags that describe what a function might do, in addition to reading
92239281Sgonzo   its arguments and returning a result.  */
93239281Sgonzoconst unsigned int CP_READ_FPCR = 1U << 0;
94239281Sgonzoconst unsigned int CP_RAISE_FP_EXCEPTIONS = 1U << 1;
95239281Sgonzoconst unsigned int CP_READ_MEMORY = 1U << 2;
96239281Sgonzoconst unsigned int CP_PREFETCH_MEMORY = 1U << 3;
97239281Sgonzoconst unsigned int CP_WRITE_MEMORY = 1U << 4;
98239281Sgonzoconst unsigned int CP_READ_FFR = 1U << 5;
99239281Sgonzoconst unsigned int CP_WRITE_FFR = 1U << 6;
100239281Sgonzo
101239281Sgonzo/* Enumerates the SVE predicate and (data) vector types, together called
102239281Sgonzo   "vector types" for brevity.  */
103239281Sgonzoenum vector_type_index
104239281Sgonzo{
105239281Sgonzo#define DEF_SVE_TYPE(ACLE_NAME, NCHARS, ABI_NAME, SCALAR_TYPE) \
106239281Sgonzo  VECTOR_TYPE_ ## ACLE_NAME,
107239281Sgonzo#include "aarch64-sve-builtins.def"
108239281Sgonzo  NUM_VECTOR_TYPES
109239281Sgonzo};
110246850Sgonzo
111239281Sgonzo/* Classifies the available measurement units for an address displacement.  */
112239281Sgonzoenum units_index
113239281Sgonzo{
114239281Sgonzo  UNITS_none,
115239281Sgonzo  UNITS_bytes,
116239281Sgonzo  UNITS_elements,
117239281Sgonzo  UNITS_vectors
118239281Sgonzo};
119239281Sgonzo
120239281Sgonzo/* Describes the various uses of a governing predicate.  */
121239281Sgonzoenum predication_index
122239281Sgonzo{
123295123Smmel  /* No governing predicate is present.  */
124239281Sgonzo  PRED_none,
125239281Sgonzo
126239281Sgonzo  /* A governing predicate is present but there is no predication suffix
127239281Sgonzo     associated with it.  This is used when the result is neither a vector
128239281Sgonzo     nor a predicate, since the distinction between "zeroing" and "merging"
129245137Sgonzo     doesn't apply in that case.  It is also used when a suffix would be
130245137Sgonzo     redundant (such as for loads and comparisons, which are inherently
131239281Sgonzo     zeroing operations).  */
132245137Sgonzo  PRED_implicit,
133245137Sgonzo
134245137Sgonzo  /* Merging predication: copy inactive lanes from the first data argument
135245137Sgonzo     to the vector result.  */
136245137Sgonzo  PRED_m,
137245137Sgonzo
138245137Sgonzo  /* "Don't care" predication: set inactive lanes of the vector result
139245137Sgonzo     to arbitrary values.  */
140239281Sgonzo  PRED_x,
141245137Sgonzo
142239281Sgonzo  /* Zero predication: set inactive lanes of the vector result to zero.  */
143245137Sgonzo  PRED_z,
144245137Sgonzo
145239281Sgonzo  NUM_PREDS
146245137Sgonzo};
147245137Sgonzo
148239281Sgonzo/* Classifies element types, based on type suffixes with the bit count
149245137Sgonzo   removed.  */
150245137Sgonzoenum type_class_index
151239281Sgonzo{
152245137Sgonzo  TYPE_bool,
153245137Sgonzo  TYPE_bfloat,
154245137Sgonzo  TYPE_float,
155245137Sgonzo  TYPE_signed,
156245137Sgonzo  TYPE_unsigned,
157239281Sgonzo  NUM_TYPE_CLASSES
158245137Sgonzo};
159245137Sgonzo
160245137Sgonzo/* Classifies an operation into "modes"; for example, to distinguish
161245137Sgonzo   vector-scalar operations from vector-vector operations, or to
162245137Sgonzo   distinguish between different addressing modes.  This classification
163245137Sgonzo   accounts for the function suffixes that occur between the base name
164245137Sgonzo   and the first type suffix.  */
165245137Sgonzoenum mode_suffix_index
166245137Sgonzo{
167245137Sgonzo#define DEF_SVE_MODE(NAME, BASE, DISPLACEMENT, UNITS) MODE_##NAME,
168245137Sgonzo#include "aarch64-sve-builtins.def"
169245137Sgonzo  MODE_none
170245137Sgonzo};
171245137Sgonzo
172245137Sgonzo/* Enumerates the possible type suffixes.  Each suffix is associated with
173245137Sgonzo   a vector type, but for predicates provides extra information about the
174245137Sgonzo   element size.  */
175245137Sgonzoenum type_suffix_index
176245137Sgonzo{
177245137Sgonzo#define DEF_SVE_TYPE_SUFFIX(NAME, ACLE_TYPE, CLASS, BITS, MODE) \
178245137Sgonzo  TYPE_SUFFIX_ ## NAME,
179245137Sgonzo#include "aarch64-sve-builtins.def"
180245137Sgonzo  NUM_TYPE_SUFFIXES
181245137Sgonzo};
182245137Sgonzo
183245137Sgonzo/* Combines two type suffixes.  */
184239281Sgonzotypedef enum type_suffix_index type_suffix_pair[2];
185239281Sgonzo
186245137Sgonzoclass function_base;
187239281Sgonzoclass function_shape;
188239281Sgonzo
189245137Sgonzo/* Static information about a mode suffix.  */
190245137Sgonzostruct mode_suffix_info
191245137Sgonzo{
192245137Sgonzo  /* The suffix string itself.  */
193245137Sgonzo  const char *string;
194245137Sgonzo
195245137Sgonzo  /* The type of the vector base address, or NUM_VECTOR_TYPES if the
196245137Sgonzo     mode does not include a vector base address.  */
197245137Sgonzo  vector_type_index base_vector_type;
198239281Sgonzo
199239281Sgonzo  /* The type of the vector displacement, or NUM_VECTOR_TYPES if the
200239281Sgonzo     mode does not include a vector displacement.  (Note that scalar
201239281Sgonzo     displacements are always int64_t.)  */
202239281Sgonzo  vector_type_index displacement_vector_type;
203239281Sgonzo
204239281Sgonzo  /* The units in which the vector or scalar displacement is measured,
205239281Sgonzo     or UNITS_none if the mode doesn't take a displacement.  */
206239281Sgonzo  units_index displacement_units;
207239281Sgonzo};
208239281Sgonzo
209239281Sgonzo/* Static information about a type suffix.  */
210239281Sgonzostruct type_suffix_info
211239281Sgonzo{
212239281Sgonzo  /* The suffix string itself.  */
213239281Sgonzo  const char *string;
214239281Sgonzo
215239281Sgonzo  /* The associated ACLE vector or predicate type.  */
216239281Sgonzo  vector_type_index vector_type : 8;
217239281Sgonzo
218239281Sgonzo  /* What kind of type the suffix represents.  */
219239281Sgonzo  type_class_index tclass : 8;
220239281Sgonzo
221239281Sgonzo  /* The number of bits and bytes in an element.  For predicates this
222239281Sgonzo     measures the associated data elements.  */
223239281Sgonzo  unsigned int element_bits : 8;
224239281Sgonzo  unsigned int element_bytes : 8;
225239281Sgonzo
226239281Sgonzo  /* True if the suffix is for an integer type.  */
227239281Sgonzo  unsigned int integer_p : 1;
228239281Sgonzo  /* True if the suffix is for an unsigned type.  */
229239281Sgonzo  unsigned int unsigned_p : 1;
230239281Sgonzo  /* True if the suffix is for a floating-point type.  */
231239281Sgonzo  unsigned int float_p : 1;
232239281Sgonzo  /* True if the suffix is for a boolean type.  */
233239281Sgonzo  unsigned int bool_p : 1;
234239281Sgonzo  unsigned int spare : 12;
235239281Sgonzo
236239281Sgonzo  /* The associated vector or predicate mode.  */
237239281Sgonzo  machine_mode vector_mode : 16;
238239281Sgonzo};
239239281Sgonzo
240239281Sgonzo/* Static information about a set of functions.  */
241239281Sgonzostruct function_group_info
242239281Sgonzo{
243239281Sgonzo  /* The base name, as a string.  */
244239281Sgonzo  const char *base_name;
245239281Sgonzo
246239281Sgonzo  /* Describes the behavior associated with the function base name.  */
247239281Sgonzo  const function_base *const *base;
248239281Sgonzo
249239281Sgonzo  /* The shape of the functions, as described above the class definition.
250239281Sgonzo     It's possible to have entries with the same base name but different
251239281Sgonzo     shapes.  */
252239281Sgonzo  const function_shape *const *shape;
253239281Sgonzo
254239281Sgonzo  /* A list of the available type suffixes, and of the available predication
255239281Sgonzo     types.  The function supports every combination of the two.
256239281Sgonzo
257239281Sgonzo     The list of type suffixes is terminated by two NUM_TYPE_SUFFIXES
258239281Sgonzo     while the list of predication types is terminated by NUM_PREDS.
259239281Sgonzo     The list of type suffixes is lexicographically ordered based
260239281Sgonzo     on the index value.  */
261239281Sgonzo  const type_suffix_pair *types;
262239281Sgonzo  const predication_index *preds;
263239281Sgonzo
264239281Sgonzo  /* The architecture extensions that the functions require, as a set of
265239281Sgonzo     AARCH64_FL_* flags.  */
266  uint64_t required_extensions;
267};
268
269/* Describes a single fully-resolved function (i.e. one that has a
270   unique full name).  */
271class GTY((user)) function_instance
272{
273public:
274  function_instance (const char *, const function_base *,
275		     const function_shape *, mode_suffix_index,
276		     const type_suffix_pair &, predication_index);
277
278  bool operator== (const function_instance &) const;
279  bool operator!= (const function_instance &) const;
280  hashval_t hash () const;
281
282  unsigned int call_properties () const;
283  bool reads_global_state_p () const;
284  bool modifies_global_state_p () const;
285  bool could_trap_p () const;
286
287  unsigned int vectors_per_tuple () const;
288  tree memory_scalar_type () const;
289  machine_mode memory_vector_mode () const;
290
291  const mode_suffix_info &mode_suffix () const;
292  tree base_vector_type () const;
293  tree displacement_vector_type () const;
294  units_index displacement_units () const;
295
296  const type_suffix_info &type_suffix (unsigned int) const;
297  tree scalar_type (unsigned int) const;
298  tree vector_type (unsigned int) const;
299  tree tuple_type (unsigned int) const;
300  unsigned int elements_per_vq (unsigned int i) const;
301  machine_mode vector_mode (unsigned int) const;
302  machine_mode gp_mode (unsigned int) const;
303
304  /* The properties of the function.  (The explicit "enum"s are required
305     for gengtype.)  */
306  const char *base_name;
307  const function_base *base;
308  const function_shape *shape;
309  enum mode_suffix_index mode_suffix_id;
310  type_suffix_pair type_suffix_ids;
311  enum predication_index pred;
312};
313
314class registered_function;
315
316/* A class for building and registering function decls.  */
317class function_builder
318{
319public:
320  function_builder ();
321  ~function_builder ();
322
323  void add_unique_function (const function_instance &, tree,
324			    vec<tree> &, uint64_t, bool);
325  void add_overloaded_function (const function_instance &, uint64_t);
326  void add_overloaded_functions (const function_group_info &,
327				 mode_suffix_index);
328
329  void register_function_group (const function_group_info &);
330
331private:
332  void append_name (const char *);
333  char *finish_name ();
334
335  char *get_name (const function_instance &, bool);
336
337  tree get_attributes (const function_instance &);
338
339  registered_function &add_function (const function_instance &,
340				     const char *, tree, tree,
341				     uint64_t, bool, bool);
342
343  /* The function type to use for functions that are resolved by
344     function_resolver.  */
345  tree m_overload_type;
346
347  /* True if we should create a separate decl for each instance of an
348     overloaded function, instead of using function_resolver.  */
349  bool m_direct_overloads;
350
351  /* Used for building up function names.  */
352  obstack m_string_obstack;
353
354  /* Maps all overloaded function names that we've registered so far
355     to their associated function_instances.  */
356  hash_map<nofree_string_hash, registered_function *> m_overload_names;
357};
358
359/* A base class for handling calls to built-in functions.  */
360class function_call_info : public function_instance
361{
362public:
363  function_call_info (location_t, const function_instance &, tree);
364
365  bool function_returns_void_p ();
366
367  /* The location of the call.  */
368  location_t location;
369
370  /* The FUNCTION_DECL that is being called.  */
371  tree fndecl;
372};
373
374/* A class for resolving an overloaded function call.  */
375class function_resolver : public function_call_info
376{
377public:
378  enum { SAME_SIZE = 256, HALF_SIZE, QUARTER_SIZE };
379  static const type_class_index SAME_TYPE_CLASS = NUM_TYPE_CLASSES;
380
381  function_resolver (location_t, const function_instance &, tree,
382		     vec<tree, va_gc> &);
383
384  tree get_vector_type (type_suffix_index);
385  const char *get_scalar_type_name (type_suffix_index);
386  tree get_argument_type (unsigned int);
387  bool scalar_argument_p (unsigned int);
388
389  tree report_no_such_form (type_suffix_index);
390  tree lookup_form (mode_suffix_index,
391		    type_suffix_index = NUM_TYPE_SUFFIXES,
392		    type_suffix_index = NUM_TYPE_SUFFIXES);
393  tree resolve_to (mode_suffix_index,
394		   type_suffix_index = NUM_TYPE_SUFFIXES,
395		   type_suffix_index = NUM_TYPE_SUFFIXES);
396
397  type_suffix_index infer_integer_scalar_type (unsigned int);
398  type_suffix_index infer_pointer_type (unsigned int, bool = false);
399  type_suffix_index infer_vector_or_tuple_type (unsigned int, unsigned int);
400  type_suffix_index infer_vector_type (unsigned int);
401  type_suffix_index infer_integer_vector_type (unsigned int);
402  type_suffix_index infer_unsigned_vector_type (unsigned int);
403  type_suffix_index infer_sd_vector_type (unsigned int);
404  type_suffix_index infer_tuple_type (unsigned int);
405
406  bool require_vector_or_scalar_type (unsigned int);
407
408  bool require_vector_type (unsigned int, vector_type_index);
409  bool require_matching_vector_type (unsigned int, type_suffix_index);
410  bool require_derived_vector_type (unsigned int, unsigned int,
411				    type_suffix_index,
412				    type_class_index = SAME_TYPE_CLASS,
413				    unsigned int = SAME_SIZE);
414
415  bool require_scalar_type (unsigned int, const char *);
416  bool require_pointer_type (unsigned int);
417  bool require_matching_integer_scalar_type (unsigned int, unsigned int,
418					     type_suffix_index);
419  bool require_derived_scalar_type (unsigned int, type_class_index,
420				    unsigned int = SAME_SIZE);
421  bool require_matching_pointer_type (unsigned int, unsigned int,
422				      type_suffix_index);
423  bool require_integer_immediate (unsigned int);
424
425  vector_type_index infer_vector_base_type (unsigned int);
426  vector_type_index infer_vector_displacement_type (unsigned int);
427
428  mode_suffix_index resolve_sv_displacement (unsigned int,
429					     type_suffix_index, bool);
430  mode_suffix_index resolve_gather_address (unsigned int,
431					    type_suffix_index, bool);
432  mode_suffix_index resolve_adr_address (unsigned int);
433
434  bool check_num_arguments (unsigned int);
435  bool check_gp_argument (unsigned int, unsigned int &, unsigned int &);
436  tree resolve_unary (type_class_index = SAME_TYPE_CLASS,
437		      unsigned int = SAME_SIZE, bool = false);
438  tree resolve_uniform (unsigned int, unsigned int = 0);
439  tree resolve_uniform_opt_n (unsigned int);
440  tree finish_opt_n_resolution (unsigned int, unsigned int, type_suffix_index,
441				type_class_index = SAME_TYPE_CLASS,
442				unsigned int = SAME_SIZE,
443				type_suffix_index = NUM_TYPE_SUFFIXES);
444
445  tree resolve ();
446
447private:
448  /* The arguments to the overloaded function.  */
449  vec<tree, va_gc> &m_arglist;
450};
451
452/* A class for checking that the semantic constraints on a function call are
453   satisfied, such as arguments being integer constant expressions with
454   a particular range.  The parent class's FNDECL is the decl that was
455   called in the original source, before overload resolution.  */
456class function_checker : public function_call_info
457{
458public:
459  function_checker (location_t, const function_instance &, tree,
460		    tree, unsigned int, tree *);
461
462  bool require_immediate_either_or (unsigned int, HOST_WIDE_INT,
463				    HOST_WIDE_INT);
464  bool require_immediate_enum (unsigned int, tree);
465  bool require_immediate_lane_index (unsigned int, unsigned int = 1);
466  bool require_immediate_one_of (unsigned int, HOST_WIDE_INT, HOST_WIDE_INT,
467				 HOST_WIDE_INT, HOST_WIDE_INT);
468  bool require_immediate_range (unsigned int, HOST_WIDE_INT, HOST_WIDE_INT);
469
470  bool check ();
471
472private:
473  bool argument_exists_p (unsigned int);
474
475  bool require_immediate (unsigned int, HOST_WIDE_INT &);
476
477  /* The type of the resolved function.  */
478  tree m_fntype;
479
480  /* The arguments to the function.  */
481  unsigned int m_nargs;
482  tree *m_args;
483
484  /* The first argument not associated with the function's predication
485     type.  */
486  unsigned int m_base_arg;
487};
488
489/* A class for folding a gimple function call.  */
490class gimple_folder : public function_call_info
491{
492public:
493  gimple_folder (const function_instance &, tree,
494		 gimple_stmt_iterator *, gcall *);
495
496  tree force_vector (gimple_seq &, tree, tree);
497  tree convert_pred (gimple_seq &, tree, unsigned int);
498  tree fold_contiguous_base (gimple_seq &, tree);
499  tree load_store_cookie (tree);
500
501  gimple *redirect_call (const function_instance &);
502  gimple *fold_to_pfalse ();
503  gimple *fold_to_ptrue ();
504  gimple *fold_to_vl_pred (unsigned int);
505
506  gimple *fold ();
507
508  /* Where to insert extra statements that feed the final replacement.  */
509  gimple_stmt_iterator *gsi;
510
511  /* The call we're folding.  */
512  gcall *call;
513
514  /* The result of the call, or null if none.  */
515  tree lhs;
516};
517
518/* A class for expanding a function call into RTL.  */
519class function_expander : public function_call_info
520{
521public:
522  function_expander (const function_instance &, tree, tree, rtx);
523  rtx expand ();
524
525  insn_code direct_optab_handler (optab, unsigned int = 0);
526  insn_code direct_optab_handler_for_sign (optab, optab, unsigned int = 0,
527					   machine_mode = E_VOIDmode);
528
529  bool overlaps_input_p (rtx);
530
531  rtx convert_to_pmode (rtx);
532  rtx get_contiguous_base (machine_mode);
533  rtx get_fallback_value (machine_mode, unsigned int,
534			  unsigned int, unsigned int &);
535  rtx get_reg_target ();
536  rtx get_nonoverlapping_reg_target ();
537
538  void add_output_operand (insn_code);
539  void add_input_operand (insn_code, rtx);
540  void add_integer_operand (HOST_WIDE_INT);
541  void add_mem_operand (machine_mode, rtx);
542  void add_address_operand (rtx);
543  void add_fixed_operand (rtx);
544  rtx generate_insn (insn_code);
545
546  void prepare_gather_address_operands (unsigned int, bool = true);
547  void prepare_prefetch_operands ();
548  void add_ptrue_hint (unsigned int, machine_mode);
549  void rotate_inputs_left (unsigned int, unsigned int);
550  bool try_negating_argument (unsigned int, machine_mode);
551
552  rtx use_exact_insn (insn_code);
553  rtx use_unpred_insn (insn_code);
554  rtx use_pred_x_insn (insn_code);
555  rtx use_cond_insn (insn_code, unsigned int = DEFAULT_MERGE_ARGNO);
556  rtx use_vcond_mask_insn (insn_code, unsigned int = DEFAULT_MERGE_ARGNO);
557  rtx use_contiguous_load_insn (insn_code);
558  rtx use_contiguous_prefetch_insn (insn_code);
559  rtx use_contiguous_store_insn (insn_code);
560
561  rtx map_to_rtx_codes (rtx_code, rtx_code, int,
562			unsigned int = DEFAULT_MERGE_ARGNO);
563  rtx map_to_unspecs (int, int, int, unsigned int = DEFAULT_MERGE_ARGNO);
564
565  /* The function call expression.  */
566  tree call_expr;
567
568  /* For functions that return a value, this is the preferred location
569     of that value.  It could be null or could have a different mode
570     from the function return type.  */
571  rtx possible_target;
572
573  /* The expanded arguments.  */
574  auto_vec<rtx, 16> args;
575
576private:
577  /* Used to build up the operands to an instruction.  */
578  auto_vec<expand_operand, 8> m_ops;
579};
580
581/* Provides information about a particular function base name, and handles
582   tasks related to the base name.  */
583class function_base
584{
585public:
586  /* Return a set of CP_* flags that describe what the function might do,
587     in addition to reading its arguments and returning a result.  */
588  virtual unsigned int call_properties (const function_instance &) const;
589
590  /* If the function operates on tuples of vectors, return the number
591     of vectors in the tuples, otherwise return 1.  */
592  virtual unsigned int vectors_per_tuple () const { return 1; }
593
594  /* If the function addresses memory, return the type of a single
595     scalar memory element.  */
596  virtual tree
597  memory_scalar_type (const function_instance &) const
598  {
599    gcc_unreachable ();
600  }
601
602  /* If the function addresses memory, return a vector mode whose
603     GET_MODE_NUNITS is the number of elements addressed and whose
604     GET_MODE_INNER is the mode of a single scalar memory element.  */
605  virtual machine_mode
606  memory_vector_mode (const function_instance &) const
607  {
608    gcc_unreachable ();
609  }
610
611  /* Try to fold the given gimple call.  Return the new gimple statement
612     on success, otherwise return null.  */
613  virtual gimple *fold (gimple_folder &) const { return NULL; }
614
615  /* Expand the given call into rtl.  Return the result of the function,
616     or an arbitrary value if the function doesn't return a result.  */
617  virtual rtx expand (function_expander &) const = 0;
618};
619
620/* Classifies functions into "shapes".  The idea is to take all the
621   type signatures for a set of functions, remove the governing predicate
622   (if any), and classify what's left based on:
623
624   - the number of arguments
625
626   - the process of determining the types in the signature from the mode
627     and type suffixes in the function name (including types that are not
628     affected by the suffixes)
629
630   - which arguments must be integer constant expressions, and what range
631     those arguments have
632
633   - the process for mapping overloaded names to "full" names.  */
634class function_shape
635{
636public:
637  virtual bool explicit_type_suffix_p (unsigned int) const = 0;
638
639  /* Define all functions associated with the given group.  */
640  virtual void build (function_builder &,
641		      const function_group_info &) const = 0;
642
643  /* Try to resolve the overloaded call.  Return the non-overloaded
644     function decl on success and error_mark_node on failure.  */
645  virtual tree resolve (function_resolver &) const = 0;
646
647  /* Check whether the given call is semantically valid.  Return true
648     if it is, otherwise report an error and return false.  */
649  virtual bool check (function_checker &) const { return true; }
650};
651
652/* RAII class for enabling enough SVE features to define the built-in
653   types and implement the arm_sve.h pragma.  */
654class sve_switcher
655{
656public:
657  sve_switcher ();
658  ~sve_switcher ();
659
660private:
661  unsigned long m_old_isa_flags;
662  bool m_old_general_regs_only;
663  bool m_old_have_regs_of_mode[MAX_MACHINE_MODE];
664};
665
666extern const type_suffix_info type_suffixes[NUM_TYPE_SUFFIXES + 1];
667extern const mode_suffix_info mode_suffixes[MODE_none + 1];
668
669extern tree scalar_types[NUM_VECTOR_TYPES];
670extern tree acle_vector_types[MAX_TUPLE_SIZE][NUM_VECTOR_TYPES + 1];
671extern tree acle_svpattern;
672extern tree acle_svprfop;
673
674/* Return the ACLE type svbool_t.  */
675inline tree
676get_svbool_t (void)
677{
678  return acle_vector_types[0][VECTOR_TYPE_svbool_t];
679}
680
681/* Try to find a mode with the given mode_suffix_info fields.  Return the
682   mode on success or MODE_none on failure.  */
683inline mode_suffix_index
684find_mode_suffix (vector_type_index base_vector_type,
685		  vector_type_index displacement_vector_type,
686		  units_index displacement_units)
687{
688  for (unsigned int mode_i = 0; mode_i < ARRAY_SIZE (mode_suffixes); ++mode_i)
689    {
690      const mode_suffix_info &mode = mode_suffixes[mode_i];
691      if (mode.base_vector_type == base_vector_type
692	  && mode.displacement_vector_type == displacement_vector_type
693	  && mode.displacement_units == displacement_units)
694	return mode_suffix_index (mode_i);
695    }
696  return MODE_none;
697}
698
699/* Return the type suffix associated with ELEMENT_BITS-bit elements of type
700   class TCLASS.  */
701inline type_suffix_index
702find_type_suffix (type_class_index tclass, unsigned int element_bits)
703{
704  for (unsigned int i = 0; i < NUM_TYPE_SUFFIXES; ++i)
705    if (type_suffixes[i].tclass == tclass
706	&& type_suffixes[i].element_bits == element_bits)
707      return type_suffix_index (i);
708  gcc_unreachable ();
709}
710
711/* Return the single field in tuple type TYPE.  */
712inline tree
713tuple_type_field (tree type)
714{
715  for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
716    if (TREE_CODE (field) == FIELD_DECL)
717      return field;
718  gcc_unreachable ();
719}
720
721inline function_instance::
722function_instance (const char *base_name_in,
723		   const function_base *base_in,
724		   const function_shape *shape_in,
725		   mode_suffix_index mode_suffix_id_in,
726		   const type_suffix_pair &type_suffix_ids_in,
727		   predication_index pred_in)
728  : base_name (base_name_in), base (base_in), shape (shape_in),
729    mode_suffix_id (mode_suffix_id_in), pred (pred_in)
730{
731  memcpy (type_suffix_ids, type_suffix_ids_in, sizeof (type_suffix_ids));
732}
733
734inline bool
735function_instance::operator== (const function_instance &other) const
736{
737  return (base == other.base
738	  && shape == other.shape
739	  && mode_suffix_id == other.mode_suffix_id
740	  && pred == other.pred
741	  && type_suffix_ids[0] == other.type_suffix_ids[0]
742	  && type_suffix_ids[1] == other.type_suffix_ids[1]);
743}
744
745inline bool
746function_instance::operator!= (const function_instance &other) const
747{
748  return !operator== (other);
749}
750
751/* If the function operates on tuples of vectors, return the number
752   of vectors in the tuples, otherwise return 1.  */
753inline unsigned int
754function_instance::vectors_per_tuple () const
755{
756  return base->vectors_per_tuple ();
757}
758
759/* If the function addresses memory, return the type of a single
760   scalar memory element.  */
761inline tree
762function_instance::memory_scalar_type () const
763{
764  return base->memory_scalar_type (*this);
765}
766
767/* If the function addresses memory, return a vector mode whose
768   GET_MODE_NUNITS is the number of elements addressed and whose
769   GET_MODE_INNER is the mode of a single scalar memory element.  */
770inline machine_mode
771function_instance::memory_vector_mode () const
772{
773  return base->memory_vector_mode (*this);
774}
775
776/* Return information about the function's mode suffix.  */
777inline const mode_suffix_info &
778function_instance::mode_suffix () const
779{
780  return mode_suffixes[mode_suffix_id];
781}
782
783/* Return the type of the function's vector base address argument,
784   or null it doesn't have a vector base address.  */
785inline tree
786function_instance::base_vector_type () const
787{
788  return acle_vector_types[0][mode_suffix ().base_vector_type];
789}
790
791/* Return the type of the function's vector index or offset argument,
792   or null if doesn't have a vector index or offset argument.  */
793inline tree
794function_instance::displacement_vector_type () const
795{
796  return acle_vector_types[0][mode_suffix ().displacement_vector_type];
797}
798
799/* If the function takes a vector or scalar displacement, return the units
800   in which the displacement is measured, otherwise return UNITS_none.  */
801inline units_index
802function_instance::displacement_units () const
803{
804  return mode_suffix ().displacement_units;
805}
806
807/* Return information about type suffix I.  */
808inline const type_suffix_info &
809function_instance::type_suffix (unsigned int i) const
810{
811  return type_suffixes[type_suffix_ids[i]];
812}
813
814/* Return the scalar type associated with type suffix I.  */
815inline tree
816function_instance::scalar_type (unsigned int i) const
817{
818  return scalar_types[type_suffix (i).vector_type];
819}
820
821/* Return the vector type associated with type suffix I.  */
822inline tree
823function_instance::vector_type (unsigned int i) const
824{
825  return acle_vector_types[0][type_suffix (i).vector_type];
826}
827
828/* If the function operates on tuples of vectors, return the tuple type
829   associated with type suffix I, otherwise return the vector type associated
830   with type suffix I.  */
831inline tree
832function_instance::tuple_type (unsigned int i) const
833{
834  unsigned int num_vectors = vectors_per_tuple ();
835  return acle_vector_types[num_vectors - 1][type_suffix (i).vector_type];
836}
837
838/* Return the number of elements of type suffix I that fit within a
839   128-bit block.  */
840inline unsigned int
841function_instance::elements_per_vq (unsigned int i) const
842{
843  return 128 / type_suffix (i).element_bits;
844}
845
846/* Return the vector or predicate mode associated with type suffix I.  */
847inline machine_mode
848function_instance::vector_mode (unsigned int i) const
849{
850  return type_suffix (i).vector_mode;
851}
852
853/* Return the mode of the governing predicate to use when operating on
854   type suffix I.  */
855inline machine_mode
856function_instance::gp_mode (unsigned int i) const
857{
858  return aarch64_sve_pred_mode (type_suffix (i).element_bytes).require ();
859}
860
861/* Return true if the function has no return value.  */
862inline bool
863function_call_info::function_returns_void_p ()
864{
865  return TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node;
866}
867
868/* Default implementation of function::call_properties, with conservatively
869   correct behavior for floating-point instructions.  */
870inline unsigned int
871function_base::call_properties (const function_instance &instance) const
872{
873  unsigned int flags = 0;
874  if (instance.type_suffix (0).float_p || instance.type_suffix (1).float_p)
875    flags |= CP_READ_FPCR | CP_RAISE_FP_EXCEPTIONS;
876  return flags;
877}
878
879}
880
881#endif
882