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