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