1 /* Machine description for AArch64 architecture. 2 Copyright (C) 2009-2024 Free Software Foundation, Inc. 3 Contributed by ARM Ltd. 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 GCC is distributed in the hope that it will be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 22 #ifndef GCC_AARCH64_PROTOS_H 23 #define GCC_AARCH64_PROTOS_H 24 25 #include "input.h" 26 #include "config/arm/aarch-common.h" 27 28 /* SYMBOL_SMALL_ABSOLUTE: Generate symbol accesses through 29 high and lo relocs that calculate the base address using a PC 30 relative reloc. 31 So to get the address of foo, we generate 32 adrp x0, foo 33 add x0, x0, :lo12:foo 34 35 To load or store something to foo, we could use the corresponding 36 load store variants that generate an 37 ldr x0, [x0,:lo12:foo] 38 or 39 str x1, [x0, :lo12:foo] 40 41 This corresponds to the small code model of the compiler. 42 43 SYMBOL_SMALL_GOT_4G: Similar to the one above but this 44 gives us the GOT entry of the symbol being referred to : 45 Thus calculating the GOT entry for foo is done using the 46 following sequence of instructions. The ADRP instruction 47 gets us to the page containing the GOT entry of the symbol 48 and the got_lo12 gets us the actual offset in it, together 49 the base and offset, we can address 4G size GOT table. 50 51 adrp x0, :got:foo 52 ldr x0, [x0, :gotoff_lo12:foo] 53 54 This corresponds to the small PIC model of the compiler. 55 56 SYMBOL_SMALL_GOT_28K: Similar to SYMBOL_SMALL_GOT_4G, but used for symbol 57 restricted within 28K GOT table size. 58 59 ldr reg, [gp, #:gotpage_lo15:sym] 60 61 This corresponds to -fpic model for small memory model of the compiler. 62 63 SYMBOL_SMALL_TLSGD 64 SYMBOL_SMALL_TLSDESC 65 SYMBOL_SMALL_TLSIE 66 SYMBOL_TINY_TLSIE 67 SYMBOL_TLSLE12 68 SYMBOL_TLSLE24 69 SYMBOL_TLSLE32 70 SYMBOL_TLSLE48 71 Each of these represents a thread-local symbol, and corresponds to the 72 thread local storage relocation operator for the symbol being referred to. 73 74 SYMBOL_TINY_ABSOLUTE 75 76 Generate symbol accesses as a PC relative address using a single 77 instruction. To compute the address of symbol foo, we generate: 78 79 ADR x0, foo 80 81 SYMBOL_TINY_GOT 82 83 Generate symbol accesses via the GOT using a single PC relative 84 instruction. To compute the address of symbol foo, we generate: 85 86 ldr t0, :got:foo 87 88 The value of foo can subsequently read using: 89 90 ldrb t0, [t0] 91 92 SYMBOL_FORCE_TO_MEM : Global variables are addressed using 93 constant pool. All variable addresses are spilled into constant 94 pools. The constant pools themselves are addressed using PC 95 relative accesses. This only works for the large code model. 96 */ 97 enum aarch64_symbol_type 98 { 99 SYMBOL_SMALL_ABSOLUTE, 100 SYMBOL_SMALL_GOT_28K, 101 SYMBOL_SMALL_GOT_4G, 102 SYMBOL_SMALL_TLSGD, 103 SYMBOL_SMALL_TLSDESC, 104 SYMBOL_SMALL_TLSIE, 105 SYMBOL_TINY_ABSOLUTE, 106 SYMBOL_TINY_GOT, 107 SYMBOL_TINY_TLSIE, 108 SYMBOL_TLSLE12, 109 SYMBOL_TLSLE24, 110 SYMBOL_TLSLE32, 111 SYMBOL_TLSLE48, 112 SYMBOL_FORCE_TO_MEM 113 }; 114 115 /* Classifies the type of an address query. 116 117 ADDR_QUERY_M 118 Query what is valid for an "m" constraint and a memory_operand 119 (the rules are the same for both). 120 121 ADDR_QUERY_LDP_STP 122 Query what is valid for a load/store pair. 123 124 ADDR_QUERY_LDP_STP_N 125 Query what is valid for a load/store pair, but narrow the incoming mode 126 for address checking. This is used for the store_pair_lanes patterns. 127 128 ADDR_QUERY_ANY 129 Query what is valid for at least one memory constraint, which may 130 allow things that "m" doesn't. For example, the SVE LDR and STR 131 addressing modes allow a wider range of immediate offsets than "m" 132 does. */ 133 enum aarch64_addr_query_type { 134 ADDR_QUERY_M, 135 ADDR_QUERY_LDP_STP, 136 ADDR_QUERY_LDP_STP_N, 137 ADDR_QUERY_ANY 138 }; 139 140 /* Enumerates values that can be arbitrarily mixed into a calculation 141 in order to make the result of the calculation unique to its use case. 142 143 AARCH64_SALT_SSP_SET 144 AARCH64_SALT_SSP_TEST 145 Used when calculating the address of the stack protection canary value. 146 There is a separate value for setting and testing the canary, meaning 147 that these two operations produce unique addresses: they are different 148 from each other, and from all other address calculations. 149 150 The main purpose of this is to prevent the SET address being spilled 151 to the stack and reloaded for the TEST, since that would give an 152 attacker the opportunity to change the address of the expected 153 canary value. */ 154 enum aarch64_salt_type { 155 AARCH64_SALT_SSP_SET, 156 AARCH64_SALT_SSP_TEST 157 }; 158 159 /* A set of tuning parameters contains references to size and time 160 cost models and vectors for address cost calculations, register 161 move costs and memory move costs. */ 162 163 /* Scaled addressing modes can vary cost depending on the mode of the 164 value to be loaded/stored. QImode values cannot use scaled 165 addressing modes. */ 166 167 struct scale_addr_mode_cost 168 { 169 const int hi; 170 const int si; 171 const int di; 172 const int ti; 173 }; 174 175 /* Additional cost for addresses. */ 176 struct cpu_addrcost_table 177 { 178 const struct scale_addr_mode_cost addr_scale_costs; 179 const int pre_modify; 180 const int post_modify; 181 const int post_modify_ld3_st3; 182 const int post_modify_ld4_st4; 183 const int register_offset; 184 const int register_sextend; 185 const int register_zextend; 186 const int imm_offset; 187 }; 188 189 /* Additional costs for register copies. Cost is for one register. */ 190 struct cpu_regmove_cost 191 { 192 const int GP2GP; 193 const int GP2FP; 194 const int FP2GP; 195 const int FP2FP; 196 }; 197 198 struct simd_vec_cost 199 { 200 /* Cost of any integer vector operation, excluding the ones handled 201 specially below. */ 202 const int int_stmt_cost; 203 204 /* Cost of any fp vector operation, excluding the ones handled 205 specially below. */ 206 const int fp_stmt_cost; 207 208 /* Per-vector cost of permuting vectors after an LD2, LD3 or LD4, 209 as well as the per-vector cost of permuting vectors before 210 an ST2, ST3 or ST4. */ 211 const int ld2_st2_permute_cost; 212 const int ld3_st3_permute_cost; 213 const int ld4_st4_permute_cost; 214 215 /* Cost of a permute operation. */ 216 const int permute_cost; 217 218 /* Cost of reductions for various vector types: iN is for N-bit 219 integer elements and fN is for N-bit floating-point elements. 220 We need to single out the element type because it affects the 221 depth of the reduction. */ 222 const int reduc_i8_cost; 223 const int reduc_i16_cost; 224 const int reduc_i32_cost; 225 const int reduc_i64_cost; 226 const int reduc_f16_cost; 227 const int reduc_f32_cost; 228 const int reduc_f64_cost; 229 230 /* Additional cost of storing a single vector element, on top of the 231 normal cost of a scalar store. */ 232 const int store_elt_extra_cost; 233 234 /* Cost of a vector-to-scalar operation. */ 235 const int vec_to_scalar_cost; 236 237 /* Cost of a scalar-to-vector operation. */ 238 const int scalar_to_vec_cost; 239 240 /* Cost of an aligned vector load. */ 241 const int align_load_cost; 242 243 /* Cost of an unaligned vector load. */ 244 const int unalign_load_cost; 245 246 /* Cost of an unaligned vector store. */ 247 const int unalign_store_cost; 248 249 /* Cost of a vector store. */ 250 const int store_cost; 251 }; 252 253 typedef struct simd_vec_cost advsimd_vec_cost; 254 255 /* SVE-specific extensions to the information provided by simd_vec_cost. */ 256 struct sve_vec_cost : simd_vec_cost 257 { 258 CONSTEXPR sve_vec_cost (const simd_vec_cost &base, 259 unsigned int clast_cost, 260 unsigned int fadda_f16_cost, 261 unsigned int fadda_f32_cost, 262 unsigned int fadda_f64_cost, 263 unsigned int gather_load_x32_cost, 264 unsigned int gather_load_x64_cost, 265 unsigned int scatter_store_elt_cost) 266 : simd_vec_cost (base), 267 clast_cost (clast_cost), 268 fadda_f16_cost (fadda_f16_cost), 269 fadda_f32_cost (fadda_f32_cost), 270 fadda_f64_cost (fadda_f64_cost), 271 gather_load_x32_cost (gather_load_x32_cost), 272 gather_load_x64_cost (gather_load_x64_cost), 273 scatter_store_elt_cost (scatter_store_elt_cost) 274 {} 275 276 /* The cost of a vector-to-scalar CLASTA or CLASTB instruction, 277 with the scalar being stored in FP registers. This cost is 278 assumed to be a cycle latency. */ 279 const int clast_cost; 280 281 /* The costs of FADDA for the three data types that it supports. 282 These costs are assumed to be cycle latencies. */ 283 const int fadda_f16_cost; 284 const int fadda_f32_cost; 285 const int fadda_f64_cost; 286 287 /* The cost of a gather load instruction. The x32 value is for loads 288 of 32-bit elements and the x64 value is for loads of 64-bit elements. */ 289 const int gather_load_x32_cost; 290 const int gather_load_x64_cost; 291 292 /* The per-element cost of a scatter store. */ 293 const int scatter_store_elt_cost; 294 }; 295 296 /* Base information about how the CPU issues code, containing 297 information that is relevant to scalar, Advanced SIMD and SVE 298 operations. 299 300 The structure uses the general term "operation" to refer to 301 whichever subdivision of an instruction makes sense for the CPU. 302 These operations would typically be micro operations or macro 303 operations. 304 305 Note that this structure and the ones derived from it are only 306 as general as they need to be for the CPUs that currently use them. 307 They will probably need to be extended or refined as more CPUs are 308 added. */ 309 struct aarch64_base_vec_issue_info 310 { 311 /* How many loads and stores can be issued per cycle. */ 312 const unsigned int loads_stores_per_cycle; 313 314 /* How many stores can be issued per cycle. */ 315 const unsigned int stores_per_cycle; 316 317 /* How many integer or FP/SIMD operations can be issued per cycle. 318 319 Currently we don't try to distinguish the two. For vector code, 320 we only really track FP/SIMD operations during vector costing; 321 we don't for example try to cost arithmetic operations like 322 address calculations, which are only decided later during ivopts. 323 324 For scalar code, we effectively assume that code operates entirely 325 on integers or entirely on floating-point values. Again, we don't 326 try to take address calculations into account. 327 328 This is not very precise, but it's only meant to be a heuristic. 329 We could certainly try to do better in future if there's an example 330 of something that would benefit. */ 331 const unsigned int general_ops_per_cycle; 332 333 /* How many FP/SIMD operations to count for a floating-point or 334 vector load operation. 335 336 When constructing an Advanced SIMD vector from elements that have 337 been loaded from memory, these values apply to each individual load. 338 When using an SVE gather load, the values apply to each element of 339 the gather. */ 340 const unsigned int fp_simd_load_general_ops; 341 342 /* How many FP/SIMD operations to count for a floating-point or 343 vector store operation. 344 345 When storing individual elements of an Advanced SIMD vector out to 346 memory, these values apply to each individual store. When using an 347 SVE scatter store, these values apply to each element of the scatter. */ 348 const unsigned int fp_simd_store_general_ops; 349 }; 350 351 using aarch64_scalar_vec_issue_info = aarch64_base_vec_issue_info; 352 353 /* Base information about the issue stage for vector operations. 354 This structure contains information that is relevant to both 355 Advanced SIMD and SVE. */ 356 struct aarch64_simd_vec_issue_info : aarch64_base_vec_issue_info 357 { 358 CONSTEXPR aarch64_simd_vec_issue_info (aarch64_base_vec_issue_info base, 359 unsigned int ld2_st2_general_ops, 360 unsigned int ld3_st3_general_ops, 361 unsigned int ld4_st4_general_ops) 362 : aarch64_base_vec_issue_info (base), 363 ld2_st2_general_ops (ld2_st2_general_ops), 364 ld3_st3_general_ops (ld3_st3_general_ops), 365 ld4_st4_general_ops (ld4_st4_general_ops) 366 {} 367 368 /* How many FP/SIMD operations to count for each vector loaded or 369 stored by an LD[234] or ST[234] operation, in addition to the 370 base costs given in the parent class. For example, the full 371 number of operations for an LD3 would be: 372 373 load ops: 3 374 general ops: 3 * (fp_simd_load_general_ops + ld3_st3_general_ops). */ 375 const unsigned int ld2_st2_general_ops; 376 const unsigned int ld3_st3_general_ops; 377 const unsigned int ld4_st4_general_ops; 378 }; 379 380 using aarch64_advsimd_vec_issue_info = aarch64_simd_vec_issue_info; 381 382 /* Information about the issue stage for SVE. The main thing this adds 383 is a concept of "predicate operations". */ 384 struct aarch64_sve_vec_issue_info : aarch64_simd_vec_issue_info 385 { 386 CONSTEXPR aarch64_sve_vec_issue_info 387 (aarch64_simd_vec_issue_info base, 388 unsigned int pred_ops_per_cycle, 389 unsigned int while_pred_ops, 390 unsigned int int_cmp_pred_ops, 391 unsigned int fp_cmp_pred_ops, 392 unsigned int gather_scatter_pair_general_ops, 393 unsigned int gather_scatter_pair_pred_ops) 394 : aarch64_simd_vec_issue_info (base), 395 pred_ops_per_cycle (pred_ops_per_cycle), 396 while_pred_ops (while_pred_ops), 397 int_cmp_pred_ops (int_cmp_pred_ops), 398 fp_cmp_pred_ops (fp_cmp_pred_ops), 399 gather_scatter_pair_general_ops (gather_scatter_pair_general_ops), 400 gather_scatter_pair_pred_ops (gather_scatter_pair_pred_ops) 401 {} 402 403 /* How many predicate operations can be issued per cycle. */ 404 const unsigned int pred_ops_per_cycle; 405 406 /* How many predicate operations are generated by a WHILExx 407 instruction. */ 408 const unsigned int while_pred_ops; 409 410 /* How many predicate operations are generated by an integer 411 comparison instruction. */ 412 const unsigned int int_cmp_pred_ops; 413 414 /* How many predicate operations are generated by a floating-point 415 comparison instruction. */ 416 const unsigned int fp_cmp_pred_ops; 417 418 /* How many general and predicate operations are generated by each pair 419 of elements in a gather load or scatter store. These values apply 420 on top of the per-element counts recorded in fp_simd_load_general_ops 421 and fp_simd_store_general_ops. 422 423 The reason for using pairs is that that is the largest possible 424 granule size for 128-bit SVE, which can load and store 2 64-bit 425 elements or 4 32-bit elements. */ 426 const unsigned int gather_scatter_pair_general_ops; 427 const unsigned int gather_scatter_pair_pred_ops; 428 }; 429 430 /* Information related to instruction issue for a particular CPU. */ 431 struct aarch64_vec_issue_info 432 { 433 const aarch64_base_vec_issue_info *const scalar; 434 const aarch64_simd_vec_issue_info *const advsimd; 435 const aarch64_sve_vec_issue_info *const sve; 436 }; 437 438 /* Cost for vector insn classes. */ 439 struct cpu_vector_cost 440 { 441 /* Cost of any integer scalar operation, excluding load and store. */ 442 const int scalar_int_stmt_cost; 443 444 /* Cost of any fp scalar operation, excluding load and store. */ 445 const int scalar_fp_stmt_cost; 446 447 /* Cost of a scalar load. */ 448 const int scalar_load_cost; 449 450 /* Cost of a scalar store. */ 451 const int scalar_store_cost; 452 453 /* Cost of a taken branch. */ 454 const int cond_taken_branch_cost; 455 456 /* Cost of a not-taken branch. */ 457 const int cond_not_taken_branch_cost; 458 459 /* Cost of an Advanced SIMD operations. */ 460 const advsimd_vec_cost *advsimd; 461 462 /* Cost of an SVE operations, or null if SVE is not implemented. */ 463 const sve_vec_cost *sve; 464 465 /* Issue information, or null if none is provided. */ 466 const aarch64_vec_issue_info *const issue_info; 467 }; 468 469 /* Branch costs. */ 470 struct cpu_branch_cost 471 { 472 const int predictable; /* Predictable branch or optimizing for size. */ 473 const int unpredictable; /* Unpredictable branch or optimizing for speed. */ 474 }; 475 476 /* Control approximate alternatives to certain FP operators. */ 477 #define AARCH64_APPROX_MODE(MODE) \ 478 ((MIN_MODE_FLOAT <= (MODE) && (MODE) <= MAX_MODE_FLOAT) \ 479 ? ((uint64_t) 1 << ((MODE) - MIN_MODE_FLOAT)) \ 480 : (MIN_MODE_VECTOR_FLOAT <= (MODE) && (MODE) <= MAX_MODE_VECTOR_FLOAT) \ 481 ? ((uint64_t) 1 << ((MODE) - MIN_MODE_VECTOR_FLOAT \ 482 + MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1)) \ 483 : (0)) 484 #define AARCH64_APPROX_NONE ((uint64_t) 0) 485 #define AARCH64_APPROX_ALL (~(uint64_t) 0) 486 487 /* Allowed modes for approximations. */ 488 struct cpu_approx_modes 489 { 490 const uint64_t division; /* Division. */ 491 const uint64_t sqrt; /* Square root. */ 492 const uint64_t recip_sqrt; /* Reciprocal square root. */ 493 }; 494 495 /* Cache prefetch settings for prefetch-loop-arrays. */ 496 struct cpu_prefetch_tune 497 { 498 const int num_slots; 499 const int l1_cache_size; 500 const int l1_cache_line_size; 501 const int l2_cache_size; 502 /* Whether software prefetch hints should be issued for non-constant 503 strides. */ 504 const bool prefetch_dynamic_strides; 505 /* The minimum constant stride beyond which we should use prefetch 506 hints for. */ 507 const int minimum_stride; 508 const int default_opt_level; 509 }; 510 511 /* Model the costs for loads/stores for the register allocators so that it can 512 do more accurate spill heuristics. */ 513 struct cpu_memmov_cost 514 { 515 int load_int; 516 int store_int; 517 int load_fp; 518 int store_fp; 519 int load_pred; 520 int store_pred; 521 }; 522 523 struct tune_params 524 { 525 const struct cpu_cost_table *insn_extra_cost; 526 const struct cpu_addrcost_table *addr_cost; 527 const struct cpu_regmove_cost *regmove_cost; 528 const struct cpu_vector_cost *vec_costs; 529 const struct cpu_branch_cost *branch_costs; 530 const struct cpu_approx_modes *approx_modes; 531 /* A bitmask of the possible SVE register widths in bits, 532 or SVE_NOT_IMPLEMENTED if not applicable. Only used for tuning 533 decisions, does not disable VLA vectorization. */ 534 unsigned int sve_width; 535 /* Structure used by reload to cost spills. */ 536 struct cpu_memmov_cost memmov_cost; 537 int issue_rate; 538 unsigned int fusible_ops; 539 const char *function_align; 540 const char *jump_align; 541 const char *loop_align; 542 int int_reassoc_width; 543 int fp_reassoc_width; 544 int fma_reassoc_width; 545 int vec_reassoc_width; 546 int min_div_recip_mul_sf; 547 int min_div_recip_mul_df; 548 /* Value for aarch64_case_values_threshold; or 0 for the default. */ 549 unsigned int max_case_values; 550 /* An enum specifying how to take into account CPU autoprefetch capabilities 551 during instruction scheduling: 552 - AUTOPREFETCHER_OFF: Do not take autoprefetch capabilities into account. 553 - AUTOPREFETCHER_WEAK: Attempt to sort sequences of loads/store in order of 554 offsets but allow the pipeline hazard recognizer to alter that order to 555 maximize multi-issue opportunities. 556 - AUTOPREFETCHER_STRONG: Attempt to sort sequences of loads/store in order of 557 offsets and prefer this even if it restricts multi-issue opportunities. */ 558 559 enum aarch64_autoprefetch_model 560 { 561 AUTOPREFETCHER_OFF, 562 AUTOPREFETCHER_WEAK, 563 AUTOPREFETCHER_STRONG 564 } autoprefetcher_model; 565 566 unsigned int extra_tuning_flags; 567 568 /* Place prefetch struct pointer at the end to enable type checking 569 errors when tune_params misses elements (e.g., from erroneous merges). */ 570 const struct cpu_prefetch_tune *prefetch; 571 572 /* Define models for the aarch64_ldp_stp_policy. */ 573 enum aarch64_ldp_stp_policy ldp_policy_model, stp_policy_model; 574 }; 575 576 /* Classifies an address. 577 578 ADDRESS_REG_IMM 579 A simple base register plus immediate offset. 580 581 ADDRESS_REG_WB 582 A base register indexed by immediate offset with writeback. 583 584 ADDRESS_REG_REG 585 A base register indexed by (optionally scaled) register. 586 587 ADDRESS_REG_UXTW 588 A base register indexed by (optionally scaled) zero-extended register. 589 590 ADDRESS_REG_SXTW 591 A base register indexed by (optionally scaled) sign-extended register. 592 593 ADDRESS_LO_SUM 594 A LO_SUM rtx with a base register and "LO12" symbol relocation. 595 596 ADDRESS_SYMBOLIC: 597 A constant symbolic address, in pc-relative literal pool. */ 598 599 enum aarch64_address_type { 600 ADDRESS_REG_IMM, 601 ADDRESS_REG_WB, 602 ADDRESS_REG_REG, 603 ADDRESS_REG_UXTW, 604 ADDRESS_REG_SXTW, 605 ADDRESS_LO_SUM, 606 ADDRESS_SYMBOLIC 607 }; 608 609 /* Address information. */ 610 struct aarch64_address_info { 611 enum aarch64_address_type type; 612 rtx base; 613 rtx offset; 614 poly_int64 const_offset; 615 int shift; 616 enum aarch64_symbol_type symbol_type; 617 }; 618 619 #define AARCH64_FUSION_PAIR(x, name) \ 620 AARCH64_FUSE_##name##_index, 621 /* Supported fusion operations. */ 622 enum aarch64_fusion_pairs_index 623 { 624 #include "aarch64-fusion-pairs.def" 625 AARCH64_FUSE_index_END 626 }; 627 628 #define AARCH64_FUSION_PAIR(x, name) \ 629 AARCH64_FUSE_##name = (1u << AARCH64_FUSE_##name##_index), 630 /* Supported fusion operations. */ 631 enum aarch64_fusion_pairs 632 { 633 AARCH64_FUSE_NOTHING = 0, 634 #include "aarch64-fusion-pairs.def" 635 AARCH64_FUSE_ALL = (1u << AARCH64_FUSE_index_END) - 1 636 }; 637 638 #define AARCH64_EXTRA_TUNING_OPTION(x, name) \ 639 AARCH64_EXTRA_TUNE_##name##_index, 640 /* Supported tuning flags indexes. */ 641 enum aarch64_extra_tuning_flags_index 642 { 643 #include "aarch64-tuning-flags.def" 644 AARCH64_EXTRA_TUNE_index_END 645 }; 646 647 648 #define AARCH64_EXTRA_TUNING_OPTION(x, name) \ 649 AARCH64_EXTRA_TUNE_##name = (1u << AARCH64_EXTRA_TUNE_##name##_index), 650 /* Supported tuning flags. */ 651 enum aarch64_extra_tuning_flags 652 { 653 AARCH64_EXTRA_TUNE_NONE = 0, 654 #include "aarch64-tuning-flags.def" 655 AARCH64_EXTRA_TUNE_ALL = (1u << AARCH64_EXTRA_TUNE_index_END) - 1 656 }; 657 658 /* Enum to distinguish which type of check is to be done in 659 aarch64_simd_valid_immediate. This is used as a bitmask where 660 AARCH64_CHECK_MOV has both bits set. Thus AARCH64_CHECK_MOV will 661 perform all checks. Adding new types would require changes accordingly. */ 662 enum simd_immediate_check { 663 AARCH64_CHECK_ORR = 1 << 0, 664 AARCH64_CHECK_BIC = 1 << 1, 665 AARCH64_CHECK_MOV = AARCH64_CHECK_ORR | AARCH64_CHECK_BIC 666 }; 667 668 extern struct tune_params aarch64_tune_params; 669 670 /* The available SVE predicate patterns, known in the ACLE as "svpattern". */ 671 #define AARCH64_FOR_SVPATTERN(T) \ 672 T (POW2, pow2, 0) \ 673 T (VL1, vl1, 1) \ 674 T (VL2, vl2, 2) \ 675 T (VL3, vl3, 3) \ 676 T (VL4, vl4, 4) \ 677 T (VL5, vl5, 5) \ 678 T (VL6, vl6, 6) \ 679 T (VL7, vl7, 7) \ 680 T (VL8, vl8, 8) \ 681 T (VL16, vl16, 9) \ 682 T (VL32, vl32, 10) \ 683 T (VL64, vl64, 11) \ 684 T (VL128, vl128, 12) \ 685 T (VL256, vl256, 13) \ 686 T (MUL4, mul4, 29) \ 687 T (MUL3, mul3, 30) \ 688 T (ALL, all, 31) 689 690 /* The available SVE prefetch operations, known in the ACLE as "svprfop". */ 691 #define AARCH64_FOR_SVPRFOP(T) \ 692 T (PLDL1KEEP, pldl1keep, 0) \ 693 T (PLDL1STRM, pldl1strm, 1) \ 694 T (PLDL2KEEP, pldl2keep, 2) \ 695 T (PLDL2STRM, pldl2strm, 3) \ 696 T (PLDL3KEEP, pldl3keep, 4) \ 697 T (PLDL3STRM, pldl3strm, 5) \ 698 T (PSTL1KEEP, pstl1keep, 8) \ 699 T (PSTL1STRM, pstl1strm, 9) \ 700 T (PSTL2KEEP, pstl2keep, 10) \ 701 T (PSTL2STRM, pstl2strm, 11) \ 702 T (PSTL3KEEP, pstl3keep, 12) \ 703 T (PSTL3STRM, pstl3strm, 13) 704 705 #define AARCH64_SVENUM(UPPER, LOWER, VALUE) AARCH64_SV_##UPPER = VALUE, 706 enum aarch64_svpattern { 707 AARCH64_FOR_SVPATTERN (AARCH64_SVENUM) 708 AARCH64_NUM_SVPATTERNS 709 }; 710 711 enum aarch64_svprfop { 712 AARCH64_FOR_SVPRFOP (AARCH64_SVENUM) 713 AARCH64_NUM_SVPRFOPS 714 }; 715 #undef AARCH64_SVENUM 716 717 /* It's convenient to divide the built-in function codes into groups, 718 rather than having everything in a single enum. This type enumerates 719 those groups. */ 720 enum aarch64_builtin_class 721 { 722 AARCH64_BUILTIN_GENERAL, 723 AARCH64_BUILTIN_SVE 724 }; 725 726 /* Built-in function codes are structured so that the low 727 AARCH64_BUILTIN_SHIFT bits contain the aarch64_builtin_class 728 and the upper bits contain a group-specific subcode. */ 729 const unsigned int AARCH64_BUILTIN_SHIFT = 1; 730 731 /* Mask that selects the aarch64_builtin_class part of a function code. */ 732 const unsigned int AARCH64_BUILTIN_CLASS = (1 << AARCH64_BUILTIN_SHIFT) - 1; 733 734 /* RAII class for enabling enough features to define built-in types 735 and implement the arm_neon.h pragma. */ 736 class aarch64_simd_switcher 737 { 738 public: 739 aarch64_simd_switcher (aarch64_feature_flags extra_flags = 0); 740 ~aarch64_simd_switcher (); 741 742 private: 743 aarch64_feature_flags m_old_asm_isa_flags; 744 bool m_old_general_regs_only; 745 }; 746 747 void aarch64_post_cfi_startproc (void); 748 poly_int64 aarch64_initial_elimination_offset (unsigned, unsigned); 749 int aarch64_get_condition_code (rtx); 750 bool aarch64_address_valid_for_prefetch_p (rtx, bool); 751 bool aarch64_bitmask_imm (unsigned HOST_WIDE_INT val, machine_mode); 752 unsigned HOST_WIDE_INT aarch64_and_split_imm1 (HOST_WIDE_INT val_in); 753 unsigned HOST_WIDE_INT aarch64_and_split_imm2 (HOST_WIDE_INT val_in); 754 bool aarch64_and_bitmask_imm (unsigned HOST_WIDE_INT val_in, machine_mode mode); 755 int aarch64_branch_cost (bool, bool); 756 enum aarch64_symbol_type aarch64_classify_symbolic_expression (rtx); 757 bool aarch64_advsimd_struct_mode_p (machine_mode mode); 758 opt_machine_mode aarch64_vq_mode (scalar_mode); 759 opt_machine_mode aarch64_full_sve_mode (scalar_mode); 760 bool aarch64_can_const_movi_rtx_p (rtx x, machine_mode mode); 761 bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT); 762 bool aarch64_const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT, 763 HOST_WIDE_INT); 764 bool aarch64_const_vec_rnd_cst_p (rtx, rtx); 765 bool aarch64_rnd_imm_p (rtx); 766 bool aarch64_constant_address_p (rtx); 767 bool aarch64_emit_approx_div (rtx, rtx, rtx); 768 bool aarch64_emit_approx_sqrt (rtx, rtx, bool); 769 tree aarch64_vector_load_decl (tree); 770 rtx aarch64_gen_callee_cookie (aarch64_feature_flags, arm_pcs); 771 void aarch64_expand_call (rtx, rtx, rtx, bool); 772 bool aarch64_expand_cpymem_mops (rtx *, bool); 773 bool aarch64_expand_cpymem (rtx *, bool); 774 bool aarch64_expand_setmem (rtx *); 775 bool aarch64_float_const_zero_rtx_p (rtx); 776 bool aarch64_float_const_rtx_p (rtx); 777 bool aarch64_const_zero_rtx_p (rtx); 778 bool aarch64_function_arg_regno_p (unsigned); 779 bool aarch64_fusion_enabled_p (enum aarch64_fusion_pairs); 780 bool aarch64_gen_cpymemqi (rtx *); 781 bool aarch64_is_extend_from_extract (scalar_int_mode, rtx, rtx); 782 bool aarch64_is_long_call_p (rtx); 783 bool aarch64_is_noplt_call_p (rtx); 784 bool aarch64_label_mentioned_p (rtx); 785 void aarch64_declare_function_name (FILE *, const char*, tree); 786 void aarch64_asm_output_alias (FILE *, const tree, const tree); 787 void aarch64_asm_output_external (FILE *, tree, const char*); 788 bool aarch64_legitimate_pic_operand_p (rtx); 789 bool aarch64_mask_and_shift_for_ubfiz_p (scalar_int_mode, rtx, rtx); 790 bool aarch64_masks_and_shift_for_bfi_p (scalar_int_mode, unsigned HOST_WIDE_INT, 791 unsigned HOST_WIDE_INT, 792 unsigned HOST_WIDE_INT); 793 rtx aarch64_sve_reinterpret (machine_mode, rtx); 794 bool aarch64_zero_extend_const_eq (machine_mode, rtx, machine_mode, rtx); 795 bool aarch64_move_imm (unsigned HOST_WIDE_INT, machine_mode); 796 machine_mode aarch64_sve_int_mode (machine_mode); 797 opt_machine_mode aarch64_sve_pred_mode (unsigned int); 798 machine_mode aarch64_sve_pred_mode (machine_mode); 799 opt_machine_mode aarch64_sve_data_mode (scalar_mode, poly_uint64); 800 bool aarch64_sve_mode_p (machine_mode); 801 HOST_WIDE_INT aarch64_fold_sve_cnt_pat (aarch64_svpattern, unsigned int); 802 bool aarch64_sve_cnt_immediate_p (rtx); 803 bool aarch64_sve_scalar_inc_dec_immediate_p (rtx); 804 bool aarch64_sve_rdvl_immediate_p (rtx); 805 bool aarch64_sve_addvl_addpl_immediate_p (rtx); 806 bool aarch64_sve_vector_inc_dec_immediate_p (rtx); 807 int aarch64_add_offset_temporaries (rtx); 808 void aarch64_split_add_offset (scalar_int_mode, rtx, rtx, rtx, rtx, rtx); 809 bool aarch64_rdsvl_immediate_p (const_rtx); 810 rtx aarch64_sme_vq_immediate (machine_mode mode, HOST_WIDE_INT, 811 aarch64_feature_flags); 812 char *aarch64_output_rdsvl (const_rtx); 813 bool aarch64_addsvl_addspl_immediate_p (const_rtx); 814 char *aarch64_output_addsvl_addspl (rtx); 815 bool aarch64_mov_operand_p (rtx, machine_mode); 816 rtx aarch64_reverse_mask (machine_mode, unsigned int); 817 bool aarch64_offset_7bit_signed_scaled_p (machine_mode, poly_int64); 818 bool aarch64_offset_9bit_signed_unscaled_p (machine_mode, poly_int64); 819 char *aarch64_output_sve_prefetch (const char *, rtx, const char *); 820 char *aarch64_output_sve_cnt_immediate (const char *, const char *, rtx); 821 char *aarch64_output_sve_cnt_pat_immediate (const char *, const char *, rtx *); 822 char *aarch64_output_sve_scalar_inc_dec (rtx); 823 char *aarch64_output_sve_rdvl (rtx); 824 char *aarch64_output_sve_addvl_addpl (rtx); 825 char *aarch64_output_sve_vector_inc_dec (const char *, rtx); 826 char *aarch64_output_scalar_simd_mov_immediate (rtx, scalar_int_mode); 827 char *aarch64_output_simd_mov_immediate (rtx, unsigned, 828 enum simd_immediate_check w = AARCH64_CHECK_MOV); 829 char *aarch64_output_sve_mov_immediate (rtx); 830 char *aarch64_output_sve_ptrues (rtx); 831 bool aarch64_pad_reg_upward (machine_mode, const_tree, bool); 832 bool aarch64_regno_ok_for_base_p (int, bool); 833 bool aarch64_regno_ok_for_index_p (int, bool); 834 bool aarch64_reinterpret_float_as_int (rtx value, unsigned HOST_WIDE_INT *fail); 835 bool aarch64_simd_check_vect_par_cnst_half (rtx op, machine_mode mode, 836 bool high); 837 bool aarch64_parallel_select_half_p (machine_mode, rtx); 838 bool aarch64_pars_overlap_p (rtx, rtx); 839 bool aarch64_simd_scalar_immediate_valid_for_move (rtx, scalar_int_mode); 840 bool aarch64_simd_shift_imm_p (rtx, machine_mode, bool); 841 bool aarch64_sve_ptrue_svpattern_p (rtx, struct simd_immediate_info *); 842 bool aarch64_simd_valid_immediate (rtx, struct simd_immediate_info *, 843 enum simd_immediate_check w = AARCH64_CHECK_MOV); 844 bool aarch64_valid_sysreg_name_p (const char *); 845 const char *aarch64_retrieve_sysreg (const char *, bool, bool); 846 rtx aarch64_check_zero_based_sve_index_immediate (rtx); 847 bool aarch64_maybe_generate_simd_constant (rtx, rtx, machine_mode); 848 bool aarch64_simd_special_constant_p (rtx, machine_mode); 849 bool aarch64_sve_index_immediate_p (rtx); 850 bool aarch64_sve_arith_immediate_p (machine_mode, rtx, bool); 851 bool aarch64_sve_sqadd_sqsub_immediate_p (machine_mode, rtx, bool); 852 bool aarch64_sve_bitmask_immediate_p (rtx); 853 bool aarch64_sve_dup_immediate_p (rtx); 854 bool aarch64_sve_cmp_immediate_p (rtx, bool); 855 bool aarch64_sve_float_arith_immediate_p (rtx, bool); 856 bool aarch64_sve_float_mul_immediate_p (rtx); 857 bool aarch64_split_dimode_const_store (rtx, rtx); 858 bool aarch64_symbolic_address_p (rtx); 859 bool aarch64_uimm12_shift (unsigned HOST_WIDE_INT); 860 int aarch64_movk_shift (const wide_int_ref &, const wide_int_ref &); 861 bool aarch64_is_mov_xn_imm (unsigned HOST_WIDE_INT); 862 bool aarch64_use_return_insn_p (void); 863 const char *aarch64_output_casesi (rtx *); 864 const char *aarch64_output_load_tp (rtx); 865 const char *aarch64_output_sme_zero_za (rtx); 866 867 arm_pcs aarch64_tlsdesc_abi_id (); 868 enum aarch64_symbol_type aarch64_classify_symbol (rtx, HOST_WIDE_INT); 869 enum aarch64_symbol_type aarch64_classify_tls_symbol (rtx); 870 enum reg_class aarch64_regno_regclass (unsigned); 871 int aarch64_asm_preferred_eh_data_format (int, int); 872 int aarch64_fpconst_pow_of_2 (rtx); 873 int aarch64_fpconst_pow2_recip (rtx); 874 machine_mode aarch64_hard_regno_caller_save_mode (unsigned, unsigned, 875 machine_mode); 876 int aarch64_uxt_size (int, HOST_WIDE_INT); 877 int aarch64_vec_fpconst_pow_of_2 (rtx); 878 rtx aarch64_mask_from_zextract_ops (rtx, rtx); 879 rtx aarch64_return_addr_rtx (void); 880 rtx aarch64_return_addr (int, rtx); 881 rtx aarch64_simd_gen_const_vector_dup (machine_mode, HOST_WIDE_INT); 882 rtx aarch64_gen_shareable_zero (machine_mode); 883 bool aarch64_split_simd_shift_p (rtx_insn *); 884 bool aarch64_simd_mem_operand_p (rtx); 885 bool aarch64_sve_ld1r_operand_p (rtx); 886 bool aarch64_sve_ld1rq_operand_p (rtx); 887 bool aarch64_sve_ld1ro_operand_p (rtx, scalar_mode); 888 bool aarch64_sve_ldff1_operand_p (rtx); 889 bool aarch64_sve_ldnf1_operand_p (rtx); 890 bool aarch64_sve_ldr_operand_p (rtx); 891 bool aarch64_sve_prefetch_operand_p (rtx, machine_mode); 892 bool aarch64_sve_struct_memory_operand_p (rtx); 893 bool aarch64_sme_ldr_vnum_offset_p (rtx, rtx); 894 rtx aarch64_simd_vect_par_cnst_half (machine_mode, int, bool); 895 rtx aarch64_gen_stepped_int_parallel (unsigned int, int, int); 896 bool aarch64_stepped_int_parallel_p (rtx, int); 897 bool aarch64_strided_registers_p (rtx *, unsigned int, unsigned int); 898 rtx aarch64_tls_get_addr (void); 899 unsigned aarch64_debugger_regno (unsigned); 900 unsigned aarch64_trampoline_size (void); 901 void aarch64_asm_output_labelref (FILE *, const char *); 902 void aarch64_cpu_cpp_builtins (cpp_reader *); 903 const char * aarch64_gen_far_branch (rtx *, int, const char *, const char *); 904 const char * aarch64_output_probe_stack_range (rtx, rtx); 905 const char * aarch64_output_probe_sve_stack_clash (rtx, rtx, rtx, rtx); 906 void aarch64_err_no_fpadvsimd (machine_mode); 907 void aarch64_expand_epilogue (rtx_call_insn *); 908 rtx aarch64_ptrue_all (unsigned int); 909 opt_machine_mode aarch64_ptrue_all_mode (rtx); 910 rtx aarch64_convert_sve_data_to_pred (rtx, machine_mode, rtx); 911 rtx aarch64_expand_sve_dupq (rtx, machine_mode, rtx); 912 void aarch64_expand_mov_immediate (rtx, rtx); 913 rtx aarch64_stack_protect_canary_mem (machine_mode, rtx, aarch64_salt_type); 914 rtx aarch64_ptrue_reg (machine_mode); 915 rtx aarch64_pfalse_reg (machine_mode); 916 bool aarch64_sve_same_pred_for_ptest_p (rtx *, rtx *); 917 void aarch64_emit_sve_pred_move (rtx, rtx, rtx); 918 void aarch64_expand_sve_mem_move (rtx, rtx, machine_mode); 919 bool aarch64_maybe_expand_sve_subreg_move (rtx, rtx); 920 rtx aarch64_replace_reg_mode (rtx, machine_mode); 921 void aarch64_split_sve_subreg_move (rtx, rtx, rtx); 922 void aarch64_expand_prologue (void); 923 void aarch64_expand_vector_init (rtx, rtx); 924 void aarch64_sve_expand_vector_init (rtx, rtx); 925 void aarch64_init_cumulative_args (CUMULATIVE_ARGS *, const_tree, rtx, 926 const_tree, unsigned, bool = false); 927 void aarch64_init_expanders (void); 928 rtx_call_insn *aarch64_emit_call_insn (rtx); 929 void aarch64_register_pragmas (void); 930 void aarch64_relayout_simd_types (void); 931 void aarch64_reset_previous_fndecl (void); 932 bool aarch64_return_address_signing_enabled (void); 933 void aarch64_save_restore_target_globals (tree); 934 void aarch64_addti_scratch_regs (rtx, rtx, rtx *, 935 rtx *, rtx *, 936 rtx *, rtx *, 937 rtx *); 938 void aarch64_subvti_scratch_regs (rtx, rtx, rtx *, 939 rtx *, rtx *, 940 rtx *, rtx *, rtx *); 941 void aarch64_expand_subvti (rtx, rtx, rtx, 942 rtx, rtx, rtx, rtx, bool); 943 944 945 /* Initialize builtins for SIMD intrinsics. */ 946 void init_aarch64_simd_builtins (void); 947 948 void aarch64_simd_emit_reg_reg_move (rtx *, machine_mode, unsigned int); 949 950 /* Expand builtins for SIMD intrinsics. */ 951 rtx aarch64_simd_expand_builtin (int, tree, rtx); 952 953 void aarch64_simd_lane_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT, const_tree); 954 rtx aarch64_endian_lane_rtx (machine_mode, unsigned int); 955 956 void aarch64_split_double_move (rtx, rtx, machine_mode); 957 void aarch64_split_128bit_move (rtx, rtx); 958 959 bool aarch64_split_128bit_move_p (rtx, rtx); 960 961 bool aarch64_mov128_immediate (rtx); 962 963 void aarch64_split_simd_move (rtx, rtx); 964 965 /* Check for a legitimate floating point constant for FMOV. */ 966 bool aarch64_float_const_representable_p (rtx); 967 968 extern int aarch64_epilogue_uses (int); 969 970 #if defined (RTX_CODE) 971 void aarch64_gen_unlikely_cbranch (enum rtx_code, machine_mode cc_mode, 972 rtx label_ref); 973 bool aarch64_legitimate_address_p (machine_mode, rtx, bool, 974 aarch64_addr_query_type = ADDR_QUERY_M); 975 machine_mode aarch64_select_cc_mode (RTX_CODE, rtx, rtx); 976 rtx aarch64_gen_compare_reg (RTX_CODE, rtx, rtx); 977 bool aarch64_maxmin_plus_const (rtx_code, rtx *, bool); 978 rtx aarch64_load_tp (rtx); 979 980 void aarch64_expand_compare_and_swap (rtx op[]); 981 void aarch64_split_compare_and_swap (rtx op[]); 982 983 void aarch64_split_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx, rtx); 984 985 bool aarch64_gen_adjusted_ldpstp (rtx *, bool, machine_mode, RTX_CODE); 986 void aarch64_finish_ldpstp_peephole (rtx *, bool, 987 enum rtx_code = (enum rtx_code)0); 988 989 void aarch64_expand_sve_vec_cmp_int (rtx, rtx_code, rtx, rtx); 990 bool aarch64_expand_sve_vec_cmp_float (rtx, rtx_code, rtx, rtx, bool); 991 void aarch64_expand_sve_vcond (machine_mode, machine_mode, rtx *); 992 993 bool aarch64_prepare_sve_int_fma (rtx *, rtx_code); 994 bool aarch64_prepare_sve_cond_int_fma (rtx *, rtx_code); 995 #endif /* RTX_CODE */ 996 997 bool aarch64_process_target_attr (tree); 998 void aarch64_override_options_internal (struct gcc_options *); 999 1000 const char *aarch64_general_mangle_builtin_type (const_tree); 1001 void aarch64_general_init_builtins (void); 1002 tree aarch64_general_fold_builtin (unsigned int, tree, unsigned int, tree *); 1003 gimple *aarch64_general_gimple_fold_builtin (unsigned int, gcall *, 1004 gimple_stmt_iterator *); 1005 rtx aarch64_general_expand_builtin (unsigned int, tree, rtx, int); 1006 tree aarch64_general_builtin_decl (unsigned, bool); 1007 tree aarch64_general_builtin_rsqrt (unsigned int); 1008 void handle_arm_acle_h (void); 1009 void handle_arm_neon_h (void); 1010 1011 bool aarch64_check_required_extensions (location_t, tree, 1012 aarch64_feature_flags); 1013 bool aarch64_general_check_builtin_call (location_t, vec<location_t>, 1014 unsigned int, tree, unsigned int, 1015 tree *); 1016 1017 namespace aarch64_sve { 1018 void init_builtins (); 1019 void handle_arm_sve_h (bool); 1020 void handle_arm_sme_h (bool); 1021 void handle_arm_neon_sve_bridge_h (bool); 1022 tree builtin_decl (unsigned, bool); 1023 bool builtin_type_p (const_tree); 1024 bool builtin_type_p (const_tree, unsigned int *, unsigned int *); 1025 const char *mangle_builtin_type (const_tree); 1026 tree resolve_overloaded_builtin (location_t, unsigned int, 1027 vec<tree, va_gc> *); 1028 bool check_builtin_call (location_t, vec<location_t>, unsigned int, 1029 tree, unsigned int, tree *); 1030 gimple *gimple_fold_builtin (unsigned int, gimple_stmt_iterator *, gcall *); 1031 rtx expand_builtin (unsigned int, tree, rtx); 1032 tree handle_arm_sve_vector_bits_attribute (tree *, tree, tree, int, bool *); 1033 #ifdef GCC_TARGET_H 1034 bool verify_type_context (location_t, type_context_kind, const_tree, bool); 1035 #endif 1036 } 1037 1038 extern void aarch64_split_combinev16qi (rtx operands[3]); 1039 extern void aarch64_expand_vec_perm (rtx, rtx, rtx, rtx, unsigned int); 1040 extern void aarch64_expand_sve_vec_perm (rtx, rtx, rtx, rtx); 1041 extern bool aarch64_madd_needs_nop (rtx_insn *); 1042 extern void aarch64_final_prescan_insn (rtx_insn *); 1043 void aarch64_atomic_assign_expand_fenv (tree *, tree *, tree *); 1044 int aarch64_ccmp_mode_to_code (machine_mode mode); 1045 1046 bool extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset); 1047 bool aarch64_mergeable_load_pair_p (machine_mode, rtx, rtx); 1048 bool aarch64_operands_ok_for_ldpstp (rtx *, bool); 1049 bool aarch64_operands_adjust_ok_for_ldpstp (rtx *, bool, machine_mode); 1050 bool aarch64_mem_ok_with_ldpstp_policy_model (rtx, bool, machine_mode); 1051 bool aarch64_ldpstp_operand_mode_p (machine_mode); 1052 rtx aarch64_gen_load_pair (rtx, rtx, rtx, enum rtx_code = (enum rtx_code)0); 1053 rtx aarch64_gen_store_pair (rtx, rtx, rtx); 1054 1055 extern void aarch64_asm_output_pool_epilogue (FILE *, const char *, 1056 tree, HOST_WIDE_INT); 1057 1058 1059 extern bool aarch64_classify_address (struct aarch64_address_info *, rtx, 1060 machine_mode, bool, 1061 aarch64_addr_query_type = ADDR_QUERY_M); 1062 1063 void aarch64_set_asm_isa_flags (aarch64_feature_flags); 1064 1065 /* Defined in common/config/aarch64-common.cc. */ 1066 void aarch64_set_asm_isa_flags (gcc_options *, aarch64_feature_flags); 1067 bool aarch64_handle_option (struct gcc_options *, struct gcc_options *, 1068 const struct cl_decoded_option *, location_t); 1069 const char *aarch64_rewrite_selected_cpu (const char *name); 1070 enum aarch_parse_opt_result aarch64_parse_extension (const char *, 1071 aarch64_feature_flags *, 1072 std::string *); 1073 void aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates); 1074 std::string aarch64_get_extension_string_for_isa_flags (aarch64_feature_flags, 1075 aarch64_feature_flags); 1076 1077 rtl_opt_pass *make_pass_aarch64_early_ra (gcc::context *); 1078 rtl_opt_pass *make_pass_fma_steering (gcc::context *); 1079 rtl_opt_pass *make_pass_track_speculation (gcc::context *); 1080 rtl_opt_pass *make_pass_late_track_speculation (gcc::context *); 1081 rtl_opt_pass *make_pass_tag_collision_avoidance (gcc::context *); 1082 rtl_opt_pass *make_pass_insert_bti (gcc::context *ctxt); 1083 rtl_opt_pass *make_pass_cc_fusion (gcc::context *ctxt); 1084 rtl_opt_pass *make_pass_switch_pstate_sm (gcc::context *ctxt); 1085 rtl_opt_pass *make_pass_ldp_fusion (gcc::context *); 1086 1087 poly_uint64 aarch64_regmode_natural_size (machine_mode); 1088 1089 bool aarch64_high_bits_all_ones_p (HOST_WIDE_INT); 1090 1091 struct atomic_ool_names 1092 { 1093 const char *str[5][5]; 1094 }; 1095 1096 rtx aarch64_atomic_ool_func(machine_mode mode, rtx model_rtx, 1097 const atomic_ool_names *names); 1098 extern const atomic_ool_names aarch64_ool_swp_names; 1099 extern const atomic_ool_names aarch64_ool_ldadd_names; 1100 extern const atomic_ool_names aarch64_ool_ldset_names; 1101 extern const atomic_ool_names aarch64_ool_ldclr_names; 1102 extern const atomic_ool_names aarch64_ool_ldeor_names; 1103 1104 tree aarch64_resolve_overloaded_builtin_general (location_t, tree, void *); 1105 1106 const char *aarch64_sls_barrier (int); 1107 const char *aarch64_indirect_call_asm (rtx); 1108 extern bool aarch64_harden_sls_retbr_p (void); 1109 extern bool aarch64_harden_sls_blr_p (void); 1110 1111 extern void aarch64_output_patchable_area (unsigned int, bool); 1112 1113 extern void aarch64_adjust_reg_alloc_order (); 1114 1115 bool aarch64_optimize_mode_switching (aarch64_mode_entity); 1116 void aarch64_restore_za (rtx); 1117 1118 #endif /* GCC_AARCH64_PROTOS_H */ 1119