aarch64-sve-builtins.h revision 1.1 1 1.1 mrg /* ACLE support for AArch64 SVE
2 1.1 mrg Copyright (C) 2018-2020 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 mrg class sve_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 mrg unsigned long m_old_isa_flags;
662 1.1 mrg bool m_old_general_regs_only;
663 1.1 mrg bool m_old_have_regs_of_mode[MAX_MACHINE_MODE];
664 1.1 mrg };
665 1.1 mrg
666 1.1 mrg extern const type_suffix_info type_suffixes[NUM_TYPE_SUFFIXES + 1];
667 1.1 mrg extern const mode_suffix_info mode_suffixes[MODE_none + 1];
668 1.1 mrg
669 1.1 mrg extern tree scalar_types[NUM_VECTOR_TYPES];
670 1.1 mrg extern tree acle_vector_types[MAX_TUPLE_SIZE][NUM_VECTOR_TYPES + 1];
671 1.1 mrg extern tree acle_svpattern;
672 1.1 mrg extern tree acle_svprfop;
673 1.1 mrg
674 1.1 mrg /* Return the ACLE type svbool_t. */
675 1.1 mrg inline tree
676 1.1 mrg get_svbool_t (void)
677 1.1 mrg {
678 1.1 mrg return acle_vector_types[0][VECTOR_TYPE_svbool_t];
679 1.1 mrg }
680 1.1 mrg
681 1.1 mrg /* Try to find a mode with the given mode_suffix_info fields. Return the
682 1.1 mrg mode on success or MODE_none on failure. */
683 1.1 mrg inline mode_suffix_index
684 1.1 mrg find_mode_suffix (vector_type_index base_vector_type,
685 1.1 mrg vector_type_index displacement_vector_type,
686 1.1 mrg units_index displacement_units)
687 1.1 mrg {
688 1.1 mrg for (unsigned int mode_i = 0; mode_i < ARRAY_SIZE (mode_suffixes); ++mode_i)
689 1.1 mrg {
690 1.1 mrg const mode_suffix_info &mode = mode_suffixes[mode_i];
691 1.1 mrg if (mode.base_vector_type == base_vector_type
692 1.1 mrg && mode.displacement_vector_type == displacement_vector_type
693 1.1 mrg && mode.displacement_units == displacement_units)
694 1.1 mrg return mode_suffix_index (mode_i);
695 1.1 mrg }
696 1.1 mrg return MODE_none;
697 1.1 mrg }
698 1.1 mrg
699 1.1 mrg /* Return the type suffix associated with ELEMENT_BITS-bit elements of type
700 1.1 mrg class TCLASS. */
701 1.1 mrg inline type_suffix_index
702 1.1 mrg find_type_suffix (type_class_index tclass, unsigned int element_bits)
703 1.1 mrg {
704 1.1 mrg for (unsigned int i = 0; i < NUM_TYPE_SUFFIXES; ++i)
705 1.1 mrg if (type_suffixes[i].tclass == tclass
706 1.1 mrg && type_suffixes[i].element_bits == element_bits)
707 1.1 mrg return type_suffix_index (i);
708 1.1 mrg gcc_unreachable ();
709 1.1 mrg }
710 1.1 mrg
711 1.1 mrg /* Return the single field in tuple type TYPE. */
712 1.1 mrg inline tree
713 1.1 mrg tuple_type_field (tree type)
714 1.1 mrg {
715 1.1 mrg for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
716 1.1 mrg if (TREE_CODE (field) == FIELD_DECL)
717 1.1 mrg return field;
718 1.1 mrg gcc_unreachable ();
719 1.1 mrg }
720 1.1 mrg
721 1.1 mrg inline function_instance::
722 1.1 mrg function_instance (const char *base_name_in,
723 1.1 mrg const function_base *base_in,
724 1.1 mrg const function_shape *shape_in,
725 1.1 mrg mode_suffix_index mode_suffix_id_in,
726 1.1 mrg const type_suffix_pair &type_suffix_ids_in,
727 1.1 mrg predication_index pred_in)
728 1.1 mrg : base_name (base_name_in), base (base_in), shape (shape_in),
729 1.1 mrg mode_suffix_id (mode_suffix_id_in), pred (pred_in)
730 1.1 mrg {
731 1.1 mrg memcpy (type_suffix_ids, type_suffix_ids_in, sizeof (type_suffix_ids));
732 1.1 mrg }
733 1.1 mrg
734 1.1 mrg inline bool
735 1.1 mrg function_instance::operator== (const function_instance &other) const
736 1.1 mrg {
737 1.1 mrg return (base == other.base
738 1.1 mrg && shape == other.shape
739 1.1 mrg && mode_suffix_id == other.mode_suffix_id
740 1.1 mrg && pred == other.pred
741 1.1 mrg && type_suffix_ids[0] == other.type_suffix_ids[0]
742 1.1 mrg && type_suffix_ids[1] == other.type_suffix_ids[1]);
743 1.1 mrg }
744 1.1 mrg
745 1.1 mrg inline bool
746 1.1 mrg function_instance::operator!= (const function_instance &other) const
747 1.1 mrg {
748 1.1 mrg return !operator== (other);
749 1.1 mrg }
750 1.1 mrg
751 1.1 mrg /* If the function operates on tuples of vectors, return the number
752 1.1 mrg of vectors in the tuples, otherwise return 1. */
753 1.1 mrg inline unsigned int
754 1.1 mrg function_instance::vectors_per_tuple () const
755 1.1 mrg {
756 1.1 mrg return base->vectors_per_tuple ();
757 1.1 mrg }
758 1.1 mrg
759 1.1 mrg /* If the function addresses memory, return the type of a single
760 1.1 mrg scalar memory element. */
761 1.1 mrg inline tree
762 1.1 mrg function_instance::memory_scalar_type () const
763 1.1 mrg {
764 1.1 mrg return base->memory_scalar_type (*this);
765 1.1 mrg }
766 1.1 mrg
767 1.1 mrg /* If the function addresses memory, return a vector mode whose
768 1.1 mrg GET_MODE_NUNITS is the number of elements addressed and whose
769 1.1 mrg GET_MODE_INNER is the mode of a single scalar memory element. */
770 1.1 mrg inline machine_mode
771 1.1 mrg function_instance::memory_vector_mode () const
772 1.1 mrg {
773 1.1 mrg return base->memory_vector_mode (*this);
774 1.1 mrg }
775 1.1 mrg
776 1.1 mrg /* Return information about the function's mode suffix. */
777 1.1 mrg inline const mode_suffix_info &
778 1.1 mrg function_instance::mode_suffix () const
779 1.1 mrg {
780 1.1 mrg return mode_suffixes[mode_suffix_id];
781 1.1 mrg }
782 1.1 mrg
783 1.1 mrg /* Return the type of the function's vector base address argument,
784 1.1 mrg or null it doesn't have a vector base address. */
785 1.1 mrg inline tree
786 1.1 mrg function_instance::base_vector_type () const
787 1.1 mrg {
788 1.1 mrg return acle_vector_types[0][mode_suffix ().base_vector_type];
789 1.1 mrg }
790 1.1 mrg
791 1.1 mrg /* Return the type of the function's vector index or offset argument,
792 1.1 mrg or null if doesn't have a vector index or offset argument. */
793 1.1 mrg inline tree
794 1.1 mrg function_instance::displacement_vector_type () const
795 1.1 mrg {
796 1.1 mrg return acle_vector_types[0][mode_suffix ().displacement_vector_type];
797 1.1 mrg }
798 1.1 mrg
799 1.1 mrg /* If the function takes a vector or scalar displacement, return the units
800 1.1 mrg in which the displacement is measured, otherwise return UNITS_none. */
801 1.1 mrg inline units_index
802 1.1 mrg function_instance::displacement_units () const
803 1.1 mrg {
804 1.1 mrg return mode_suffix ().displacement_units;
805 1.1 mrg }
806 1.1 mrg
807 1.1 mrg /* Return information about type suffix I. */
808 1.1 mrg inline const type_suffix_info &
809 1.1 mrg function_instance::type_suffix (unsigned int i) const
810 1.1 mrg {
811 1.1 mrg return type_suffixes[type_suffix_ids[i]];
812 1.1 mrg }
813 1.1 mrg
814 1.1 mrg /* Return the scalar type associated with type suffix I. */
815 1.1 mrg inline tree
816 1.1 mrg function_instance::scalar_type (unsigned int i) const
817 1.1 mrg {
818 1.1 mrg return scalar_types[type_suffix (i).vector_type];
819 1.1 mrg }
820 1.1 mrg
821 1.1 mrg /* Return the vector type associated with type suffix I. */
822 1.1 mrg inline tree
823 1.1 mrg function_instance::vector_type (unsigned int i) const
824 1.1 mrg {
825 1.1 mrg return acle_vector_types[0][type_suffix (i).vector_type];
826 1.1 mrg }
827 1.1 mrg
828 1.1 mrg /* If the function operates on tuples of vectors, return the tuple type
829 1.1 mrg associated with type suffix I, otherwise return the vector type associated
830 1.1 mrg with type suffix I. */
831 1.1 mrg inline tree
832 1.1 mrg function_instance::tuple_type (unsigned int i) const
833 1.1 mrg {
834 1.1 mrg unsigned int num_vectors = vectors_per_tuple ();
835 1.1 mrg return acle_vector_types[num_vectors - 1][type_suffix (i).vector_type];
836 1.1 mrg }
837 1.1 mrg
838 1.1 mrg /* Return the number of elements of type suffix I that fit within a
839 1.1 mrg 128-bit block. */
840 1.1 mrg inline unsigned int
841 1.1 mrg function_instance::elements_per_vq (unsigned int i) const
842 1.1 mrg {
843 1.1 mrg return 128 / type_suffix (i).element_bits;
844 1.1 mrg }
845 1.1 mrg
846 1.1 mrg /* Return the vector or predicate mode associated with type suffix I. */
847 1.1 mrg inline machine_mode
848 1.1 mrg function_instance::vector_mode (unsigned int i) const
849 1.1 mrg {
850 1.1 mrg return type_suffix (i).vector_mode;
851 1.1 mrg }
852 1.1 mrg
853 1.1 mrg /* Return the mode of the governing predicate to use when operating on
854 1.1 mrg type suffix I. */
855 1.1 mrg inline machine_mode
856 1.1 mrg function_instance::gp_mode (unsigned int i) const
857 1.1 mrg {
858 1.1 mrg return aarch64_sve_pred_mode (type_suffix (i).element_bytes).require ();
859 1.1 mrg }
860 1.1 mrg
861 1.1 mrg /* Return true if the function has no return value. */
862 1.1 mrg inline bool
863 1.1 mrg function_call_info::function_returns_void_p ()
864 1.1 mrg {
865 1.1 mrg return TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node;
866 1.1 mrg }
867 1.1 mrg
868 1.1 mrg /* Default implementation of function::call_properties, with conservatively
869 1.1 mrg correct behavior for floating-point instructions. */
870 1.1 mrg inline unsigned int
871 1.1 mrg function_base::call_properties (const function_instance &instance) const
872 1.1 mrg {
873 1.1 mrg unsigned int flags = 0;
874 1.1 mrg if (instance.type_suffix (0).float_p || instance.type_suffix (1).float_p)
875 1.1 mrg flags |= CP_READ_FPCR | CP_RAISE_FP_EXCEPTIONS;
876 1.1 mrg return flags;
877 1.1 mrg }
878 1.1 mrg
879 1.1 mrg }
880 1.1 mrg
881 1.1 mrg #endif
882