1 /* ACLE support for AArch64 SVE
2    Copyright (C) 2018-2021 Free Software Foundation, Inc.
3 
4    This file is part of GCC.
5 
6    GCC is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10 
11    GCC is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with GCC; see the file COPYING3.  If not see
18    <http://www.gnu.org/licenses/>.  */
19 
20 #ifndef GCC_AARCH64_SVE_BUILTINS_H
21 #define GCC_AARCH64_SVE_BUILTINS_H
22 
23 /* The full name of an SVE ACLE function is the concatenation of:
24 
25    - the base name ("svadd", etc.)
26    - the "mode" suffix ("_n", "_index", etc.)
27    - the type suffixes ("_s32", "_b8", etc.)
28    - the predication suffix ("_x", "_z", etc.)
29 
30    Each piece of information is individually useful, so we retain this
31    classification throughout:
32 
33    - function_base represents the base name
34 
35    - mode_suffix_index represents the mode suffix
36 
37    - type_suffix_index represents individual type suffixes, while
38      type_suffix_pair represents a pair of them
39 
40    - prediction_index extends the predication suffix with an additional
41      alternative: PRED_implicit for implicitly-predicated operations
42 
43    In addition to its unique full name, a function may have a shorter
44    overloaded alias.  This alias removes pieces of the suffixes that
45    can be inferred from the arguments, such as by shortening the mode
46    suffix or dropping some of the type suffixes.  The base name and the
47    predication suffix stay the same.
48 
49    The function_shape class describes what arguments a given function
50    takes and what its overloaded alias is called.  In broad terms,
51    function_base describes how the underlying instruction behaves while
52    function_shape describes how that instruction has been presented at
53    the language level.
54 
55    The static list of functions uses function_group to describe a group
56    of related functions.  The function_builder class is responsible for
57    expanding this static description into a list of individual functions
58    and registering the associated built-in functions.  function_instance
59    describes one of these individual functions in terms of the properties
60    described above.
61 
62    The classes involved in compiling a function call are:
63 
64    - function_resolver, which resolves an overloaded function call to a
65      specific function_instance and its associated function decl
66 
67    - function_checker, which checks whether the values of the arguments
68      conform to the ACLE specification
69 
70    - gimple_folder, which tries to fold a function call at the gimple level
71 
72    - function_expander, which expands a function call into rtl instructions
73 
74    function_resolver and function_checker operate at the language level
75    and so are associated with the function_shape.  gimple_folder and
76    function_expander are concerned with the behavior of the function
77    and so are associated with the function_base.
78 
79    Note that we've specifically chosen not to fold calls in the frontend,
80    since SVE intrinsics will hardly ever fold a useful language-level
81    constant.  */
82 namespace aarch64_sve
83 {
84 /* The maximum number of vectors in an ACLE tuple type.  */
85 const unsigned int MAX_TUPLE_SIZE = 4;
86 
87 /* Used to represent the default merge argument index for _m functions.
88    The actual index depends on how many arguments the function takes.  */
89 const unsigned int DEFAULT_MERGE_ARGNO = ~0U;
90 
91 /* Flags that describe what a function might do, in addition to reading
92    its arguments and returning a result.  */
93 const unsigned int CP_READ_FPCR = 1U << 0;
94 const unsigned int CP_RAISE_FP_EXCEPTIONS = 1U << 1;
95 const unsigned int CP_READ_MEMORY = 1U << 2;
96 const unsigned int CP_PREFETCH_MEMORY = 1U << 3;
97 const unsigned int CP_WRITE_MEMORY = 1U << 4;
98 const unsigned int CP_READ_FFR = 1U << 5;
99 const unsigned int CP_WRITE_FFR = 1U << 6;
100 
101 /* Enumerates the SVE predicate and (data) vector types, together called
102    "vector types" for brevity.  */
103 enum vector_type_index
104 {
105 #define DEF_SVE_TYPE(ACLE_NAME, NCHARS, ABI_NAME, SCALAR_TYPE) \
106   VECTOR_TYPE_ ## ACLE_NAME,
107 #include "aarch64-sve-builtins.def"
108   NUM_VECTOR_TYPES
109 };
110 
111 /* Classifies the available measurement units for an address displacement.  */
112 enum units_index
113 {
114   UNITS_none,
115   UNITS_bytes,
116   UNITS_elements,
117   UNITS_vectors
118 };
119 
120 /* Describes the various uses of a governing predicate.  */
121 enum predication_index
122 {
123   /* No governing predicate is present.  */
124   PRED_none,
125 
126   /* A governing predicate is present but there is no predication suffix
127      associated with it.  This is used when the result is neither a vector
128      nor a predicate, since the distinction between "zeroing" and "merging"
129      doesn't apply in that case.  It is also used when a suffix would be
130      redundant (such as for loads and comparisons, which are inherently
131      zeroing operations).  */
132   PRED_implicit,
133 
134   /* Merging predication: copy inactive lanes from the first data argument
135      to the vector result.  */
136   PRED_m,
137 
138   /* "Don't care" predication: set inactive lanes of the vector result
139      to arbitrary values.  */
140   PRED_x,
141 
142   /* Zero predication: set inactive lanes of the vector result to zero.  */
143   PRED_z,
144 
145   NUM_PREDS
146 };
147 
148 /* Classifies element types, based on type suffixes with the bit count
149    removed.  */
150 enum type_class_index
151 {
152   TYPE_bool,
153   TYPE_bfloat,
154   TYPE_float,
155   TYPE_signed,
156   TYPE_unsigned,
157   NUM_TYPE_CLASSES
158 };
159 
160 /* Classifies an operation into "modes"; for example, to distinguish
161    vector-scalar operations from vector-vector operations, or to
162    distinguish between different addressing modes.  This classification
163    accounts for the function suffixes that occur between the base name
164    and the first type suffix.  */
165 enum mode_suffix_index
166 {
167 #define DEF_SVE_MODE(NAME, BASE, DISPLACEMENT, UNITS) MODE_##NAME,
168 #include "aarch64-sve-builtins.def"
169   MODE_none
170 };
171 
172 /* Enumerates the possible type suffixes.  Each suffix is associated with
173    a vector type, but for predicates provides extra information about the
174    element size.  */
175 enum type_suffix_index
176 {
177 #define DEF_SVE_TYPE_SUFFIX(NAME, ACLE_TYPE, CLASS, BITS, MODE) \
178   TYPE_SUFFIX_ ## NAME,
179 #include "aarch64-sve-builtins.def"
180   NUM_TYPE_SUFFIXES
181 };
182 
183 /* Combines two type suffixes.  */
184 typedef enum type_suffix_index type_suffix_pair[2];
185 
186 class function_base;
187 class function_shape;
188 
189 /* Static information about a mode suffix.  */
190 struct mode_suffix_info
191 {
192   /* The suffix string itself.  */
193   const char *string;
194 
195   /* The type of the vector base address, or NUM_VECTOR_TYPES if the
196      mode does not include a vector base address.  */
197   vector_type_index base_vector_type;
198 
199   /* The type of the vector displacement, or NUM_VECTOR_TYPES if the
200      mode does not include a vector displacement.  (Note that scalar
201      displacements are always int64_t.)  */
202   vector_type_index displacement_vector_type;
203 
204   /* The units in which the vector or scalar displacement is measured,
205      or UNITS_none if the mode doesn't take a displacement.  */
206   units_index displacement_units;
207 };
208 
209 /* Static information about a type suffix.  */
210 struct type_suffix_info
211 {
212   /* The suffix string itself.  */
213   const char *string;
214 
215   /* The associated ACLE vector or predicate type.  */
216   vector_type_index vector_type : 8;
217 
218   /* What kind of type the suffix represents.  */
219   type_class_index tclass : 8;
220 
221   /* The number of bits and bytes in an element.  For predicates this
222      measures the associated data elements.  */
223   unsigned int element_bits : 8;
224   unsigned int element_bytes : 8;
225 
226   /* True if the suffix is for an integer type.  */
227   unsigned int integer_p : 1;
228   /* True if the suffix is for an unsigned type.  */
229   unsigned int unsigned_p : 1;
230   /* True if the suffix is for a floating-point type.  */
231   unsigned int float_p : 1;
232   /* True if the suffix is for a boolean type.  */
233   unsigned int bool_p : 1;
234   unsigned int spare : 12;
235 
236   /* The associated vector or predicate mode.  */
237   machine_mode vector_mode : 16;
238 };
239 
240 /* Static information about a set of functions.  */
241 struct function_group_info
242 {
243   /* The base name, as a string.  */
244   const char *base_name;
245 
246   /* Describes the behavior associated with the function base name.  */
247   const function_base *const *base;
248 
249   /* The shape of the functions, as described above the class definition.
250      It's possible to have entries with the same base name but different
251      shapes.  */
252   const function_shape *const *shape;
253 
254   /* A list of the available type suffixes, and of the available predication
255      types.  The function supports every combination of the two.
256 
257      The list of type suffixes is terminated by two NUM_TYPE_SUFFIXES
258      while the list of predication types is terminated by NUM_PREDS.
259      The list of type suffixes is lexicographically ordered based
260      on the index value.  */
261   const type_suffix_pair *types;
262   const predication_index *preds;
263 
264   /* The architecture extensions that the functions require, as a set of
265      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).  */
class(user)271 class GTY((user)) function_instance
272 {
273 public:
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 
314 class registered_function;
315 
316 /* A class for building and registering function decls.  */
317 class function_builder
318 {
319 public:
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 
331 private:
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.  */
360 class function_call_info : public function_instance
361 {
362 public:
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.  */
375 class function_resolver : public function_call_info
376 {
377 public:
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 
447 private:
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.  */
456 class function_checker : public function_call_info
457 {
458 public:
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 
472 private:
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.  */
490 class gimple_folder : public function_call_info
491 {
492 public:
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.  */
519 class function_expander : public function_call_info
520 {
521 public:
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 
576 private:
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.  */
583 class function_base
584 {
585 public:
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.  */
vectors_per_tuple()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
memory_scalar_type(const function_instance &)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
memory_vector_mode(const function_instance &)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.  */
fold(gimple_folder &)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.  */
634 class function_shape
635 {
636 public:
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.  */
check(function_checker &)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.  */
654 class sve_switcher
655 {
656 public:
657   sve_switcher ();
658   ~sve_switcher ();
659 
660 private:
661   unsigned long m_old_isa_flags;
662   unsigned int m_old_maximum_field_alignment;
663   bool m_old_general_regs_only;
664   bool m_old_have_regs_of_mode[MAX_MACHINE_MODE];
665 };
666 
667 extern const type_suffix_info type_suffixes[NUM_TYPE_SUFFIXES + 1];
668 extern const mode_suffix_info mode_suffixes[MODE_none + 1];
669 
670 extern tree scalar_types[NUM_VECTOR_TYPES];
671 extern tree acle_vector_types[MAX_TUPLE_SIZE][NUM_VECTOR_TYPES + 1];
672 extern tree acle_svpattern;
673 extern tree acle_svprfop;
674 
675 /* Return the ACLE type svbool_t.  */
676 inline tree
get_svbool_t(void)677 get_svbool_t (void)
678 {
679   return acle_vector_types[0][VECTOR_TYPE_svbool_t];
680 }
681 
682 /* Try to find a mode with the given mode_suffix_info fields.  Return the
683    mode on success or MODE_none on failure.  */
684 inline mode_suffix_index
find_mode_suffix(vector_type_index base_vector_type,vector_type_index displacement_vector_type,units_index displacement_units)685 find_mode_suffix (vector_type_index base_vector_type,
686 		  vector_type_index displacement_vector_type,
687 		  units_index displacement_units)
688 {
689   for (unsigned int mode_i = 0; mode_i < ARRAY_SIZE (mode_suffixes); ++mode_i)
690     {
691       const mode_suffix_info &mode = mode_suffixes[mode_i];
692       if (mode.base_vector_type == base_vector_type
693 	  && mode.displacement_vector_type == displacement_vector_type
694 	  && mode.displacement_units == displacement_units)
695 	return mode_suffix_index (mode_i);
696     }
697   return MODE_none;
698 }
699 
700 /* Return the type suffix associated with ELEMENT_BITS-bit elements of type
701    class TCLASS.  */
702 inline type_suffix_index
find_type_suffix(type_class_index tclass,unsigned int element_bits)703 find_type_suffix (type_class_index tclass, unsigned int element_bits)
704 {
705   for (unsigned int i = 0; i < NUM_TYPE_SUFFIXES; ++i)
706     if (type_suffixes[i].tclass == tclass
707 	&& type_suffixes[i].element_bits == element_bits)
708       return type_suffix_index (i);
709   gcc_unreachable ();
710 }
711 
712 /* Return the single field in tuple type TYPE.  */
713 inline tree
tuple_type_field(tree type)714 tuple_type_field (tree type)
715 {
716   for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
717     if (TREE_CODE (field) == FIELD_DECL)
718       return field;
719   gcc_unreachable ();
720 }
721 
722 inline function_instance::
function_instance(const char * base_name_in,const function_base * base_in,const function_shape * shape_in,mode_suffix_index mode_suffix_id_in,const type_suffix_pair & type_suffix_ids_in,predication_index pred_in)723 function_instance (const char *base_name_in,
724 		   const function_base *base_in,
725 		   const function_shape *shape_in,
726 		   mode_suffix_index mode_suffix_id_in,
727 		   const type_suffix_pair &type_suffix_ids_in,
728 		   predication_index pred_in)
729   : base_name (base_name_in), base (base_in), shape (shape_in),
730     mode_suffix_id (mode_suffix_id_in), pred (pred_in)
731 {
732   memcpy (type_suffix_ids, type_suffix_ids_in, sizeof (type_suffix_ids));
733 }
734 
735 inline bool
736 function_instance::operator== (const function_instance &other) const
737 {
738   return (base == other.base
739 	  && shape == other.shape
740 	  && mode_suffix_id == other.mode_suffix_id
741 	  && pred == other.pred
742 	  && type_suffix_ids[0] == other.type_suffix_ids[0]
743 	  && type_suffix_ids[1] == other.type_suffix_ids[1]);
744 }
745 
746 inline bool
747 function_instance::operator!= (const function_instance &other) const
748 {
749   return !operator== (other);
750 }
751 
752 /* If the function operates on tuples of vectors, return the number
753    of vectors in the tuples, otherwise return 1.  */
754 inline unsigned int
vectors_per_tuple()755 function_instance::vectors_per_tuple () const
756 {
757   return base->vectors_per_tuple ();
758 }
759 
760 /* If the function addresses memory, return the type of a single
761    scalar memory element.  */
762 inline tree
memory_scalar_type()763 function_instance::memory_scalar_type () const
764 {
765   return base->memory_scalar_type (*this);
766 }
767 
768 /* If the function addresses memory, return a vector mode whose
769    GET_MODE_NUNITS is the number of elements addressed and whose
770    GET_MODE_INNER is the mode of a single scalar memory element.  */
771 inline machine_mode
memory_vector_mode()772 function_instance::memory_vector_mode () const
773 {
774   return base->memory_vector_mode (*this);
775 }
776 
777 /* Return information about the function's mode suffix.  */
778 inline const mode_suffix_info &
mode_suffix()779 function_instance::mode_suffix () const
780 {
781   return mode_suffixes[mode_suffix_id];
782 }
783 
784 /* Return the type of the function's vector base address argument,
785    or null it doesn't have a vector base address.  */
786 inline tree
base_vector_type()787 function_instance::base_vector_type () const
788 {
789   return acle_vector_types[0][mode_suffix ().base_vector_type];
790 }
791 
792 /* Return the type of the function's vector index or offset argument,
793    or null if doesn't have a vector index or offset argument.  */
794 inline tree
displacement_vector_type()795 function_instance::displacement_vector_type () const
796 {
797   return acle_vector_types[0][mode_suffix ().displacement_vector_type];
798 }
799 
800 /* If the function takes a vector or scalar displacement, return the units
801    in which the displacement is measured, otherwise return UNITS_none.  */
802 inline units_index
displacement_units()803 function_instance::displacement_units () const
804 {
805   return mode_suffix ().displacement_units;
806 }
807 
808 /* Return information about type suffix I.  */
809 inline const type_suffix_info &
type_suffix(unsigned int i)810 function_instance::type_suffix (unsigned int i) const
811 {
812   return type_suffixes[type_suffix_ids[i]];
813 }
814 
815 /* Return the scalar type associated with type suffix I.  */
816 inline tree
scalar_type(unsigned int i)817 function_instance::scalar_type (unsigned int i) const
818 {
819   return scalar_types[type_suffix (i).vector_type];
820 }
821 
822 /* Return the vector type associated with type suffix I.  */
823 inline tree
vector_type(unsigned int i)824 function_instance::vector_type (unsigned int i) const
825 {
826   return acle_vector_types[0][type_suffix (i).vector_type];
827 }
828 
829 /* If the function operates on tuples of vectors, return the tuple type
830    associated with type suffix I, otherwise return the vector type associated
831    with type suffix I.  */
832 inline tree
tuple_type(unsigned int i)833 function_instance::tuple_type (unsigned int i) const
834 {
835   unsigned int num_vectors = vectors_per_tuple ();
836   return acle_vector_types[num_vectors - 1][type_suffix (i).vector_type];
837 }
838 
839 /* Return the number of elements of type suffix I that fit within a
840    128-bit block.  */
841 inline unsigned int
elements_per_vq(unsigned int i)842 function_instance::elements_per_vq (unsigned int i) const
843 {
844   return 128 / type_suffix (i).element_bits;
845 }
846 
847 /* Return the vector or predicate mode associated with type suffix I.  */
848 inline machine_mode
vector_mode(unsigned int i)849 function_instance::vector_mode (unsigned int i) const
850 {
851   return type_suffix (i).vector_mode;
852 }
853 
854 /* Return the mode of the governing predicate to use when operating on
855    type suffix I.  */
856 inline machine_mode
gp_mode(unsigned int i)857 function_instance::gp_mode (unsigned int i) const
858 {
859   return aarch64_sve_pred_mode (type_suffix (i).element_bytes).require ();
860 }
861 
862 /* Return true if the function has no return value.  */
863 inline bool
function_returns_void_p()864 function_call_info::function_returns_void_p ()
865 {
866   return TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node;
867 }
868 
869 /* Default implementation of function::call_properties, with conservatively
870    correct behavior for floating-point instructions.  */
871 inline unsigned int
call_properties(const function_instance & instance)872 function_base::call_properties (const function_instance &instance) const
873 {
874   unsigned int flags = 0;
875   if (instance.type_suffix (0).float_p || instance.type_suffix (1).float_p)
876     flags |= CP_READ_FPCR | CP_RAISE_FP_EXCEPTIONS;
877   return flags;
878 }
879 
880 }
881 
882 #endif
883