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 #define IN_TARGET_CODE 1 22 23 #define INCLUDE_STRING 24 #define INCLUDE_ALGORITHM 25 #define INCLUDE_VECTOR 26 #include "config.h" 27 #include "system.h" 28 #include "coretypes.h" 29 #include "backend.h" 30 #include "target.h" 31 #include "rtl.h" 32 #include "tree.h" 33 #include "memmodel.h" 34 #include "gimple.h" 35 #include "cfghooks.h" 36 #include "cfgloop.h" 37 #include "df.h" 38 #include "tm_p.h" 39 #include "stringpool.h" 40 #include "attribs.h" 41 #include "optabs.h" 42 #include "regs.h" 43 #include "emit-rtl.h" 44 #include "recog.h" 45 #include "cgraph.h" 46 #include "diagnostic.h" 47 #include "insn-attr.h" 48 #include "alias.h" 49 #include "fold-const.h" 50 #include "stor-layout.h" 51 #include "calls.h" 52 #include "varasm.h" 53 #include "output.h" 54 #include "flags.h" 55 #include "explow.h" 56 #include "expr.h" 57 #include "reload.h" 58 #include "langhooks.h" 59 #include "opts.h" 60 #include "gimplify.h" 61 #include "dwarf2.h" 62 #include "gimple-iterator.h" 63 #include "tree-vectorizer.h" 64 #include "aarch64-cost-tables.h" 65 #include "dumpfile.h" 66 #include "builtins.h" 67 #include "rtl-iter.h" 68 #include "tm-constrs.h" 69 #include "sched-int.h" 70 #include "target-globals.h" 71 #include "common/common-target.h" 72 #include "cfgrtl.h" 73 #include "selftest.h" 74 #include "selftest-rtl.h" 75 #include "rtx-vector-builder.h" 76 #include "intl.h" 77 #include "expmed.h" 78 #include "function-abi.h" 79 #include "gimple-pretty-print.h" 80 #include "tree-ssa-loop-niter.h" 81 #include "fractional-cost.h" 82 #include "rtlanal.h" 83 #include "tree-dfa.h" 84 #include "asan.h" 85 #include "aarch64-feature-deps.h" 86 #include "config/arm/aarch-common.h" 87 #include "config/arm/aarch-common-protos.h" 88 #include "common/config/aarch64/cpuinfo.h" 89 #include "ssa.h" 90 #include "except.h" 91 #include "tree-pass.h" 92 #include "cfgbuild.h" 93 #include "symbol-summary.h" 94 #include "sreal.h" 95 #include "ipa-cp.h" 96 #include "ipa-prop.h" 97 #include "ipa-fnsummary.h" 98 #include "hash-map.h" 99 100 /* This file should be included last. */ 101 #include "target-def.h" 102 103 /* Defined for convenience. */ 104 #define POINTER_BYTES (POINTER_SIZE / BITS_PER_UNIT) 105 106 /* Flags that describe how a function shares certain architectural state 107 with its callers. 108 109 - AARCH64_STATE_SHARED indicates that the function does share the state 110 with callers. 111 112 - AARCH64_STATE_IN indicates that the function reads (or might read) the 113 incoming state. The converse is that the function ignores the incoming 114 state. 115 116 - AARCH64_STATE_OUT indicates that the function returns new state. 117 The converse is that the state on return is the same as it was on entry. 118 119 A function that partially modifies the state treats it as both IN 120 and OUT (because the value on return depends to some extent on the 121 value on input). */ 122 constexpr auto AARCH64_STATE_SHARED = 1U << 0; 123 constexpr auto AARCH64_STATE_IN = 1U << 1; 124 constexpr auto AARCH64_STATE_OUT = 1U << 2; 125 126 /* Information about a legitimate vector immediate operand. */ 127 struct simd_immediate_info 128 { 129 enum insn_type { MOV, MVN, INDEX, PTRUE }; 130 enum modifier_type { LSL, MSL }; 131 132 simd_immediate_info () {} 133 simd_immediate_info (scalar_float_mode, rtx); 134 simd_immediate_info (scalar_int_mode, unsigned HOST_WIDE_INT, 135 insn_type = MOV, modifier_type = LSL, 136 unsigned int = 0); 137 simd_immediate_info (scalar_mode, rtx, rtx); 138 simd_immediate_info (scalar_int_mode, aarch64_svpattern); 139 140 /* The mode of the elements. */ 141 scalar_mode elt_mode; 142 143 /* The instruction to use to move the immediate into a vector. */ 144 insn_type insn; 145 146 union 147 { 148 /* For MOV and MVN. */ 149 struct 150 { 151 /* The value of each element. */ 152 rtx value; 153 154 /* The kind of shift modifier to use, and the number of bits to shift. 155 This is (LSL, 0) if no shift is needed. */ 156 modifier_type modifier; 157 unsigned int shift; 158 } mov; 159 160 /* For INDEX. */ 161 struct 162 { 163 /* The value of the first element and the step to be added for each 164 subsequent element. */ 165 rtx base, step; 166 } index; 167 168 /* For PTRUE. */ 169 aarch64_svpattern pattern; 170 } u; 171 }; 172 173 /* Construct a floating-point immediate in which each element has mode 174 ELT_MODE_IN and value VALUE_IN. */ 175 inline simd_immediate_info 176 ::simd_immediate_info (scalar_float_mode elt_mode_in, rtx value_in) 177 : elt_mode (elt_mode_in), insn (MOV) 178 { 179 u.mov.value = value_in; 180 u.mov.modifier = LSL; 181 u.mov.shift = 0; 182 } 183 184 /* Construct an integer immediate in which each element has mode ELT_MODE_IN 185 and value VALUE_IN. The other parameters are as for the structure 186 fields. */ 187 inline simd_immediate_info 188 ::simd_immediate_info (scalar_int_mode elt_mode_in, 189 unsigned HOST_WIDE_INT value_in, 190 insn_type insn_in, modifier_type modifier_in, 191 unsigned int shift_in) 192 : elt_mode (elt_mode_in), insn (insn_in) 193 { 194 u.mov.value = gen_int_mode (value_in, elt_mode_in); 195 u.mov.modifier = modifier_in; 196 u.mov.shift = shift_in; 197 } 198 199 /* Construct an integer immediate in which each element has mode ELT_MODE_IN 200 and where element I is equal to BASE_IN + I * STEP_IN. */ 201 inline simd_immediate_info 202 ::simd_immediate_info (scalar_mode elt_mode_in, rtx base_in, rtx step_in) 203 : elt_mode (elt_mode_in), insn (INDEX) 204 { 205 u.index.base = base_in; 206 u.index.step = step_in; 207 } 208 209 /* Construct a predicate that controls elements of mode ELT_MODE_IN 210 and has PTRUE pattern PATTERN_IN. */ 211 inline simd_immediate_info 212 ::simd_immediate_info (scalar_int_mode elt_mode_in, 213 aarch64_svpattern pattern_in) 214 : elt_mode (elt_mode_in), insn (PTRUE) 215 { 216 u.pattern = pattern_in; 217 } 218 219 namespace { 220 221 /* Describes types that map to Pure Scalable Types (PSTs) in the AAPCS64. */ 222 class pure_scalable_type_info 223 { 224 public: 225 /* Represents the result of analyzing a type. All values are nonzero, 226 in the possibly forlorn hope that accidental conversions to bool 227 trigger a warning. */ 228 enum analysis_result 229 { 230 /* The type does not have an ABI identity; i.e. it doesn't contain 231 at least one object whose type is a Fundamental Data Type. */ 232 NO_ABI_IDENTITY = 1, 233 234 /* The type is definitely a Pure Scalable Type. */ 235 IS_PST, 236 237 /* The type is definitely not a Pure Scalable Type. */ 238 ISNT_PST, 239 240 /* It doesn't matter for PCS purposes whether the type is a Pure 241 Scalable Type or not, since the type will be handled the same 242 way regardless. 243 244 Specifically, this means that if the type is a Pure Scalable Type, 245 there aren't enough argument registers to hold it, and so it will 246 need to be passed or returned in memory. If the type isn't a 247 Pure Scalable Type, it's too big to be passed or returned in core 248 or SIMD&FP registers, and so again will need to go in memory. */ 249 DOESNT_MATTER 250 }; 251 252 /* Aggregates of 17 bytes or more are normally passed and returned 253 in memory, so aggregates of that size can safely be analyzed as 254 DOESNT_MATTER. We need to be able to collect enough pieces to 255 represent a PST that is smaller than that. Since predicates are 256 2 bytes in size for -msve-vector-bits=128, that means we need to be 257 able to store at least 8 pieces. 258 259 We also need to be able to store enough pieces to represent 260 a single vector in each vector argument register and a single 261 predicate in each predicate argument register. This means that 262 we need at least 12 pieces. */ 263 static const unsigned int MAX_PIECES = NUM_FP_ARG_REGS + NUM_PR_ARG_REGS; 264 static_assert (MAX_PIECES >= 8, "Need to store at least 8 predicates"); 265 266 /* Describes one piece of a PST. Each piece is one of: 267 268 - a single Scalable Vector Type (SVT) 269 - a single Scalable Predicate Type (SPT) 270 - a PST containing 2, 3 or 4 SVTs, with no padding 271 272 It either represents a single built-in type or a PST formed from 273 multiple homogeneous built-in types. */ 274 struct piece 275 { 276 rtx get_rtx (unsigned int, unsigned int) const; 277 278 /* The number of vector and predicate registers that the piece 279 occupies. One of the two is always zero. */ 280 unsigned int num_zr; 281 unsigned int num_pr; 282 283 /* The mode of the registers described above. */ 284 machine_mode mode; 285 286 /* If this piece is formed from multiple homogeneous built-in types, 287 this is the mode of the built-in types, otherwise it is MODE. */ 288 machine_mode orig_mode; 289 290 /* The offset in bytes of the piece from the start of the type. */ 291 poly_uint64 offset; 292 }; 293 294 /* Divides types analyzed as IS_PST into individual pieces. The pieces 295 are in memory order. */ 296 auto_vec<piece, MAX_PIECES> pieces; 297 298 unsigned int num_zr () const; 299 unsigned int num_pr () const; 300 301 rtx get_rtx (machine_mode mode, unsigned int, unsigned int) const; 302 303 analysis_result analyze (const_tree); 304 bool analyze_registers (const_tree); 305 306 private: 307 analysis_result analyze_array (const_tree); 308 analysis_result analyze_record (const_tree); 309 void add_piece (const piece &); 310 }; 311 } 312 313 /* The current code model. */ 314 enum aarch64_code_model aarch64_cmodel; 315 316 enum aarch64_tp_reg aarch64_tpidr_register; 317 318 /* The number of 64-bit elements in an SVE vector. */ 319 poly_uint16 aarch64_sve_vg; 320 321 #ifdef HAVE_AS_TLS 322 #undef TARGET_HAVE_TLS 323 #define TARGET_HAVE_TLS 1 324 #endif 325 326 static bool aarch64_composite_type_p (const_tree, machine_mode); 327 static bool aarch64_return_in_memory_1 (const_tree); 328 static bool aarch64_vfp_is_call_or_return_candidate (machine_mode, 329 const_tree, 330 machine_mode *, int *, 331 bool *, bool); 332 static void aarch64_elf_asm_constructor (rtx, int) ATTRIBUTE_UNUSED; 333 static void aarch64_elf_asm_destructor (rtx, int) ATTRIBUTE_UNUSED; 334 static void aarch64_override_options_after_change (void); 335 static bool aarch64_vector_mode_supported_p (machine_mode); 336 static int aarch64_address_cost (rtx, machine_mode, addr_space_t, bool); 337 static bool aarch64_builtin_support_vector_misalignment (machine_mode mode, 338 const_tree type, 339 int misalignment, 340 bool is_packed); 341 static machine_mode aarch64_simd_container_mode (scalar_mode, poly_int64); 342 static bool aarch64_print_address_internal (FILE*, machine_mode, rtx, 343 aarch64_addr_query_type); 344 345 /* The processor for which instructions should be scheduled. */ 346 enum aarch64_processor aarch64_tune = cortexa53; 347 348 /* Mask to specify which instruction scheduling options should be used. */ 349 uint64_t aarch64_tune_flags = 0; 350 351 /* Global flag for PC relative loads. */ 352 bool aarch64_pcrelative_literal_loads; 353 354 /* Global flag for whether frame pointer is enabled. */ 355 bool aarch64_use_frame_pointer; 356 357 /* Support for command line parsing of boolean flags in the tuning 358 structures. */ 359 struct aarch64_flag_desc 360 { 361 const char* name; 362 unsigned int flag; 363 }; 364 365 #define AARCH64_FUSION_PAIR(name, internal_name) \ 366 { name, AARCH64_FUSE_##internal_name }, 367 static const struct aarch64_flag_desc aarch64_fusible_pairs[] = 368 { 369 { "none", AARCH64_FUSE_NOTHING }, 370 #include "aarch64-fusion-pairs.def" 371 { "all", AARCH64_FUSE_ALL }, 372 { NULL, AARCH64_FUSE_NOTHING } 373 }; 374 375 #define AARCH64_EXTRA_TUNING_OPTION(name, internal_name) \ 376 { name, AARCH64_EXTRA_TUNE_##internal_name }, 377 static const struct aarch64_flag_desc aarch64_tuning_flags[] = 378 { 379 { "none", AARCH64_EXTRA_TUNE_NONE }, 380 #include "aarch64-tuning-flags.def" 381 { "all", AARCH64_EXTRA_TUNE_ALL }, 382 { NULL, AARCH64_EXTRA_TUNE_NONE } 383 }; 384 385 /* Tuning parameters. */ 386 #include "tuning_models/generic.h" 387 #include "tuning_models/generic_armv8_a.h" 388 #include "tuning_models/generic_armv9_a.h" 389 #include "tuning_models/cortexa35.h" 390 #include "tuning_models/cortexa53.h" 391 #include "tuning_models/cortexa57.h" 392 #include "tuning_models/cortexa72.h" 393 #include "tuning_models/cortexa73.h" 394 #include "tuning_models/exynosm1.h" 395 #include "tuning_models/thunderxt88.h" 396 #include "tuning_models/thunderx.h" 397 #include "tuning_models/tsv110.h" 398 #include "tuning_models/xgene1.h" 399 #include "tuning_models/emag.h" 400 #include "tuning_models/qdf24xx.h" 401 #include "tuning_models/saphira.h" 402 #include "tuning_models/thunderx2t99.h" 403 #include "tuning_models/thunderx3t110.h" 404 #include "tuning_models/neoversen1.h" 405 #include "tuning_models/ampere1.h" 406 #include "tuning_models/ampere1a.h" 407 #include "tuning_models/ampere1b.h" 408 #include "tuning_models/neoversev1.h" 409 #include "tuning_models/neoverse512tvb.h" 410 #include "tuning_models/neoversen2.h" 411 #include "tuning_models/neoversev2.h" 412 #include "tuning_models/a64fx.h" 413 #include "tuning_models/fujitsu_monaka.h" 414 415 /* Support for fine-grained override of the tuning structures. */ 416 struct aarch64_tuning_override_function 417 { 418 const char* name; 419 void (*parse_override)(const char*, struct tune_params*); 420 }; 421 422 static void aarch64_parse_fuse_string (const char*, struct tune_params*); 423 static void aarch64_parse_tune_string (const char*, struct tune_params*); 424 static void aarch64_parse_sve_width_string (const char*, struct tune_params*); 425 426 static const struct aarch64_tuning_override_function 427 aarch64_tuning_override_functions[] = 428 { 429 { "fuse", aarch64_parse_fuse_string }, 430 { "tune", aarch64_parse_tune_string }, 431 { "sve_width", aarch64_parse_sve_width_string }, 432 { NULL, NULL } 433 }; 434 435 /* A processor implementing AArch64. */ 436 struct processor 437 { 438 const char *name; 439 aarch64_processor ident; 440 aarch64_processor sched_core; 441 aarch64_arch arch; 442 aarch64_feature_flags flags; 443 const tune_params *tune; 444 }; 445 446 /* Architectures implementing AArch64. */ 447 static CONSTEXPR const processor all_architectures[] = 448 { 449 #define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, D, E) \ 450 {NAME, CORE, CORE, AARCH64_ARCH_##ARCH_IDENT, \ 451 feature_deps::ARCH_IDENT ().enable, NULL}, 452 #include "aarch64-arches.def" 453 {NULL, aarch64_none, aarch64_none, aarch64_no_arch, 0, NULL} 454 }; 455 456 /* Processor cores implementing AArch64. */ 457 static const struct processor all_cores[] = 458 { 459 #define AARCH64_CORE(NAME, IDENT, SCHED, ARCH, E, COSTS, G, H, I) \ 460 {NAME, IDENT, SCHED, AARCH64_ARCH_##ARCH, \ 461 feature_deps::cpu_##IDENT, &COSTS##_tunings}, 462 #include "aarch64-cores.def" 463 {NULL, aarch64_none, aarch64_none, aarch64_no_arch, 0, NULL} 464 }; 465 /* Internal representation of system registers. */ 466 typedef struct { 467 const char *name; 468 /* Stringified sysreg encoding values, represented as 469 s<sn>_<op1>_c<cn>_c<cm>_<op2>. */ 470 const char *encoding; 471 /* Flags affecting sysreg usage, such as read/write-only. */ 472 unsigned properties; 473 /* Architectural features implied by sysreg. */ 474 aarch64_feature_flags arch_reqs; 475 } sysreg_t; 476 477 /* An aarch64_feature_set initializer for a single feature, 478 AARCH64_FEATURE_<FEAT>. */ 479 #define AARCH64_FEATURE(FEAT) AARCH64_FL_##FEAT 480 481 /* Used by AARCH64_FEATURES. */ 482 #define AARCH64_OR_FEATURES_1(X, F1) \ 483 AARCH64_FEATURE (F1) 484 #define AARCH64_OR_FEATURES_2(X, F1, F2) \ 485 (AARCH64_FEATURE (F1) | AARCH64_OR_FEATURES_1 (X, F2)) 486 #define AARCH64_OR_FEATURES_3(X, F1, ...) \ 487 (AARCH64_FEATURE (F1) | AARCH64_OR_FEATURES_2 (X, __VA_ARGS__)) 488 489 /* An aarch64_feature_set initializer for the N features listed in "...". */ 490 #define AARCH64_FEATURES(N, ...) \ 491 AARCH64_OR_FEATURES_##N (0, __VA_ARGS__) 492 493 #define AARCH64_NO_FEATURES 0 494 495 /* Flags associated with the properties of system registers. It mainly serves 496 to mark particular registers as read or write only. */ 497 #define F_DEPRECATED (1 << 1) 498 #define F_REG_READ (1 << 2) 499 #define F_REG_WRITE (1 << 3) 500 #define F_ARCHEXT (1 << 4) 501 /* Flag indicating register name is alias for another system register. */ 502 #define F_REG_ALIAS (1 << 5) 503 /* Flag indicatinig registers which may be implemented with 128-bits. */ 504 #define F_REG_128 (1 << 6) 505 506 /* Database of system registers, their encodings and architectural 507 requirements. */ 508 const sysreg_t aarch64_sysregs[] = 509 { 510 #define CPENC(SN, OP1, CN, CM, OP2) "s"#SN"_"#OP1"_c"#CN"_c"#CM"_"#OP2 511 #define SYSREG(NAME, ENC, FLAGS, ARCH) \ 512 { NAME, ENC, FLAGS, ARCH }, 513 #include "aarch64-sys-regs.def" 514 #undef CPENC 515 }; 516 517 #undef AARCH64_NO_FEATURES 518 519 using sysreg_map_t = hash_map<nofree_string_hash, const sysreg_t *>; 520 static sysreg_map_t *sysreg_map = nullptr; 521 522 /* Map system register names to their hardware metadata: encoding, 523 feature flags and architectural feature requirements, all of which 524 are encoded in a sysreg_t struct. */ 525 void 526 aarch64_register_sysreg (const char *name, const sysreg_t *metadata) 527 { 528 bool dup = sysreg_map->put (name, metadata); 529 gcc_checking_assert (!dup); 530 } 531 532 /* Lazily initialize hash table for system register validation, 533 checking the validity of supplied register name and returning 534 register's associated metadata. */ 535 static void 536 aarch64_init_sysregs (void) 537 { 538 gcc_assert (!sysreg_map); 539 sysreg_map = new sysreg_map_t; 540 541 542 for (unsigned i = 0; i < ARRAY_SIZE (aarch64_sysregs); i++) 543 { 544 const sysreg_t *reg = aarch64_sysregs + i; 545 aarch64_register_sysreg (reg->name, reg); 546 } 547 } 548 549 /* No direct access to the sysreg hash-map should be made. Doing so 550 risks trying to acess an unitialized hash-map and dereferencing the 551 returned double pointer without due care risks dereferencing a 552 null-pointer. */ 553 const sysreg_t * 554 aarch64_lookup_sysreg_map (const char *regname) 555 { 556 if (!sysreg_map) 557 aarch64_init_sysregs (); 558 559 const sysreg_t **sysreg_entry = sysreg_map->get (regname); 560 if (sysreg_entry != NULL) 561 return *sysreg_entry; 562 return NULL; 563 } 564 565 /* The current tuning set. */ 566 struct tune_params aarch64_tune_params = generic_tunings; 567 568 /* If NAME is the name of an arm:: attribute that describes shared state, 569 return its associated AARCH64_STATE_* flags, otherwise return 0. */ 570 static unsigned int 571 aarch64_attribute_shared_state_flags (const char *name) 572 { 573 if (strcmp (name, "in") == 0) 574 return AARCH64_STATE_SHARED | AARCH64_STATE_IN; 575 if (strcmp (name, "inout") == 0) 576 return AARCH64_STATE_SHARED | AARCH64_STATE_IN | AARCH64_STATE_OUT; 577 if (strcmp (name, "out") == 0) 578 return AARCH64_STATE_SHARED | AARCH64_STATE_OUT; 579 if (strcmp (name, "preserves") == 0) 580 return AARCH64_STATE_SHARED; 581 return 0; 582 } 583 584 /* See whether attribute list ATTRS has any sharing information 585 for state STATE_NAME. Return the associated state flags if so, 586 otherwise return 0. */ 587 static unsigned int 588 aarch64_lookup_shared_state_flags (tree attrs, const char *state_name) 589 { 590 for (tree attr = attrs; attr; attr = TREE_CHAIN (attr)) 591 { 592 if (!cxx11_attribute_p (attr)) 593 continue; 594 595 auto ns = IDENTIFIER_POINTER (TREE_PURPOSE (TREE_PURPOSE (attr))); 596 if (strcmp (ns, "arm") != 0) 597 continue; 598 599 auto attr_name = IDENTIFIER_POINTER (TREE_VALUE (TREE_PURPOSE (attr))); 600 auto flags = aarch64_attribute_shared_state_flags (attr_name); 601 if (!flags) 602 continue; 603 604 for (tree arg = TREE_VALUE (attr); arg; arg = TREE_CHAIN (arg)) 605 { 606 tree value = TREE_VALUE (arg); 607 if (TREE_CODE (value) == STRING_CST 608 && strcmp (TREE_STRING_POINTER (value), state_name) == 0) 609 return flags; 610 } 611 } 612 return 0; 613 } 614 615 /* Return true if DECL creates a new scope for state STATE_STRING. */ 616 static bool 617 aarch64_fndecl_has_new_state (const_tree decl, const char *state_name) 618 { 619 if (tree attr = lookup_attribute ("arm", "new", DECL_ATTRIBUTES (decl))) 620 for (tree arg = TREE_VALUE (attr); arg; arg = TREE_CHAIN (arg)) 621 { 622 tree value = TREE_VALUE (arg); 623 if (TREE_CODE (value) == STRING_CST 624 && strcmp (TREE_STRING_POINTER (value), state_name) == 0) 625 return true; 626 } 627 return false; 628 } 629 630 /* Return true if attribute argument VALUE is a recognized state string, 631 otherwise report an error. NAME is the name of the attribute to which 632 VALUE is being passed. */ 633 static bool 634 aarch64_check_state_string (tree name, tree value) 635 { 636 if (TREE_CODE (value) != STRING_CST) 637 { 638 error ("the arguments to %qE must be constant strings", name); 639 return false; 640 } 641 642 const char *state_name = TREE_STRING_POINTER (value); 643 if (strcmp (state_name, "za") != 0 644 && strcmp (state_name, "zt0") != 0) 645 { 646 error ("unrecognized state string %qs", state_name); 647 return false; 648 } 649 650 return true; 651 } 652 653 /* qsort callback to compare two STRING_CSTs. */ 654 static int 655 cmp_string_csts (const void *a, const void *b) 656 { 657 return strcmp (TREE_STRING_POINTER (*(const_tree const *) a), 658 TREE_STRING_POINTER (*(const_tree const *) b)); 659 } 660 661 /* Canonicalize a list of state strings. ARGS contains the arguments to 662 a new attribute while OLD_ATTR, if nonnull, contains a previous attribute 663 of the same type. If CAN_MERGE_IN_PLACE, it is safe to adjust OLD_ATTR's 664 arguments and drop the new attribute. Otherwise, the new attribute must 665 be kept and ARGS must include the information in OLD_ATTR. 666 667 In both cases, the new arguments must be a sorted list of state strings 668 with duplicates removed. 669 670 Return true if new attribute should be kept, false if it should be 671 dropped. */ 672 static bool 673 aarch64_merge_string_arguments (tree args, tree old_attr, 674 bool can_merge_in_place) 675 { 676 /* Get a sorted list of all state strings (including duplicates). */ 677 auto add_args = [](vec<tree> &strings, const_tree args) 678 { 679 for (const_tree arg = args; arg; arg = TREE_CHAIN (arg)) 680 if (TREE_CODE (TREE_VALUE (arg)) == STRING_CST) 681 strings.safe_push (TREE_VALUE (arg)); 682 }; 683 auto_vec<tree, 16> strings; 684 add_args (strings, args); 685 if (old_attr) 686 add_args (strings, TREE_VALUE (old_attr)); 687 strings.qsort (cmp_string_csts); 688 689 /* The list can be empty if there was no previous attribute and if all 690 the new arguments are erroneous. Drop the attribute in that case. */ 691 if (strings.is_empty ()) 692 return false; 693 694 /* Destructively modify one of the argument lists, removing duplicates 695 on the fly. */ 696 bool use_old_attr = old_attr && can_merge_in_place; 697 tree *end = use_old_attr ? &TREE_VALUE (old_attr) : &args; 698 tree prev = NULL_TREE; 699 for (tree arg : strings) 700 { 701 if (prev && simple_cst_equal (arg, prev)) 702 continue; 703 prev = arg; 704 if (!*end) 705 *end = tree_cons (NULL_TREE, arg, NULL_TREE); 706 else 707 TREE_VALUE (*end) = arg; 708 end = &TREE_CHAIN (*end); 709 } 710 *end = NULL_TREE; 711 return !use_old_attr; 712 } 713 714 /* Check whether an 'aarch64_vector_pcs' attribute is valid. */ 715 716 static tree 717 handle_aarch64_vector_pcs_attribute (tree *node, tree name, tree, 718 int, bool *no_add_attrs) 719 { 720 /* Since we set fn_type_req to true, the caller should have checked 721 this for us. */ 722 gcc_assert (FUNC_OR_METHOD_TYPE_P (*node)); 723 switch ((arm_pcs) fntype_abi (*node).id ()) 724 { 725 case ARM_PCS_AAPCS64: 726 case ARM_PCS_SIMD: 727 return NULL_TREE; 728 729 case ARM_PCS_SVE: 730 error ("the %qE attribute cannot be applied to an SVE function type", 731 name); 732 *no_add_attrs = true; 733 return NULL_TREE; 734 735 case ARM_PCS_TLSDESC: 736 case ARM_PCS_UNKNOWN: 737 break; 738 } 739 gcc_unreachable (); 740 } 741 742 /* Return true if arm::new(ARGS) is compatible with the type of decl DECL, 743 otherwise report an error. */ 744 static bool 745 aarch64_check_arm_new_against_type (tree args, tree decl) 746 { 747 tree type_attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl)); 748 for (tree arg = args; arg; arg = TREE_CHAIN (arg)) 749 { 750 tree value = TREE_VALUE (arg); 751 if (TREE_CODE (value) == STRING_CST) 752 { 753 const char *state_name = TREE_STRING_POINTER (value); 754 if (aarch64_lookup_shared_state_flags (type_attrs, state_name)) 755 { 756 error_at (DECL_SOURCE_LOCATION (decl), 757 "cannot create a new %qs scope since %qs is shared" 758 " with callers", state_name, state_name); 759 return false; 760 } 761 } 762 } 763 return true; 764 } 765 766 /* Callback for arm::new attributes. */ 767 static tree 768 handle_arm_new (tree *node, tree name, tree args, int, bool *no_add_attrs) 769 { 770 tree decl = *node; 771 if (TREE_CODE (decl) != FUNCTION_DECL) 772 { 773 error ("%qE attribute applies only to function definitions", name); 774 *no_add_attrs = true; 775 return NULL_TREE; 776 } 777 if (TREE_TYPE (decl) == error_mark_node) 778 { 779 *no_add_attrs = true; 780 return NULL_TREE; 781 } 782 783 for (tree arg = args; arg; arg = TREE_CHAIN (arg)) 784 aarch64_check_state_string (name, TREE_VALUE (arg)); 785 786 if (!aarch64_check_arm_new_against_type (args, decl)) 787 { 788 *no_add_attrs = true; 789 return NULL_TREE; 790 } 791 792 /* If there is an old attribute, we should try to update it in-place, 793 so that there is only one (definitive) arm::new attribute on the decl. */ 794 tree old_attr = lookup_attribute ("arm", "new", DECL_ATTRIBUTES (decl)); 795 if (!aarch64_merge_string_arguments (args, old_attr, true)) 796 *no_add_attrs = true; 797 798 return NULL_TREE; 799 } 800 801 /* Callback for arm::{in,out,inout,preserves} attributes. */ 802 static tree 803 handle_arm_shared (tree *node, tree name, tree args, 804 int, bool *no_add_attrs) 805 { 806 tree type = *node; 807 tree old_attrs = TYPE_ATTRIBUTES (type); 808 auto flags = aarch64_attribute_shared_state_flags (IDENTIFIER_POINTER (name)); 809 for (tree arg = args; arg; arg = TREE_CHAIN (arg)) 810 { 811 tree value = TREE_VALUE (arg); 812 if (aarch64_check_state_string (name, value)) 813 { 814 const char *state_name = TREE_STRING_POINTER (value); 815 auto old_flags = aarch64_lookup_shared_state_flags (old_attrs, 816 state_name); 817 if (old_flags && old_flags != flags) 818 { 819 error ("inconsistent attributes for state %qs", state_name); 820 *no_add_attrs = true; 821 return NULL_TREE; 822 } 823 } 824 } 825 826 /* We can't update an old attribute in-place, since types are shared. 827 Instead make sure that this new attribute contains all the 828 information, so that the old attribute becomes redundant. */ 829 tree old_attr = lookup_attribute ("arm", IDENTIFIER_POINTER (name), 830 old_attrs); 831 if (!aarch64_merge_string_arguments (args, old_attr, false)) 832 *no_add_attrs = true; 833 834 return NULL_TREE; 835 } 836 837 /* Mutually-exclusive function type attributes for controlling PSTATE.SM. */ 838 static const struct attribute_spec::exclusions attr_streaming_exclusions[] = 839 { 840 /* Attribute name exclusion applies to: 841 function, type, variable */ 842 { "streaming", false, true, false }, 843 { "streaming_compatible", false, true, false }, 844 { NULL, false, false, false } 845 }; 846 847 /* Table of machine attributes. */ 848 static const attribute_spec aarch64_gnu_attributes[] = 849 { 850 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, 851 affects_type_identity, handler, exclude } */ 852 { "aarch64_vector_pcs", 0, 0, false, true, true, true, 853 handle_aarch64_vector_pcs_attribute, NULL }, 854 { "arm_sve_vector_bits", 1, 1, false, true, false, true, 855 aarch64_sve::handle_arm_sve_vector_bits_attribute, 856 NULL }, 857 { "Advanced SIMD type", 1, 1, false, true, false, true, NULL, NULL }, 858 { "SVE type", 3, 3, false, true, false, true, NULL, NULL }, 859 { "SVE sizeless type", 0, 0, false, true, false, true, NULL, NULL } 860 }; 861 862 static const scoped_attribute_specs aarch64_gnu_attribute_table = 863 { 864 "gnu", { aarch64_gnu_attributes } 865 }; 866 867 static const attribute_spec aarch64_arm_attributes[] = 868 { 869 { "streaming", 0, 0, false, true, true, true, 870 NULL, attr_streaming_exclusions }, 871 { "streaming_compatible", 0, 0, false, true, true, true, 872 NULL, attr_streaming_exclusions }, 873 { "locally_streaming", 0, 0, true, false, false, false, NULL, NULL }, 874 { "new", 1, -1, true, false, false, false, 875 handle_arm_new, NULL }, 876 { "preserves", 1, -1, false, true, true, true, 877 handle_arm_shared, NULL }, 878 { "in", 1, -1, false, true, true, true, 879 handle_arm_shared, NULL }, 880 { "out", 1, -1, false, true, true, true, 881 handle_arm_shared, NULL }, 882 { "inout", 1, -1, false, true, true, true, 883 handle_arm_shared, NULL } 884 }; 885 886 static const scoped_attribute_specs aarch64_arm_attribute_table = 887 { 888 "arm", { aarch64_arm_attributes } 889 }; 890 891 static const scoped_attribute_specs *const aarch64_attribute_table[] = 892 { 893 &aarch64_gnu_attribute_table, 894 &aarch64_arm_attribute_table 895 }; 896 897 typedef enum aarch64_cond_code 898 { 899 AARCH64_EQ = 0, AARCH64_NE, AARCH64_CS, AARCH64_CC, AARCH64_MI, AARCH64_PL, 900 AARCH64_VS, AARCH64_VC, AARCH64_HI, AARCH64_LS, AARCH64_GE, AARCH64_LT, 901 AARCH64_GT, AARCH64_LE, AARCH64_AL, AARCH64_NV 902 } 903 aarch64_cc; 904 905 #define AARCH64_INVERSE_CONDITION_CODE(X) ((aarch64_cc) (((int) X) ^ 1)) 906 907 908 /* The condition codes of the processor, and the inverse function. */ 909 static const char * const aarch64_condition_codes[] = 910 { 911 "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", 912 "hi", "ls", "ge", "lt", "gt", "le", "al", "nv" 913 }; 914 915 /* The preferred condition codes for SVE conditions. */ 916 static const char *const aarch64_sve_condition_codes[] = 917 { 918 "none", "any", "nlast", "last", "first", "nfrst", "vs", "vc", 919 "pmore", "plast", "tcont", "tstop", "gt", "le", "al", "nv" 920 }; 921 922 /* Return the assembly token for svpattern value VALUE. */ 923 924 static const char * 925 svpattern_token (enum aarch64_svpattern pattern) 926 { 927 switch (pattern) 928 { 929 #define CASE(UPPER, LOWER, VALUE) case AARCH64_SV_##UPPER: return #LOWER; 930 AARCH64_FOR_SVPATTERN (CASE) 931 #undef CASE 932 case AARCH64_NUM_SVPATTERNS: 933 break; 934 } 935 gcc_unreachable (); 936 } 937 938 /* Return the location of a piece that is known to be passed or returned 939 in registers. FIRST_ZR is the first unused vector argument register 940 and FIRST_PR is the first unused predicate argument register. */ 941 942 rtx 943 pure_scalable_type_info::piece::get_rtx (unsigned int first_zr, 944 unsigned int first_pr) const 945 { 946 gcc_assert (VECTOR_MODE_P (mode) 947 && first_zr + num_zr <= V0_REGNUM + NUM_FP_ARG_REGS 948 && first_pr + num_pr <= P0_REGNUM + NUM_PR_ARG_REGS); 949 950 if (num_zr > 0 && num_pr == 0) 951 return gen_rtx_REG (mode, first_zr); 952 953 if (num_zr == 0 && num_pr <= 2) 954 return gen_rtx_REG (mode, first_pr); 955 956 gcc_unreachable (); 957 } 958 959 /* Return the total number of vector registers required by the PST. */ 960 961 unsigned int 962 pure_scalable_type_info::num_zr () const 963 { 964 unsigned int res = 0; 965 for (unsigned int i = 0; i < pieces.length (); ++i) 966 res += pieces[i].num_zr; 967 return res; 968 } 969 970 /* Return the total number of predicate registers required by the PST. */ 971 972 unsigned int 973 pure_scalable_type_info::num_pr () const 974 { 975 unsigned int res = 0; 976 for (unsigned int i = 0; i < pieces.length (); ++i) 977 res += pieces[i].num_pr; 978 return res; 979 } 980 981 /* Return the location of a PST that is known to be passed or returned 982 in registers. FIRST_ZR is the first unused vector argument register 983 and FIRST_PR is the first unused predicate argument register. */ 984 985 rtx 986 pure_scalable_type_info::get_rtx (machine_mode mode, 987 unsigned int first_zr, 988 unsigned int first_pr) const 989 { 990 /* Try to return a single REG if possible. This leads to better 991 code generation; it isn't required for correctness. */ 992 if (mode == pieces[0].mode) 993 { 994 gcc_assert (pieces.length () == 1); 995 return pieces[0].get_rtx (first_zr, first_pr); 996 } 997 998 /* Build up a PARALLEL that contains the individual pieces. */ 999 rtvec rtxes = rtvec_alloc (pieces.length ()); 1000 for (unsigned int i = 0; i < pieces.length (); ++i) 1001 { 1002 rtx reg = pieces[i].get_rtx (first_zr, first_pr); 1003 rtx offset = gen_int_mode (pieces[i].offset, Pmode); 1004 RTVEC_ELT (rtxes, i) = gen_rtx_EXPR_LIST (VOIDmode, reg, offset); 1005 first_zr += pieces[i].num_zr; 1006 first_pr += pieces[i].num_pr; 1007 } 1008 return gen_rtx_PARALLEL (mode, rtxes); 1009 } 1010 1011 /* Analyze whether TYPE is a Pure Scalable Type according to the rules 1012 in the AAPCS64. */ 1013 1014 pure_scalable_type_info::analysis_result 1015 pure_scalable_type_info::analyze (const_tree type) 1016 { 1017 /* Prevent accidental reuse. */ 1018 gcc_assert (pieces.is_empty ()); 1019 1020 /* No code will be generated for erroneous types, so we won't establish 1021 an ABI mapping. */ 1022 if (type == error_mark_node) 1023 return NO_ABI_IDENTITY; 1024 1025 /* Zero-sized types disappear in the language->ABI mapping. */ 1026 if (TYPE_SIZE (type) && integer_zerop (TYPE_SIZE (type))) 1027 return NO_ABI_IDENTITY; 1028 1029 /* Check for SVTs, SPTs, and built-in tuple types that map to PSTs. */ 1030 piece p = {}; 1031 if (aarch64_sve::builtin_type_p (type, &p.num_zr, &p.num_pr)) 1032 { 1033 machine_mode mode = TYPE_MODE_RAW (type); 1034 gcc_assert (VECTOR_MODE_P (mode) 1035 && (!TARGET_SVE || aarch64_sve_mode_p (mode))); 1036 1037 p.mode = p.orig_mode = mode; 1038 add_piece (p); 1039 return IS_PST; 1040 } 1041 1042 /* Check for user-defined PSTs. */ 1043 if (TREE_CODE (type) == ARRAY_TYPE) 1044 return analyze_array (type); 1045 if (TREE_CODE (type) == RECORD_TYPE) 1046 return analyze_record (type); 1047 1048 return ISNT_PST; 1049 } 1050 1051 /* Analyze a type that is known not to be passed or returned in memory. 1052 Return true if it has an ABI identity and is a Pure Scalable Type. */ 1053 1054 bool 1055 pure_scalable_type_info::analyze_registers (const_tree type) 1056 { 1057 analysis_result result = analyze (type); 1058 gcc_assert (result != DOESNT_MATTER); 1059 return result == IS_PST; 1060 } 1061 1062 /* Subroutine of analyze for handling ARRAY_TYPEs. */ 1063 1064 pure_scalable_type_info::analysis_result 1065 pure_scalable_type_info::analyze_array (const_tree type) 1066 { 1067 /* Analyze the element type. */ 1068 pure_scalable_type_info element_info; 1069 analysis_result result = element_info.analyze (TREE_TYPE (type)); 1070 if (result != IS_PST) 1071 return result; 1072 1073 /* An array of unknown, flexible or variable length will be passed and 1074 returned by reference whatever we do. */ 1075 tree nelts_minus_one = array_type_nelts (type); 1076 if (!tree_fits_uhwi_p (nelts_minus_one)) 1077 return DOESNT_MATTER; 1078 1079 /* Likewise if the array is constant-sized but too big to be interesting. 1080 The double checks against MAX_PIECES are to protect against overflow. */ 1081 unsigned HOST_WIDE_INT count = tree_to_uhwi (nelts_minus_one); 1082 if (count > MAX_PIECES) 1083 return DOESNT_MATTER; 1084 count += 1; 1085 if (count * element_info.pieces.length () > MAX_PIECES) 1086 return DOESNT_MATTER; 1087 1088 /* The above checks should have weeded out elements of unknown size. */ 1089 poly_uint64 element_bytes; 1090 if (!poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (type)), &element_bytes)) 1091 gcc_unreachable (); 1092 1093 /* Build up the list of individual vectors and predicates. */ 1094 gcc_assert (!element_info.pieces.is_empty ()); 1095 for (unsigned int i = 0; i < count; ++i) 1096 for (unsigned int j = 0; j < element_info.pieces.length (); ++j) 1097 { 1098 piece p = element_info.pieces[j]; 1099 p.offset += i * element_bytes; 1100 add_piece (p); 1101 } 1102 return IS_PST; 1103 } 1104 1105 /* Subroutine of analyze for handling RECORD_TYPEs. */ 1106 1107 pure_scalable_type_info::analysis_result 1108 pure_scalable_type_info::analyze_record (const_tree type) 1109 { 1110 for (tree field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) 1111 { 1112 if (TREE_CODE (field) != FIELD_DECL) 1113 continue; 1114 1115 /* Zero-sized fields disappear in the language->ABI mapping. */ 1116 if (DECL_SIZE (field) && integer_zerop (DECL_SIZE (field))) 1117 continue; 1118 1119 /* All fields with an ABI identity must be PSTs for the record as 1120 a whole to be a PST. If any individual field is too big to be 1121 interesting then the record is too. */ 1122 pure_scalable_type_info field_info; 1123 analysis_result subresult = field_info.analyze (TREE_TYPE (field)); 1124 if (subresult == NO_ABI_IDENTITY) 1125 continue; 1126 if (subresult != IS_PST) 1127 return subresult; 1128 1129 /* Since all previous fields are PSTs, we ought to be able to track 1130 the field offset using poly_ints. */ 1131 tree bitpos = bit_position (field); 1132 gcc_assert (poly_int_tree_p (bitpos)); 1133 1134 /* For the same reason, it shouldn't be possible to create a PST field 1135 whose offset isn't byte-aligned. */ 1136 poly_widest_int wide_bytepos = exact_div (wi::to_poly_widest (bitpos), 1137 BITS_PER_UNIT); 1138 1139 /* Punt if the record is too big to be interesting. */ 1140 poly_uint64 bytepos; 1141 if (!wide_bytepos.to_uhwi (&bytepos) 1142 || pieces.length () + field_info.pieces.length () > MAX_PIECES) 1143 return DOESNT_MATTER; 1144 1145 /* Add the individual vectors and predicates in the field to the 1146 record's list. */ 1147 gcc_assert (!field_info.pieces.is_empty ()); 1148 for (unsigned int i = 0; i < field_info.pieces.length (); ++i) 1149 { 1150 piece p = field_info.pieces[i]; 1151 p.offset += bytepos; 1152 add_piece (p); 1153 } 1154 } 1155 /* Empty structures disappear in the language->ABI mapping. */ 1156 return pieces.is_empty () ? NO_ABI_IDENTITY : IS_PST; 1157 } 1158 1159 /* Add P to the list of pieces in the type. */ 1160 1161 void 1162 pure_scalable_type_info::add_piece (const piece &p) 1163 { 1164 /* Try to fold the new piece into the previous one to form a 1165 single-mode PST. For example, if we see three consecutive vectors 1166 of the same mode, we can represent them using the corresponding 1167 3-tuple mode. 1168 1169 This is purely an optimization. */ 1170 if (!pieces.is_empty ()) 1171 { 1172 piece &prev = pieces.last (); 1173 gcc_assert (VECTOR_MODE_P (p.mode) && VECTOR_MODE_P (prev.mode)); 1174 unsigned int nelems1, nelems2; 1175 if (prev.orig_mode == p.orig_mode 1176 && GET_MODE_CLASS (p.orig_mode) != MODE_VECTOR_BOOL 1177 && known_eq (prev.offset + GET_MODE_SIZE (prev.mode), p.offset) 1178 && constant_multiple_p (GET_MODE_NUNITS (prev.mode), 1179 GET_MODE_NUNITS (p.orig_mode), &nelems1) 1180 && constant_multiple_p (GET_MODE_NUNITS (p.mode), 1181 GET_MODE_NUNITS (p.orig_mode), &nelems2) 1182 && targetm.array_mode (p.orig_mode, 1183 nelems1 + nelems2).exists (&prev.mode)) 1184 { 1185 prev.num_zr += p.num_zr; 1186 prev.num_pr += p.num_pr; 1187 return; 1188 } 1189 } 1190 pieces.quick_push (p); 1191 } 1192 1193 /* Return true if at least one possible value of type TYPE includes at 1194 least one object of Pure Scalable Type, in the sense of the AAPCS64. 1195 1196 This is a relatively expensive test for some types, so it should 1197 generally be made as late as possible. */ 1198 1199 static bool 1200 aarch64_some_values_include_pst_objects_p (const_tree type) 1201 { 1202 if (TYPE_SIZE (type) && integer_zerop (TYPE_SIZE (type))) 1203 return false; 1204 1205 if (aarch64_sve::builtin_type_p (type)) 1206 return true; 1207 1208 if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == COMPLEX_TYPE) 1209 return aarch64_some_values_include_pst_objects_p (TREE_TYPE (type)); 1210 1211 if (RECORD_OR_UNION_TYPE_P (type)) 1212 for (tree field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) 1213 if (TREE_CODE (field) == FIELD_DECL 1214 && aarch64_some_values_include_pst_objects_p (TREE_TYPE (field))) 1215 return true; 1216 1217 return false; 1218 } 1219 1220 /* Return the descriptor of the SIMD ABI. */ 1221 1222 static const predefined_function_abi & 1223 aarch64_simd_abi (void) 1224 { 1225 predefined_function_abi &simd_abi = function_abis[ARM_PCS_SIMD]; 1226 if (!simd_abi.initialized_p ()) 1227 { 1228 HARD_REG_SET full_reg_clobbers 1229 = default_function_abi.full_reg_clobbers (); 1230 for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 1231 if (FP_SIMD_SAVED_REGNUM_P (regno)) 1232 CLEAR_HARD_REG_BIT (full_reg_clobbers, regno); 1233 simd_abi.initialize (ARM_PCS_SIMD, full_reg_clobbers); 1234 } 1235 return simd_abi; 1236 } 1237 1238 /* Return the descriptor of the SVE PCS. */ 1239 1240 static const predefined_function_abi & 1241 aarch64_sve_abi (void) 1242 { 1243 predefined_function_abi &sve_abi = function_abis[ARM_PCS_SVE]; 1244 if (!sve_abi.initialized_p ()) 1245 { 1246 HARD_REG_SET full_reg_clobbers 1247 = default_function_abi.full_reg_clobbers (); 1248 for (int regno = V8_REGNUM; regno <= V23_REGNUM; ++regno) 1249 CLEAR_HARD_REG_BIT (full_reg_clobbers, regno); 1250 for (int regno = P4_REGNUM; regno <= P15_REGNUM; ++regno) 1251 CLEAR_HARD_REG_BIT (full_reg_clobbers, regno); 1252 sve_abi.initialize (ARM_PCS_SVE, full_reg_clobbers); 1253 } 1254 return sve_abi; 1255 } 1256 1257 /* If X is an UNSPEC_SALT_ADDR expression, return the address that it 1258 wraps, otherwise return X itself. */ 1259 1260 static rtx 1261 strip_salt (rtx x) 1262 { 1263 rtx search = x; 1264 if (GET_CODE (search) == CONST) 1265 search = XEXP (search, 0); 1266 if (GET_CODE (search) == UNSPEC && XINT (search, 1) == UNSPEC_SALT_ADDR) 1267 x = XVECEXP (search, 0, 0); 1268 return x; 1269 } 1270 1271 /* Like strip_offset, but also strip any UNSPEC_SALT_ADDR from the 1272 expression. */ 1273 1274 static rtx 1275 strip_offset_and_salt (rtx addr, poly_int64 *offset) 1276 { 1277 return strip_salt (strip_offset (addr, offset)); 1278 } 1279 1280 /* Generate code to enable conditional branches in functions over 1 MiB. */ 1281 const char * 1282 aarch64_gen_far_branch (rtx * operands, int pos_label, const char * dest, 1283 const char * branch_format) 1284 { 1285 rtx_code_label * tmp_label = gen_label_rtx (); 1286 char label_buf[256]; 1287 char buffer[128]; 1288 ASM_GENERATE_INTERNAL_LABEL (label_buf, dest, 1289 CODE_LABEL_NUMBER (tmp_label)); 1290 const char *label_ptr = targetm.strip_name_encoding (label_buf); 1291 rtx dest_label = operands[pos_label]; 1292 operands[pos_label] = tmp_label; 1293 1294 snprintf (buffer, sizeof (buffer), "%s%s", branch_format, label_ptr); 1295 output_asm_insn (buffer, operands); 1296 1297 snprintf (buffer, sizeof (buffer), "b\t%%l%d\n%s:", pos_label, label_ptr); 1298 operands[pos_label] = dest_label; 1299 output_asm_insn (buffer, operands); 1300 return ""; 1301 } 1302 1303 void 1304 aarch64_err_no_fpadvsimd (machine_mode mode) 1305 { 1306 if (TARGET_GENERAL_REGS_ONLY) 1307 if (FLOAT_MODE_P (mode)) 1308 error ("%qs is incompatible with the use of floating-point types", 1309 "-mgeneral-regs-only"); 1310 else 1311 error ("%qs is incompatible with the use of vector types", 1312 "-mgeneral-regs-only"); 1313 else 1314 if (FLOAT_MODE_P (mode)) 1315 error ("%qs feature modifier is incompatible with the use of" 1316 " floating-point types", "+nofp"); 1317 else 1318 error ("%qs feature modifier is incompatible with the use of" 1319 " vector types", "+nofp"); 1320 } 1321 1322 /* Report when we try to do something that requires SVE when SVE is disabled. 1323 This is an error of last resort and isn't very high-quality. It usually 1324 involves attempts to measure the vector length in some way. */ 1325 static void 1326 aarch64_report_sve_required (void) 1327 { 1328 static bool reported_p = false; 1329 1330 /* Avoid reporting a slew of messages for a single oversight. */ 1331 if (reported_p) 1332 return; 1333 1334 error ("this operation requires the SVE ISA extension"); 1335 inform (input_location, "you can enable SVE using the command-line" 1336 " option %<-march%>, or by using the %<target%>" 1337 " attribute or pragma"); 1338 reported_p = true; 1339 } 1340 1341 /* Return true if REGNO is P0-P15 or one of the special FFR-related 1342 registers. */ 1343 inline bool 1344 pr_or_ffr_regnum_p (unsigned int regno) 1345 { 1346 return PR_REGNUM_P (regno) || regno == FFR_REGNUM || regno == FFRT_REGNUM; 1347 } 1348 1349 /* Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS. 1350 The register allocator chooses POINTER_AND_FP_REGS if FP_REGS and 1351 GENERAL_REGS have the same cost - even if POINTER_AND_FP_REGS has a much 1352 higher cost. POINTER_AND_FP_REGS is also used if the cost of both FP_REGS 1353 and GENERAL_REGS is lower than the memory cost (in this case the best class 1354 is the lowest cost one). Using POINTER_AND_FP_REGS irrespectively of its 1355 cost results in bad allocations with many redundant int<->FP moves which 1356 are expensive on various cores. 1357 To avoid this we don't allow POINTER_AND_FP_REGS as the allocno class, but 1358 force a decision between FP_REGS and GENERAL_REGS. We use the allocno class 1359 if it isn't POINTER_AND_FP_REGS. Similarly, use the best class if it isn't 1360 POINTER_AND_FP_REGS. Otherwise set the allocno class depending on the mode. 1361 The result of this is that it is no longer inefficient to have a higher 1362 memory move cost than the register move cost. 1363 */ 1364 1365 static reg_class_t 1366 aarch64_ira_change_pseudo_allocno_class (int regno, reg_class_t allocno_class, 1367 reg_class_t best_class) 1368 { 1369 machine_mode mode; 1370 1371 if (!reg_class_subset_p (GENERAL_REGS, allocno_class) 1372 || !reg_class_subset_p (FP_REGS, allocno_class)) 1373 return allocno_class; 1374 1375 if (!reg_class_subset_p (GENERAL_REGS, best_class) 1376 || !reg_class_subset_p (FP_REGS, best_class)) 1377 return best_class; 1378 1379 mode = PSEUDO_REGNO_MODE (regno); 1380 return FLOAT_MODE_P (mode) || VECTOR_MODE_P (mode) ? FP_REGS : GENERAL_REGS; 1381 } 1382 1383 static unsigned int 1384 aarch64_min_divisions_for_recip_mul (machine_mode mode) 1385 { 1386 if (GET_MODE_UNIT_SIZE (mode) == 4) 1387 return aarch64_tune_params.min_div_recip_mul_sf; 1388 return aarch64_tune_params.min_div_recip_mul_df; 1389 } 1390 1391 /* Return the reassociation width of treeop OPC with mode MODE. */ 1392 static int 1393 aarch64_reassociation_width (unsigned opc, machine_mode mode) 1394 { 1395 if (VECTOR_MODE_P (mode)) 1396 return aarch64_tune_params.vec_reassoc_width; 1397 if (INTEGRAL_MODE_P (mode)) 1398 return aarch64_tune_params.int_reassoc_width; 1399 /* Reassociation reduces the number of FMAs which may result in worse 1400 performance. Use a per-CPU setting for FMA reassociation which allows 1401 narrow CPUs with few FP pipes to switch it off (value of 1), and wider 1402 CPUs with many FP pipes to enable reassociation. 1403 Since the reassociation pass doesn't understand FMA at all, assume 1404 that any FP addition might turn into FMA. */ 1405 if (FLOAT_MODE_P (mode)) 1406 return opc == PLUS_EXPR ? aarch64_tune_params.fma_reassoc_width 1407 : aarch64_tune_params.fp_reassoc_width; 1408 return 1; 1409 } 1410 1411 /* Provide a mapping from gcc register numbers to dwarf register numbers. */ 1412 unsigned 1413 aarch64_debugger_regno (unsigned regno) 1414 { 1415 if (GP_REGNUM_P (regno)) 1416 return AARCH64_DWARF_R0 + regno - R0_REGNUM; 1417 else if (regno == SP_REGNUM) 1418 return AARCH64_DWARF_SP; 1419 else if (FP_REGNUM_P (regno)) 1420 return AARCH64_DWARF_V0 + regno - V0_REGNUM; 1421 else if (PR_REGNUM_P (regno)) 1422 return AARCH64_DWARF_P0 + regno - P0_REGNUM; 1423 else if (regno == VG_REGNUM) 1424 return AARCH64_DWARF_VG; 1425 1426 /* Return values >= DWARF_FRAME_REGISTERS indicate that there is no 1427 equivalent DWARF register. */ 1428 return DWARF_FRAME_REGISTERS; 1429 } 1430 1431 /* Implement TARGET_DWARF_FRAME_REG_MODE. */ 1432 static machine_mode 1433 aarch64_dwarf_frame_reg_mode (int regno) 1434 { 1435 /* Predicate registers are call-clobbered in the EH ABI (which is 1436 ARM_PCS_AAPCS64), so they should not be described by CFI. 1437 Their size changes as VL changes, so any values computed by 1438 __builtin_init_dwarf_reg_size_table might not be valid for 1439 all frames. */ 1440 if (PR_REGNUM_P (regno)) 1441 return VOIDmode; 1442 return default_dwarf_frame_reg_mode (regno); 1443 } 1444 1445 /* If X is a CONST_DOUBLE, return its bit representation as a constant 1446 integer, otherwise return X unmodified. */ 1447 static rtx 1448 aarch64_bit_representation (rtx x) 1449 { 1450 if (CONST_DOUBLE_P (x)) 1451 x = gen_lowpart (int_mode_for_mode (GET_MODE (x)).require (), x); 1452 return x; 1453 } 1454 1455 /* Return an estimate for the number of quadwords in an SVE vector. This is 1456 equivalent to the number of Advanced SIMD vectors in an SVE vector. */ 1457 static unsigned int 1458 aarch64_estimated_sve_vq () 1459 { 1460 return estimated_poly_value (BITS_PER_SVE_VECTOR) / 128; 1461 } 1462 1463 /* Return true if MODE is an SVE predicate mode. */ 1464 static bool 1465 aarch64_sve_pred_mode_p (machine_mode mode) 1466 { 1467 return (TARGET_SVE 1468 && (mode == VNx16BImode 1469 || mode == VNx8BImode 1470 || mode == VNx4BImode 1471 || mode == VNx2BImode)); 1472 } 1473 1474 /* Three mutually-exclusive flags describing a vector or predicate type. */ 1475 const unsigned int VEC_ADVSIMD = 1; 1476 const unsigned int VEC_SVE_DATA = 2; 1477 const unsigned int VEC_SVE_PRED = 4; 1478 /* Indicates a structure of 2, 3 or 4 vectors or predicates. */ 1479 const unsigned int VEC_STRUCT = 8; 1480 /* Can be used in combination with VEC_SVE_DATA to indicate that the 1481 vector has fewer significant bytes than a full SVE vector. */ 1482 const unsigned int VEC_PARTIAL = 16; 1483 /* Useful combinations of the above. */ 1484 const unsigned int VEC_ANY_SVE = VEC_SVE_DATA | VEC_SVE_PRED; 1485 const unsigned int VEC_ANY_DATA = VEC_ADVSIMD | VEC_SVE_DATA; 1486 1487 /* Return a set of flags describing the vector properties of mode MODE. 1488 If ANY_TARGET_P is false (the default), ignore modes that are not supported 1489 by the current target. Otherwise categorize the modes that can be used 1490 with the set of all targets supported by the port. */ 1491 1492 static unsigned int 1493 aarch64_classify_vector_mode (machine_mode mode, bool any_target_p = false) 1494 { 1495 if (aarch64_sve_pred_mode_p (mode)) 1496 return VEC_SVE_PRED; 1497 1498 /* Make the decision based on the mode's enum value rather than its 1499 properties, so that we keep the correct classification regardless 1500 of -msve-vector-bits. */ 1501 switch (mode) 1502 { 1503 /* Partial SVE QI vectors. */ 1504 case E_VNx2QImode: 1505 case E_VNx4QImode: 1506 case E_VNx8QImode: 1507 /* Partial SVE HI vectors. */ 1508 case E_VNx2HImode: 1509 case E_VNx4HImode: 1510 /* Partial SVE SI vector. */ 1511 case E_VNx2SImode: 1512 /* Partial SVE HF vectors. */ 1513 case E_VNx2HFmode: 1514 case E_VNx4HFmode: 1515 /* Partial SVE BF vectors. */ 1516 case E_VNx2BFmode: 1517 case E_VNx4BFmode: 1518 /* Partial SVE SF vector. */ 1519 case E_VNx2SFmode: 1520 return (TARGET_SVE || any_target_p) ? VEC_SVE_DATA | VEC_PARTIAL : 0; 1521 1522 case E_VNx16QImode: 1523 case E_VNx8HImode: 1524 case E_VNx4SImode: 1525 case E_VNx2DImode: 1526 case E_VNx8BFmode: 1527 case E_VNx8HFmode: 1528 case E_VNx4SFmode: 1529 case E_VNx2DFmode: 1530 return (TARGET_SVE || any_target_p) ? VEC_SVE_DATA : 0; 1531 1532 /* x2 SVE vectors. */ 1533 case E_VNx32QImode: 1534 case E_VNx16HImode: 1535 case E_VNx8SImode: 1536 case E_VNx4DImode: 1537 case E_VNx16BFmode: 1538 case E_VNx16HFmode: 1539 case E_VNx8SFmode: 1540 case E_VNx4DFmode: 1541 /* x3 SVE vectors. */ 1542 case E_VNx48QImode: 1543 case E_VNx24HImode: 1544 case E_VNx12SImode: 1545 case E_VNx6DImode: 1546 case E_VNx24BFmode: 1547 case E_VNx24HFmode: 1548 case E_VNx12SFmode: 1549 case E_VNx6DFmode: 1550 /* x4 SVE vectors. */ 1551 case E_VNx64QImode: 1552 case E_VNx32HImode: 1553 case E_VNx16SImode: 1554 case E_VNx8DImode: 1555 case E_VNx32BFmode: 1556 case E_VNx32HFmode: 1557 case E_VNx16SFmode: 1558 case E_VNx8DFmode: 1559 return (TARGET_SVE || any_target_p) ? VEC_SVE_DATA | VEC_STRUCT : 0; 1560 1561 case E_OImode: 1562 case E_CImode: 1563 case E_XImode: 1564 return (TARGET_FLOAT || any_target_p) ? VEC_ADVSIMD | VEC_STRUCT : 0; 1565 1566 /* Structures of 64-bit Advanced SIMD vectors. */ 1567 case E_V2x8QImode: 1568 case E_V2x4HImode: 1569 case E_V2x2SImode: 1570 case E_V2x1DImode: 1571 case E_V2x4BFmode: 1572 case E_V2x4HFmode: 1573 case E_V2x2SFmode: 1574 case E_V2x1DFmode: 1575 case E_V3x8QImode: 1576 case E_V3x4HImode: 1577 case E_V3x2SImode: 1578 case E_V3x1DImode: 1579 case E_V3x4BFmode: 1580 case E_V3x4HFmode: 1581 case E_V3x2SFmode: 1582 case E_V3x1DFmode: 1583 case E_V4x8QImode: 1584 case E_V4x4HImode: 1585 case E_V4x2SImode: 1586 case E_V4x1DImode: 1587 case E_V4x4BFmode: 1588 case E_V4x4HFmode: 1589 case E_V4x2SFmode: 1590 case E_V4x1DFmode: 1591 return (TARGET_FLOAT || any_target_p) 1592 ? VEC_ADVSIMD | VEC_STRUCT | VEC_PARTIAL : 0; 1593 1594 /* Structures of 128-bit Advanced SIMD vectors. */ 1595 case E_V2x16QImode: 1596 case E_V2x8HImode: 1597 case E_V2x4SImode: 1598 case E_V2x2DImode: 1599 case E_V2x8BFmode: 1600 case E_V2x8HFmode: 1601 case E_V2x4SFmode: 1602 case E_V2x2DFmode: 1603 case E_V3x16QImode: 1604 case E_V3x8HImode: 1605 case E_V3x4SImode: 1606 case E_V3x2DImode: 1607 case E_V3x8BFmode: 1608 case E_V3x8HFmode: 1609 case E_V3x4SFmode: 1610 case E_V3x2DFmode: 1611 case E_V4x16QImode: 1612 case E_V4x8HImode: 1613 case E_V4x4SImode: 1614 case E_V4x2DImode: 1615 case E_V4x8BFmode: 1616 case E_V4x8HFmode: 1617 case E_V4x4SFmode: 1618 case E_V4x2DFmode: 1619 return (TARGET_FLOAT || any_target_p) ? VEC_ADVSIMD | VEC_STRUCT : 0; 1620 1621 /* 64-bit Advanced SIMD vectors. */ 1622 case E_V8QImode: 1623 case E_V4HImode: 1624 case E_V2SImode: 1625 case E_V1DImode: 1626 case E_V4HFmode: 1627 case E_V4BFmode: 1628 case E_V2SFmode: 1629 case E_V1DFmode: 1630 /* 128-bit Advanced SIMD vectors. */ 1631 case E_V16QImode: 1632 case E_V8HImode: 1633 case E_V4SImode: 1634 case E_V2DImode: 1635 case E_V8HFmode: 1636 case E_V8BFmode: 1637 case E_V4SFmode: 1638 case E_V2DFmode: 1639 return (TARGET_FLOAT || any_target_p) ? VEC_ADVSIMD : 0; 1640 1641 case E_VNx32BImode: 1642 return TARGET_SVE ? VEC_SVE_PRED | VEC_STRUCT : 0; 1643 1644 default: 1645 return 0; 1646 } 1647 } 1648 1649 /* Return true if MODE is any of the Advanced SIMD structure modes. */ 1650 bool 1651 aarch64_advsimd_struct_mode_p (machine_mode mode) 1652 { 1653 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 1654 return (vec_flags & VEC_ADVSIMD) && (vec_flags & VEC_STRUCT); 1655 } 1656 1657 /* Return true if MODE is an Advanced SIMD D-register structure mode. */ 1658 static bool 1659 aarch64_advsimd_partial_struct_mode_p (machine_mode mode) 1660 { 1661 return (aarch64_classify_vector_mode (mode) 1662 == (VEC_ADVSIMD | VEC_STRUCT | VEC_PARTIAL)); 1663 } 1664 1665 /* Return true if MODE is an Advanced SIMD Q-register structure mode. */ 1666 static bool 1667 aarch64_advsimd_full_struct_mode_p (machine_mode mode) 1668 { 1669 return (aarch64_classify_vector_mode (mode) == (VEC_ADVSIMD | VEC_STRUCT)); 1670 } 1671 1672 /* Return true if MODE is any of the data vector modes, including 1673 structure modes. */ 1674 static bool 1675 aarch64_vector_data_mode_p (machine_mode mode) 1676 { 1677 return aarch64_classify_vector_mode (mode) & VEC_ANY_DATA; 1678 } 1679 1680 /* Return true if MODE is any form of SVE mode, including predicates, 1681 vectors and structures. */ 1682 bool 1683 aarch64_sve_mode_p (machine_mode mode) 1684 { 1685 return aarch64_classify_vector_mode (mode) & VEC_ANY_SVE; 1686 } 1687 1688 /* Return true if MODE is an SVE data vector mode; either a single vector 1689 or a structure of vectors. */ 1690 static bool 1691 aarch64_sve_data_mode_p (machine_mode mode) 1692 { 1693 return aarch64_classify_vector_mode (mode) & VEC_SVE_DATA; 1694 } 1695 1696 /* Return the number of defined bytes in one constituent vector of 1697 SVE mode MODE, which has vector flags VEC_FLAGS. */ 1698 static poly_int64 1699 aarch64_vl_bytes (machine_mode mode, unsigned int vec_flags) 1700 { 1701 if (vec_flags & VEC_PARTIAL) 1702 /* A single partial vector. */ 1703 return GET_MODE_SIZE (mode); 1704 1705 if (vec_flags & VEC_SVE_DATA) 1706 /* A single vector or a tuple. */ 1707 return BYTES_PER_SVE_VECTOR; 1708 1709 /* A single predicate. */ 1710 gcc_assert (vec_flags & VEC_SVE_PRED); 1711 return BYTES_PER_SVE_PRED; 1712 } 1713 1714 /* If MODE holds an array of vectors, return the number of vectors 1715 in the array, otherwise return 1. */ 1716 1717 static unsigned int 1718 aarch64_ldn_stn_vectors (machine_mode mode) 1719 { 1720 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 1721 if (vec_flags == (VEC_ADVSIMD | VEC_PARTIAL | VEC_STRUCT)) 1722 return exact_div (GET_MODE_SIZE (mode), 8).to_constant (); 1723 if (vec_flags == (VEC_ADVSIMD | VEC_STRUCT)) 1724 return exact_div (GET_MODE_SIZE (mode), 16).to_constant (); 1725 if (vec_flags == (VEC_SVE_DATA | VEC_STRUCT)) 1726 return exact_div (GET_MODE_SIZE (mode), 1727 BYTES_PER_SVE_VECTOR).to_constant (); 1728 return 1; 1729 } 1730 1731 /* Given an Advanced SIMD vector mode MODE and a tuple size NELEMS, return the 1732 corresponding vector structure mode. */ 1733 static opt_machine_mode 1734 aarch64_advsimd_vector_array_mode (machine_mode mode, 1735 unsigned HOST_WIDE_INT nelems) 1736 { 1737 unsigned int flags = VEC_ADVSIMD | VEC_STRUCT; 1738 if (known_eq (GET_MODE_SIZE (mode), 8)) 1739 flags |= VEC_PARTIAL; 1740 1741 machine_mode struct_mode; 1742 FOR_EACH_MODE_IN_CLASS (struct_mode, GET_MODE_CLASS (mode)) 1743 if (aarch64_classify_vector_mode (struct_mode) == flags 1744 && GET_MODE_INNER (struct_mode) == GET_MODE_INNER (mode) 1745 && known_eq (GET_MODE_NUNITS (struct_mode), 1746 GET_MODE_NUNITS (mode) * nelems)) 1747 return struct_mode; 1748 return opt_machine_mode (); 1749 } 1750 1751 /* Return the SVE vector mode that has NUNITS elements of mode INNER_MODE. */ 1752 1753 opt_machine_mode 1754 aarch64_sve_data_mode (scalar_mode inner_mode, poly_uint64 nunits) 1755 { 1756 enum mode_class mclass = (is_a <scalar_float_mode> (inner_mode) 1757 ? MODE_VECTOR_FLOAT : MODE_VECTOR_INT); 1758 machine_mode mode; 1759 FOR_EACH_MODE_IN_CLASS (mode, mclass) 1760 if (inner_mode == GET_MODE_INNER (mode) 1761 && known_eq (nunits, GET_MODE_NUNITS (mode)) 1762 && aarch64_sve_data_mode_p (mode)) 1763 return mode; 1764 return opt_machine_mode (); 1765 } 1766 1767 /* Implement target hook TARGET_ARRAY_MODE. */ 1768 static opt_machine_mode 1769 aarch64_array_mode (machine_mode mode, unsigned HOST_WIDE_INT nelems) 1770 { 1771 if (TARGET_SVE && GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL) 1772 { 1773 /* Use VNx32BI for pairs of predicates, but explicitly reject giving 1774 a mode to other array sizes. Using integer modes requires a round 1775 trip through memory and generates terrible code. */ 1776 if (nelems == 1) 1777 return mode; 1778 if (mode == VNx16BImode && nelems == 2) 1779 return VNx32BImode; 1780 return BLKmode; 1781 } 1782 1783 auto flags = aarch64_classify_vector_mode (mode); 1784 if (flags == VEC_SVE_DATA && IN_RANGE (nelems, 2, 4)) 1785 return aarch64_sve_data_mode (GET_MODE_INNER (mode), 1786 GET_MODE_NUNITS (mode) * nelems); 1787 1788 if (flags == VEC_ADVSIMD && IN_RANGE (nelems, 2, 4)) 1789 return aarch64_advsimd_vector_array_mode (mode, nelems); 1790 1791 return opt_machine_mode (); 1792 } 1793 1794 /* Implement target hook TARGET_ARRAY_MODE_SUPPORTED_P. */ 1795 static bool 1796 aarch64_array_mode_supported_p (machine_mode mode, 1797 unsigned HOST_WIDE_INT nelems) 1798 { 1799 if (TARGET_BASE_SIMD 1800 && (AARCH64_VALID_SIMD_QREG_MODE (mode) 1801 || AARCH64_VALID_SIMD_DREG_MODE (mode)) 1802 && (nelems >= 2 && nelems <= 4)) 1803 return true; 1804 1805 return false; 1806 } 1807 1808 /* MODE is some form of SVE vector mode. For data modes, return the number 1809 of vector register bits that each element of MODE occupies, such as 64 1810 for both VNx2DImode and VNx2SImode (where each 32-bit value is stored 1811 in a 64-bit container). For predicate modes, return the number of 1812 data bits controlled by each significant predicate bit. */ 1813 1814 static unsigned int 1815 aarch64_sve_container_bits (machine_mode mode) 1816 { 1817 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 1818 poly_uint64 vector_bits = (vec_flags & (VEC_PARTIAL | VEC_SVE_PRED) 1819 ? BITS_PER_SVE_VECTOR 1820 : GET_MODE_BITSIZE (mode)); 1821 return vector_element_size (vector_bits, GET_MODE_NUNITS (mode)); 1822 } 1823 1824 /* Return the SVE predicate mode to use for elements that have 1825 ELEM_NBYTES bytes, if such a mode exists. */ 1826 1827 opt_machine_mode 1828 aarch64_sve_pred_mode (unsigned int elem_nbytes) 1829 { 1830 if (TARGET_SVE) 1831 { 1832 if (elem_nbytes == 1) 1833 return VNx16BImode; 1834 if (elem_nbytes == 2) 1835 return VNx8BImode; 1836 if (elem_nbytes == 4) 1837 return VNx4BImode; 1838 if (elem_nbytes == 8) 1839 return VNx2BImode; 1840 } 1841 return opt_machine_mode (); 1842 } 1843 1844 /* Return the SVE predicate mode that should be used to control 1845 SVE mode MODE. */ 1846 1847 machine_mode 1848 aarch64_sve_pred_mode (machine_mode mode) 1849 { 1850 unsigned int bits = aarch64_sve_container_bits (mode); 1851 return aarch64_sve_pred_mode (bits / BITS_PER_UNIT).require (); 1852 } 1853 1854 /* Implement TARGET_VECTORIZE_GET_MASK_MODE. */ 1855 1856 static opt_machine_mode 1857 aarch64_get_mask_mode (machine_mode mode) 1858 { 1859 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 1860 if (vec_flags & VEC_SVE_DATA) 1861 return aarch64_sve_pred_mode (mode); 1862 1863 return default_get_mask_mode (mode); 1864 } 1865 1866 /* Return the integer element mode associated with SVE mode MODE. */ 1867 1868 static scalar_int_mode 1869 aarch64_sve_element_int_mode (machine_mode mode) 1870 { 1871 poly_uint64 vector_bits = (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL 1872 ? BITS_PER_SVE_VECTOR 1873 : GET_MODE_BITSIZE (mode)); 1874 unsigned int elt_bits = vector_element_size (vector_bits, 1875 GET_MODE_NUNITS (mode)); 1876 return int_mode_for_size (elt_bits, 0).require (); 1877 } 1878 1879 /* Return an integer element mode that contains exactly 1880 aarch64_sve_container_bits (MODE) bits. This is wider than 1881 aarch64_sve_element_int_mode if MODE is a partial vector, 1882 otherwise it's the same. */ 1883 1884 static scalar_int_mode 1885 aarch64_sve_container_int_mode (machine_mode mode) 1886 { 1887 return int_mode_for_size (aarch64_sve_container_bits (mode), 0).require (); 1888 } 1889 1890 /* Return the integer vector mode associated with SVE mode MODE. 1891 Unlike related_int_vector_mode, this can handle the case in which 1892 MODE is a predicate (and thus has a different total size). */ 1893 1894 machine_mode 1895 aarch64_sve_int_mode (machine_mode mode) 1896 { 1897 scalar_int_mode int_mode = aarch64_sve_element_int_mode (mode); 1898 return aarch64_sve_data_mode (int_mode, GET_MODE_NUNITS (mode)).require (); 1899 } 1900 1901 /* Implement TARGET_VECTORIZE_RELATED_MODE. */ 1902 1903 static opt_machine_mode 1904 aarch64_vectorize_related_mode (machine_mode vector_mode, 1905 scalar_mode element_mode, 1906 poly_uint64 nunits) 1907 { 1908 unsigned int vec_flags = aarch64_classify_vector_mode (vector_mode); 1909 1910 /* If we're operating on SVE vectors, try to return an SVE mode. */ 1911 poly_uint64 sve_nunits; 1912 if ((vec_flags & VEC_SVE_DATA) 1913 && multiple_p (BYTES_PER_SVE_VECTOR, 1914 GET_MODE_SIZE (element_mode), &sve_nunits)) 1915 { 1916 machine_mode sve_mode; 1917 if (maybe_ne (nunits, 0U)) 1918 { 1919 /* Try to find a full or partial SVE mode with exactly 1920 NUNITS units. */ 1921 if (multiple_p (sve_nunits, nunits) 1922 && aarch64_sve_data_mode (element_mode, 1923 nunits).exists (&sve_mode)) 1924 return sve_mode; 1925 } 1926 else 1927 { 1928 /* Take the preferred number of units from the number of bytes 1929 that fit in VECTOR_MODE. We always start by "autodetecting" 1930 a full vector mode with preferred_simd_mode, so vectors 1931 chosen here will also be full vector modes. Then 1932 autovectorize_vector_modes tries smaller starting modes 1933 and thus smaller preferred numbers of units. */ 1934 sve_nunits = ordered_min (sve_nunits, GET_MODE_SIZE (vector_mode)); 1935 if (aarch64_sve_data_mode (element_mode, 1936 sve_nunits).exists (&sve_mode)) 1937 return sve_mode; 1938 } 1939 } 1940 1941 /* Prefer to use 1 128-bit vector instead of 2 64-bit vectors. */ 1942 if (TARGET_SIMD 1943 && (vec_flags & VEC_ADVSIMD) 1944 && known_eq (nunits, 0U) 1945 && known_eq (GET_MODE_BITSIZE (vector_mode), 64U) 1946 && maybe_ge (GET_MODE_BITSIZE (element_mode) 1947 * GET_MODE_NUNITS (vector_mode), 128U)) 1948 { 1949 machine_mode res = aarch64_simd_container_mode (element_mode, 128); 1950 if (VECTOR_MODE_P (res)) 1951 return res; 1952 } 1953 1954 return default_vectorize_related_mode (vector_mode, element_mode, nunits); 1955 } 1956 1957 /* Implement TARGET_VECTORIZE_PREFERRED_DIV_AS_SHIFTS_OVER_MULT. */ 1958 1959 static bool 1960 aarch64_vectorize_preferred_div_as_shifts_over_mult (const_tree type) 1961 { 1962 machine_mode mode = TYPE_MODE (type); 1963 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 1964 bool sve_p = (vec_flags & VEC_ANY_SVE); 1965 bool simd_p = (vec_flags & VEC_ADVSIMD); 1966 1967 return (sve_p && TARGET_SVE2) || (simd_p && TARGET_SIMD); 1968 } 1969 1970 /* Implement TARGET_PREFERRED_ELSE_VALUE. For binary operations, 1971 prefer to use the first arithmetic operand as the else value if 1972 the else value doesn't matter, since that exactly matches the SVE 1973 destructive merging form. For ternary operations we could either 1974 pick the first operand and use FMAD-like instructions or the last 1975 operand and use FMLA-like instructions; the latter seems more 1976 natural. */ 1977 1978 static tree 1979 aarch64_preferred_else_value (unsigned, tree, unsigned int nops, tree *ops) 1980 { 1981 return nops == 3 ? ops[2] : ops[0]; 1982 } 1983 1984 /* Implement TARGET_HARD_REGNO_NREGS. */ 1985 1986 static unsigned int 1987 aarch64_hard_regno_nregs (unsigned regno, machine_mode mode) 1988 { 1989 /* ??? Logically we should only need to provide a value when 1990 HARD_REGNO_MODE_OK says that the combination is valid, 1991 but at the moment we need to handle all modes. Just ignore 1992 any runtime parts for registers that can't store them. */ 1993 HOST_WIDE_INT lowest_size = constant_lower_bound (GET_MODE_SIZE (mode)); 1994 switch (aarch64_regno_regclass (regno)) 1995 { 1996 case FP_REGS: 1997 case FP_LO_REGS: 1998 case FP_LO8_REGS: 1999 { 2000 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 2001 if (vec_flags & VEC_SVE_DATA) 2002 return exact_div (GET_MODE_SIZE (mode), 2003 aarch64_vl_bytes (mode, vec_flags)).to_constant (); 2004 if (vec_flags == (VEC_ADVSIMD | VEC_STRUCT | VEC_PARTIAL)) 2005 return GET_MODE_SIZE (mode).to_constant () / 8; 2006 return CEIL (lowest_size, UNITS_PER_VREG); 2007 } 2008 2009 case PR_REGS: 2010 case PR_LO_REGS: 2011 case PR_HI_REGS: 2012 return mode == VNx32BImode ? 2 : 1; 2013 2014 case FFR_REGS: 2015 case PR_AND_FFR_REGS: 2016 case FAKE_REGS: 2017 return 1; 2018 2019 default: 2020 return CEIL (lowest_size, UNITS_PER_WORD); 2021 } 2022 gcc_unreachable (); 2023 } 2024 2025 /* Implement TARGET_HARD_REGNO_MODE_OK. */ 2026 2027 static bool 2028 aarch64_hard_regno_mode_ok (unsigned regno, machine_mode mode) 2029 { 2030 if (mode == V8DImode) 2031 return IN_RANGE (regno, R0_REGNUM, R23_REGNUM) 2032 && multiple_p (regno - R0_REGNUM, 2); 2033 2034 if (GET_MODE_CLASS (mode) == MODE_CC) 2035 return regno == CC_REGNUM; 2036 2037 if (regno == VG_REGNUM) 2038 /* This must have the same size as _Unwind_Word. */ 2039 return mode == DImode; 2040 2041 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 2042 if (vec_flags == VEC_SVE_PRED) 2043 return pr_or_ffr_regnum_p (regno); 2044 2045 if (vec_flags == (VEC_SVE_PRED | VEC_STRUCT)) 2046 return PR_REGNUM_P (regno); 2047 2048 if (pr_or_ffr_regnum_p (regno)) 2049 return false; 2050 2051 /* These registers are abstract; their modes don't matter. */ 2052 if (FAKE_REGNUM_P (regno)) 2053 return true; 2054 2055 if (regno == SP_REGNUM) 2056 /* The purpose of comparing with ptr_mode is to support the 2057 global register variable associated with the stack pointer 2058 register via the syntax of asm ("wsp") in ILP32. */ 2059 return mode == Pmode || mode == ptr_mode; 2060 2061 if (regno == FRAME_POINTER_REGNUM || regno == ARG_POINTER_REGNUM) 2062 return mode == Pmode; 2063 2064 if (GP_REGNUM_P (regno)) 2065 { 2066 if (vec_flags & (VEC_ANY_SVE | VEC_STRUCT)) 2067 return false; 2068 if (known_le (GET_MODE_SIZE (mode), 8)) 2069 return true; 2070 if (known_le (GET_MODE_SIZE (mode), 16)) 2071 return (regno & 1) == 0; 2072 } 2073 else if (FP_REGNUM_P (regno)) 2074 { 2075 if (vec_flags & VEC_STRUCT) 2076 return end_hard_regno (mode, regno) - 1 <= V31_REGNUM; 2077 else 2078 return !VECTOR_MODE_P (mode) || vec_flags != 0; 2079 } 2080 2081 return false; 2082 } 2083 2084 /* Return true if a function with type FNTYPE returns its value in 2085 SVE vector or predicate registers. */ 2086 2087 static bool 2088 aarch64_returns_value_in_sve_regs_p (const_tree fntype) 2089 { 2090 tree return_type = TREE_TYPE (fntype); 2091 2092 pure_scalable_type_info pst_info; 2093 switch (pst_info.analyze (return_type)) 2094 { 2095 case pure_scalable_type_info::IS_PST: 2096 return (pst_info.num_zr () <= NUM_FP_ARG_REGS 2097 && pst_info.num_pr () <= NUM_PR_ARG_REGS); 2098 2099 case pure_scalable_type_info::DOESNT_MATTER: 2100 gcc_assert (aarch64_return_in_memory_1 (return_type)); 2101 return false; 2102 2103 case pure_scalable_type_info::NO_ABI_IDENTITY: 2104 case pure_scalable_type_info::ISNT_PST: 2105 return false; 2106 } 2107 gcc_unreachable (); 2108 } 2109 2110 /* Return true if a function with type FNTYPE takes arguments in 2111 SVE vector or predicate registers. */ 2112 2113 static bool 2114 aarch64_takes_arguments_in_sve_regs_p (const_tree fntype) 2115 { 2116 CUMULATIVE_ARGS args_so_far_v; 2117 aarch64_init_cumulative_args (&args_so_far_v, NULL_TREE, NULL_RTX, 2118 NULL_TREE, 0, true); 2119 cumulative_args_t args_so_far = pack_cumulative_args (&args_so_far_v); 2120 2121 for (tree chain = TYPE_ARG_TYPES (fntype); 2122 chain && chain != void_list_node; 2123 chain = TREE_CHAIN (chain)) 2124 { 2125 tree arg_type = TREE_VALUE (chain); 2126 if (arg_type == error_mark_node) 2127 return false; 2128 2129 function_arg_info arg (arg_type, /*named=*/true); 2130 apply_pass_by_reference_rules (&args_so_far_v, arg); 2131 pure_scalable_type_info pst_info; 2132 if (pst_info.analyze_registers (arg.type)) 2133 { 2134 unsigned int end_zr = args_so_far_v.aapcs_nvrn + pst_info.num_zr (); 2135 unsigned int end_pr = args_so_far_v.aapcs_nprn + pst_info.num_pr (); 2136 gcc_assert (end_zr <= NUM_FP_ARG_REGS && end_pr <= NUM_PR_ARG_REGS); 2137 return true; 2138 } 2139 2140 targetm.calls.function_arg_advance (args_so_far, arg); 2141 } 2142 return false; 2143 } 2144 2145 /* Implement TARGET_FNTYPE_ABI. */ 2146 2147 static const predefined_function_abi & 2148 aarch64_fntype_abi (const_tree fntype) 2149 { 2150 if (lookup_attribute ("aarch64_vector_pcs", TYPE_ATTRIBUTES (fntype))) 2151 return aarch64_simd_abi (); 2152 2153 if (aarch64_returns_value_in_sve_regs_p (fntype) 2154 || aarch64_takes_arguments_in_sve_regs_p (fntype)) 2155 return aarch64_sve_abi (); 2156 2157 return default_function_abi; 2158 } 2159 2160 /* Return the state of PSTATE.SM on entry to functions of type FNTYPE. */ 2161 2162 static aarch64_feature_flags 2163 aarch64_fntype_pstate_sm (const_tree fntype) 2164 { 2165 if (lookup_attribute ("arm", "streaming", TYPE_ATTRIBUTES (fntype))) 2166 return AARCH64_FL_SM_ON; 2167 2168 if (lookup_attribute ("arm", "streaming_compatible", 2169 TYPE_ATTRIBUTES (fntype))) 2170 return 0; 2171 2172 return AARCH64_FL_SM_OFF; 2173 } 2174 2175 /* Return state flags that describe whether and how functions of type 2176 FNTYPE share state STATE_NAME with their callers. */ 2177 2178 static unsigned int 2179 aarch64_fntype_shared_flags (const_tree fntype, const char *state_name) 2180 { 2181 return aarch64_lookup_shared_state_flags (TYPE_ATTRIBUTES (fntype), 2182 state_name); 2183 } 2184 2185 /* Return the state of PSTATE.ZA on entry to functions of type FNTYPE. */ 2186 2187 static aarch64_feature_flags 2188 aarch64_fntype_pstate_za (const_tree fntype) 2189 { 2190 if (aarch64_fntype_shared_flags (fntype, "za") 2191 || aarch64_fntype_shared_flags (fntype, "zt0")) 2192 return AARCH64_FL_ZA_ON; 2193 2194 return 0; 2195 } 2196 2197 /* Return the ISA mode on entry to functions of type FNTYPE. */ 2198 2199 static aarch64_feature_flags 2200 aarch64_fntype_isa_mode (const_tree fntype) 2201 { 2202 return (aarch64_fntype_pstate_sm (fntype) 2203 | aarch64_fntype_pstate_za (fntype)); 2204 } 2205 2206 /* Return true if FNDECL uses streaming mode internally, as an 2207 implementation choice. */ 2208 2209 static bool 2210 aarch64_fndecl_is_locally_streaming (const_tree fndecl) 2211 { 2212 return lookup_attribute ("arm", "locally_streaming", 2213 DECL_ATTRIBUTES (fndecl)); 2214 } 2215 2216 /* Return the state of PSTATE.SM when compiling the body of 2217 function FNDECL. This might be different from the state of 2218 PSTATE.SM on entry. */ 2219 2220 static aarch64_feature_flags 2221 aarch64_fndecl_pstate_sm (const_tree fndecl) 2222 { 2223 if (aarch64_fndecl_is_locally_streaming (fndecl)) 2224 return AARCH64_FL_SM_ON; 2225 2226 return aarch64_fntype_pstate_sm (TREE_TYPE (fndecl)); 2227 } 2228 2229 /* Return true if function FNDECL has state STATE_NAME, either by creating 2230 new state itself or by sharing state with callers. */ 2231 2232 static bool 2233 aarch64_fndecl_has_state (tree fndecl, const char *state_name) 2234 { 2235 return (aarch64_fndecl_has_new_state (fndecl, state_name) 2236 || aarch64_fntype_shared_flags (TREE_TYPE (fndecl), 2237 state_name) != 0); 2238 } 2239 2240 /* Return the state of PSTATE.ZA when compiling the body of function FNDECL. 2241 This might be different from the state of PSTATE.ZA on entry. */ 2242 2243 static aarch64_feature_flags 2244 aarch64_fndecl_pstate_za (const_tree fndecl) 2245 { 2246 if (aarch64_fndecl_has_new_state (fndecl, "za") 2247 || aarch64_fndecl_has_new_state (fndecl, "zt0")) 2248 return AARCH64_FL_ZA_ON; 2249 2250 return aarch64_fntype_pstate_za (TREE_TYPE (fndecl)); 2251 } 2252 2253 /* Return the ISA mode that should be used to compile the body of 2254 function FNDECL. */ 2255 2256 static aarch64_feature_flags 2257 aarch64_fndecl_isa_mode (const_tree fndecl) 2258 { 2259 return (aarch64_fndecl_pstate_sm (fndecl) 2260 | aarch64_fndecl_pstate_za (fndecl)); 2261 } 2262 2263 /* Return the state of PSTATE.SM on entry to the current function. 2264 This might be different from the state of PSTATE.SM in the function 2265 body. */ 2266 2267 static aarch64_feature_flags 2268 aarch64_cfun_incoming_pstate_sm () 2269 { 2270 return aarch64_fntype_pstate_sm (TREE_TYPE (cfun->decl)); 2271 } 2272 2273 /* Return the state of PSTATE.ZA on entry to the current function. 2274 This might be different from the state of PSTATE.ZA in the function 2275 body. */ 2276 2277 static aarch64_feature_flags 2278 aarch64_cfun_incoming_pstate_za () 2279 { 2280 return aarch64_fntype_pstate_za (TREE_TYPE (cfun->decl)); 2281 } 2282 2283 /* Return state flags that describe whether and how the current function shares 2284 state STATE_NAME with callers. */ 2285 2286 static unsigned int 2287 aarch64_cfun_shared_flags (const char *state_name) 2288 { 2289 return aarch64_fntype_shared_flags (TREE_TYPE (cfun->decl), state_name); 2290 } 2291 2292 /* Return true if the current function creates new state of type STATE_NAME 2293 (as opposed to sharing the state with its callers or ignoring the state 2294 altogether). */ 2295 2296 static bool 2297 aarch64_cfun_has_new_state (const char *state_name) 2298 { 2299 return aarch64_fndecl_has_new_state (cfun->decl, state_name); 2300 } 2301 2302 /* Return true if PSTATE.SM is 1 in the body of the current function, 2303 but is not guaranteed to be 1 on entry. */ 2304 2305 static bool 2306 aarch64_cfun_enables_pstate_sm () 2307 { 2308 return (aarch64_fndecl_is_locally_streaming (cfun->decl) 2309 && aarch64_cfun_incoming_pstate_sm () != AARCH64_FL_SM_ON); 2310 } 2311 2312 /* Return true if the current function has state STATE_NAME, either by 2313 creating new state itself or by sharing state with callers. */ 2314 2315 static bool 2316 aarch64_cfun_has_state (const char *state_name) 2317 { 2318 return aarch64_fndecl_has_state (cfun->decl, state_name); 2319 } 2320 2321 /* Return true if a call from the current function to a function with 2322 ISA mode CALLEE_MODE would involve a change to PSTATE.SM around 2323 the BL instruction. */ 2324 2325 static bool 2326 aarch64_call_switches_pstate_sm (aarch64_feature_flags callee_mode) 2327 { 2328 return (callee_mode & ~AARCH64_ISA_MODE & AARCH64_FL_SM_STATE) != 0; 2329 } 2330 2331 /* Implement TARGET_COMPATIBLE_VECTOR_TYPES_P. */ 2332 2333 static bool 2334 aarch64_compatible_vector_types_p (const_tree type1, const_tree type2) 2335 { 2336 return (aarch64_sve::builtin_type_p (type1) 2337 == aarch64_sve::builtin_type_p (type2)); 2338 } 2339 2340 /* Return true if we should emit CFI for register REGNO. */ 2341 2342 static bool 2343 aarch64_emit_cfi_for_reg_p (unsigned int regno) 2344 { 2345 return (GP_REGNUM_P (regno) 2346 || !default_function_abi.clobbers_full_reg_p (regno)); 2347 } 2348 2349 /* Return the mode we should use to save and restore register REGNO. */ 2350 2351 static machine_mode 2352 aarch64_reg_save_mode (unsigned int regno) 2353 { 2354 if (GP_REGNUM_P (regno) || regno == VG_REGNUM) 2355 return DImode; 2356 2357 if (FP_REGNUM_P (regno)) 2358 switch (crtl->abi->id ()) 2359 { 2360 case ARM_PCS_AAPCS64: 2361 /* Only the low 64 bits are saved by the base PCS. */ 2362 return DFmode; 2363 2364 case ARM_PCS_SIMD: 2365 /* The vector PCS saves the low 128 bits (which is the full 2366 register on non-SVE targets). */ 2367 return V16QImode; 2368 2369 case ARM_PCS_SVE: 2370 /* Use vectors of DImode for registers that need frame 2371 information, so that the first 64 bytes of the save slot 2372 are always the equivalent of what storing D<n> would give. */ 2373 if (aarch64_emit_cfi_for_reg_p (regno)) 2374 return VNx2DImode; 2375 2376 /* Use vectors of bytes otherwise, so that the layout is 2377 endian-agnostic, and so that we can use LDR and STR for 2378 big-endian targets. */ 2379 return VNx16QImode; 2380 2381 case ARM_PCS_TLSDESC: 2382 case ARM_PCS_UNKNOWN: 2383 break; 2384 } 2385 2386 if (PR_REGNUM_P (regno)) 2387 /* Save the full predicate register. */ 2388 return VNx16BImode; 2389 2390 gcc_unreachable (); 2391 } 2392 2393 /* Given the ISA mode on entry to a callee and the ABI of the callee, 2394 return the CONST_INT that should be placed in an UNSPEC_CALLEE_ABI rtx. */ 2395 2396 rtx 2397 aarch64_gen_callee_cookie (aarch64_feature_flags isa_mode, arm_pcs pcs_variant) 2398 { 2399 return gen_int_mode ((unsigned int) isa_mode 2400 | (unsigned int) pcs_variant << AARCH64_NUM_ISA_MODES, 2401 DImode); 2402 } 2403 2404 /* COOKIE is a CONST_INT from an UNSPEC_CALLEE_ABI rtx. Return the 2405 callee's ABI. */ 2406 2407 static const predefined_function_abi & 2408 aarch64_callee_abi (rtx cookie) 2409 { 2410 return function_abis[UINTVAL (cookie) >> AARCH64_NUM_ISA_MODES]; 2411 } 2412 2413 /* COOKIE is a CONST_INT from an UNSPEC_CALLEE_ABI rtx. Return the 2414 required ISA mode on entry to the callee, which is also the ISA 2415 mode on return from the callee. */ 2416 2417 static aarch64_feature_flags 2418 aarch64_callee_isa_mode (rtx cookie) 2419 { 2420 return UINTVAL (cookie) & AARCH64_FL_ISA_MODES; 2421 } 2422 2423 /* INSN is a call instruction. Return the CONST_INT stored in its 2424 UNSPEC_CALLEE_ABI rtx. */ 2425 2426 static rtx 2427 aarch64_insn_callee_cookie (const rtx_insn *insn) 2428 { 2429 rtx pat = PATTERN (insn); 2430 gcc_assert (GET_CODE (pat) == PARALLEL); 2431 rtx unspec = XVECEXP (pat, 0, 1); 2432 gcc_assert (GET_CODE (unspec) == UNSPEC 2433 && XINT (unspec, 1) == UNSPEC_CALLEE_ABI); 2434 return XVECEXP (unspec, 0, 0); 2435 } 2436 2437 /* Implement TARGET_INSN_CALLEE_ABI. */ 2438 2439 const predefined_function_abi & 2440 aarch64_insn_callee_abi (const rtx_insn *insn) 2441 { 2442 return aarch64_callee_abi (aarch64_insn_callee_cookie (insn)); 2443 } 2444 2445 /* INSN is a call instruction. Return the required ISA mode on entry to 2446 the callee, which is also the ISA mode on return from the callee. */ 2447 2448 static aarch64_feature_flags 2449 aarch64_insn_callee_isa_mode (const rtx_insn *insn) 2450 { 2451 return aarch64_callee_isa_mode (aarch64_insn_callee_cookie (insn)); 2452 } 2453 2454 /* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. The callee only saves 2455 the lower 64 bits of a 128-bit register. Tell the compiler the callee 2456 clobbers the top 64 bits when restoring the bottom 64 bits. */ 2457 2458 static bool 2459 aarch64_hard_regno_call_part_clobbered (unsigned int abi_id, 2460 unsigned int regno, 2461 machine_mode mode) 2462 { 2463 if (FP_REGNUM_P (regno) && abi_id != ARM_PCS_SVE) 2464 { 2465 poly_int64 per_register_size = GET_MODE_SIZE (mode); 2466 unsigned int nregs = hard_regno_nregs (regno, mode); 2467 if (nregs > 1) 2468 per_register_size = exact_div (per_register_size, nregs); 2469 if (abi_id == ARM_PCS_SIMD || abi_id == ARM_PCS_TLSDESC) 2470 return maybe_gt (per_register_size, 16); 2471 return maybe_gt (per_register_size, 8); 2472 } 2473 return false; 2474 } 2475 2476 /* Implement REGMODE_NATURAL_SIZE. */ 2477 poly_uint64 2478 aarch64_regmode_natural_size (machine_mode mode) 2479 { 2480 /* The natural size for SVE data modes is one SVE data vector, 2481 and similarly for predicates. We can't independently modify 2482 anything smaller than that. */ 2483 /* ??? For now, only do this for variable-width SVE registers. 2484 Doing it for constant-sized registers breaks lower-subreg.cc. */ 2485 /* ??? And once that's fixed, we should probably have similar 2486 code for Advanced SIMD. */ 2487 if (!aarch64_sve_vg.is_constant ()) 2488 { 2489 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 2490 if (vec_flags & VEC_SVE_PRED) 2491 return BYTES_PER_SVE_PRED; 2492 if (vec_flags & VEC_SVE_DATA) 2493 return BYTES_PER_SVE_VECTOR; 2494 } 2495 return UNITS_PER_WORD; 2496 } 2497 2498 /* Implement HARD_REGNO_CALLER_SAVE_MODE. */ 2499 machine_mode 2500 aarch64_hard_regno_caller_save_mode (unsigned regno, unsigned, 2501 machine_mode mode) 2502 { 2503 /* The predicate mode determines which bits are significant and 2504 which are "don't care". Decreasing the number of lanes would 2505 lose data while increasing the number of lanes would make bits 2506 unnecessarily significant. */ 2507 if (PR_REGNUM_P (regno)) 2508 return mode; 2509 if (known_lt (GET_MODE_SIZE (mode), 4) 2510 && REG_CAN_CHANGE_MODE_P (regno, mode, SImode) 2511 && REG_CAN_CHANGE_MODE_P (regno, SImode, mode)) 2512 return SImode; 2513 return mode; 2514 } 2515 2516 /* Return true if I's bits are consecutive ones from the MSB. */ 2517 bool 2518 aarch64_high_bits_all_ones_p (HOST_WIDE_INT i) 2519 { 2520 return exact_log2 (-i) != HOST_WIDE_INT_M1; 2521 } 2522 2523 /* Implement TARGET_CONSTANT_ALIGNMENT. Make strings word-aligned so 2524 that strcpy from constants will be faster. */ 2525 2526 static HOST_WIDE_INT 2527 aarch64_constant_alignment (const_tree exp, HOST_WIDE_INT align) 2528 { 2529 if (TREE_CODE (exp) == STRING_CST && !optimize_size) 2530 return MAX (align, BITS_PER_WORD); 2531 return align; 2532 } 2533 2534 /* Return true if calls to DECL should be treated as 2535 long-calls (ie called via a register). */ 2536 static bool 2537 aarch64_decl_is_long_call_p (const_tree decl ATTRIBUTE_UNUSED) 2538 { 2539 return false; 2540 } 2541 2542 /* Return true if calls to symbol-ref SYM should be treated as 2543 long-calls (ie called via a register). */ 2544 bool 2545 aarch64_is_long_call_p (rtx sym) 2546 { 2547 return aarch64_decl_is_long_call_p (SYMBOL_REF_DECL (sym)); 2548 } 2549 2550 /* Return true if calls to symbol-ref SYM should not go through 2551 plt stubs. */ 2552 2553 bool 2554 aarch64_is_noplt_call_p (rtx sym) 2555 { 2556 const_tree decl = SYMBOL_REF_DECL (sym); 2557 2558 if (flag_pic 2559 && decl 2560 && (!flag_plt 2561 || lookup_attribute ("noplt", DECL_ATTRIBUTES (decl))) 2562 && !targetm.binds_local_p (decl)) 2563 return true; 2564 2565 return false; 2566 } 2567 2568 /* Emit an insn that's a simple single-set. Both the operands must be 2569 known to be valid. */ 2570 inline static rtx_insn * 2571 emit_set_insn (rtx x, rtx y) 2572 { 2573 return emit_insn (gen_rtx_SET (x, y)); 2574 } 2575 2576 /* X and Y are two things to compare using CODE. Emit the compare insn and 2577 return the rtx for register 0 in the proper mode. */ 2578 rtx 2579 aarch64_gen_compare_reg (RTX_CODE code, rtx x, rtx y) 2580 { 2581 machine_mode cmp_mode = GET_MODE (x); 2582 machine_mode cc_mode; 2583 rtx cc_reg; 2584 2585 if (cmp_mode == TImode) 2586 { 2587 gcc_assert (code == NE); 2588 2589 cc_mode = CCmode; 2590 cc_reg = gen_rtx_REG (cc_mode, CC_REGNUM); 2591 2592 rtx x_lo = operand_subword (x, 0, 0, TImode); 2593 rtx y_lo = operand_subword (y, 0, 0, TImode); 2594 emit_set_insn (cc_reg, gen_rtx_COMPARE (cc_mode, x_lo, y_lo)); 2595 2596 rtx x_hi = operand_subword (x, 1, 0, TImode); 2597 rtx y_hi = operand_subword (y, 1, 0, TImode); 2598 emit_insn (gen_ccmpccdi (cc_reg, cc_reg, x_hi, y_hi, 2599 gen_rtx_EQ (cc_mode, cc_reg, const0_rtx), 2600 GEN_INT (AARCH64_EQ))); 2601 } 2602 else 2603 { 2604 cc_mode = SELECT_CC_MODE (code, x, y); 2605 cc_reg = gen_rtx_REG (cc_mode, CC_REGNUM); 2606 emit_set_insn (cc_reg, gen_rtx_COMPARE (cc_mode, x, y)); 2607 } 2608 return cc_reg; 2609 } 2610 2611 /* Similarly, but maybe zero-extend Y if Y_MODE < SImode. */ 2612 2613 static rtx 2614 aarch64_gen_compare_reg_maybe_ze (RTX_CODE code, rtx x, rtx y, 2615 machine_mode y_mode) 2616 { 2617 if (y_mode == E_QImode || y_mode == E_HImode) 2618 { 2619 if (CONST_INT_P (y)) 2620 { 2621 y = GEN_INT (INTVAL (y) & GET_MODE_MASK (y_mode)); 2622 y_mode = SImode; 2623 } 2624 else 2625 { 2626 rtx t, cc_reg; 2627 machine_mode cc_mode; 2628 2629 t = gen_rtx_ZERO_EXTEND (SImode, y); 2630 t = gen_rtx_COMPARE (CC_SWPmode, t, x); 2631 cc_mode = CC_SWPmode; 2632 cc_reg = gen_rtx_REG (cc_mode, CC_REGNUM); 2633 emit_set_insn (cc_reg, t); 2634 return cc_reg; 2635 } 2636 } 2637 2638 if (!aarch64_plus_operand (y, y_mode)) 2639 y = force_reg (y_mode, y); 2640 2641 return aarch64_gen_compare_reg (code, x, y); 2642 } 2643 2644 /* Generate conditional branch to LABEL, comparing X to 0 using CODE. 2645 Return the jump instruction. */ 2646 2647 static rtx 2648 aarch64_gen_compare_zero_and_branch (rtx_code code, rtx x, 2649 rtx_code_label *label) 2650 { 2651 if (aarch64_track_speculation) 2652 { 2653 /* Emit an explicit compare instruction, so that we can correctly 2654 track the condition codes. */ 2655 rtx cc_reg = aarch64_gen_compare_reg (code, x, const0_rtx); 2656 x = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); 2657 } 2658 else 2659 x = gen_rtx_fmt_ee (code, VOIDmode, x, const0_rtx); 2660 2661 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, 2662 gen_rtx_LABEL_REF (Pmode, label), pc_rtx); 2663 return gen_rtx_SET (pc_rtx, x); 2664 } 2665 2666 /* Return an rtx that branches to LABEL based on the value of bit BITNUM of X. 2667 If CODE is NE, it branches to LABEL when the bit is set; if CODE is EQ, 2668 it branches to LABEL when the bit is clear. */ 2669 2670 static rtx 2671 aarch64_gen_test_and_branch (rtx_code code, rtx x, int bitnum, 2672 rtx_code_label *label) 2673 { 2674 auto mode = GET_MODE (x); 2675 if (aarch64_track_speculation) 2676 { 2677 auto mask = gen_int_mode (HOST_WIDE_INT_1U << bitnum, mode); 2678 emit_insn (gen_aarch64_and3nr_compare0 (mode, x, mask)); 2679 rtx cc_reg = gen_rtx_REG (CC_NZVmode, CC_REGNUM); 2680 rtx x = gen_rtx_fmt_ee (code, CC_NZVmode, cc_reg, const0_rtx); 2681 return gen_condjump (x, cc_reg, label); 2682 } 2683 return gen_aarch64_tb (code, mode, mode, 2684 x, gen_int_mode (bitnum, mode), label); 2685 } 2686 2687 /* Consider the operation: 2688 2689 OPERANDS[0] = CODE (OPERANDS[1], OPERANDS[2]) + OPERANDS[3] 2690 2691 where: 2692 2693 - CODE is [SU]MAX or [SU]MIN 2694 - OPERANDS[2] and OPERANDS[3] are constant integers 2695 - OPERANDS[3] is a positive or negative shifted 12-bit immediate 2696 - all operands have mode MODE 2697 2698 Decide whether it is possible to implement the operation using: 2699 2700 SUBS <tmp>, OPERANDS[1], -OPERANDS[3] 2701 or 2702 ADDS <tmp>, OPERANDS[1], OPERANDS[3] 2703 2704 followed by: 2705 2706 <insn> OPERANDS[0], <tmp>, [wx]zr, <cond> 2707 2708 where <insn> is one of CSEL, CSINV or CSINC. Return true if so. 2709 If GENERATE_P is true, also update OPERANDS as follows: 2710 2711 OPERANDS[4] = -OPERANDS[3] 2712 OPERANDS[5] = the rtl condition representing <cond> 2713 OPERANDS[6] = <tmp> 2714 OPERANDS[7] = 0 for CSEL, -1 for CSINV or 1 for CSINC. */ 2715 bool 2716 aarch64_maxmin_plus_const (rtx_code code, rtx *operands, bool generate_p) 2717 { 2718 signop sgn = (code == UMAX || code == UMIN ? UNSIGNED : SIGNED); 2719 rtx dst = operands[0]; 2720 rtx maxmin_op = operands[2]; 2721 rtx add_op = operands[3]; 2722 machine_mode mode = GET_MODE (dst); 2723 2724 /* max (x, y) - z == (x >= y + 1 ? x : y) - z 2725 == (x >= y ? x : y) - z 2726 == (x > y ? x : y) - z 2727 == (x > y - 1 ? x : y) - z 2728 2729 min (x, y) - z == (x <= y - 1 ? x : y) - z 2730 == (x <= y ? x : y) - z 2731 == (x < y ? x : y) - z 2732 == (x < y + 1 ? x : y) - z 2733 2734 Check whether z is in { y - 1, y, y + 1 } and pick the form(s) for 2735 which x is compared with z. Set DIFF to y - z. Thus the supported 2736 combinations are as follows, with DIFF being the value after the ":": 2737 2738 max (x, y) - z == x >= y + 1 ? x - (y + 1) : -1 [z == y + 1] 2739 == x >= y ? x - y : 0 [z == y] 2740 == x > y ? x - y : 0 [z == y] 2741 == x > y - 1 ? x - (y - 1) : 1 [z == y - 1] 2742 2743 min (x, y) - z == x <= y - 1 ? x - (y - 1) : 1 [z == y - 1] 2744 == x <= y ? x - y : 0 [z == y] 2745 == x < y ? x - y : 0 [z == y] 2746 == x < y + 1 ? x - (y + 1) : -1 [z == y + 1]. */ 2747 auto maxmin_val = rtx_mode_t (maxmin_op, mode); 2748 auto add_val = rtx_mode_t (add_op, mode); 2749 auto sub_val = wi::neg (add_val); 2750 auto diff = wi::sub (maxmin_val, sub_val); 2751 if (!(diff == 0 2752 || (diff == 1 && wi::gt_p (maxmin_val, sub_val, sgn)) 2753 || (diff == -1 && wi::lt_p (maxmin_val, sub_val, sgn)))) 2754 return false; 2755 2756 if (!generate_p) 2757 return true; 2758 2759 rtx_code cmp; 2760 switch (code) 2761 { 2762 case SMAX: 2763 cmp = diff == 1 ? GT : GE; 2764 break; 2765 case UMAX: 2766 cmp = diff == 1 ? GTU : GEU; 2767 break; 2768 case SMIN: 2769 cmp = diff == -1 ? LT : LE; 2770 break; 2771 case UMIN: 2772 cmp = diff == -1 ? LTU : LEU; 2773 break; 2774 default: 2775 gcc_unreachable (); 2776 } 2777 rtx cc = gen_rtx_REG (CCmode, CC_REGNUM); 2778 2779 operands[4] = immed_wide_int_const (sub_val, mode); 2780 operands[5] = gen_rtx_fmt_ee (cmp, VOIDmode, cc, const0_rtx); 2781 if (can_create_pseudo_p ()) 2782 operands[6] = gen_reg_rtx (mode); 2783 else 2784 operands[6] = dst; 2785 operands[7] = immed_wide_int_const (diff, mode); 2786 2787 return true; 2788 } 2789 2790 2791 /* Build the SYMBOL_REF for __tls_get_addr. */ 2792 2793 static GTY(()) rtx tls_get_addr_libfunc; 2794 2795 rtx 2796 aarch64_tls_get_addr (void) 2797 { 2798 if (!tls_get_addr_libfunc) 2799 tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr"); 2800 return tls_get_addr_libfunc; 2801 } 2802 2803 /* Return the TLS model to use for ADDR. */ 2804 2805 static enum tls_model 2806 tls_symbolic_operand_type (rtx addr) 2807 { 2808 enum tls_model tls_kind = TLS_MODEL_NONE; 2809 poly_int64 offset; 2810 addr = strip_offset_and_salt (addr, &offset); 2811 if (SYMBOL_REF_P (addr)) 2812 tls_kind = SYMBOL_REF_TLS_MODEL (addr); 2813 2814 return tls_kind; 2815 } 2816 2817 /* We'll allow lo_sum's in addresses in our legitimate addresses 2818 so that combine would take care of combining addresses where 2819 necessary, but for generation purposes, we'll generate the address 2820 as : 2821 RTL Absolute 2822 tmp = hi (symbol_ref); adrp x1, foo 2823 dest = lo_sum (tmp, symbol_ref); add dest, x1, :lo_12:foo 2824 nop 2825 2826 PIC TLS 2827 adrp x1, :got:foo adrp tmp, :tlsgd:foo 2828 ldr x1, [:got_lo12:foo] add dest, tmp, :tlsgd_lo12:foo 2829 bl __tls_get_addr 2830 nop 2831 2832 Load TLS symbol, depending on TLS mechanism and TLS access model. 2833 2834 Global Dynamic - Traditional TLS: 2835 adrp tmp, :tlsgd:imm 2836 add dest, tmp, #:tlsgd_lo12:imm 2837 bl __tls_get_addr 2838 2839 Global Dynamic - TLS Descriptors: 2840 adrp dest, :tlsdesc:imm 2841 ldr tmp, [dest, #:tlsdesc_lo12:imm] 2842 add dest, dest, #:tlsdesc_lo12:imm 2843 blr tmp 2844 mrs tp, tpidr_el0 2845 add dest, dest, tp 2846 2847 Initial Exec: 2848 mrs tp, tpidr_el0 2849 adrp tmp, :gottprel:imm 2850 ldr dest, [tmp, #:gottprel_lo12:imm] 2851 add dest, dest, tp 2852 2853 Local Exec: 2854 mrs tp, tpidr_el0 2855 add t0, tp, #:tprel_hi12:imm, lsl #12 2856 add t0, t0, #:tprel_lo12_nc:imm 2857 */ 2858 2859 static void 2860 aarch64_load_symref_appropriately (rtx dest, rtx imm, 2861 enum aarch64_symbol_type type) 2862 { 2863 switch (type) 2864 { 2865 case SYMBOL_SMALL_ABSOLUTE: 2866 { 2867 /* In ILP32, the mode of dest can be either SImode or DImode. */ 2868 rtx tmp_reg = dest; 2869 machine_mode mode = GET_MODE (dest); 2870 2871 gcc_assert (mode == Pmode || mode == ptr_mode); 2872 2873 if (can_create_pseudo_p ()) 2874 tmp_reg = gen_reg_rtx (mode); 2875 2876 emit_move_insn (tmp_reg, gen_rtx_HIGH (mode, copy_rtx (imm))); 2877 emit_insn (gen_add_losym (dest, tmp_reg, imm)); 2878 return; 2879 } 2880 2881 case SYMBOL_TINY_ABSOLUTE: 2882 emit_insn (gen_rtx_SET (dest, imm)); 2883 return; 2884 2885 case SYMBOL_SMALL_GOT_28K: 2886 { 2887 machine_mode mode = GET_MODE (dest); 2888 rtx gp_rtx = pic_offset_table_rtx; 2889 rtx insn; 2890 rtx mem; 2891 2892 /* NOTE: pic_offset_table_rtx can be NULL_RTX, because we can reach 2893 here before rtl expand. Tree IVOPT will generate rtl pattern to 2894 decide rtx costs, in which case pic_offset_table_rtx is not 2895 initialized. For that case no need to generate the first adrp 2896 instruction as the final cost for global variable access is 2897 one instruction. */ 2898 if (gp_rtx != NULL) 2899 { 2900 /* -fpic for -mcmodel=small allow 32K GOT table size (but we are 2901 using the page base as GOT base, the first page may be wasted, 2902 in the worst scenario, there is only 28K space for GOT). 2903 2904 The generate instruction sequence for accessing global variable 2905 is: 2906 2907 ldr reg, [pic_offset_table_rtx, #:gotpage_lo15:sym] 2908 2909 Only one instruction needed. But we must initialize 2910 pic_offset_table_rtx properly. We generate initialize insn for 2911 every global access, and allow CSE to remove all redundant. 2912 2913 The final instruction sequences will look like the following 2914 for multiply global variables access. 2915 2916 adrp pic_offset_table_rtx, _GLOBAL_OFFSET_TABLE_ 2917 2918 ldr reg, [pic_offset_table_rtx, #:gotpage_lo15:sym1] 2919 ldr reg, [pic_offset_table_rtx, #:gotpage_lo15:sym2] 2920 ldr reg, [pic_offset_table_rtx, #:gotpage_lo15:sym3] 2921 ... */ 2922 2923 rtx s = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); 2924 crtl->uses_pic_offset_table = 1; 2925 emit_move_insn (gp_rtx, gen_rtx_HIGH (Pmode, s)); 2926 2927 if (mode != GET_MODE (gp_rtx)) 2928 gp_rtx = gen_lowpart (mode, gp_rtx); 2929 2930 } 2931 2932 if (mode == ptr_mode) 2933 { 2934 if (mode == DImode) 2935 insn = gen_ldr_got_small_28k_di (dest, gp_rtx, imm); 2936 else 2937 insn = gen_ldr_got_small_28k_si (dest, gp_rtx, imm); 2938 2939 mem = XVECEXP (SET_SRC (insn), 0, 0); 2940 } 2941 else 2942 { 2943 gcc_assert (mode == Pmode); 2944 2945 insn = gen_ldr_got_small_28k_sidi (dest, gp_rtx, imm); 2946 mem = XVECEXP (XEXP (SET_SRC (insn), 0), 0, 0); 2947 } 2948 2949 /* The operand is expected to be MEM. Whenever the related insn 2950 pattern changed, above code which calculate mem should be 2951 updated. */ 2952 gcc_assert (MEM_P (mem)); 2953 MEM_READONLY_P (mem) = 1; 2954 MEM_NOTRAP_P (mem) = 1; 2955 emit_insn (insn); 2956 return; 2957 } 2958 2959 case SYMBOL_SMALL_GOT_4G: 2960 emit_insn (gen_rtx_SET (dest, imm)); 2961 return; 2962 2963 case SYMBOL_SMALL_TLSGD: 2964 { 2965 rtx_insn *insns; 2966 /* The return type of __tls_get_addr is the C pointer type 2967 so use ptr_mode. */ 2968 rtx result = gen_rtx_REG (ptr_mode, R0_REGNUM); 2969 rtx tmp_reg = dest; 2970 2971 if (GET_MODE (dest) != ptr_mode) 2972 tmp_reg = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : result; 2973 2974 start_sequence (); 2975 if (ptr_mode == SImode) 2976 aarch64_emit_call_insn (gen_tlsgd_small_si (result, imm)); 2977 else 2978 aarch64_emit_call_insn (gen_tlsgd_small_di (result, imm)); 2979 insns = get_insns (); 2980 end_sequence (); 2981 2982 RTL_CONST_CALL_P (insns) = 1; 2983 emit_libcall_block (insns, tmp_reg, result, imm); 2984 /* Convert back to the mode of the dest adding a zero_extend 2985 from SImode (ptr_mode) to DImode (Pmode). */ 2986 if (dest != tmp_reg) 2987 convert_move (dest, tmp_reg, true); 2988 return; 2989 } 2990 2991 case SYMBOL_SMALL_TLSDESC: 2992 { 2993 machine_mode mode = GET_MODE (dest); 2994 rtx x0 = gen_rtx_REG (mode, R0_REGNUM); 2995 rtx tp; 2996 2997 gcc_assert (mode == Pmode || mode == ptr_mode); 2998 2999 /* In ILP32, the got entry is always of SImode size. Unlike 3000 small GOT, the dest is fixed at reg 0. */ 3001 if (TARGET_ILP32) 3002 emit_insn (gen_tlsdesc_small_si (imm)); 3003 else 3004 emit_insn (gen_tlsdesc_small_di (imm)); 3005 tp = aarch64_load_tp (NULL); 3006 3007 if (mode != Pmode) 3008 tp = gen_lowpart (mode, tp); 3009 3010 emit_insn (gen_rtx_SET (dest, gen_rtx_PLUS (mode, tp, x0))); 3011 if (REG_P (dest)) 3012 set_unique_reg_note (get_last_insn (), REG_EQUIV, imm); 3013 return; 3014 } 3015 3016 case SYMBOL_SMALL_TLSIE: 3017 { 3018 /* In ILP32, the mode of dest can be either SImode or DImode, 3019 while the got entry is always of SImode size. The mode of 3020 dest depends on how dest is used: if dest is assigned to a 3021 pointer (e.g. in the memory), it has SImode; it may have 3022 DImode if dest is dereferenced to access the memeory. 3023 This is why we have to handle three different tlsie_small 3024 patterns here (two patterns for ILP32). */ 3025 machine_mode mode = GET_MODE (dest); 3026 rtx tmp_reg = gen_reg_rtx (mode); 3027 rtx tp = aarch64_load_tp (NULL); 3028 3029 if (mode == ptr_mode) 3030 { 3031 if (mode == DImode) 3032 emit_insn (gen_tlsie_small_di (tmp_reg, imm)); 3033 else 3034 { 3035 emit_insn (gen_tlsie_small_si (tmp_reg, imm)); 3036 tp = gen_lowpart (mode, tp); 3037 } 3038 } 3039 else 3040 { 3041 gcc_assert (mode == Pmode); 3042 emit_insn (gen_tlsie_small_sidi (tmp_reg, imm)); 3043 } 3044 3045 emit_insn (gen_rtx_SET (dest, gen_rtx_PLUS (mode, tp, tmp_reg))); 3046 if (REG_P (dest)) 3047 set_unique_reg_note (get_last_insn (), REG_EQUIV, imm); 3048 return; 3049 } 3050 3051 case SYMBOL_TLSLE12: 3052 case SYMBOL_TLSLE24: 3053 case SYMBOL_TLSLE32: 3054 case SYMBOL_TLSLE48: 3055 { 3056 machine_mode mode = GET_MODE (dest); 3057 rtx tp = aarch64_load_tp (NULL); 3058 3059 if (mode != Pmode) 3060 tp = gen_lowpart (mode, tp); 3061 3062 switch (type) 3063 { 3064 case SYMBOL_TLSLE12: 3065 emit_insn ((mode == DImode ? gen_tlsle12_di : gen_tlsle12_si) 3066 (dest, tp, imm)); 3067 break; 3068 case SYMBOL_TLSLE24: 3069 emit_insn ((mode == DImode ? gen_tlsle24_di : gen_tlsle24_si) 3070 (dest, tp, imm)); 3071 break; 3072 case SYMBOL_TLSLE32: 3073 emit_insn ((mode == DImode ? gen_tlsle32_di : gen_tlsle32_si) 3074 (dest, imm)); 3075 emit_insn ((mode == DImode ? gen_adddi3 : gen_addsi3) 3076 (dest, dest, tp)); 3077 break; 3078 case SYMBOL_TLSLE48: 3079 emit_insn ((mode == DImode ? gen_tlsle48_di : gen_tlsle48_si) 3080 (dest, imm)); 3081 emit_insn ((mode == DImode ? gen_adddi3 : gen_addsi3) 3082 (dest, dest, tp)); 3083 break; 3084 default: 3085 gcc_unreachable (); 3086 } 3087 3088 if (REG_P (dest)) 3089 set_unique_reg_note (get_last_insn (), REG_EQUIV, imm); 3090 return; 3091 } 3092 3093 case SYMBOL_TINY_GOT: 3094 { 3095 rtx insn; 3096 machine_mode mode = GET_MODE (dest); 3097 3098 if (mode == ptr_mode) 3099 insn = gen_ldr_got_tiny (mode, dest, imm); 3100 else 3101 { 3102 gcc_assert (mode == Pmode); 3103 insn = gen_ldr_got_tiny_sidi (dest, imm); 3104 } 3105 3106 emit_insn (insn); 3107 return; 3108 } 3109 3110 case SYMBOL_TINY_TLSIE: 3111 { 3112 machine_mode mode = GET_MODE (dest); 3113 rtx tp = aarch64_load_tp (NULL); 3114 3115 if (mode == ptr_mode) 3116 { 3117 if (mode == DImode) 3118 emit_insn (gen_tlsie_tiny_di (dest, imm, tp)); 3119 else 3120 { 3121 tp = gen_lowpart (mode, tp); 3122 emit_insn (gen_tlsie_tiny_si (dest, imm, tp)); 3123 } 3124 } 3125 else 3126 { 3127 gcc_assert (mode == Pmode); 3128 emit_insn (gen_tlsie_tiny_sidi (dest, imm, tp)); 3129 } 3130 3131 if (REG_P (dest)) 3132 set_unique_reg_note (get_last_insn (), REG_EQUIV, imm); 3133 return; 3134 } 3135 3136 default: 3137 gcc_unreachable (); 3138 } 3139 } 3140 3141 /* Emit a move from SRC to DEST. Assume that the move expanders can 3142 handle all moves if !can_create_pseudo_p (). The distinction is 3143 important because, unlike emit_move_insn, the move expanders know 3144 how to force Pmode objects into the constant pool even when the 3145 constant pool address is not itself legitimate. */ 3146 static rtx 3147 aarch64_emit_move (rtx dest, rtx src) 3148 { 3149 return (can_create_pseudo_p () 3150 ? emit_move_insn (dest, src) 3151 : emit_move_insn_1 (dest, src)); 3152 } 3153 3154 /* Apply UNOPTAB to OP and store the result in DEST. */ 3155 3156 static void 3157 aarch64_emit_unop (rtx dest, optab unoptab, rtx op) 3158 { 3159 rtx tmp = expand_unop (GET_MODE (dest), unoptab, op, dest, 0); 3160 if (dest != tmp) 3161 emit_move_insn (dest, tmp); 3162 } 3163 3164 /* Apply BINOPTAB to OP0 and OP1 and store the result in DEST. */ 3165 3166 static void 3167 aarch64_emit_binop (rtx dest, optab binoptab, rtx op0, rtx op1) 3168 { 3169 rtx tmp = expand_binop (GET_MODE (dest), binoptab, op0, op1, dest, 0, 3170 OPTAB_DIRECT); 3171 if (dest != tmp) 3172 emit_move_insn (dest, tmp); 3173 } 3174 3175 /* Split a move from SRC to DST into two moves of mode SINGLE_MODE. */ 3176 3177 void 3178 aarch64_split_double_move (rtx dst, rtx src, machine_mode single_mode) 3179 { 3180 machine_mode mode = GET_MODE (dst); 3181 3182 rtx dst0 = simplify_gen_subreg (single_mode, dst, mode, 0); 3183 rtx dst1 = simplify_gen_subreg (single_mode, dst, mode, 3184 GET_MODE_SIZE (single_mode)); 3185 rtx src0 = simplify_gen_subreg (single_mode, src, mode, 0); 3186 rtx src1 = simplify_gen_subreg (single_mode, src, mode, 3187 GET_MODE_SIZE (single_mode)); 3188 3189 /* At most one pairing may overlap. */ 3190 if (reg_overlap_mentioned_p (dst0, src1)) 3191 { 3192 aarch64_emit_move (dst1, src1); 3193 aarch64_emit_move (dst0, src0); 3194 } 3195 else 3196 { 3197 aarch64_emit_move (dst0, src0); 3198 aarch64_emit_move (dst1, src1); 3199 } 3200 } 3201 3202 /* Split a 128-bit move operation into two 64-bit move operations, 3203 taking care to handle partial overlap of register to register 3204 copies. Special cases are needed when moving between GP regs and 3205 FP regs. SRC can be a register, constant or memory; DST a register 3206 or memory. If either operand is memory it must not have any side 3207 effects. */ 3208 void 3209 aarch64_split_128bit_move (rtx dst, rtx src) 3210 { 3211 machine_mode mode = GET_MODE (dst); 3212 3213 gcc_assert (mode == TImode || mode == TFmode || mode == TDmode); 3214 gcc_assert (!(side_effects_p (src) || side_effects_p (dst))); 3215 gcc_assert (mode == GET_MODE (src) || GET_MODE (src) == VOIDmode); 3216 3217 if (REG_P (dst) && REG_P (src)) 3218 { 3219 int src_regno = REGNO (src); 3220 int dst_regno = REGNO (dst); 3221 3222 /* Handle FP <-> GP regs. */ 3223 if (FP_REGNUM_P (dst_regno) && GP_REGNUM_P (src_regno)) 3224 { 3225 rtx src_lo = gen_lowpart (word_mode, src); 3226 rtx src_hi = gen_highpart (word_mode, src); 3227 3228 emit_insn (gen_aarch64_movlow_di (mode, dst, src_lo)); 3229 emit_insn (gen_aarch64_movhigh_di (mode, dst, src_hi)); 3230 return; 3231 } 3232 else if (GP_REGNUM_P (dst_regno) && FP_REGNUM_P (src_regno)) 3233 { 3234 rtx dst_lo = gen_lowpart (word_mode, dst); 3235 rtx dst_hi = gen_highpart (word_mode, dst); 3236 3237 emit_insn (gen_aarch64_movdi_low (mode, dst_lo, src)); 3238 emit_insn (gen_aarch64_movdi_high (mode, dst_hi, src)); 3239 return; 3240 } 3241 } 3242 3243 aarch64_split_double_move (dst, src, word_mode); 3244 } 3245 3246 /* Return true if we should split a move from 128-bit value SRC 3247 to 128-bit register DEST. */ 3248 3249 bool 3250 aarch64_split_128bit_move_p (rtx dst, rtx src) 3251 { 3252 if (FP_REGNUM_P (REGNO (dst))) 3253 return REG_P (src) && !FP_REGNUM_P (REGNO (src)); 3254 /* All moves to GPRs need to be split. */ 3255 return true; 3256 } 3257 3258 /* Split a complex SIMD move. */ 3259 3260 void 3261 aarch64_split_simd_move (rtx dst, rtx src) 3262 { 3263 machine_mode src_mode = GET_MODE (src); 3264 machine_mode dst_mode = GET_MODE (dst); 3265 3266 gcc_assert (VECTOR_MODE_P (dst_mode)); 3267 3268 if (REG_P (dst) && REG_P (src)) 3269 { 3270 gcc_assert (VECTOR_MODE_P (src_mode)); 3271 emit_insn (gen_aarch64_split_simd_mov (src_mode, dst, src)); 3272 } 3273 } 3274 3275 /* Return a register that contains SVE value X reinterpreted as SVE mode MODE. 3276 The semantics of those of svreinterpret rather than those of subregs; 3277 see the comment at the head of aarch64-sve.md for details about the 3278 difference. */ 3279 3280 rtx 3281 aarch64_sve_reinterpret (machine_mode mode, rtx x) 3282 { 3283 if (GET_MODE (x) == mode) 3284 return x; 3285 3286 /* can_change_mode_class must only return true if subregs and svreinterprets 3287 have the same semantics. */ 3288 if (targetm.can_change_mode_class (GET_MODE (x), mode, FP_REGS)) 3289 return lowpart_subreg (mode, x, GET_MODE (x)); 3290 3291 rtx res = gen_reg_rtx (mode); 3292 x = force_reg (GET_MODE (x), x); 3293 emit_insn (gen_aarch64_sve_reinterpret (mode, res, x)); 3294 return res; 3295 } 3296 3297 bool 3298 aarch64_zero_extend_const_eq (machine_mode xmode, rtx x, 3299 machine_mode ymode, rtx y) 3300 { 3301 rtx r = simplify_const_unary_operation (ZERO_EXTEND, xmode, y, ymode); 3302 gcc_assert (r != NULL); 3303 return rtx_equal_p (x, r); 3304 } 3305 3306 /* Return TARGET if it is nonnull and a register of mode MODE. 3307 Otherwise, return a fresh register of mode MODE if we can, 3308 or TARGET reinterpreted as MODE if we can't. */ 3309 3310 static rtx 3311 aarch64_target_reg (rtx target, machine_mode mode) 3312 { 3313 if (target && REG_P (target) && GET_MODE (target) == mode) 3314 return target; 3315 if (!can_create_pseudo_p ()) 3316 { 3317 gcc_assert (target); 3318 return gen_lowpart (mode, target); 3319 } 3320 return gen_reg_rtx (mode); 3321 } 3322 3323 /* Return a register that contains the constant in BUILDER, given that 3324 the constant is a legitimate move operand. Use TARGET as the register 3325 if it is nonnull and convenient. */ 3326 3327 static rtx 3328 aarch64_emit_set_immediate (rtx target, rtx_vector_builder &builder) 3329 { 3330 rtx src = builder.build (); 3331 target = aarch64_target_reg (target, GET_MODE (src)); 3332 emit_insn (gen_rtx_SET (target, src)); 3333 return target; 3334 } 3335 3336 static rtx 3337 aarch64_force_temporary (machine_mode mode, rtx x, rtx value) 3338 { 3339 if (can_create_pseudo_p ()) 3340 return force_reg (mode, value); 3341 else 3342 { 3343 gcc_assert (x); 3344 aarch64_emit_move (x, value); 3345 return x; 3346 } 3347 } 3348 3349 /* Return true if predicate value X is a constant in which every element 3350 is a CONST_INT. When returning true, describe X in BUILDER as a VNx16BI 3351 value, i.e. as a predicate in which all bits are significant. */ 3352 3353 static bool 3354 aarch64_get_sve_pred_bits (rtx_vector_builder &builder, rtx x) 3355 { 3356 if (!CONST_VECTOR_P (x)) 3357 return false; 3358 3359 unsigned int factor = vector_element_size (GET_MODE_NUNITS (VNx16BImode), 3360 GET_MODE_NUNITS (GET_MODE (x))); 3361 unsigned int npatterns = CONST_VECTOR_NPATTERNS (x) * factor; 3362 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x); 3363 builder.new_vector (VNx16BImode, npatterns, nelts_per_pattern); 3364 3365 unsigned int nelts = const_vector_encoded_nelts (x); 3366 for (unsigned int i = 0; i < nelts; ++i) 3367 { 3368 rtx elt = CONST_VECTOR_ENCODED_ELT (x, i); 3369 if (!CONST_INT_P (elt)) 3370 return false; 3371 3372 builder.quick_push (elt); 3373 for (unsigned int j = 1; j < factor; ++j) 3374 builder.quick_push (const0_rtx); 3375 } 3376 builder.finalize (); 3377 return true; 3378 } 3379 3380 /* BUILDER contains a predicate constant of mode VNx16BI. Return the 3381 widest predicate element size it can have (that is, the largest size 3382 for which each element would still be 0 or 1). */ 3383 3384 unsigned int 3385 aarch64_widest_sve_pred_elt_size (rtx_vector_builder &builder) 3386 { 3387 /* Start with the most optimistic assumption: that we only need 3388 one bit per pattern. This is what we will use if only the first 3389 bit in each pattern is ever set. */ 3390 unsigned int mask = GET_MODE_SIZE (DImode); 3391 mask |= builder.npatterns (); 3392 3393 /* Look for set bits. */ 3394 unsigned int nelts = builder.encoded_nelts (); 3395 for (unsigned int i = 1; i < nelts; ++i) 3396 if (INTVAL (builder.elt (i)) != 0) 3397 { 3398 if (i & 1) 3399 return 1; 3400 mask |= i; 3401 } 3402 return mask & -mask; 3403 } 3404 3405 /* If VNx16BImode rtx X is a canonical PTRUE for a predicate mode, 3406 return that predicate mode, otherwise return opt_machine_mode (). */ 3407 3408 opt_machine_mode 3409 aarch64_ptrue_all_mode (rtx x) 3410 { 3411 gcc_assert (GET_MODE (x) == VNx16BImode); 3412 if (!CONST_VECTOR_P (x) 3413 || !CONST_VECTOR_DUPLICATE_P (x) 3414 || !CONST_INT_P (CONST_VECTOR_ENCODED_ELT (x, 0)) 3415 || INTVAL (CONST_VECTOR_ENCODED_ELT (x, 0)) == 0) 3416 return opt_machine_mode (); 3417 3418 unsigned int nelts = const_vector_encoded_nelts (x); 3419 for (unsigned int i = 1; i < nelts; ++i) 3420 if (CONST_VECTOR_ENCODED_ELT (x, i) != const0_rtx) 3421 return opt_machine_mode (); 3422 3423 return aarch64_sve_pred_mode (nelts); 3424 } 3425 3426 /* BUILDER is a predicate constant of mode VNx16BI. Consider the value 3427 that the constant would have with predicate element size ELT_SIZE 3428 (ignoring the upper bits in each element) and return: 3429 3430 * -1 if all bits are set 3431 * N if the predicate has N leading set bits followed by all clear bits 3432 * 0 if the predicate does not have any of these forms. */ 3433 3434 int 3435 aarch64_partial_ptrue_length (rtx_vector_builder &builder, 3436 unsigned int elt_size) 3437 { 3438 /* If nelts_per_pattern is 3, we have set bits followed by clear bits 3439 followed by set bits. */ 3440 if (builder.nelts_per_pattern () == 3) 3441 return 0; 3442 3443 /* Skip over leading set bits. */ 3444 unsigned int nelts = builder.encoded_nelts (); 3445 unsigned int i = 0; 3446 for (; i < nelts; i += elt_size) 3447 if (INTVAL (builder.elt (i)) == 0) 3448 break; 3449 unsigned int vl = i / elt_size; 3450 3451 /* Check for the all-true case. */ 3452 if (i == nelts) 3453 return -1; 3454 3455 /* If nelts_per_pattern is 1, then either VL is zero, or we have a 3456 repeating pattern of set bits followed by clear bits. */ 3457 if (builder.nelts_per_pattern () != 2) 3458 return 0; 3459 3460 /* We have a "foreground" value and a duplicated "background" value. 3461 If the background might repeat and the last set bit belongs to it, 3462 we might have set bits followed by clear bits followed by set bits. */ 3463 if (i > builder.npatterns () && maybe_ne (nelts, builder.full_nelts ())) 3464 return 0; 3465 3466 /* Make sure that the rest are all clear. */ 3467 for (; i < nelts; i += elt_size) 3468 if (INTVAL (builder.elt (i)) != 0) 3469 return 0; 3470 3471 return vl; 3472 } 3473 3474 /* See if there is an svpattern that encodes an SVE predicate of mode 3475 PRED_MODE in which the first VL bits are set and the rest are clear. 3476 Return the pattern if so, otherwise return AARCH64_NUM_SVPATTERNS. 3477 A VL of -1 indicates an all-true vector. */ 3478 3479 aarch64_svpattern 3480 aarch64_svpattern_for_vl (machine_mode pred_mode, int vl) 3481 { 3482 if (vl < 0) 3483 return AARCH64_SV_ALL; 3484 3485 if (maybe_gt (vl, GET_MODE_NUNITS (pred_mode))) 3486 return AARCH64_NUM_SVPATTERNS; 3487 3488 if (vl >= 1 && vl <= 8) 3489 return aarch64_svpattern (AARCH64_SV_VL1 + (vl - 1)); 3490 3491 if (vl >= 16 && vl <= 256 && pow2p_hwi (vl)) 3492 return aarch64_svpattern (AARCH64_SV_VL16 + (exact_log2 (vl) - 4)); 3493 3494 int max_vl; 3495 if (GET_MODE_NUNITS (pred_mode).is_constant (&max_vl)) 3496 { 3497 if (vl == (max_vl / 3) * 3) 3498 return AARCH64_SV_MUL3; 3499 /* These would only trigger for non-power-of-2 lengths. */ 3500 if (vl == (max_vl & -4)) 3501 return AARCH64_SV_MUL4; 3502 if (vl == (1 << floor_log2 (max_vl))) 3503 return AARCH64_SV_POW2; 3504 if (vl == max_vl) 3505 return AARCH64_SV_ALL; 3506 } 3507 return AARCH64_NUM_SVPATTERNS; 3508 } 3509 3510 /* Return a VNx16BImode constant in which every sequence of ELT_SIZE 3511 bits has the lowest bit set and the upper bits clear. This is the 3512 VNx16BImode equivalent of a PTRUE for controlling elements of 3513 ELT_SIZE bytes. However, because the constant is VNx16BImode, 3514 all bits are significant, even the upper zeros. */ 3515 3516 rtx 3517 aarch64_ptrue_all (unsigned int elt_size) 3518 { 3519 rtx_vector_builder builder (VNx16BImode, elt_size, 1); 3520 builder.quick_push (const1_rtx); 3521 for (unsigned int i = 1; i < elt_size; ++i) 3522 builder.quick_push (const0_rtx); 3523 return builder.build (); 3524 } 3525 3526 /* Return an all-true predicate register of mode MODE. */ 3527 3528 rtx 3529 aarch64_ptrue_reg (machine_mode mode) 3530 { 3531 gcc_assert (aarch64_sve_pred_mode_p (mode)); 3532 rtx reg = force_reg (VNx16BImode, CONSTM1_RTX (VNx16BImode)); 3533 return gen_lowpart (mode, reg); 3534 } 3535 3536 /* Return an all-false predicate register of mode MODE. */ 3537 3538 rtx 3539 aarch64_pfalse_reg (machine_mode mode) 3540 { 3541 gcc_assert (aarch64_sve_pred_mode_p (mode)); 3542 rtx reg = force_reg (VNx16BImode, CONST0_RTX (VNx16BImode)); 3543 return gen_lowpart (mode, reg); 3544 } 3545 3546 /* PRED1[0] is a PTEST predicate and PRED1[1] is an aarch64_sve_ptrue_flag 3547 for it. PRED2[0] is the predicate for the instruction whose result 3548 is tested by the PTEST and PRED2[1] is again an aarch64_sve_ptrue_flag 3549 for it. Return true if we can prove that the two predicates are 3550 equivalent for PTEST purposes; that is, if we can replace PRED2[0] 3551 with PRED1[0] without changing behavior. */ 3552 3553 bool 3554 aarch64_sve_same_pred_for_ptest_p (rtx *pred1, rtx *pred2) 3555 { 3556 machine_mode mode = GET_MODE (pred1[0]); 3557 gcc_assert (aarch64_sve_pred_mode_p (mode) 3558 && mode == GET_MODE (pred2[0]) 3559 && aarch64_sve_ptrue_flag (pred1[1], SImode) 3560 && aarch64_sve_ptrue_flag (pred2[1], SImode)); 3561 3562 bool ptrue1_p = (pred1[0] == CONSTM1_RTX (mode) 3563 || INTVAL (pred1[1]) == SVE_KNOWN_PTRUE); 3564 bool ptrue2_p = (pred2[0] == CONSTM1_RTX (mode) 3565 || INTVAL (pred2[1]) == SVE_KNOWN_PTRUE); 3566 return (ptrue1_p && ptrue2_p) || rtx_equal_p (pred1[0], pred2[0]); 3567 } 3568 3569 /* Emit a comparison CMP between OP0 and OP1, both of which have mode 3570 DATA_MODE, and return the result in a predicate of mode PRED_MODE. 3571 Use TARGET as the target register if nonnull and convenient. */ 3572 3573 static rtx 3574 aarch64_sve_emit_int_cmp (rtx target, machine_mode pred_mode, rtx_code cmp, 3575 machine_mode data_mode, rtx op1, rtx op2) 3576 { 3577 insn_code icode = code_for_aarch64_pred_cmp (cmp, data_mode); 3578 expand_operand ops[5]; 3579 create_output_operand (&ops[0], target, pred_mode); 3580 create_input_operand (&ops[1], CONSTM1_RTX (pred_mode), pred_mode); 3581 create_integer_operand (&ops[2], SVE_KNOWN_PTRUE); 3582 create_input_operand (&ops[3], op1, data_mode); 3583 create_input_operand (&ops[4], op2, data_mode); 3584 expand_insn (icode, 5, ops); 3585 return ops[0].value; 3586 } 3587 3588 /* Use a comparison to convert integer vector SRC into MODE, which is 3589 the corresponding SVE predicate mode. Use TARGET for the result 3590 if it's nonnull and convenient. */ 3591 3592 rtx 3593 aarch64_convert_sve_data_to_pred (rtx target, machine_mode mode, rtx src) 3594 { 3595 machine_mode src_mode = GET_MODE (src); 3596 return aarch64_sve_emit_int_cmp (target, mode, NE, src_mode, 3597 src, CONST0_RTX (src_mode)); 3598 } 3599 3600 /* Return the assembly token for svprfop value PRFOP. */ 3601 3602 static const char * 3603 svprfop_token (enum aarch64_svprfop prfop) 3604 { 3605 switch (prfop) 3606 { 3607 #define CASE(UPPER, LOWER, VALUE) case AARCH64_SV_##UPPER: return #LOWER; 3608 AARCH64_FOR_SVPRFOP (CASE) 3609 #undef CASE 3610 case AARCH64_NUM_SVPRFOPS: 3611 break; 3612 } 3613 gcc_unreachable (); 3614 } 3615 3616 /* Return the assembly string for an SVE prefetch operation with 3617 mnemonic MNEMONIC, given that PRFOP_RTX is the prefetch operation 3618 and that SUFFIX is the format for the remaining operands. */ 3619 3620 char * 3621 aarch64_output_sve_prefetch (const char *mnemonic, rtx prfop_rtx, 3622 const char *suffix) 3623 { 3624 static char buffer[128]; 3625 aarch64_svprfop prfop = (aarch64_svprfop) INTVAL (prfop_rtx); 3626 unsigned int written = snprintf (buffer, sizeof (buffer), "%s\t%s, %s", 3627 mnemonic, svprfop_token (prfop), suffix); 3628 gcc_assert (written < sizeof (buffer)); 3629 return buffer; 3630 } 3631 3632 /* Check whether we can calculate the number of elements in PATTERN 3633 at compile time, given that there are NELTS_PER_VQ elements per 3634 128-bit block. Return the value if so, otherwise return -1. */ 3635 3636 HOST_WIDE_INT 3637 aarch64_fold_sve_cnt_pat (aarch64_svpattern pattern, unsigned int nelts_per_vq) 3638 { 3639 unsigned int vl, const_vg; 3640 if (pattern >= AARCH64_SV_VL1 && pattern <= AARCH64_SV_VL8) 3641 vl = 1 + (pattern - AARCH64_SV_VL1); 3642 else if (pattern >= AARCH64_SV_VL16 && pattern <= AARCH64_SV_VL256) 3643 vl = 16 << (pattern - AARCH64_SV_VL16); 3644 else if (aarch64_sve_vg.is_constant (&const_vg)) 3645 { 3646 /* There are two vector granules per quadword. */ 3647 unsigned int nelts = (const_vg / 2) * nelts_per_vq; 3648 switch (pattern) 3649 { 3650 case AARCH64_SV_POW2: return 1 << floor_log2 (nelts); 3651 case AARCH64_SV_MUL4: return nelts & -4; 3652 case AARCH64_SV_MUL3: return (nelts / 3) * 3; 3653 case AARCH64_SV_ALL: return nelts; 3654 default: gcc_unreachable (); 3655 } 3656 } 3657 else 3658 return -1; 3659 3660 /* There are two vector granules per quadword. */ 3661 poly_uint64 nelts_all = exact_div (aarch64_sve_vg, 2) * nelts_per_vq; 3662 if (known_le (vl, nelts_all)) 3663 return vl; 3664 3665 /* Requesting more elements than are available results in a PFALSE. */ 3666 if (known_gt (vl, nelts_all)) 3667 return 0; 3668 3669 return -1; 3670 } 3671 3672 /* Return true if a single CNT[BHWD] instruction can multiply FACTOR 3673 by the number of 128-bit quadwords in an SVE vector. */ 3674 3675 static bool 3676 aarch64_sve_cnt_factor_p (HOST_WIDE_INT factor) 3677 { 3678 /* The coefficient must be [1, 16] * {2, 4, 8, 16}. */ 3679 return (IN_RANGE (factor, 2, 16 * 16) 3680 && (factor & 1) == 0 3681 && factor <= 16 * (factor & -factor)); 3682 } 3683 3684 /* Return true if we can move VALUE into a register using a single 3685 CNT[BHWD] instruction. */ 3686 3687 static bool 3688 aarch64_sve_cnt_immediate_p (poly_int64 value) 3689 { 3690 HOST_WIDE_INT factor = value.coeffs[0]; 3691 return value.coeffs[1] == factor && aarch64_sve_cnt_factor_p (factor); 3692 } 3693 3694 /* Likewise for rtx X. */ 3695 3696 bool 3697 aarch64_sve_cnt_immediate_p (rtx x) 3698 { 3699 poly_int64 value; 3700 return poly_int_rtx_p (x, &value) && aarch64_sve_cnt_immediate_p (value); 3701 } 3702 3703 /* Return the asm string for an instruction with a CNT-like vector size 3704 operand (a vector pattern followed by a multiplier in the range [1, 16]). 3705 PREFIX is the mnemonic without the size suffix and OPERANDS is the 3706 first part of the operands template (the part that comes before the 3707 vector size itself). PATTERN is the pattern to use. FACTOR is the 3708 number of quadwords. NELTS_PER_VQ, if nonzero, is the number of elements 3709 in each quadword. If it is zero, we can use any element size. */ 3710 3711 static char * 3712 aarch64_output_sve_cnt_immediate (const char *prefix, const char *operands, 3713 aarch64_svpattern pattern, 3714 unsigned int factor, 3715 unsigned int nelts_per_vq) 3716 { 3717 static char buffer[sizeof ("sqincd\t%x0, %w0, vl256, mul #16")]; 3718 3719 if (nelts_per_vq == 0) 3720 /* There is some overlap in the ranges of the four CNT instructions. 3721 Here we always use the smallest possible element size, so that the 3722 multiplier is 1 whereever possible. */ 3723 nelts_per_vq = factor & -factor; 3724 int shift = std::min (exact_log2 (nelts_per_vq), 4); 3725 gcc_assert (IN_RANGE (shift, 1, 4)); 3726 char suffix = "dwhb"[shift - 1]; 3727 3728 factor >>= shift; 3729 unsigned int written; 3730 if (pattern == AARCH64_SV_ALL && factor == 1) 3731 written = snprintf (buffer, sizeof (buffer), "%s%c\t%s", 3732 prefix, suffix, operands); 3733 else if (factor == 1) 3734 written = snprintf (buffer, sizeof (buffer), "%s%c\t%s, %s", 3735 prefix, suffix, operands, svpattern_token (pattern)); 3736 else 3737 written = snprintf (buffer, sizeof (buffer), "%s%c\t%s, %s, mul #%d", 3738 prefix, suffix, operands, svpattern_token (pattern), 3739 factor); 3740 gcc_assert (written < sizeof (buffer)); 3741 return buffer; 3742 } 3743 3744 /* Return the asm string for an instruction with a CNT-like vector size 3745 operand (a vector pattern followed by a multiplier in the range [1, 16]). 3746 PREFIX is the mnemonic without the size suffix and OPERANDS is the 3747 first part of the operands template (the part that comes before the 3748 vector size itself). X is the value of the vector size operand, 3749 as a polynomial integer rtx; we need to convert this into an "all" 3750 pattern with a multiplier. */ 3751 3752 char * 3753 aarch64_output_sve_cnt_immediate (const char *prefix, const char *operands, 3754 rtx x) 3755 { 3756 poly_int64 value = rtx_to_poly_int64 (x); 3757 gcc_assert (aarch64_sve_cnt_immediate_p (value)); 3758 return aarch64_output_sve_cnt_immediate (prefix, operands, AARCH64_SV_ALL, 3759 value.coeffs[1], 0); 3760 } 3761 3762 /* Return the asm string for an instruction with a CNT-like vector size 3763 operand (a vector pattern followed by a multiplier in the range [1, 16]). 3764 PREFIX is the mnemonic without the size suffix and OPERANDS is the 3765 first part of the operands template (the part that comes before the 3766 vector size itself). CNT_PAT[0..2] are the operands of the 3767 UNSPEC_SVE_CNT_PAT; see aarch64_sve_cnt_pat for details. */ 3768 3769 char * 3770 aarch64_output_sve_cnt_pat_immediate (const char *prefix, 3771 const char *operands, rtx *cnt_pat) 3772 { 3773 aarch64_svpattern pattern = (aarch64_svpattern) INTVAL (cnt_pat[0]); 3774 unsigned int nelts_per_vq = INTVAL (cnt_pat[1]); 3775 unsigned int factor = INTVAL (cnt_pat[2]) * nelts_per_vq; 3776 return aarch64_output_sve_cnt_immediate (prefix, operands, pattern, 3777 factor, nelts_per_vq); 3778 } 3779 3780 /* Return true if we can add X using a single SVE INC or DEC instruction. */ 3781 3782 bool 3783 aarch64_sve_scalar_inc_dec_immediate_p (rtx x) 3784 { 3785 poly_int64 value; 3786 return (poly_int_rtx_p (x, &value) 3787 && (aarch64_sve_cnt_immediate_p (value) 3788 || aarch64_sve_cnt_immediate_p (-value))); 3789 } 3790 3791 /* Return the asm string for adding SVE INC/DEC immediate OFFSET to 3792 operand 0. */ 3793 3794 char * 3795 aarch64_output_sve_scalar_inc_dec (rtx offset) 3796 { 3797 poly_int64 offset_value = rtx_to_poly_int64 (offset); 3798 gcc_assert (offset_value.coeffs[0] == offset_value.coeffs[1]); 3799 if (offset_value.coeffs[1] > 0) 3800 return aarch64_output_sve_cnt_immediate ("inc", "%x0", AARCH64_SV_ALL, 3801 offset_value.coeffs[1], 0); 3802 else 3803 return aarch64_output_sve_cnt_immediate ("dec", "%x0", AARCH64_SV_ALL, 3804 -offset_value.coeffs[1], 0); 3805 } 3806 3807 /* Return true if a single RDVL instruction can multiply FACTOR by the 3808 number of 128-bit quadwords in an SVE vector. This is also the 3809 range of ADDVL. */ 3810 3811 static bool 3812 aarch64_sve_rdvl_addvl_factor_p (HOST_WIDE_INT factor) 3813 { 3814 return (multiple_p (factor, 16) 3815 && IN_RANGE (factor, -32 * 16, 31 * 16)); 3816 } 3817 3818 /* Return true if ADDPL can be used to add FACTOR multiplied by the number 3819 of quadwords in an SVE vector. */ 3820 3821 static bool 3822 aarch64_sve_addpl_factor_p (HOST_WIDE_INT factor) 3823 { 3824 return (multiple_p (factor, 2) 3825 && IN_RANGE (factor, -32 * 2, 31 * 2)); 3826 } 3827 3828 /* Return true if we can move VALUE into a register using a single 3829 RDVL instruction. */ 3830 3831 static bool 3832 aarch64_sve_rdvl_immediate_p (poly_int64 value) 3833 { 3834 HOST_WIDE_INT factor = value.coeffs[0]; 3835 return value.coeffs[1] == factor && aarch64_sve_rdvl_addvl_factor_p (factor); 3836 } 3837 3838 /* Likewise for rtx X. */ 3839 3840 bool 3841 aarch64_sve_rdvl_immediate_p (rtx x) 3842 { 3843 poly_int64 value; 3844 return poly_int_rtx_p (x, &value) && aarch64_sve_rdvl_immediate_p (value); 3845 } 3846 3847 /* Return the asm string for moving RDVL immediate OFFSET into register 3848 operand 0. */ 3849 3850 char * 3851 aarch64_output_sve_rdvl (rtx offset) 3852 { 3853 static char buffer[sizeof ("rdvl\t%x0, #-") + 3 * sizeof (int)]; 3854 poly_int64 offset_value = rtx_to_poly_int64 (offset); 3855 gcc_assert (aarch64_sve_rdvl_immediate_p (offset_value)); 3856 3857 int factor = offset_value.coeffs[1]; 3858 snprintf (buffer, sizeof (buffer), "rdvl\t%%x0, #%d", factor / 16); 3859 return buffer; 3860 } 3861 3862 /* Return true if we can add VALUE to a register using a single ADDVL 3863 or ADDPL instruction. */ 3864 3865 static bool 3866 aarch64_sve_addvl_addpl_immediate_p (poly_int64 value) 3867 { 3868 HOST_WIDE_INT factor = value.coeffs[0]; 3869 if (factor == 0 || value.coeffs[1] != factor) 3870 return false; 3871 return (aarch64_sve_rdvl_addvl_factor_p (factor) 3872 || aarch64_sve_addpl_factor_p (factor)); 3873 } 3874 3875 /* Likewise for rtx X. */ 3876 3877 bool 3878 aarch64_sve_addvl_addpl_immediate_p (rtx x) 3879 { 3880 poly_int64 value; 3881 return (poly_int_rtx_p (x, &value) 3882 && aarch64_sve_addvl_addpl_immediate_p (value)); 3883 } 3884 3885 /* Return the asm string for adding ADDVL or ADDPL immediate OFFSET 3886 to operand 1 and storing the result in operand 0. */ 3887 3888 char * 3889 aarch64_output_sve_addvl_addpl (rtx offset) 3890 { 3891 static char buffer[sizeof ("addpl\t%x0, %x1, #-") + 3 * sizeof (int)]; 3892 poly_int64 offset_value = rtx_to_poly_int64 (offset); 3893 gcc_assert (aarch64_sve_addvl_addpl_immediate_p (offset_value)); 3894 3895 int factor = offset_value.coeffs[1]; 3896 if ((factor & 15) == 0) 3897 snprintf (buffer, sizeof (buffer), "addvl\t%%x0, %%x1, #%d", factor / 16); 3898 else 3899 snprintf (buffer, sizeof (buffer), "addpl\t%%x0, %%x1, #%d", factor / 2); 3900 return buffer; 3901 } 3902 3903 /* Return true if X is a valid immediate for an SVE vector INC or DEC 3904 instruction. If it is, store the number of elements in each vector 3905 quadword in *NELTS_PER_VQ_OUT (if nonnull) and store the multiplication 3906 factor in *FACTOR_OUT (if nonnull). */ 3907 3908 bool 3909 aarch64_sve_vector_inc_dec_immediate_p (rtx x, int *factor_out, 3910 unsigned int *nelts_per_vq_out) 3911 { 3912 rtx elt; 3913 poly_int64 value; 3914 3915 if (!const_vec_duplicate_p (x, &elt) 3916 || !poly_int_rtx_p (elt, &value)) 3917 return false; 3918 3919 unsigned int nelts_per_vq = 128 / GET_MODE_UNIT_BITSIZE (GET_MODE (x)); 3920 if (nelts_per_vq != 8 && nelts_per_vq != 4 && nelts_per_vq != 2) 3921 /* There's no vector INCB. */ 3922 return false; 3923 3924 HOST_WIDE_INT factor = value.coeffs[0]; 3925 if (value.coeffs[1] != factor) 3926 return false; 3927 3928 /* The coefficient must be [1, 16] * NELTS_PER_VQ. */ 3929 if ((factor % nelts_per_vq) != 0 3930 || !IN_RANGE (abs (factor), nelts_per_vq, 16 * nelts_per_vq)) 3931 return false; 3932 3933 if (factor_out) 3934 *factor_out = factor; 3935 if (nelts_per_vq_out) 3936 *nelts_per_vq_out = nelts_per_vq; 3937 return true; 3938 } 3939 3940 /* Return true if X is a valid immediate for an SVE vector INC or DEC 3941 instruction. */ 3942 3943 bool 3944 aarch64_sve_vector_inc_dec_immediate_p (rtx x) 3945 { 3946 return aarch64_sve_vector_inc_dec_immediate_p (x, NULL, NULL); 3947 } 3948 3949 /* Return the asm template for an SVE vector INC or DEC instruction. 3950 OPERANDS gives the operands before the vector count and X is the 3951 value of the vector count operand itself. */ 3952 3953 char * 3954 aarch64_output_sve_vector_inc_dec (const char *operands, rtx x) 3955 { 3956 int factor; 3957 unsigned int nelts_per_vq; 3958 if (!aarch64_sve_vector_inc_dec_immediate_p (x, &factor, &nelts_per_vq)) 3959 gcc_unreachable (); 3960 if (factor < 0) 3961 return aarch64_output_sve_cnt_immediate ("dec", operands, AARCH64_SV_ALL, 3962 -factor, nelts_per_vq); 3963 else 3964 return aarch64_output_sve_cnt_immediate ("inc", operands, AARCH64_SV_ALL, 3965 factor, nelts_per_vq); 3966 } 3967 3968 /* Return a constant that represents FACTOR multiplied by the 3969 number of 128-bit quadwords in an SME vector. ISA_MODE is the 3970 ISA mode in which the calculation is being performed. */ 3971 3972 rtx 3973 aarch64_sme_vq_immediate (machine_mode mode, HOST_WIDE_INT factor, 3974 aarch64_feature_flags isa_mode) 3975 { 3976 gcc_assert (aarch64_sve_rdvl_addvl_factor_p (factor)); 3977 if (isa_mode & AARCH64_FL_SM_ON) 3978 /* We're in streaming mode, so we can use normal poly-int values. */ 3979 return gen_int_mode ({ factor, factor }, mode); 3980 3981 rtvec vec = gen_rtvec (1, gen_int_mode (factor, SImode)); 3982 rtx unspec = gen_rtx_UNSPEC (mode, vec, UNSPEC_SME_VQ); 3983 return gen_rtx_CONST (mode, unspec); 3984 } 3985 3986 /* Return true if X is a constant that represents some number X 3987 multiplied by the number of quadwords in an SME vector. Store this X 3988 in *FACTOR if so. */ 3989 3990 static bool 3991 aarch64_sme_vq_unspec_p (const_rtx x, HOST_WIDE_INT *factor) 3992 { 3993 if (!TARGET_SME || GET_CODE (x) != CONST) 3994 return false; 3995 3996 x = XEXP (x, 0); 3997 if (GET_CODE (x) != UNSPEC 3998 || XINT (x, 1) != UNSPEC_SME_VQ 3999 || XVECLEN (x, 0) != 1) 4000 return false; 4001 4002 x = XVECEXP (x, 0, 0); 4003 if (!CONST_INT_P (x)) 4004 return false; 4005 4006 *factor = INTVAL (x); 4007 return true; 4008 } 4009 4010 /* Return true if X is a constant that represents some number Y 4011 multiplied by the number of quadwords in an SME vector, and if 4012 that Y is in the range of RDSVL. */ 4013 4014 bool 4015 aarch64_rdsvl_immediate_p (const_rtx x) 4016 { 4017 HOST_WIDE_INT factor; 4018 return (aarch64_sme_vq_unspec_p (x, &factor) 4019 && aarch64_sve_rdvl_addvl_factor_p (factor)); 4020 } 4021 4022 /* Return the asm string for an RDSVL instruction that calculates X, 4023 which is a constant that satisfies aarch64_rdsvl_immediate_p. */ 4024 4025 char * 4026 aarch64_output_rdsvl (const_rtx x) 4027 { 4028 gcc_assert (aarch64_rdsvl_immediate_p (x)); 4029 static char buffer[sizeof ("rdsvl\t%x0, #-") + 3 * sizeof (int)]; 4030 x = XVECEXP (XEXP (x, 0), 0, 0); 4031 snprintf (buffer, sizeof (buffer), "rdsvl\t%%x0, #%d", 4032 (int) INTVAL (x) / 16); 4033 return buffer; 4034 } 4035 4036 /* Return true if X is a constant that can be added using ADDSVL or ADDSPL. */ 4037 4038 bool 4039 aarch64_addsvl_addspl_immediate_p (const_rtx x) 4040 { 4041 HOST_WIDE_INT factor; 4042 return (aarch64_sme_vq_unspec_p (x, &factor) 4043 && (aarch64_sve_rdvl_addvl_factor_p (factor) 4044 || aarch64_sve_addpl_factor_p (factor))); 4045 } 4046 4047 /* X is a constant that satisfies aarch64_addsvl_addspl_immediate_p. 4048 Return the asm string for the associated instruction. */ 4049 4050 char * 4051 aarch64_output_addsvl_addspl (rtx x) 4052 { 4053 static char buffer[sizeof ("addspl\t%x0, %x1, #-") + 3 * sizeof (int)]; 4054 HOST_WIDE_INT factor; 4055 if (!aarch64_sme_vq_unspec_p (x, &factor)) 4056 gcc_unreachable (); 4057 if (aarch64_sve_rdvl_addvl_factor_p (factor)) 4058 snprintf (buffer, sizeof (buffer), "addsvl\t%%x0, %%x1, #%d", 4059 (int) factor / 16); 4060 else if (aarch64_sve_addpl_factor_p (factor)) 4061 snprintf (buffer, sizeof (buffer), "addspl\t%%x0, %%x1, #%d", 4062 (int) factor / 2); 4063 else 4064 gcc_unreachable (); 4065 return buffer; 4066 } 4067 4068 /* Multipliers for repeating bitmasks of width 32, 16, 8, 4, and 2. */ 4069 4070 static const unsigned HOST_WIDE_INT bitmask_imm_mul[] = 4071 { 4072 0x0000000100000001ull, 4073 0x0001000100010001ull, 4074 0x0101010101010101ull, 4075 0x1111111111111111ull, 4076 0x5555555555555555ull, 4077 }; 4078 4079 4080 4081 /* Return true if 64-bit VAL is a valid bitmask immediate. */ 4082 static bool 4083 aarch64_bitmask_imm (unsigned HOST_WIDE_INT val) 4084 { 4085 unsigned HOST_WIDE_INT tmp, mask, first_one, next_one; 4086 int bits; 4087 4088 /* Check for a single sequence of one bits and return quickly if so. 4089 The special cases of all ones and all zeroes returns false. */ 4090 tmp = val + (val & -val); 4091 4092 if (tmp == (tmp & -tmp)) 4093 return (val + 1) > 1; 4094 4095 /* Invert if the immediate doesn't start with a zero bit - this means we 4096 only need to search for sequences of one bits. */ 4097 if (val & 1) 4098 val = ~val; 4099 4100 /* Find the first set bit and set tmp to val with the first sequence of one 4101 bits removed. Return success if there is a single sequence of ones. */ 4102 first_one = val & -val; 4103 tmp = val & (val + first_one); 4104 4105 if (tmp == 0) 4106 return true; 4107 4108 /* Find the next set bit and compute the difference in bit position. */ 4109 next_one = tmp & -tmp; 4110 bits = clz_hwi (first_one) - clz_hwi (next_one); 4111 mask = val ^ tmp; 4112 4113 /* Check the bit position difference is a power of 2, and that the first 4114 sequence of one bits fits within 'bits' bits. */ 4115 if ((mask >> bits) != 0 || bits != (bits & -bits)) 4116 return false; 4117 4118 /* Check the sequence of one bits is repeated 64/bits times. */ 4119 return val == mask * bitmask_imm_mul[__builtin_clz (bits) - 26]; 4120 } 4121 4122 4123 /* Return true if VAL is a valid bitmask immediate for MODE. */ 4124 bool 4125 aarch64_bitmask_imm (unsigned HOST_WIDE_INT val, machine_mode mode) 4126 { 4127 if (mode == DImode) 4128 return aarch64_bitmask_imm (val); 4129 4130 if (mode == SImode) 4131 return aarch64_bitmask_imm ((val & 0xffffffff) | (val << 32)); 4132 4133 /* Replicate small immediates to fit 64 bits. */ 4134 int size = GET_MODE_UNIT_PRECISION (mode); 4135 val &= (HOST_WIDE_INT_1U << size) - 1; 4136 val *= bitmask_imm_mul[__builtin_clz (size) - 26]; 4137 4138 return aarch64_bitmask_imm (val); 4139 } 4140 4141 4142 /* Return true if the immediate VAL can be a bitfield immediate 4143 by changing the given MASK bits in VAL to zeroes, ones or bits 4144 from the other half of VAL. Return the new immediate in VAL2. */ 4145 static inline bool 4146 aarch64_check_bitmask (unsigned HOST_WIDE_INT val, 4147 unsigned HOST_WIDE_INT &val2, 4148 unsigned HOST_WIDE_INT mask) 4149 { 4150 val2 = val & ~mask; 4151 if (val2 != val && aarch64_bitmask_imm (val2)) 4152 return true; 4153 val2 = val | mask; 4154 if (val2 != val && aarch64_bitmask_imm (val2)) 4155 return true; 4156 val = val & ~mask; 4157 val2 = val | (((val >> 32) | (val << 32)) & mask); 4158 if (val2 != val && aarch64_bitmask_imm (val2)) 4159 return true; 4160 val2 = val | (((val >> 16) | (val << 48)) & mask); 4161 if (val2 != val && aarch64_bitmask_imm (val2)) 4162 return true; 4163 return false; 4164 } 4165 4166 4167 /* Return true if VAL is a valid MOVZ immediate. */ 4168 static inline bool 4169 aarch64_is_movz (unsigned HOST_WIDE_INT val) 4170 { 4171 return (val >> (ctz_hwi (val) & 48)) < 65536; 4172 } 4173 4174 4175 /* Return true if immediate VAL can be created by a 64-bit MOVI/MOVN/MOVZ. */ 4176 bool 4177 aarch64_is_mov_xn_imm (unsigned HOST_WIDE_INT val) 4178 { 4179 return aarch64_is_movz (val) || aarch64_is_movz (~val) 4180 || aarch64_bitmask_imm (val); 4181 } 4182 4183 4184 /* Return true if VAL is an immediate that can be created by a single 4185 MOV instruction. */ 4186 bool 4187 aarch64_move_imm (unsigned HOST_WIDE_INT val, machine_mode mode) 4188 { 4189 gcc_assert (mode == SImode || mode == DImode); 4190 4191 if (val < 65536) 4192 return true; 4193 4194 unsigned HOST_WIDE_INT mask = 4195 (val >> 32) == 0 || mode == SImode ? 0xffffffff : HOST_WIDE_INT_M1U; 4196 4197 if (aarch64_is_movz (val & mask) || aarch64_is_movz (~val & mask)) 4198 return true; 4199 4200 val = (val & mask) | ((val << 32) & ~mask); 4201 return aarch64_bitmask_imm (val); 4202 } 4203 4204 4205 static int 4206 aarch64_internal_mov_immediate (rtx dest, rtx imm, bool generate, 4207 machine_mode mode) 4208 { 4209 int i; 4210 unsigned HOST_WIDE_INT val, val2, val3, mask; 4211 int one_match, zero_match; 4212 int num_insns; 4213 4214 gcc_assert (mode == SImode || mode == DImode); 4215 4216 val = INTVAL (imm); 4217 4218 if (aarch64_move_imm (val, mode)) 4219 { 4220 if (generate) 4221 emit_insn (gen_rtx_SET (dest, imm)); 4222 return 1; 4223 } 4224 4225 if ((val >> 32) == 0 || mode == SImode) 4226 { 4227 if (generate) 4228 { 4229 emit_insn (gen_rtx_SET (dest, GEN_INT (val & 0xffff))); 4230 if (mode == SImode) 4231 emit_insn (gen_insv_immsi (dest, GEN_INT (16), 4232 GEN_INT ((val >> 16) & 0xffff))); 4233 else 4234 emit_insn (gen_insv_immdi (dest, GEN_INT (16), 4235 GEN_INT ((val >> 16) & 0xffff))); 4236 } 4237 return 2; 4238 } 4239 4240 /* Remaining cases are all for DImode. */ 4241 4242 mask = 0xffff; 4243 zero_match = ((val & mask) == 0) + ((val & (mask << 16)) == 0) + 4244 ((val & (mask << 32)) == 0) + ((val & (mask << 48)) == 0); 4245 one_match = ((~val & mask) == 0) + ((~val & (mask << 16)) == 0) + 4246 ((~val & (mask << 32)) == 0) + ((~val & (mask << 48)) == 0); 4247 4248 /* Try a bitmask immediate and a movk to generate the immediate 4249 in 2 instructions. */ 4250 4251 if (zero_match < 2 && one_match < 2) 4252 { 4253 for (i = 0; i < 64; i += 16) 4254 { 4255 if (aarch64_check_bitmask (val, val2, mask << i)) 4256 break; 4257 4258 val2 = val & ~(mask << i); 4259 if ((val2 >> 32) == 0 && aarch64_move_imm (val2, DImode)) 4260 break; 4261 } 4262 4263 if (i != 64) 4264 { 4265 if (generate) 4266 { 4267 emit_insn (gen_rtx_SET (dest, GEN_INT (val2))); 4268 emit_insn (gen_insv_immdi (dest, GEN_INT (i), 4269 GEN_INT ((val >> i) & 0xffff))); 4270 } 4271 return 2; 4272 } 4273 4274 /* Try 2 bitmask immediates which are xor'd together. */ 4275 for (i = 0; i < 64; i += 16) 4276 { 4277 val2 = (val >> i) & mask; 4278 val2 |= val2 << 16; 4279 val2 |= val2 << 32; 4280 if (aarch64_bitmask_imm (val2) && aarch64_bitmask_imm (val ^ val2)) 4281 break; 4282 } 4283 4284 if (i != 64) 4285 { 4286 if (generate) 4287 { 4288 emit_insn (gen_rtx_SET (dest, GEN_INT (val2))); 4289 emit_insn (gen_xordi3 (dest, dest, GEN_INT (val ^ val2))); 4290 } 4291 return 2; 4292 } 4293 } 4294 4295 /* Try a bitmask plus 2 movk to generate the immediate in 3 instructions. */ 4296 if (zero_match + one_match == 0) 4297 { 4298 for (i = 0; i < 48; i += 16) 4299 for (int j = i + 16; j < 64; j += 16) 4300 if (aarch64_check_bitmask (val, val2, (mask << i) | (mask << j))) 4301 { 4302 if (generate) 4303 { 4304 emit_insn (gen_rtx_SET (dest, GEN_INT (val2))); 4305 emit_insn (gen_insv_immdi (dest, GEN_INT (i), 4306 GEN_INT ((val >> i) & 0xffff))); 4307 emit_insn (gen_insv_immdi (dest, GEN_INT (j), 4308 GEN_INT ((val >> j) & 0xffff))); 4309 } 4310 return 3; 4311 } 4312 4313 /* Try shifting and inserting the bottom 32-bits into the top bits. */ 4314 val2 = val & 0xffffffff; 4315 val3 = 0xffffffff; 4316 val3 = val2 | (val3 << 32); 4317 for (i = 17; i < 48; i++) 4318 if ((val2 | (val2 << i)) == val) 4319 { 4320 if (generate) 4321 { 4322 emit_insn (gen_rtx_SET (dest, GEN_INT (val2 & 0xffff))); 4323 emit_insn (gen_insv_immdi (dest, GEN_INT (16), 4324 GEN_INT (val2 >> 16))); 4325 emit_insn (gen_ior_ashldi3 (dest, dest, GEN_INT (i), dest)); 4326 } 4327 return 3; 4328 } 4329 else if ((val3 & ~(val3 << i)) == val) 4330 { 4331 if (generate) 4332 { 4333 emit_insn (gen_rtx_SET (dest, GEN_INT (val3 | 0xffff0000))); 4334 emit_insn (gen_insv_immdi (dest, GEN_INT (16), 4335 GEN_INT (val2 >> 16))); 4336 emit_insn (gen_and_one_cmpl_ashldi3 (dest, dest, GEN_INT (i), 4337 dest)); 4338 } 4339 return 3; 4340 } 4341 } 4342 4343 /* Generate 2-4 instructions, skipping 16 bits of all zeroes or ones which 4344 are emitted by the initial mov. If one_match > zero_match, skip set bits, 4345 otherwise skip zero bits. */ 4346 4347 num_insns = 1; 4348 mask = 0xffff; 4349 val2 = one_match > zero_match ? ~val : val; 4350 i = (val2 & mask) != 0 ? 0 : (val2 & (mask << 16)) != 0 ? 16 : 32; 4351 4352 if (generate) 4353 emit_insn (gen_rtx_SET (dest, GEN_INT (one_match > zero_match 4354 ? (val | ~(mask << i)) 4355 : (val & (mask << i))))); 4356 for (i += 16; i < 64; i += 16) 4357 { 4358 if ((val2 & (mask << i)) == 0) 4359 continue; 4360 if (generate) 4361 emit_insn (gen_insv_immdi (dest, GEN_INT (i), 4362 GEN_INT ((val >> i) & 0xffff))); 4363 num_insns ++; 4364 } 4365 4366 return num_insns; 4367 } 4368 4369 /* Return whether imm is a 128-bit immediate which is simple enough to 4370 expand inline. */ 4371 bool 4372 aarch64_mov128_immediate (rtx imm) 4373 { 4374 if (CONST_INT_P (imm)) 4375 return true; 4376 4377 gcc_assert (CONST_WIDE_INT_NUNITS (imm) == 2); 4378 4379 rtx lo = GEN_INT (CONST_WIDE_INT_ELT (imm, 0)); 4380 rtx hi = GEN_INT (CONST_WIDE_INT_ELT (imm, 1)); 4381 4382 return aarch64_internal_mov_immediate (NULL_RTX, lo, false, DImode) 4383 + aarch64_internal_mov_immediate (NULL_RTX, hi, false, DImode) <= 4; 4384 } 4385 4386 4387 /* Return true if val can be encoded as a 12-bit unsigned immediate with 4388 a left shift of 0 or 12 bits. */ 4389 bool 4390 aarch64_uimm12_shift (unsigned HOST_WIDE_INT val) 4391 { 4392 return val < 4096 || (val & 0xfff000) == val; 4393 } 4394 4395 /* Returns the nearest value to VAL that will fit as a 12-bit unsigned immediate 4396 that can be created with a left shift of 0 or 12. */ 4397 static HOST_WIDE_INT 4398 aarch64_clamp_to_uimm12_shift (unsigned HOST_WIDE_INT val) 4399 { 4400 /* Check to see if the value fits in 24 bits, as that is the maximum we can 4401 handle correctly. */ 4402 gcc_assert (val < 0x1000000); 4403 4404 if (val < 4096) 4405 return val; 4406 4407 return val & 0xfff000; 4408 } 4409 4410 4411 /* Test whether: 4412 4413 X = (X & AND_VAL) | IOR_VAL; 4414 4415 can be implemented using: 4416 4417 MOVK X, #(IOR_VAL >> shift), LSL #shift 4418 4419 Return the shift if so, otherwise return -1. */ 4420 int 4421 aarch64_movk_shift (const wide_int_ref &and_val, 4422 const wide_int_ref &ior_val) 4423 { 4424 unsigned int precision = and_val.get_precision (); 4425 unsigned HOST_WIDE_INT mask = 0xffff; 4426 for (unsigned int shift = 0; shift < precision; shift += 16) 4427 { 4428 if (and_val == ~mask && (ior_val & mask) == ior_val) 4429 return shift; 4430 mask <<= 16; 4431 } 4432 return -1; 4433 } 4434 4435 /* Create mask of ones, covering the lowest to highest bits set in VAL_IN. 4436 Assumed precondition: VAL_IN Is not zero. */ 4437 4438 unsigned HOST_WIDE_INT 4439 aarch64_and_split_imm1 (HOST_WIDE_INT val_in) 4440 { 4441 int lowest_bit_set = ctz_hwi (val_in); 4442 int highest_bit_set = floor_log2 (val_in); 4443 gcc_assert (val_in != 0); 4444 4445 return ((HOST_WIDE_INT_UC (2) << highest_bit_set) - 4446 (HOST_WIDE_INT_1U << lowest_bit_set)); 4447 } 4448 4449 /* Create constant where bits outside of lowest bit set to highest bit set 4450 are set to 1. */ 4451 4452 unsigned HOST_WIDE_INT 4453 aarch64_and_split_imm2 (HOST_WIDE_INT val_in) 4454 { 4455 return val_in | ~aarch64_and_split_imm1 (val_in); 4456 } 4457 4458 /* Return true if VAL_IN is a valid 'and' bitmask immediate. */ 4459 4460 bool 4461 aarch64_and_bitmask_imm (unsigned HOST_WIDE_INT val_in, machine_mode mode) 4462 { 4463 scalar_int_mode int_mode; 4464 if (!is_a <scalar_int_mode> (mode, &int_mode)) 4465 return false; 4466 4467 if (aarch64_bitmask_imm (val_in, int_mode)) 4468 return false; 4469 4470 if (aarch64_move_imm (val_in, int_mode)) 4471 return false; 4472 4473 unsigned HOST_WIDE_INT imm2 = aarch64_and_split_imm2 (val_in); 4474 4475 return aarch64_bitmask_imm (imm2, int_mode); 4476 } 4477 4478 /* Return the number of temporary registers that aarch64_add_offset_1 4479 would need to add OFFSET to a register. */ 4480 4481 static unsigned int 4482 aarch64_add_offset_1_temporaries (HOST_WIDE_INT offset) 4483 { 4484 return absu_hwi (offset) < 0x1000000 ? 0 : 1; 4485 } 4486 4487 /* A subroutine of aarch64_add_offset. Set DEST to SRC + OFFSET for 4488 a non-polynomial OFFSET. MODE is the mode of the addition. 4489 FRAME_RELATED_P is true if the RTX_FRAME_RELATED flag should 4490 be set and CFA adjustments added to the generated instructions. 4491 4492 TEMP1, if nonnull, is a register of mode MODE that can be used as a 4493 temporary if register allocation is already complete. This temporary 4494 register may overlap DEST but must not overlap SRC. If TEMP1 is known 4495 to hold abs (OFFSET), EMIT_MOVE_IMM can be set to false to avoid emitting 4496 the immediate again. 4497 4498 Since this function may be used to adjust the stack pointer, we must 4499 ensure that it cannot cause transient stack deallocation (for example 4500 by first incrementing SP and then decrementing when adjusting by a 4501 large immediate). */ 4502 4503 static void 4504 aarch64_add_offset_1 (scalar_int_mode mode, rtx dest, 4505 rtx src, HOST_WIDE_INT offset, rtx temp1, 4506 bool frame_related_p, bool emit_move_imm) 4507 { 4508 gcc_assert (emit_move_imm || temp1 != NULL_RTX); 4509 gcc_assert (temp1 == NULL_RTX || !reg_overlap_mentioned_p (temp1, src)); 4510 4511 unsigned HOST_WIDE_INT moffset = absu_hwi (offset); 4512 rtx_insn *insn; 4513 4514 if (!moffset) 4515 { 4516 if (!rtx_equal_p (dest, src)) 4517 { 4518 insn = emit_insn (gen_rtx_SET (dest, src)); 4519 RTX_FRAME_RELATED_P (insn) = frame_related_p; 4520 } 4521 return; 4522 } 4523 4524 /* Single instruction adjustment. */ 4525 if (aarch64_uimm12_shift (moffset)) 4526 { 4527 insn = emit_insn (gen_add3_insn (dest, src, GEN_INT (offset))); 4528 RTX_FRAME_RELATED_P (insn) = frame_related_p; 4529 return; 4530 } 4531 4532 /* Emit 2 additions/subtractions if the adjustment is less than 24 bits 4533 and either: 4534 4535 a) the offset cannot be loaded by a 16-bit move or 4536 b) there is no spare register into which we can move it. */ 4537 if (moffset < 0x1000000 4538 && ((!temp1 && !can_create_pseudo_p ()) 4539 || !aarch64_move_imm (moffset, mode))) 4540 { 4541 HOST_WIDE_INT low_off = moffset & 0xfff; 4542 4543 low_off = offset < 0 ? -low_off : low_off; 4544 insn = emit_insn (gen_add3_insn (dest, src, GEN_INT (low_off))); 4545 RTX_FRAME_RELATED_P (insn) = frame_related_p; 4546 insn = emit_insn (gen_add2_insn (dest, GEN_INT (offset - low_off))); 4547 RTX_FRAME_RELATED_P (insn) = frame_related_p; 4548 return; 4549 } 4550 4551 /* Emit a move immediate if required and an addition/subtraction. */ 4552 if (emit_move_imm) 4553 { 4554 gcc_assert (temp1 != NULL_RTX || can_create_pseudo_p ()); 4555 temp1 = aarch64_force_temporary (mode, temp1, 4556 gen_int_mode (moffset, mode)); 4557 } 4558 insn = emit_insn (offset < 0 4559 ? gen_sub3_insn (dest, src, temp1) 4560 : gen_add3_insn (dest, src, temp1)); 4561 if (frame_related_p) 4562 { 4563 RTX_FRAME_RELATED_P (insn) = frame_related_p; 4564 rtx adj = plus_constant (mode, src, offset); 4565 add_reg_note (insn, REG_CFA_ADJUST_CFA, gen_rtx_SET (dest, adj)); 4566 } 4567 } 4568 4569 /* Return the number of temporary registers that aarch64_add_offset 4570 would need to move OFFSET into a register or add OFFSET to a register; 4571 ADD_P is true if we want the latter rather than the former. */ 4572 4573 static unsigned int 4574 aarch64_offset_temporaries (bool add_p, poly_int64 offset) 4575 { 4576 /* This follows the same structure as aarch64_add_offset. */ 4577 if (add_p && aarch64_sve_addvl_addpl_immediate_p (offset)) 4578 return 0; 4579 4580 unsigned int count = 0; 4581 HOST_WIDE_INT factor = offset.coeffs[1]; 4582 HOST_WIDE_INT constant = offset.coeffs[0] - factor; 4583 poly_int64 poly_offset (factor, factor); 4584 if (add_p && aarch64_sve_addvl_addpl_immediate_p (poly_offset)) 4585 /* Need one register for the ADDVL/ADDPL result. */ 4586 count += 1; 4587 else if (factor != 0) 4588 { 4589 factor /= (HOST_WIDE_INT) least_bit_hwi (factor); 4590 if (!IN_RANGE (factor, -32, 31)) 4591 /* Need one register for the CNT or RDVL result and one for the 4592 multiplication factor. If necessary, the second temporary 4593 can be reused for the constant part of the offset. */ 4594 return 2; 4595 /* Need one register for the CNT or RDVL result (which might then 4596 be shifted). */ 4597 count += 1; 4598 } 4599 return count + aarch64_add_offset_1_temporaries (constant); 4600 } 4601 4602 /* If X can be represented as a poly_int64, return the number 4603 of temporaries that are required to add it to a register. 4604 Return -1 otherwise. */ 4605 4606 int 4607 aarch64_add_offset_temporaries (rtx x) 4608 { 4609 poly_int64 offset; 4610 if (!poly_int_rtx_p (x, &offset)) 4611 return -1; 4612 return aarch64_offset_temporaries (true, offset); 4613 } 4614 4615 /* Set DEST to SRC + OFFSET. MODE is the mode of the addition. 4616 FRAME_RELATED_P is true if the RTX_FRAME_RELATED flag should 4617 be set and CFA adjustments added to the generated instructions. 4618 4619 TEMP1, if nonnull, is a register of mode MODE that can be used as a 4620 temporary if register allocation is already complete. This temporary 4621 register may overlap DEST if !FRAME_RELATED_P but must not overlap SRC. 4622 If TEMP1 is known to hold abs (OFFSET), EMIT_MOVE_IMM can be set to 4623 false to avoid emitting the immediate again. 4624 4625 TEMP2, if nonnull, is a second temporary register that doesn't 4626 overlap either DEST or REG. 4627 4628 FORCE_ISA_MODE is AARCH64_FL_SM_ON if any variable component of OFFSET 4629 is measured relative to the SME vector length instead of the current 4630 prevailing vector length. It is 0 otherwise. 4631 4632 Since this function may be used to adjust the stack pointer, we must 4633 ensure that it cannot cause transient stack deallocation (for example 4634 by first incrementing SP and then decrementing when adjusting by a 4635 large immediate). */ 4636 4637 static void 4638 aarch64_add_offset (scalar_int_mode mode, rtx dest, rtx src, 4639 poly_int64 offset, rtx temp1, rtx temp2, 4640 aarch64_feature_flags force_isa_mode, 4641 bool frame_related_p, bool emit_move_imm = true) 4642 { 4643 gcc_assert (emit_move_imm || temp1 != NULL_RTX); 4644 gcc_assert (temp1 == NULL_RTX || !reg_overlap_mentioned_p (temp1, src)); 4645 gcc_assert (temp1 == NULL_RTX 4646 || !frame_related_p 4647 || !reg_overlap_mentioned_p (temp1, dest)); 4648 gcc_assert (temp2 == NULL_RTX || !reg_overlap_mentioned_p (dest, temp2)); 4649 4650 /* Try using ADDVL or ADDPL to add the whole value. */ 4651 if (src != const0_rtx && aarch64_sve_addvl_addpl_immediate_p (offset)) 4652 { 4653 gcc_assert (offset.coeffs[0] == offset.coeffs[1]); 4654 rtx offset_rtx; 4655 if (force_isa_mode == 0) 4656 offset_rtx = gen_int_mode (offset, mode); 4657 else 4658 offset_rtx = aarch64_sme_vq_immediate (mode, offset.coeffs[0], 0); 4659 rtx_insn *insn = emit_insn (gen_add3_insn (dest, src, offset_rtx)); 4660 RTX_FRAME_RELATED_P (insn) = frame_related_p; 4661 if (frame_related_p && (force_isa_mode & AARCH64_FL_SM_ON)) 4662 add_reg_note (insn, REG_CFA_ADJUST_CFA, 4663 gen_rtx_SET (dest, plus_constant (Pmode, src, 4664 offset))); 4665 return; 4666 } 4667 4668 /* Coefficient 1 is multiplied by the number of 128-bit blocks in an 4669 SVE vector register, over and above the minimum size of 128 bits. 4670 This is equivalent to half the value returned by CNTD with a 4671 vector shape of ALL. */ 4672 HOST_WIDE_INT factor = offset.coeffs[1]; 4673 HOST_WIDE_INT constant = offset.coeffs[0] - factor; 4674 4675 /* Try using ADDVL or ADDPL to add the VG-based part. */ 4676 poly_int64 poly_offset (factor, factor); 4677 if (src != const0_rtx 4678 && aarch64_sve_addvl_addpl_immediate_p (poly_offset)) 4679 { 4680 rtx offset_rtx; 4681 if (force_isa_mode == 0) 4682 offset_rtx = gen_int_mode (poly_offset, mode); 4683 else 4684 offset_rtx = aarch64_sme_vq_immediate (mode, factor, 0); 4685 if (frame_related_p) 4686 { 4687 rtx_insn *insn = emit_insn (gen_add3_insn (dest, src, offset_rtx)); 4688 RTX_FRAME_RELATED_P (insn) = true; 4689 if (force_isa_mode & AARCH64_FL_SM_ON) 4690 add_reg_note (insn, REG_CFA_ADJUST_CFA, 4691 gen_rtx_SET (dest, plus_constant (Pmode, src, 4692 poly_offset))); 4693 src = dest; 4694 } 4695 else 4696 { 4697 rtx addr = gen_rtx_PLUS (mode, src, offset_rtx); 4698 src = aarch64_force_temporary (mode, temp1, addr); 4699 temp1 = temp2; 4700 temp2 = NULL_RTX; 4701 } 4702 } 4703 /* Otherwise use a CNT-based sequence. */ 4704 else if (factor != 0) 4705 { 4706 /* Calculate CNTB * FACTOR / 16 as CNTB * REL_FACTOR * 2**SHIFT, 4707 with negative shifts indicating a shift right. */ 4708 HOST_WIDE_INT low_bit = least_bit_hwi (factor); 4709 HOST_WIDE_INT rel_factor = factor / low_bit; 4710 int shift = exact_log2 (low_bit) - 4; 4711 gcc_assert (shift >= -4 && (rel_factor & 1) != 0); 4712 4713 /* Set CODE, VAL and SHIFT so that [+-] VAL * 2**SHIFT is 4714 equal to CNTB * FACTOR / 16, with CODE being the [+-]. 4715 4716 We can avoid a multiplication if REL_FACTOR is in the range 4717 of RDVL, although there are then various optimizations that 4718 we can try on top. */ 4719 rtx_code code = PLUS; 4720 rtx val; 4721 if (IN_RANGE (rel_factor, -32, 31)) 4722 { 4723 if (force_isa_mode & AARCH64_FL_SM_ON) 4724 { 4725 /* Try to use an unshifted RDSVL, otherwise fall back on 4726 a shifted RDSVL #1. */ 4727 if (aarch64_sve_rdvl_addvl_factor_p (factor)) 4728 shift = 0; 4729 else 4730 factor = rel_factor * 16; 4731 val = aarch64_sme_vq_immediate (mode, factor, 0); 4732 } 4733 /* Try to use an unshifted CNT[BHWD] or RDVL. */ 4734 else if (aarch64_sve_cnt_factor_p (factor) 4735 || aarch64_sve_rdvl_addvl_factor_p (factor)) 4736 { 4737 val = gen_int_mode (poly_int64 (factor, factor), mode); 4738 shift = 0; 4739 } 4740 /* Try to subtract an unshifted CNT[BHWD]. */ 4741 else if (aarch64_sve_cnt_factor_p (-factor)) 4742 { 4743 code = MINUS; 4744 val = gen_int_mode (poly_int64 (-factor, -factor), mode); 4745 shift = 0; 4746 } 4747 /* If subtraction is free, prefer to load a positive constant. 4748 In the best case this will fit a shifted CNTB. */ 4749 else if (src != const0_rtx && rel_factor < 0) 4750 { 4751 code = MINUS; 4752 val = gen_int_mode (-rel_factor * BYTES_PER_SVE_VECTOR, mode); 4753 } 4754 /* Otherwise use a shifted RDVL or CNT[BHWD]. */ 4755 else 4756 val = gen_int_mode (rel_factor * BYTES_PER_SVE_VECTOR, mode); 4757 } 4758 else 4759 { 4760 /* If we can calculate CNTB << SHIFT directly, prefer to do that, 4761 since it should increase the chances of being able to use 4762 a shift and add sequence for the multiplication. 4763 If CNTB << SHIFT is out of range, stick with the current 4764 shift factor. */ 4765 if (force_isa_mode == 0 4766 && IN_RANGE (low_bit, 2, 16 * 16)) 4767 { 4768 val = gen_int_mode (poly_int64 (low_bit, low_bit), mode); 4769 shift = 0; 4770 } 4771 else if ((force_isa_mode & AARCH64_FL_SM_ON) 4772 && aarch64_sve_rdvl_addvl_factor_p (low_bit)) 4773 { 4774 val = aarch64_sme_vq_immediate (mode, low_bit, 0); 4775 shift = 0; 4776 } 4777 else 4778 val = gen_int_mode (BYTES_PER_SVE_VECTOR, mode); 4779 4780 val = aarch64_force_temporary (mode, temp1, val); 4781 4782 /* Prefer to multiply by a positive factor and subtract rather 4783 than multiply by a negative factor and add, since positive 4784 values are usually easier to move. */ 4785 if (rel_factor < 0 && src != const0_rtx) 4786 { 4787 rel_factor = -rel_factor; 4788 code = MINUS; 4789 } 4790 4791 if (can_create_pseudo_p ()) 4792 { 4793 rtx coeff1 = gen_int_mode (rel_factor, mode); 4794 val = expand_mult (mode, val, coeff1, NULL_RTX, true, true); 4795 } 4796 else 4797 { 4798 rtx coeff1 = gen_int_mode (rel_factor, mode); 4799 coeff1 = aarch64_force_temporary (mode, temp2, coeff1); 4800 val = gen_rtx_MULT (mode, val, coeff1); 4801 } 4802 } 4803 4804 /* Multiply by 2 ** SHIFT. */ 4805 if (shift > 0) 4806 { 4807 val = aarch64_force_temporary (mode, temp1, val); 4808 val = gen_rtx_ASHIFT (mode, val, GEN_INT (shift)); 4809 } 4810 else if (shift < 0) 4811 { 4812 val = aarch64_force_temporary (mode, temp1, val); 4813 val = gen_rtx_ASHIFTRT (mode, val, GEN_INT (-shift)); 4814 } 4815 4816 /* Add the result to SRC or subtract the result from SRC. */ 4817 if (src != const0_rtx) 4818 { 4819 val = aarch64_force_temporary (mode, temp1, val); 4820 val = gen_rtx_fmt_ee (code, mode, src, val); 4821 } 4822 else if (code == MINUS) 4823 { 4824 val = aarch64_force_temporary (mode, temp1, val); 4825 val = gen_rtx_NEG (mode, val); 4826 } 4827 4828 if (constant == 0 || frame_related_p) 4829 { 4830 rtx_insn *insn = emit_insn (gen_rtx_SET (dest, val)); 4831 if (frame_related_p) 4832 { 4833 RTX_FRAME_RELATED_P (insn) = true; 4834 add_reg_note (insn, REG_CFA_ADJUST_CFA, 4835 gen_rtx_SET (dest, plus_constant (Pmode, src, 4836 poly_offset))); 4837 } 4838 src = dest; 4839 if (constant == 0) 4840 return; 4841 } 4842 else 4843 { 4844 src = aarch64_force_temporary (mode, temp1, val); 4845 temp1 = temp2; 4846 temp2 = NULL_RTX; 4847 } 4848 4849 emit_move_imm = true; 4850 } 4851 4852 aarch64_add_offset_1 (mode, dest, src, constant, temp1, 4853 frame_related_p, emit_move_imm); 4854 } 4855 4856 /* Like aarch64_add_offset, but the offset is given as an rtx rather 4857 than a poly_int64. */ 4858 4859 void 4860 aarch64_split_add_offset (scalar_int_mode mode, rtx dest, rtx src, 4861 rtx offset_rtx, rtx temp1, rtx temp2) 4862 { 4863 aarch64_add_offset (mode, dest, src, rtx_to_poly_int64 (offset_rtx), 4864 temp1, temp2, 0, false); 4865 } 4866 4867 /* Add DELTA to the stack pointer, marking the instructions frame-related. 4868 TEMP1 is available as a temporary if nonnull. FORCE_ISA_MODE is as 4869 for aarch64_add_offset. EMIT_MOVE_IMM is false if TEMP1 already 4870 contains abs (DELTA). */ 4871 4872 static inline void 4873 aarch64_add_sp (rtx temp1, rtx temp2, poly_int64 delta, 4874 aarch64_feature_flags force_isa_mode, bool emit_move_imm) 4875 { 4876 aarch64_add_offset (Pmode, stack_pointer_rtx, stack_pointer_rtx, delta, 4877 temp1, temp2, force_isa_mode, true, emit_move_imm); 4878 } 4879 4880 /* Subtract DELTA from the stack pointer, marking the instructions 4881 frame-related if FRAME_RELATED_P. FORCE_ISA_MODE is as for 4882 aarch64_add_offset. TEMP1 is available as a temporary if nonnull. */ 4883 4884 static inline void 4885 aarch64_sub_sp (rtx temp1, rtx temp2, poly_int64 delta, 4886 aarch64_feature_flags force_isa_mode, 4887 bool frame_related_p, bool emit_move_imm = true) 4888 { 4889 aarch64_add_offset (Pmode, stack_pointer_rtx, stack_pointer_rtx, -delta, 4890 temp1, temp2, force_isa_mode, frame_related_p, 4891 emit_move_imm); 4892 } 4893 4894 /* A streaming-compatible function needs to switch temporarily to the known 4895 PSTATE.SM mode described by LOCAL_MODE. The low bit of OLD_SVCR contains 4896 the runtime state of PSTATE.SM in the streaming-compatible code, before 4897 the start of the switch to LOCAL_MODE. 4898 4899 Emit instructions to branch around the mode switch if PSTATE.SM already 4900 matches LOCAL_MODE. Return the label that the branch jumps to. */ 4901 4902 static rtx_insn * 4903 aarch64_guard_switch_pstate_sm (rtx old_svcr, aarch64_feature_flags local_mode) 4904 { 4905 local_mode &= AARCH64_FL_SM_STATE; 4906 gcc_assert (local_mode != 0); 4907 auto already_ok_cond = (local_mode & AARCH64_FL_SM_ON ? NE : EQ); 4908 auto *label = gen_label_rtx (); 4909 auto branch = aarch64_gen_test_and_branch (already_ok_cond, old_svcr, 0, 4910 label); 4911 auto *jump = emit_jump_insn (branch); 4912 JUMP_LABEL (jump) = label; 4913 return label; 4914 } 4915 4916 /* Emit code to switch from the PSTATE.SM state in OLD_MODE to the PSTATE.SM 4917 state in NEW_MODE. This is known to involve either an SMSTART SM or 4918 an SMSTOP SM. */ 4919 4920 static void 4921 aarch64_switch_pstate_sm (aarch64_feature_flags old_mode, 4922 aarch64_feature_flags new_mode) 4923 { 4924 old_mode &= AARCH64_FL_SM_STATE; 4925 new_mode &= AARCH64_FL_SM_STATE; 4926 gcc_assert (old_mode != new_mode); 4927 4928 if ((new_mode & AARCH64_FL_SM_ON) 4929 || (new_mode == 0 && (old_mode & AARCH64_FL_SM_OFF))) 4930 emit_insn (gen_aarch64_smstart_sm ()); 4931 else 4932 emit_insn (gen_aarch64_smstop_sm ()); 4933 } 4934 4935 /* As a side-effect, SMSTART SM and SMSTOP SM clobber the contents of all 4936 FP and predicate registers. This class emits code to preserve any 4937 necessary registers around the mode switch. 4938 4939 The class uses four approaches to saving and restoring contents, enumerated 4940 by group_type: 4941 4942 - GPR: save and restore the contents of FP registers using GPRs. 4943 This is used if the FP register contains no more than 64 significant 4944 bits. The registers used are FIRST_GPR onwards. 4945 4946 - MEM_128: save and restore 128-bit SIMD registers using memory. 4947 4948 - MEM_SVE_PRED: save and restore full SVE predicate registers using memory. 4949 4950 - MEM_SVE_DATA: save and restore full SVE vector registers using memory. 4951 4952 The save slots within each memory group are consecutive, with the 4953 MEM_SVE_PRED slots occupying a region below the MEM_SVE_DATA slots. 4954 4955 There will only be two mode switches for each use of SME, so they should 4956 not be particularly performance-sensitive. It's also rare for SIMD, SVE 4957 or predicate registers to be live across mode switches. We therefore 4958 don't preallocate the save slots but instead allocate them locally on 4959 demand. This makes the code emitted by the class self-contained. */ 4960 4961 class aarch64_sme_mode_switch_regs 4962 { 4963 public: 4964 static const unsigned int FIRST_GPR = R10_REGNUM; 4965 4966 void add_reg (machine_mode, unsigned int); 4967 void add_call_args (rtx_call_insn *); 4968 void add_call_result (rtx_call_insn *); 4969 void add_call_preserved_reg (unsigned int); 4970 void add_call_preserved_regs (bitmap); 4971 4972 void emit_prologue (); 4973 void emit_epilogue (); 4974 4975 /* The number of GPRs needed to save FP registers, starting from 4976 FIRST_GPR. */ 4977 unsigned int num_gprs () { return m_group_count[GPR]; } 4978 4979 private: 4980 enum sequence { PROLOGUE, EPILOGUE }; 4981 enum group_type { GPR, MEM_128, MEM_SVE_PRED, MEM_SVE_DATA, NUM_GROUPS }; 4982 4983 /* Information about the save location for one FP, SIMD, SVE data, or 4984 SVE predicate register. */ 4985 struct save_location { 4986 /* The register to be saved. */ 4987 rtx reg; 4988 4989 /* Which group the save location belongs to. */ 4990 group_type group; 4991 4992 /* A zero-based index of the register within the group. */ 4993 unsigned int index; 4994 }; 4995 4996 unsigned int sve_data_headroom (); 4997 rtx get_slot_mem (machine_mode, poly_int64); 4998 void emit_stack_adjust (sequence, poly_int64); 4999 void emit_mem_move (sequence, const save_location &, poly_int64); 5000 5001 void emit_gpr_moves (sequence); 5002 void emit_mem_128_moves (sequence); 5003 void emit_sve_sp_adjust (sequence); 5004 void emit_sve_pred_moves (sequence); 5005 void emit_sve_data_moves (sequence); 5006 5007 /* All save locations, in no particular order. */ 5008 auto_vec<save_location, 12> m_save_locations; 5009 5010 /* The number of registers in each group. */ 5011 unsigned int m_group_count[NUM_GROUPS] = {}; 5012 }; 5013 5014 /* Record that (reg:MODE REGNO) needs to be preserved around the mode 5015 switch. */ 5016 5017 void 5018 aarch64_sme_mode_switch_regs::add_reg (machine_mode mode, unsigned int regno) 5019 { 5020 if (!FP_REGNUM_P (regno) && !PR_REGNUM_P (regno)) 5021 return; 5022 5023 unsigned int end_regno = end_hard_regno (mode, regno); 5024 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 5025 gcc_assert ((vec_flags & VEC_STRUCT) || end_regno == regno + 1); 5026 for (; regno < end_regno; regno++) 5027 { 5028 /* Force the mode of SVE saves and restores even for single registers. 5029 This is necessary because big-endian targets only allow LDR Z and 5030 STR Z to be used with byte modes. */ 5031 machine_mode submode = mode; 5032 if (vec_flags & VEC_SVE_PRED) 5033 submode = VNx16BImode; 5034 else if (vec_flags & VEC_SVE_DATA) 5035 submode = SVE_BYTE_MODE; 5036 else if (vec_flags & VEC_STRUCT) 5037 { 5038 if (vec_flags & VEC_PARTIAL) 5039 submode = V8QImode; 5040 else 5041 submode = V16QImode; 5042 } 5043 save_location loc; 5044 loc.reg = gen_rtx_REG (submode, regno); 5045 if (vec_flags & VEC_SVE_PRED) 5046 { 5047 gcc_assert (PR_REGNUM_P (regno)); 5048 loc.group = MEM_SVE_PRED; 5049 } 5050 else 5051 { 5052 gcc_assert (FP_REGNUM_P (regno)); 5053 if (known_le (GET_MODE_SIZE (submode), 8)) 5054 loc.group = GPR; 5055 else if (known_eq (GET_MODE_SIZE (submode), 16)) 5056 loc.group = MEM_128; 5057 else 5058 loc.group = MEM_SVE_DATA; 5059 } 5060 loc.index = m_group_count[loc.group]++; 5061 m_save_locations.quick_push (loc); 5062 } 5063 } 5064 5065 /* Record that the arguments to CALL_INSN need to be preserved around 5066 the mode switch. */ 5067 5068 void 5069 aarch64_sme_mode_switch_regs::add_call_args (rtx_call_insn *call_insn) 5070 { 5071 for (rtx node = CALL_INSN_FUNCTION_USAGE (call_insn); 5072 node; node = XEXP (node, 1)) 5073 { 5074 rtx item = XEXP (node, 0); 5075 if (GET_CODE (item) != USE) 5076 continue; 5077 item = XEXP (item, 0); 5078 if (!REG_P (item)) 5079 continue; 5080 add_reg (GET_MODE (item), REGNO (item)); 5081 } 5082 } 5083 5084 /* Record that the return value from CALL_INSN (if any) needs to be 5085 preserved around the mode switch. */ 5086 5087 void 5088 aarch64_sme_mode_switch_regs::add_call_result (rtx_call_insn *call_insn) 5089 { 5090 rtx pat = PATTERN (call_insn); 5091 gcc_assert (GET_CODE (pat) == PARALLEL); 5092 pat = XVECEXP (pat, 0, 0); 5093 if (GET_CODE (pat) == CALL) 5094 return; 5095 rtx dest = SET_DEST (pat); 5096 if (GET_CODE (dest) == PARALLEL) 5097 for (int i = 0; i < XVECLEN (dest, 0); ++i) 5098 { 5099 rtx x = XVECEXP (dest, 0, i); 5100 gcc_assert (GET_CODE (x) == EXPR_LIST); 5101 rtx reg = XEXP (x, 0); 5102 add_reg (GET_MODE (reg), REGNO (reg)); 5103 } 5104 else 5105 add_reg (GET_MODE (dest), REGNO (dest)); 5106 } 5107 5108 /* REGNO is a register that is call-preserved under the current function's ABI. 5109 Record that it must be preserved around the mode switch. */ 5110 5111 void 5112 aarch64_sme_mode_switch_regs::add_call_preserved_reg (unsigned int regno) 5113 { 5114 if (FP_REGNUM_P (regno)) 5115 switch (crtl->abi->id ()) 5116 { 5117 case ARM_PCS_SVE: 5118 add_reg (VNx16QImode, regno); 5119 break; 5120 case ARM_PCS_SIMD: 5121 add_reg (V16QImode, regno); 5122 break; 5123 case ARM_PCS_AAPCS64: 5124 add_reg (DImode, regno); 5125 break; 5126 default: 5127 gcc_unreachable (); 5128 } 5129 else if (PR_REGNUM_P (regno)) 5130 add_reg (VNx16BImode, regno); 5131 } 5132 5133 /* The hard registers in REGS are call-preserved under the current function's 5134 ABI. Record that they must be preserved around the mode switch. */ 5135 5136 void 5137 aarch64_sme_mode_switch_regs::add_call_preserved_regs (bitmap regs) 5138 { 5139 bitmap_iterator bi; 5140 unsigned int regno; 5141 EXECUTE_IF_SET_IN_BITMAP (regs, 0, regno, bi) 5142 if (HARD_REGISTER_NUM_P (regno)) 5143 add_call_preserved_reg (regno); 5144 else 5145 break; 5146 } 5147 5148 /* Emit code to save registers before the mode switch. */ 5149 5150 void 5151 aarch64_sme_mode_switch_regs::emit_prologue () 5152 { 5153 emit_sve_sp_adjust (PROLOGUE); 5154 emit_sve_pred_moves (PROLOGUE); 5155 emit_sve_data_moves (PROLOGUE); 5156 emit_mem_128_moves (PROLOGUE); 5157 emit_gpr_moves (PROLOGUE); 5158 } 5159 5160 /* Emit code to restore registers after the mode switch. */ 5161 5162 void 5163 aarch64_sme_mode_switch_regs::emit_epilogue () 5164 { 5165 emit_gpr_moves (EPILOGUE); 5166 emit_mem_128_moves (EPILOGUE); 5167 emit_sve_pred_moves (EPILOGUE); 5168 emit_sve_data_moves (EPILOGUE); 5169 emit_sve_sp_adjust (EPILOGUE); 5170 } 5171 5172 /* The SVE predicate registers are stored below the SVE data registers, 5173 with the predicate save area being padded to a data-register-sized 5174 boundary. Return the size of this padded area as a whole number 5175 of data register slots. */ 5176 5177 unsigned int 5178 aarch64_sme_mode_switch_regs::sve_data_headroom () 5179 { 5180 return CEIL (m_group_count[MEM_SVE_PRED], 8); 5181 } 5182 5183 /* Return a memory reference of mode MODE to OFFSET bytes from the 5184 stack pointer. */ 5185 5186 rtx 5187 aarch64_sme_mode_switch_regs::get_slot_mem (machine_mode mode, 5188 poly_int64 offset) 5189 { 5190 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offset); 5191 return gen_rtx_MEM (mode, addr); 5192 } 5193 5194 /* Allocate or deallocate SIZE bytes of stack space: SEQ decides which. */ 5195 5196 void 5197 aarch64_sme_mode_switch_regs::emit_stack_adjust (sequence seq, 5198 poly_int64 size) 5199 { 5200 if (seq == PROLOGUE) 5201 size = -size; 5202 emit_insn (gen_rtx_SET (stack_pointer_rtx, 5203 plus_constant (Pmode, stack_pointer_rtx, size))); 5204 } 5205 5206 /* Save or restore the register in LOC, whose slot is OFFSET bytes from 5207 the stack pointer. SEQ chooses between saving and restoring. */ 5208 5209 void 5210 aarch64_sme_mode_switch_regs::emit_mem_move (sequence seq, 5211 const save_location &loc, 5212 poly_int64 offset) 5213 { 5214 rtx mem = get_slot_mem (GET_MODE (loc.reg), offset); 5215 if (seq == PROLOGUE) 5216 emit_move_insn (mem, loc.reg); 5217 else 5218 emit_move_insn (loc.reg, mem); 5219 } 5220 5221 /* Emit instructions to save or restore the GPR group. SEQ chooses between 5222 saving and restoring. */ 5223 5224 void 5225 aarch64_sme_mode_switch_regs::emit_gpr_moves (sequence seq) 5226 { 5227 for (auto &loc : m_save_locations) 5228 if (loc.group == GPR) 5229 { 5230 gcc_assert (loc.index < 8); 5231 rtx gpr = gen_rtx_REG (GET_MODE (loc.reg), FIRST_GPR + loc.index); 5232 if (seq == PROLOGUE) 5233 emit_move_insn (gpr, loc.reg); 5234 else 5235 emit_move_insn (loc.reg, gpr); 5236 } 5237 } 5238 5239 /* Emit instructions to save or restore the MEM_128 group. SEQ chooses 5240 between saving and restoring. */ 5241 5242 void 5243 aarch64_sme_mode_switch_regs::emit_mem_128_moves (sequence seq) 5244 { 5245 HOST_WIDE_INT count = m_group_count[MEM_128]; 5246 if (count == 0) 5247 return; 5248 5249 auto sp = stack_pointer_rtx; 5250 auto sp_adjust = (seq == PROLOGUE ? -count : count) * 16; 5251 5252 /* Pick a common mode that supports LDR & STR with pre/post-modification 5253 and LDP & STP with pre/post-modification. */ 5254 auto mode = TFmode; 5255 5256 /* An instruction pattern that should be emitted at the end. */ 5257 rtx last_pat = NULL_RTX; 5258 5259 /* A previous MEM_128 location that hasn't been handled yet. */ 5260 save_location *prev_loc = nullptr; 5261 5262 /* Look for LDP/STPs and record any leftover LDR/STR in PREV_LOC. */ 5263 for (auto &loc : m_save_locations) 5264 if (loc.group == MEM_128) 5265 { 5266 if (!prev_loc) 5267 { 5268 prev_loc = &loc; 5269 continue; 5270 } 5271 gcc_assert (loc.index == prev_loc->index + 1); 5272 5273 /* The offset of the base of the save area from the current 5274 stack pointer. */ 5275 HOST_WIDE_INT bias = 0; 5276 if (prev_loc->index == 0 && seq == PROLOGUE) 5277 bias = sp_adjust; 5278 5279 /* Get the two sets in the LDP/STP. */ 5280 rtx ops[] = { 5281 gen_rtx_REG (mode, REGNO (prev_loc->reg)), 5282 get_slot_mem (mode, prev_loc->index * 16 + bias), 5283 gen_rtx_REG (mode, REGNO (loc.reg)), 5284 get_slot_mem (mode, loc.index * 16 + bias) 5285 }; 5286 unsigned int lhs = (seq == PROLOGUE); 5287 rtx set1 = gen_rtx_SET (ops[lhs], ops[1 - lhs]); 5288 rtx set2 = gen_rtx_SET (ops[lhs + 2], ops[3 - lhs]); 5289 5290 /* Combine the sets with any stack allocation/deallocation. */ 5291 rtx pat; 5292 if (prev_loc->index == 0) 5293 { 5294 rtx plus_sp = plus_constant (Pmode, sp, sp_adjust); 5295 rtvec vec = gen_rtvec (3, gen_rtx_SET (sp, plus_sp), set1, set2); 5296 pat = gen_rtx_PARALLEL (VOIDmode, vec); 5297 } 5298 else if (seq == PROLOGUE) 5299 pat = aarch64_gen_store_pair (ops[1], ops[0], ops[2]); 5300 else 5301 pat = aarch64_gen_load_pair (ops[0], ops[2], ops[1]); 5302 5303 /* Queue a deallocation to the end, otherwise emit the 5304 instruction now. */ 5305 if (seq == EPILOGUE && prev_loc->index == 0) 5306 last_pat = pat; 5307 else 5308 emit_insn (pat); 5309 prev_loc = nullptr; 5310 } 5311 5312 /* Handle any leftover LDR/STR. */ 5313 if (prev_loc) 5314 { 5315 rtx reg = gen_rtx_REG (mode, REGNO (prev_loc->reg)); 5316 rtx addr; 5317 if (prev_loc->index != 0) 5318 addr = plus_constant (Pmode, sp, prev_loc->index * 16); 5319 else if (seq == PROLOGUE) 5320 { 5321 rtx allocate = plus_constant (Pmode, sp, -count * 16); 5322 addr = gen_rtx_PRE_MODIFY (Pmode, sp, allocate); 5323 } 5324 else 5325 { 5326 rtx deallocate = plus_constant (Pmode, sp, count * 16); 5327 addr = gen_rtx_POST_MODIFY (Pmode, sp, deallocate); 5328 } 5329 rtx mem = gen_rtx_MEM (mode, addr); 5330 if (seq == PROLOGUE) 5331 emit_move_insn (mem, reg); 5332 else 5333 emit_move_insn (reg, mem); 5334 } 5335 5336 if (last_pat) 5337 emit_insn (last_pat); 5338 } 5339 5340 /* Allocate or deallocate the stack space needed by the SVE groups. 5341 SEQ chooses between allocating and deallocating. */ 5342 5343 void 5344 aarch64_sme_mode_switch_regs::emit_sve_sp_adjust (sequence seq) 5345 { 5346 if (unsigned int count = m_group_count[MEM_SVE_DATA] + sve_data_headroom ()) 5347 emit_stack_adjust (seq, count * BYTES_PER_SVE_VECTOR); 5348 } 5349 5350 /* Save or restore the MEM_SVE_DATA group. SEQ chooses between saving 5351 and restoring. */ 5352 5353 void 5354 aarch64_sme_mode_switch_regs::emit_sve_data_moves (sequence seq) 5355 { 5356 for (auto &loc : m_save_locations) 5357 if (loc.group == MEM_SVE_DATA) 5358 { 5359 auto index = loc.index + sve_data_headroom (); 5360 emit_mem_move (seq, loc, index * BYTES_PER_SVE_VECTOR); 5361 } 5362 } 5363 5364 /* Save or restore the MEM_SVE_PRED group. SEQ chooses between saving 5365 and restoring. */ 5366 5367 void 5368 aarch64_sme_mode_switch_regs::emit_sve_pred_moves (sequence seq) 5369 { 5370 for (auto &loc : m_save_locations) 5371 if (loc.group == MEM_SVE_PRED) 5372 emit_mem_move (seq, loc, loc.index * BYTES_PER_SVE_PRED); 5373 } 5374 5375 /* Set DEST to (vec_series BASE STEP). */ 5376 5377 static void 5378 aarch64_expand_vec_series (rtx dest, rtx base, rtx step) 5379 { 5380 machine_mode mode = GET_MODE (dest); 5381 scalar_mode inner = GET_MODE_INNER (mode); 5382 5383 /* Each operand can be a register or an immediate in the range [-16, 15]. */ 5384 if (!aarch64_sve_index_immediate_p (base)) 5385 base = force_reg (inner, base); 5386 if (!aarch64_sve_index_immediate_p (step)) 5387 step = force_reg (inner, step); 5388 5389 emit_set_insn (dest, gen_rtx_VEC_SERIES (mode, base, step)); 5390 } 5391 5392 /* Duplicate 128-bit Advanced SIMD vector SRC so that it fills an SVE 5393 register of mode MODE. Use TARGET for the result if it's nonnull 5394 and convenient. 5395 5396 The two vector modes must have the same element mode. The behavior 5397 is to duplicate architectural lane N of SRC into architectural lanes 5398 N + I * STEP of the result. On big-endian targets, architectural 5399 lane 0 of an Advanced SIMD vector is the last element of the vector 5400 in memory layout, so for big-endian targets this operation has the 5401 effect of reversing SRC before duplicating it. Callers need to 5402 account for this. */ 5403 5404 rtx 5405 aarch64_expand_sve_dupq (rtx target, machine_mode mode, rtx src) 5406 { 5407 machine_mode src_mode = GET_MODE (src); 5408 gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER (src_mode)); 5409 insn_code icode = (BYTES_BIG_ENDIAN 5410 ? code_for_aarch64_vec_duplicate_vq_be (mode) 5411 : code_for_aarch64_vec_duplicate_vq_le (mode)); 5412 5413 unsigned int i = 0; 5414 expand_operand ops[3]; 5415 create_output_operand (&ops[i++], target, mode); 5416 create_output_operand (&ops[i++], src, src_mode); 5417 if (BYTES_BIG_ENDIAN) 5418 { 5419 /* Create a PARALLEL describing the reversal of SRC. */ 5420 unsigned int nelts_per_vq = 128 / GET_MODE_UNIT_BITSIZE (mode); 5421 rtx sel = aarch64_gen_stepped_int_parallel (nelts_per_vq, 5422 nelts_per_vq - 1, -1); 5423 create_fixed_operand (&ops[i++], sel); 5424 } 5425 expand_insn (icode, i, ops); 5426 return ops[0].value; 5427 } 5428 5429 /* Try to force 128-bit vector value SRC into memory and use LD1RQ to fetch 5430 the memory image into DEST. Return true on success. */ 5431 5432 static bool 5433 aarch64_expand_sve_ld1rq (rtx dest, rtx src) 5434 { 5435 src = force_const_mem (GET_MODE (src), src); 5436 if (!src) 5437 return false; 5438 5439 /* Make sure that the address is legitimate. */ 5440 if (!aarch64_sve_ld1rq_operand_p (src)) 5441 { 5442 rtx addr = force_reg (Pmode, XEXP (src, 0)); 5443 src = replace_equiv_address (src, addr); 5444 } 5445 5446 machine_mode mode = GET_MODE (dest); 5447 machine_mode pred_mode = aarch64_sve_pred_mode (mode); 5448 rtx ptrue = aarch64_ptrue_reg (pred_mode); 5449 emit_insn (gen_aarch64_sve_ld1rq (mode, dest, src, ptrue)); 5450 return true; 5451 } 5452 5453 /* SRC is an SVE CONST_VECTOR that contains N "foreground" values followed 5454 by N "background" values. Try to move it into TARGET using: 5455 5456 PTRUE PRED.<T>, VL<N> 5457 MOV TRUE.<T>, #<foreground> 5458 MOV FALSE.<T>, #<background> 5459 SEL TARGET.<T>, PRED.<T>, TRUE.<T>, FALSE.<T> 5460 5461 The PTRUE is always a single instruction but the MOVs might need a 5462 longer sequence. If the background value is zero (as it often is), 5463 the sequence can sometimes collapse to a PTRUE followed by a 5464 zero-predicated move. 5465 5466 Return the target on success, otherwise return null. */ 5467 5468 static rtx 5469 aarch64_expand_sve_const_vector_sel (rtx target, rtx src) 5470 { 5471 gcc_assert (CONST_VECTOR_NELTS_PER_PATTERN (src) == 2); 5472 5473 /* Make sure that the PTRUE is valid. */ 5474 machine_mode mode = GET_MODE (src); 5475 machine_mode pred_mode = aarch64_sve_pred_mode (mode); 5476 unsigned int npatterns = CONST_VECTOR_NPATTERNS (src); 5477 if (aarch64_svpattern_for_vl (pred_mode, npatterns) 5478 == AARCH64_NUM_SVPATTERNS) 5479 return NULL_RTX; 5480 5481 rtx_vector_builder pred_builder (pred_mode, npatterns, 2); 5482 rtx_vector_builder true_builder (mode, npatterns, 1); 5483 rtx_vector_builder false_builder (mode, npatterns, 1); 5484 for (unsigned int i = 0; i < npatterns; ++i) 5485 { 5486 true_builder.quick_push (CONST_VECTOR_ENCODED_ELT (src, i)); 5487 pred_builder.quick_push (CONST1_RTX (BImode)); 5488 } 5489 for (unsigned int i = 0; i < npatterns; ++i) 5490 { 5491 false_builder.quick_push (CONST_VECTOR_ENCODED_ELT (src, i + npatterns)); 5492 pred_builder.quick_push (CONST0_RTX (BImode)); 5493 } 5494 expand_operand ops[4]; 5495 create_output_operand (&ops[0], target, mode); 5496 create_input_operand (&ops[1], true_builder.build (), mode); 5497 create_input_operand (&ops[2], false_builder.build (), mode); 5498 create_input_operand (&ops[3], pred_builder.build (), pred_mode); 5499 expand_insn (code_for_vcond_mask (mode, mode), 4, ops); 5500 return target; 5501 } 5502 5503 /* Return a register containing CONST_VECTOR SRC, given that SRC has an 5504 SVE data mode and isn't a legitimate constant. Use TARGET for the 5505 result if convenient. 5506 5507 The returned register can have whatever mode seems most natural 5508 given the contents of SRC. */ 5509 5510 static rtx 5511 aarch64_expand_sve_const_vector (rtx target, rtx src) 5512 { 5513 machine_mode mode = GET_MODE (src); 5514 unsigned int npatterns = CONST_VECTOR_NPATTERNS (src); 5515 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (src); 5516 scalar_mode elt_mode = GET_MODE_INNER (mode); 5517 unsigned int elt_bits = GET_MODE_BITSIZE (elt_mode); 5518 unsigned int container_bits = aarch64_sve_container_bits (mode); 5519 unsigned int encoded_bits = npatterns * nelts_per_pattern * container_bits; 5520 5521 if (nelts_per_pattern == 1 5522 && encoded_bits <= 128 5523 && container_bits != elt_bits) 5524 { 5525 /* We have a partial vector mode and a constant whose full-vector 5526 equivalent would occupy a repeating 128-bit sequence. Build that 5527 full-vector equivalent instead, so that we have the option of 5528 using LD1RQ and Advanced SIMD operations. */ 5529 unsigned int repeat = container_bits / elt_bits; 5530 machine_mode full_mode = aarch64_full_sve_mode (elt_mode).require (); 5531 rtx_vector_builder builder (full_mode, npatterns * repeat, 1); 5532 for (unsigned int i = 0; i < npatterns; ++i) 5533 for (unsigned int j = 0; j < repeat; ++j) 5534 builder.quick_push (CONST_VECTOR_ENCODED_ELT (src, i)); 5535 target = aarch64_target_reg (target, full_mode); 5536 return aarch64_expand_sve_const_vector (target, builder.build ()); 5537 } 5538 5539 if (nelts_per_pattern == 1 && encoded_bits == 128) 5540 { 5541 /* The constant is a duplicated quadword but can't be narrowed 5542 beyond a quadword. Get the memory image of the first quadword 5543 as a 128-bit vector and try using LD1RQ to load it from memory. 5544 5545 The effect for both endiannesses is to load memory lane N into 5546 architectural lanes N + I * STEP of the result. On big-endian 5547 targets, the layout of the 128-bit vector in an Advanced SIMD 5548 register would be different from its layout in an SVE register, 5549 but this 128-bit vector is a memory value only. */ 5550 machine_mode vq_mode = aarch64_vq_mode (elt_mode).require (); 5551 rtx vq_value = simplify_gen_subreg (vq_mode, src, mode, 0); 5552 if (vq_value && aarch64_expand_sve_ld1rq (target, vq_value)) 5553 return target; 5554 } 5555 5556 if (nelts_per_pattern == 1 && encoded_bits < 128) 5557 { 5558 /* The vector is a repeating sequence of 64 bits or fewer. 5559 See if we can load them using an Advanced SIMD move and then 5560 duplicate it to fill a vector. This is better than using a GPR 5561 move because it keeps everything in the same register file. */ 5562 machine_mode vq_mode = aarch64_vq_mode (elt_mode).require (); 5563 rtx_vector_builder builder (vq_mode, npatterns, 1); 5564 for (unsigned int i = 0; i < npatterns; ++i) 5565 { 5566 /* We want memory lane N to go into architectural lane N, 5567 so reverse for big-endian targets. The DUP .Q pattern 5568 has a compensating reverse built-in. */ 5569 unsigned int srci = BYTES_BIG_ENDIAN ? npatterns - i - 1 : i; 5570 builder.quick_push (CONST_VECTOR_ENCODED_ELT (src, srci)); 5571 } 5572 rtx vq_src = builder.build (); 5573 if (aarch64_simd_valid_immediate (vq_src, NULL)) 5574 { 5575 vq_src = force_reg (vq_mode, vq_src); 5576 return aarch64_expand_sve_dupq (target, mode, vq_src); 5577 } 5578 5579 /* Get an integer representation of the repeating part of Advanced 5580 SIMD vector VQ_SRC. This preserves the endianness of VQ_SRC, 5581 which for big-endian targets is lane-swapped wrt a normal 5582 Advanced SIMD vector. This means that for both endiannesses, 5583 memory lane N of SVE vector SRC corresponds to architectural 5584 lane N of a register holding VQ_SRC. This in turn means that 5585 memory lane 0 of SVE vector SRC is in the lsb of VQ_SRC (viewed 5586 as a single 128-bit value) and thus that memory lane 0 of SRC is 5587 in the lsb of the integer. Duplicating the integer therefore 5588 ensures that memory lane N of SRC goes into architectural lane 5589 N + I * INDEX of the SVE register. */ 5590 scalar_mode int_mode = int_mode_for_size (encoded_bits, 0).require (); 5591 rtx elt_value = simplify_gen_subreg (int_mode, vq_src, vq_mode, 0); 5592 if (elt_value) 5593 { 5594 /* Pretend that we had a vector of INT_MODE to start with. */ 5595 elt_mode = int_mode; 5596 mode = aarch64_full_sve_mode (int_mode).require (); 5597 5598 /* If the integer can be moved into a general register by a 5599 single instruction, do that and duplicate the result. */ 5600 if (CONST_INT_P (elt_value) 5601 && aarch64_move_imm (INTVAL (elt_value), 5602 encoded_bits <= 32 ? SImode : DImode)) 5603 { 5604 elt_value = force_reg (elt_mode, elt_value); 5605 return expand_vector_broadcast (mode, elt_value); 5606 } 5607 } 5608 else if (npatterns == 1) 5609 /* We're duplicating a single value, but can't do better than 5610 force it to memory and load from there. This handles things 5611 like symbolic constants. */ 5612 elt_value = CONST_VECTOR_ENCODED_ELT (src, 0); 5613 5614 if (elt_value) 5615 { 5616 /* Load the element from memory if we can, otherwise move it into 5617 a register and use a DUP. */ 5618 rtx op = force_const_mem (elt_mode, elt_value); 5619 if (!op) 5620 op = force_reg (elt_mode, elt_value); 5621 return expand_vector_broadcast (mode, op); 5622 } 5623 } 5624 5625 /* Try using INDEX. */ 5626 rtx base, step; 5627 if (const_vec_series_p (src, &base, &step)) 5628 { 5629 aarch64_expand_vec_series (target, base, step); 5630 return target; 5631 } 5632 5633 /* From here on, it's better to force the whole constant to memory 5634 if we can. */ 5635 if (GET_MODE_NUNITS (mode).is_constant ()) 5636 return NULL_RTX; 5637 5638 if (nelts_per_pattern == 2) 5639 if (rtx res = aarch64_expand_sve_const_vector_sel (target, src)) 5640 return res; 5641 5642 /* Expand each pattern individually. */ 5643 gcc_assert (npatterns > 1); 5644 rtx_vector_builder builder; 5645 auto_vec<rtx, 16> vectors (npatterns); 5646 for (unsigned int i = 0; i < npatterns; ++i) 5647 { 5648 builder.new_vector (mode, 1, nelts_per_pattern); 5649 for (unsigned int j = 0; j < nelts_per_pattern; ++j) 5650 builder.quick_push (CONST_VECTOR_ELT (src, i + j * npatterns)); 5651 vectors.quick_push (force_reg (mode, builder.build ())); 5652 } 5653 5654 /* Use permutes to interleave the separate vectors. */ 5655 while (npatterns > 1) 5656 { 5657 npatterns /= 2; 5658 for (unsigned int i = 0; i < npatterns; ++i) 5659 { 5660 rtx tmp = (npatterns == 1 ? target : gen_reg_rtx (mode)); 5661 rtvec v = gen_rtvec (2, vectors[i], vectors[i + npatterns]); 5662 emit_set_insn (tmp, gen_rtx_UNSPEC (mode, v, UNSPEC_ZIP1)); 5663 vectors[i] = tmp; 5664 } 5665 } 5666 gcc_assert (vectors[0] == target); 5667 return target; 5668 } 5669 5670 /* Use WHILE to set a predicate register of mode MODE in which the first 5671 VL bits are set and the rest are clear. Use TARGET for the register 5672 if it's nonnull and convenient. */ 5673 5674 static rtx 5675 aarch64_sve_move_pred_via_while (rtx target, machine_mode mode, 5676 unsigned int vl) 5677 { 5678 rtx limit = force_reg (DImode, gen_int_mode (vl, DImode)); 5679 target = aarch64_target_reg (target, mode); 5680 emit_insn (gen_while (UNSPEC_WHILELO, DImode, mode, 5681 target, const0_rtx, limit)); 5682 return target; 5683 } 5684 5685 static rtx 5686 aarch64_expand_sve_const_pred_1 (rtx, rtx_vector_builder &, bool); 5687 5688 /* BUILDER is a constant predicate in which the index of every set bit 5689 is a multiple of ELT_SIZE (which is <= 8). Try to load the constant 5690 by inverting every element at a multiple of ELT_SIZE and EORing the 5691 result with an ELT_SIZE PTRUE. 5692 5693 Return a register that contains the constant on success, otherwise 5694 return null. Use TARGET as the register if it is nonnull and 5695 convenient. */ 5696 5697 static rtx 5698 aarch64_expand_sve_const_pred_eor (rtx target, rtx_vector_builder &builder, 5699 unsigned int elt_size) 5700 { 5701 /* Invert every element at a multiple of ELT_SIZE, keeping the 5702 other bits zero. */ 5703 rtx_vector_builder inv_builder (VNx16BImode, builder.npatterns (), 5704 builder.nelts_per_pattern ()); 5705 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i) 5706 if ((i & (elt_size - 1)) == 0 && INTVAL (builder.elt (i)) == 0) 5707 inv_builder.quick_push (const1_rtx); 5708 else 5709 inv_builder.quick_push (const0_rtx); 5710 inv_builder.finalize (); 5711 5712 /* See if we can load the constant cheaply. */ 5713 rtx inv = aarch64_expand_sve_const_pred_1 (NULL_RTX, inv_builder, false); 5714 if (!inv) 5715 return NULL_RTX; 5716 5717 /* EOR the result with an ELT_SIZE PTRUE. */ 5718 rtx mask = aarch64_ptrue_all (elt_size); 5719 mask = force_reg (VNx16BImode, mask); 5720 inv = gen_lowpart (VNx16BImode, inv); 5721 target = aarch64_target_reg (target, VNx16BImode); 5722 emit_insn (gen_aarch64_pred_z (XOR, VNx16BImode, target, mask, inv, mask)); 5723 return target; 5724 } 5725 5726 /* BUILDER is a constant predicate in which the index of every set bit 5727 is a multiple of ELT_SIZE (which is <= 8). Try to load the constant 5728 using a TRN1 of size PERMUTE_SIZE, which is >= ELT_SIZE. Return the 5729 register on success, otherwise return null. Use TARGET as the register 5730 if nonnull and convenient. */ 5731 5732 static rtx 5733 aarch64_expand_sve_const_pred_trn (rtx target, rtx_vector_builder &builder, 5734 unsigned int elt_size, 5735 unsigned int permute_size) 5736 { 5737 /* We're going to split the constant into two new constants A and B, 5738 with element I of BUILDER going into A if (I & PERMUTE_SIZE) == 0 5739 and into B otherwise. E.g. for PERMUTE_SIZE == 4 && ELT_SIZE == 1: 5740 5741 A: { 0, 1, 2, 3, _, _, _, _, 8, 9, 10, 11, _, _, _, _ } 5742 B: { 4, 5, 6, 7, _, _, _, _, 12, 13, 14, 15, _, _, _, _ } 5743 5744 where _ indicates elements that will be discarded by the permute. 5745 5746 First calculate the ELT_SIZEs for A and B. */ 5747 unsigned int a_elt_size = GET_MODE_SIZE (DImode); 5748 unsigned int b_elt_size = GET_MODE_SIZE (DImode); 5749 for (unsigned int i = 0; i < builder.encoded_nelts (); i += elt_size) 5750 if (INTVAL (builder.elt (i)) != 0) 5751 { 5752 if (i & permute_size) 5753 b_elt_size |= i - permute_size; 5754 else 5755 a_elt_size |= i; 5756 } 5757 a_elt_size &= -a_elt_size; 5758 b_elt_size &= -b_elt_size; 5759 5760 /* Now construct the vectors themselves. */ 5761 rtx_vector_builder a_builder (VNx16BImode, builder.npatterns (), 5762 builder.nelts_per_pattern ()); 5763 rtx_vector_builder b_builder (VNx16BImode, builder.npatterns (), 5764 builder.nelts_per_pattern ()); 5765 unsigned int nelts = builder.encoded_nelts (); 5766 for (unsigned int i = 0; i < nelts; ++i) 5767 if (i & (elt_size - 1)) 5768 { 5769 a_builder.quick_push (const0_rtx); 5770 b_builder.quick_push (const0_rtx); 5771 } 5772 else if ((i & permute_size) == 0) 5773 { 5774 /* The A and B elements are significant. */ 5775 a_builder.quick_push (builder.elt (i)); 5776 b_builder.quick_push (builder.elt (i + permute_size)); 5777 } 5778 else 5779 { 5780 /* The A and B elements are going to be discarded, so pick whatever 5781 is likely to give a nice constant. We are targeting element 5782 sizes A_ELT_SIZE and B_ELT_SIZE for A and B respectively, 5783 with the aim of each being a sequence of ones followed by 5784 a sequence of zeros. So: 5785 5786 * if X_ELT_SIZE <= PERMUTE_SIZE, the best approach is to 5787 duplicate the last X_ELT_SIZE element, to extend the 5788 current sequence of ones or zeros. 5789 5790 * if X_ELT_SIZE > PERMUTE_SIZE, the best approach is to add a 5791 zero, so that the constant really does have X_ELT_SIZE and 5792 not a smaller size. */ 5793 if (a_elt_size > permute_size) 5794 a_builder.quick_push (const0_rtx); 5795 else 5796 a_builder.quick_push (a_builder.elt (i - a_elt_size)); 5797 if (b_elt_size > permute_size) 5798 b_builder.quick_push (const0_rtx); 5799 else 5800 b_builder.quick_push (b_builder.elt (i - b_elt_size)); 5801 } 5802 a_builder.finalize (); 5803 b_builder.finalize (); 5804 5805 /* Try loading A into a register. */ 5806 rtx_insn *last = get_last_insn (); 5807 rtx a = aarch64_expand_sve_const_pred_1 (NULL_RTX, a_builder, false); 5808 if (!a) 5809 return NULL_RTX; 5810 5811 /* Try loading B into a register. */ 5812 rtx b = a; 5813 if (a_builder != b_builder) 5814 { 5815 b = aarch64_expand_sve_const_pred_1 (NULL_RTX, b_builder, false); 5816 if (!b) 5817 { 5818 delete_insns_since (last); 5819 return NULL_RTX; 5820 } 5821 } 5822 5823 /* Emit the TRN1 itself. We emit a TRN that operates on VNx16BI 5824 operands but permutes them as though they had mode MODE. */ 5825 machine_mode mode = aarch64_sve_pred_mode (permute_size).require (); 5826 target = aarch64_target_reg (target, GET_MODE (a)); 5827 rtx type_reg = CONST0_RTX (mode); 5828 emit_insn (gen_aarch64_sve_trn1_conv (mode, target, a, b, type_reg)); 5829 return target; 5830 } 5831 5832 /* Subroutine of aarch64_expand_sve_const_pred. Try to load the VNx16BI 5833 constant in BUILDER into an SVE predicate register. Return the register 5834 on success, otherwise return null. Use TARGET for the register if 5835 nonnull and convenient. 5836 5837 ALLOW_RECURSE_P is true if we can use methods that would call this 5838 function recursively. */ 5839 5840 static rtx 5841 aarch64_expand_sve_const_pred_1 (rtx target, rtx_vector_builder &builder, 5842 bool allow_recurse_p) 5843 { 5844 if (builder.encoded_nelts () == 1) 5845 /* A PFALSE or a PTRUE .B ALL. */ 5846 return aarch64_emit_set_immediate (target, builder); 5847 5848 unsigned int elt_size = aarch64_widest_sve_pred_elt_size (builder); 5849 if (int vl = aarch64_partial_ptrue_length (builder, elt_size)) 5850 { 5851 /* If we can load the constant using PTRUE, use it as-is. */ 5852 machine_mode mode = aarch64_sve_pred_mode (elt_size).require (); 5853 if (aarch64_svpattern_for_vl (mode, vl) != AARCH64_NUM_SVPATTERNS) 5854 return aarch64_emit_set_immediate (target, builder); 5855 5856 /* Otherwise use WHILE to set the first VL bits. */ 5857 return aarch64_sve_move_pred_via_while (target, mode, vl); 5858 } 5859 5860 if (!allow_recurse_p) 5861 return NULL_RTX; 5862 5863 /* Try inverting the vector in element size ELT_SIZE and then EORing 5864 the result with an ELT_SIZE PTRUE. */ 5865 if (INTVAL (builder.elt (0)) == 0) 5866 if (rtx res = aarch64_expand_sve_const_pred_eor (target, builder, 5867 elt_size)) 5868 return res; 5869 5870 /* Try using TRN1 to permute two simpler constants. */ 5871 for (unsigned int i = elt_size; i <= 8; i *= 2) 5872 if (rtx res = aarch64_expand_sve_const_pred_trn (target, builder, 5873 elt_size, i)) 5874 return res; 5875 5876 return NULL_RTX; 5877 } 5878 5879 /* Return an SVE predicate register that contains the VNx16BImode 5880 constant in BUILDER, without going through the move expanders. 5881 5882 The returned register can have whatever mode seems most natural 5883 given the contents of BUILDER. Use TARGET for the result if 5884 convenient. */ 5885 5886 static rtx 5887 aarch64_expand_sve_const_pred (rtx target, rtx_vector_builder &builder) 5888 { 5889 /* Try loading the constant using pure predicate operations. */ 5890 if (rtx res = aarch64_expand_sve_const_pred_1 (target, builder, true)) 5891 return res; 5892 5893 /* Try forcing the constant to memory. */ 5894 if (builder.full_nelts ().is_constant ()) 5895 if (rtx mem = force_const_mem (VNx16BImode, builder.build ())) 5896 { 5897 target = aarch64_target_reg (target, VNx16BImode); 5898 emit_move_insn (target, mem); 5899 return target; 5900 } 5901 5902 /* The last resort is to load the constant as an integer and then 5903 compare it against zero. Use -1 for set bits in order to increase 5904 the changes of using SVE DUPM or an Advanced SIMD byte mask. */ 5905 rtx_vector_builder int_builder (VNx16QImode, builder.npatterns (), 5906 builder.nelts_per_pattern ()); 5907 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i) 5908 int_builder.quick_push (INTVAL (builder.elt (i)) 5909 ? constm1_rtx : const0_rtx); 5910 return aarch64_convert_sve_data_to_pred (target, VNx16BImode, 5911 int_builder.build ()); 5912 } 5913 5914 /* Set DEST to immediate IMM. */ 5915 5916 void 5917 aarch64_expand_mov_immediate (rtx dest, rtx imm) 5918 { 5919 machine_mode mode = GET_MODE (dest); 5920 5921 /* Check on what type of symbol it is. */ 5922 scalar_int_mode int_mode; 5923 if ((SYMBOL_REF_P (imm) 5924 || LABEL_REF_P (imm) 5925 || GET_CODE (imm) == CONST 5926 || GET_CODE (imm) == CONST_POLY_INT) 5927 && is_a <scalar_int_mode> (mode, &int_mode)) 5928 { 5929 rtx mem; 5930 poly_int64 offset; 5931 HOST_WIDE_INT const_offset; 5932 enum aarch64_symbol_type sty; 5933 5934 /* If we have (const (plus symbol offset)), separate out the offset 5935 before we start classifying the symbol. */ 5936 rtx base = strip_offset (imm, &offset); 5937 5938 /* We must always add an offset involving VL separately, rather than 5939 folding it into the relocation. */ 5940 if (!offset.is_constant (&const_offset)) 5941 { 5942 if (!TARGET_SVE) 5943 { 5944 aarch64_report_sve_required (); 5945 return; 5946 } 5947 if (base == const0_rtx 5948 && (aarch64_sve_cnt_immediate_p (offset) 5949 || aarch64_sve_rdvl_immediate_p (offset))) 5950 emit_insn (gen_rtx_SET (dest, imm)); 5951 else 5952 { 5953 /* Do arithmetic on 32-bit values if the result is smaller 5954 than that. */ 5955 if (partial_subreg_p (int_mode, SImode)) 5956 { 5957 /* It is invalid to do symbol calculations in modes 5958 narrower than SImode. */ 5959 gcc_assert (base == const0_rtx); 5960 dest = gen_lowpart (SImode, dest); 5961 int_mode = SImode; 5962 } 5963 if (base != const0_rtx) 5964 { 5965 base = aarch64_force_temporary (int_mode, dest, base); 5966 aarch64_add_offset (int_mode, dest, base, offset, 5967 NULL_RTX, NULL_RTX, 0, false); 5968 } 5969 else 5970 aarch64_add_offset (int_mode, dest, base, offset, 5971 dest, NULL_RTX, 0, false); 5972 } 5973 return; 5974 } 5975 5976 if (aarch64_rdsvl_immediate_p (base)) 5977 { 5978 /* We could handle non-constant offsets if they are ever 5979 generated. */ 5980 gcc_assert (const_offset == 0); 5981 emit_insn (gen_rtx_SET (dest, imm)); 5982 return; 5983 } 5984 5985 sty = aarch64_classify_symbol (base, const_offset); 5986 switch (sty) 5987 { 5988 case SYMBOL_FORCE_TO_MEM: 5989 if (int_mode != ptr_mode) 5990 imm = convert_memory_address (ptr_mode, imm); 5991 5992 if (const_offset != 0 5993 && targetm.cannot_force_const_mem (ptr_mode, imm)) 5994 { 5995 gcc_assert (can_create_pseudo_p ()); 5996 base = aarch64_force_temporary (int_mode, dest, base); 5997 aarch64_add_offset (int_mode, dest, base, const_offset, 5998 NULL_RTX, NULL_RTX, 0, false); 5999 return; 6000 } 6001 6002 mem = force_const_mem (ptr_mode, imm); 6003 gcc_assert (mem); 6004 6005 /* If we aren't generating PC relative literals, then 6006 we need to expand the literal pool access carefully. 6007 This is something that needs to be done in a number 6008 of places, so could well live as a separate function. */ 6009 if (!aarch64_pcrelative_literal_loads) 6010 { 6011 gcc_assert (can_create_pseudo_p ()); 6012 base = gen_reg_rtx (ptr_mode); 6013 aarch64_expand_mov_immediate (base, XEXP (mem, 0)); 6014 if (ptr_mode != Pmode) 6015 base = convert_memory_address (Pmode, base); 6016 mem = gen_rtx_MEM (ptr_mode, base); 6017 } 6018 6019 if (int_mode != ptr_mode) 6020 mem = gen_rtx_ZERO_EXTEND (int_mode, mem); 6021 6022 emit_insn (gen_rtx_SET (dest, mem)); 6023 6024 return; 6025 6026 case SYMBOL_SMALL_TLSGD: 6027 case SYMBOL_SMALL_TLSDESC: 6028 case SYMBOL_SMALL_TLSIE: 6029 case SYMBOL_SMALL_GOT_28K: 6030 case SYMBOL_SMALL_GOT_4G: 6031 case SYMBOL_TINY_GOT: 6032 case SYMBOL_TINY_TLSIE: 6033 if (const_offset != 0) 6034 { 6035 gcc_assert(can_create_pseudo_p ()); 6036 base = aarch64_force_temporary (int_mode, dest, base); 6037 aarch64_add_offset (int_mode, dest, base, const_offset, 6038 NULL_RTX, NULL_RTX, 0, false); 6039 return; 6040 } 6041 /* FALLTHRU */ 6042 6043 case SYMBOL_SMALL_ABSOLUTE: 6044 case SYMBOL_TINY_ABSOLUTE: 6045 case SYMBOL_TLSLE12: 6046 case SYMBOL_TLSLE24: 6047 case SYMBOL_TLSLE32: 6048 case SYMBOL_TLSLE48: 6049 aarch64_load_symref_appropriately (dest, imm, sty); 6050 return; 6051 6052 default: 6053 gcc_unreachable (); 6054 } 6055 } 6056 6057 if (!CONST_INT_P (imm)) 6058 { 6059 if (aarch64_sve_pred_mode_p (mode)) 6060 { 6061 /* Only the low bit of each .H, .S and .D element is defined, 6062 so we can set the upper bits to whatever we like. If the 6063 predicate is all-true in MODE, prefer to set all the undefined 6064 bits as well, so that we can share a single .B predicate for 6065 all modes. */ 6066 if (imm == CONSTM1_RTX (mode)) 6067 imm = CONSTM1_RTX (VNx16BImode); 6068 6069 /* All methods for constructing predicate modes wider than VNx16BI 6070 will set the upper bits of each element to zero. Expose this 6071 by moving such constants as a VNx16BI, so that all bits are 6072 significant and so that constants for different modes can be 6073 shared. The wider constant will still be available as a 6074 REG_EQUAL note. */ 6075 rtx_vector_builder builder; 6076 if (aarch64_get_sve_pred_bits (builder, imm)) 6077 { 6078 rtx res = aarch64_expand_sve_const_pred (dest, builder); 6079 if (dest != res) 6080 emit_move_insn (dest, gen_lowpart (mode, res)); 6081 return; 6082 } 6083 } 6084 6085 if (GET_CODE (imm) == HIGH 6086 || aarch64_simd_valid_immediate (imm, NULL)) 6087 { 6088 emit_insn (gen_rtx_SET (dest, imm)); 6089 return; 6090 } 6091 6092 if (CONST_VECTOR_P (imm) && aarch64_sve_data_mode_p (mode)) 6093 if (rtx res = aarch64_expand_sve_const_vector (dest, imm)) 6094 { 6095 if (dest != res) 6096 emit_insn (gen_aarch64_sve_reinterpret (mode, dest, res)); 6097 return; 6098 } 6099 6100 rtx mem = force_const_mem (mode, imm); 6101 gcc_assert (mem); 6102 emit_move_insn (dest, mem); 6103 return; 6104 } 6105 6106 aarch64_internal_mov_immediate (dest, imm, true, mode); 6107 } 6108 6109 /* Return the MEM rtx that provides the canary value that should be used 6110 for stack-smashing protection. MODE is the mode of the memory. 6111 For SSP_GLOBAL, DECL_RTL is the MEM rtx for the canary variable 6112 (__stack_chk_guard), otherwise it has no useful value. SALT_TYPE 6113 indicates whether the caller is performing a SET or a TEST operation. */ 6114 6115 rtx 6116 aarch64_stack_protect_canary_mem (machine_mode mode, rtx decl_rtl, 6117 aarch64_salt_type salt_type) 6118 { 6119 rtx addr; 6120 if (aarch64_stack_protector_guard == SSP_GLOBAL) 6121 { 6122 gcc_assert (MEM_P (decl_rtl)); 6123 addr = XEXP (decl_rtl, 0); 6124 poly_int64 offset; 6125 rtx base = strip_offset_and_salt (addr, &offset); 6126 if (!SYMBOL_REF_P (base)) 6127 return decl_rtl; 6128 6129 rtvec v = gen_rtvec (2, base, GEN_INT (salt_type)); 6130 addr = gen_rtx_UNSPEC (Pmode, v, UNSPEC_SALT_ADDR); 6131 addr = gen_rtx_CONST (Pmode, addr); 6132 addr = plus_constant (Pmode, addr, offset); 6133 } 6134 else 6135 { 6136 /* Calculate the address from the system register. */ 6137 rtx salt = GEN_INT (salt_type); 6138 addr = gen_reg_rtx (mode); 6139 if (mode == DImode) 6140 emit_insn (gen_reg_stack_protect_address_di (addr, salt)); 6141 else 6142 { 6143 emit_insn (gen_reg_stack_protect_address_si (addr, salt)); 6144 addr = convert_memory_address (Pmode, addr); 6145 } 6146 addr = plus_constant (Pmode, addr, aarch64_stack_protector_guard_offset); 6147 } 6148 return gen_rtx_MEM (mode, force_reg (Pmode, addr)); 6149 } 6150 6151 /* Emit an SVE predicated move from SRC to DEST. PRED is a predicate 6152 that is known to contain PTRUE. */ 6153 6154 void 6155 aarch64_emit_sve_pred_move (rtx dest, rtx pred, rtx src) 6156 { 6157 expand_operand ops[3]; 6158 machine_mode mode = GET_MODE (dest); 6159 create_output_operand (&ops[0], dest, mode); 6160 create_input_operand (&ops[1], pred, GET_MODE(pred)); 6161 create_input_operand (&ops[2], src, mode); 6162 temporary_volatile_ok v (true); 6163 expand_insn (code_for_aarch64_pred_mov (mode), 3, ops); 6164 } 6165 6166 /* Expand a pre-RA SVE data move from SRC to DEST in which at least one 6167 operand is in memory. In this case we need to use the predicated LD1 6168 and ST1 instead of LDR and STR, both for correctness on big-endian 6169 targets and because LD1 and ST1 support a wider range of addressing modes. 6170 PRED_MODE is the mode of the predicate. 6171 6172 See the comment at the head of aarch64-sve.md for details about the 6173 big-endian handling. */ 6174 6175 void 6176 aarch64_expand_sve_mem_move (rtx dest, rtx src, machine_mode pred_mode) 6177 { 6178 machine_mode mode = GET_MODE (dest); 6179 rtx ptrue = aarch64_ptrue_reg (pred_mode); 6180 if (!register_operand (src, mode) 6181 && !register_operand (dest, mode)) 6182 { 6183 rtx tmp = gen_reg_rtx (mode); 6184 if (MEM_P (src)) 6185 aarch64_emit_sve_pred_move (tmp, ptrue, src); 6186 else 6187 emit_move_insn (tmp, src); 6188 src = tmp; 6189 } 6190 aarch64_emit_sve_pred_move (dest, ptrue, src); 6191 } 6192 6193 /* Called only on big-endian targets. See whether an SVE vector move 6194 from SRC to DEST is effectively a REV[BHW] instruction, because at 6195 least one operand is a subreg of an SVE vector that has wider or 6196 narrower elements. Return true and emit the instruction if so. 6197 6198 For example: 6199 6200 (set (reg:VNx8HI R1) (subreg:VNx8HI (reg:VNx16QI R2) 0)) 6201 6202 represents a VIEW_CONVERT between the following vectors, viewed 6203 in memory order: 6204 6205 R2: { [0].high, [0].low, [1].high, [1].low, ... } 6206 R1: { [0], [1], [2], [3], ... } 6207 6208 The high part of lane X in R2 should therefore correspond to lane X*2 6209 of R1, but the register representations are: 6210 6211 msb lsb 6212 R2: ...... [1].high [1].low [0].high [0].low 6213 R1: ...... [3] [2] [1] [0] 6214 6215 where the low part of lane X in R2 corresponds to lane X*2 in R1. 6216 We therefore need a reverse operation to swap the high and low values 6217 around. 6218 6219 This is purely an optimization. Without it we would spill the 6220 subreg operand to the stack in one mode and reload it in the 6221 other mode, which has the same effect as the REV. */ 6222 6223 bool 6224 aarch64_maybe_expand_sve_subreg_move (rtx dest, rtx src) 6225 { 6226 gcc_assert (BYTES_BIG_ENDIAN); 6227 6228 /* Do not try to optimize subregs that LRA has created for matched 6229 reloads. These subregs only exist as a temporary measure to make 6230 the RTL well-formed, but they are exempt from the usual 6231 TARGET_CAN_CHANGE_MODE_CLASS rules. 6232 6233 For example, if we have: 6234 6235 (set (reg:VNx8HI R1) (foo:VNx8HI (reg:VNx4SI R2))) 6236 6237 and the constraints require R1 and R2 to be in the same register, 6238 LRA may need to create RTL such as: 6239 6240 (set (subreg:VNx4SI (reg:VNx8HI TMP) 0) (reg:VNx4SI R2)) 6241 (set (reg:VNx8HI TMP) (foo:VNx8HI (subreg:VNx4SI (reg:VNx8HI TMP) 0))) 6242 (set (reg:VNx8HI R1) (reg:VNx8HI TMP)) 6243 6244 which forces both the input and output of the original instruction 6245 to use the same hard register. But for this to work, the normal 6246 rules have to be suppressed on the subreg input, otherwise LRA 6247 would need to reload that input too, meaning that the process 6248 would never terminate. To compensate for this, the normal rules 6249 are also suppressed for the subreg output of the first move. 6250 Ignoring the special case and handling the first move normally 6251 would therefore generate wrong code: we would reverse the elements 6252 for the first subreg but not reverse them back for the second subreg. */ 6253 if (SUBREG_P (dest) && !LRA_SUBREG_P (dest)) 6254 dest = SUBREG_REG (dest); 6255 if (SUBREG_P (src) && !LRA_SUBREG_P (src)) 6256 src = SUBREG_REG (src); 6257 6258 /* The optimization handles two single SVE REGs with different element 6259 sizes. */ 6260 if (!REG_P (dest) 6261 || !REG_P (src) 6262 || aarch64_classify_vector_mode (GET_MODE (dest)) != VEC_SVE_DATA 6263 || aarch64_classify_vector_mode (GET_MODE (src)) != VEC_SVE_DATA 6264 || (GET_MODE_UNIT_SIZE (GET_MODE (dest)) 6265 == GET_MODE_UNIT_SIZE (GET_MODE (src)))) 6266 return false; 6267 6268 /* Generate *aarch64_sve_mov<mode>_subreg_be. */ 6269 rtx ptrue = aarch64_ptrue_reg (VNx16BImode); 6270 rtx unspec = gen_rtx_UNSPEC (GET_MODE (dest), gen_rtvec (2, ptrue, src), 6271 UNSPEC_REV_SUBREG); 6272 emit_insn (gen_rtx_SET (dest, unspec)); 6273 return true; 6274 } 6275 6276 /* Return a copy of X with mode MODE, without changing its other 6277 attributes. Unlike gen_lowpart, this doesn't care whether the 6278 mode change is valid. */ 6279 6280 rtx 6281 aarch64_replace_reg_mode (rtx x, machine_mode mode) 6282 { 6283 if (GET_MODE (x) == mode) 6284 return x; 6285 6286 x = shallow_copy_rtx (x); 6287 set_mode_and_regno (x, mode, REGNO (x)); 6288 return x; 6289 } 6290 6291 /* Return the SVE REV[BHW] unspec for reversing quantites of mode MODE 6292 stored in wider integer containers. */ 6293 6294 static unsigned int 6295 aarch64_sve_rev_unspec (machine_mode mode) 6296 { 6297 switch (GET_MODE_UNIT_SIZE (mode)) 6298 { 6299 case 1: return UNSPEC_REVB; 6300 case 2: return UNSPEC_REVH; 6301 case 4: return UNSPEC_REVW; 6302 } 6303 gcc_unreachable (); 6304 } 6305 6306 /* Split a *aarch64_sve_mov<mode>_subreg_be pattern with the given 6307 operands. */ 6308 6309 void 6310 aarch64_split_sve_subreg_move (rtx dest, rtx ptrue, rtx src) 6311 { 6312 /* Decide which REV operation we need. The mode with wider elements 6313 determines the mode of the operands and the mode with the narrower 6314 elements determines the reverse width. */ 6315 machine_mode mode_with_wider_elts = aarch64_sve_int_mode (GET_MODE (dest)); 6316 machine_mode mode_with_narrower_elts = aarch64_sve_int_mode (GET_MODE (src)); 6317 if (GET_MODE_UNIT_SIZE (mode_with_wider_elts) 6318 < GET_MODE_UNIT_SIZE (mode_with_narrower_elts)) 6319 std::swap (mode_with_wider_elts, mode_with_narrower_elts); 6320 6321 unsigned int unspec = aarch64_sve_rev_unspec (mode_with_narrower_elts); 6322 machine_mode pred_mode = aarch64_sve_pred_mode (mode_with_wider_elts); 6323 6324 /* Get the operands in the appropriate modes and emit the instruction. */ 6325 ptrue = gen_lowpart (pred_mode, ptrue); 6326 dest = aarch64_replace_reg_mode (dest, mode_with_wider_elts); 6327 src = aarch64_replace_reg_mode (src, mode_with_wider_elts); 6328 emit_insn (gen_aarch64_pred (unspec, mode_with_wider_elts, 6329 dest, ptrue, src)); 6330 } 6331 6332 static bool 6333 aarch64_function_ok_for_sibcall (tree, tree exp) 6334 { 6335 if (crtl->abi->id () != expr_callee_abi (exp).id ()) 6336 return false; 6337 6338 tree fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp))); 6339 if (aarch64_fntype_pstate_sm (fntype) & ~aarch64_cfun_incoming_pstate_sm ()) 6340 return false; 6341 for (auto state : { "za", "zt0" }) 6342 if (bool (aarch64_cfun_shared_flags (state)) 6343 != bool (aarch64_fntype_shared_flags (fntype, state))) 6344 return false; 6345 return true; 6346 } 6347 6348 /* Subroutine of aarch64_pass_by_reference for arguments that are not 6349 passed in SVE registers. */ 6350 6351 static bool 6352 aarch64_pass_by_reference_1 (CUMULATIVE_ARGS *pcum, 6353 const function_arg_info &arg) 6354 { 6355 HOST_WIDE_INT size; 6356 machine_mode dummymode; 6357 int nregs; 6358 6359 /* GET_MODE_SIZE (BLKmode) is useless since it is 0. */ 6360 if (arg.mode == BLKmode && arg.type) 6361 size = int_size_in_bytes (arg.type); 6362 else 6363 /* No frontends can create types with variable-sized modes, so we 6364 shouldn't be asked to pass or return them. */ 6365 size = GET_MODE_SIZE (arg.mode).to_constant (); 6366 6367 /* Aggregates are passed by reference based on their size. */ 6368 if (arg.aggregate_type_p ()) 6369 size = int_size_in_bytes (arg.type); 6370 6371 /* Variable sized arguments are always returned by reference. */ 6372 if (size < 0) 6373 return true; 6374 6375 /* Can this be a candidate to be passed in fp/simd register(s)? */ 6376 if (aarch64_vfp_is_call_or_return_candidate (arg.mode, arg.type, 6377 &dummymode, &nregs, NULL, 6378 !pcum || pcum->silent_p)) 6379 return false; 6380 6381 /* Arguments which are variable sized or larger than 2 registers are 6382 passed by reference unless they are a homogenous floating point 6383 aggregate. */ 6384 return size > 2 * UNITS_PER_WORD; 6385 } 6386 6387 /* Implement TARGET_PASS_BY_REFERENCE. */ 6388 6389 static bool 6390 aarch64_pass_by_reference (cumulative_args_t pcum_v, 6391 const function_arg_info &arg) 6392 { 6393 CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v); 6394 6395 if (!arg.type) 6396 return aarch64_pass_by_reference_1 (pcum, arg); 6397 6398 pure_scalable_type_info pst_info; 6399 switch (pst_info.analyze (arg.type)) 6400 { 6401 case pure_scalable_type_info::IS_PST: 6402 if (pcum && !pcum->silent_p && !TARGET_SVE) 6403 /* We can't gracefully recover at this point, so make this a 6404 fatal error. */ 6405 fatal_error (input_location, "arguments of type %qT require" 6406 " the SVE ISA extension", arg.type); 6407 6408 /* Variadic SVE types are passed by reference. Normal non-variadic 6409 arguments are too if we've run out of registers. */ 6410 return (!arg.named 6411 || pcum->aapcs_nvrn + pst_info.num_zr () > NUM_FP_ARG_REGS 6412 || pcum->aapcs_nprn + pst_info.num_pr () > NUM_PR_ARG_REGS); 6413 6414 case pure_scalable_type_info::DOESNT_MATTER: 6415 gcc_assert (aarch64_pass_by_reference_1 (pcum, arg)); 6416 return true; 6417 6418 case pure_scalable_type_info::NO_ABI_IDENTITY: 6419 case pure_scalable_type_info::ISNT_PST: 6420 return aarch64_pass_by_reference_1 (pcum, arg); 6421 } 6422 gcc_unreachable (); 6423 } 6424 6425 /* Return TRUE if VALTYPE is padded to its least significant bits. */ 6426 static bool 6427 aarch64_return_in_msb (const_tree valtype) 6428 { 6429 machine_mode dummy_mode; 6430 int dummy_int; 6431 6432 /* Never happens in little-endian mode. */ 6433 if (!BYTES_BIG_ENDIAN) 6434 return false; 6435 6436 /* Only composite types smaller than or equal to 16 bytes can 6437 be potentially returned in registers. */ 6438 if (!aarch64_composite_type_p (valtype, TYPE_MODE (valtype)) 6439 || int_size_in_bytes (valtype) <= 0 6440 || int_size_in_bytes (valtype) > 16) 6441 return false; 6442 6443 /* But not a composite that is an HFA (Homogeneous Floating-point Aggregate) 6444 or an HVA (Homogeneous Short-Vector Aggregate); such a special composite 6445 is always passed/returned in the least significant bits of fp/simd 6446 register(s). */ 6447 if (aarch64_vfp_is_call_or_return_candidate (TYPE_MODE (valtype), valtype, 6448 &dummy_mode, &dummy_int, NULL, 6449 false)) 6450 return false; 6451 6452 /* Likewise pure scalable types for SVE vector and predicate registers. */ 6453 pure_scalable_type_info pst_info; 6454 if (pst_info.analyze_registers (valtype)) 6455 return false; 6456 6457 return true; 6458 } 6459 6460 /* Implement TARGET_FUNCTION_VALUE. 6461 Define how to find the value returned by a function. */ 6462 6463 static rtx 6464 aarch64_function_value (const_tree type, const_tree func, 6465 bool outgoing ATTRIBUTE_UNUSED) 6466 { 6467 machine_mode mode; 6468 int unsignedp; 6469 6470 mode = TYPE_MODE (type); 6471 if (INTEGRAL_TYPE_P (type)) 6472 mode = promote_function_mode (type, mode, &unsignedp, func, 1); 6473 6474 pure_scalable_type_info pst_info; 6475 if (type && pst_info.analyze_registers (type)) 6476 return pst_info.get_rtx (mode, V0_REGNUM, P0_REGNUM); 6477 6478 /* Generic vectors that map to full SVE modes with -msve-vector-bits=N 6479 are returned in memory, not by value. */ 6480 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 6481 bool sve_p = (vec_flags & VEC_ANY_SVE); 6482 6483 if (aarch64_return_in_msb (type)) 6484 { 6485 HOST_WIDE_INT size = int_size_in_bytes (type); 6486 6487 if (size % UNITS_PER_WORD != 0) 6488 { 6489 size += UNITS_PER_WORD - size % UNITS_PER_WORD; 6490 mode = int_mode_for_size (size * BITS_PER_UNIT, 0).require (); 6491 } 6492 } 6493 6494 int count; 6495 machine_mode ag_mode; 6496 if (aarch64_vfp_is_call_or_return_candidate (mode, type, &ag_mode, &count, 6497 NULL, false)) 6498 { 6499 gcc_assert (!sve_p); 6500 if (!aarch64_composite_type_p (type, mode)) 6501 { 6502 gcc_assert (count == 1 && mode == ag_mode); 6503 return gen_rtx_REG (mode, V0_REGNUM); 6504 } 6505 else if (aarch64_advsimd_full_struct_mode_p (mode) 6506 && known_eq (GET_MODE_SIZE (ag_mode), 16)) 6507 return gen_rtx_REG (mode, V0_REGNUM); 6508 else if (aarch64_advsimd_partial_struct_mode_p (mode) 6509 && known_eq (GET_MODE_SIZE (ag_mode), 8)) 6510 return gen_rtx_REG (mode, V0_REGNUM); 6511 else 6512 { 6513 int i; 6514 rtx par; 6515 6516 par = gen_rtx_PARALLEL (mode, rtvec_alloc (count)); 6517 for (i = 0; i < count; i++) 6518 { 6519 rtx tmp = gen_rtx_REG (ag_mode, V0_REGNUM + i); 6520 rtx offset = gen_int_mode (i * GET_MODE_SIZE (ag_mode), Pmode); 6521 tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, offset); 6522 XVECEXP (par, 0, i) = tmp; 6523 } 6524 return par; 6525 } 6526 } 6527 else 6528 { 6529 if (sve_p) 6530 { 6531 /* Vector types can acquire a partial SVE mode using things like 6532 __attribute__((vector_size(N))), and this is potentially useful. 6533 However, the choice of mode doesn't affect the type's ABI 6534 identity, so we should treat the types as though they had 6535 the associated integer mode, just like they did before SVE 6536 was introduced. 6537 6538 We know that the vector must be 128 bits or smaller, 6539 otherwise we'd have returned it in memory instead. */ 6540 gcc_assert (type 6541 && (aarch64_some_values_include_pst_objects_p (type) 6542 || (vec_flags & VEC_PARTIAL))); 6543 6544 scalar_int_mode int_mode = int_mode_for_mode (mode).require (); 6545 rtx reg = gen_rtx_REG (int_mode, R0_REGNUM); 6546 rtx pair = gen_rtx_EXPR_LIST (VOIDmode, reg, const0_rtx); 6547 return gen_rtx_PARALLEL (mode, gen_rtvec (1, pair)); 6548 } 6549 return gen_rtx_REG (mode, R0_REGNUM); 6550 } 6551 } 6552 6553 /* Implements TARGET_FUNCTION_VALUE_REGNO_P. 6554 Return true if REGNO is the number of a hard register in which the values 6555 of called function may come back. */ 6556 6557 static bool 6558 aarch64_function_value_regno_p (const unsigned int regno) 6559 { 6560 /* Maximum of 16 bytes can be returned in the general registers. Examples 6561 of 16-byte return values are: 128-bit integers and 16-byte small 6562 structures (excluding homogeneous floating-point aggregates). */ 6563 if (regno == R0_REGNUM || regno == R1_REGNUM) 6564 return true; 6565 6566 /* Up to four fp/simd registers can return a function value, e.g. a 6567 homogeneous floating-point aggregate having four members. */ 6568 if (regno >= V0_REGNUM && regno < V0_REGNUM + HA_MAX_NUM_FLDS) 6569 return TARGET_FLOAT; 6570 6571 if (regno >= P0_REGNUM && regno < P0_REGNUM + HA_MAX_NUM_FLDS) 6572 return TARGET_SVE; 6573 6574 return false; 6575 } 6576 6577 /* Subroutine for aarch64_return_in_memory for types that are not returned 6578 in SVE registers. */ 6579 6580 static bool 6581 aarch64_return_in_memory_1 (const_tree type) 6582 { 6583 HOST_WIDE_INT size; 6584 machine_mode ag_mode; 6585 int count; 6586 6587 if (!AGGREGATE_TYPE_P (type) 6588 && TREE_CODE (type) != BITINT_TYPE 6589 && TREE_CODE (type) != COMPLEX_TYPE 6590 && TREE_CODE (type) != VECTOR_TYPE) 6591 /* Simple scalar types always returned in registers. */ 6592 return false; 6593 6594 if (aarch64_vfp_is_call_or_return_candidate (TYPE_MODE (type), type, 6595 &ag_mode, &count, NULL, false)) 6596 return false; 6597 6598 /* Types larger than 2 registers returned in memory. */ 6599 size = int_size_in_bytes (type); 6600 return (size < 0 || size > 2 * UNITS_PER_WORD); 6601 } 6602 6603 /* Implement TARGET_RETURN_IN_MEMORY. 6604 6605 If the type T of the result of a function is such that 6606 void func (T arg) 6607 would require that arg be passed as a value in a register (or set of 6608 registers) according to the parameter passing rules, then the result 6609 is returned in the same registers as would be used for such an 6610 argument. */ 6611 6612 static bool 6613 aarch64_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED) 6614 { 6615 pure_scalable_type_info pst_info; 6616 switch (pst_info.analyze (type)) 6617 { 6618 case pure_scalable_type_info::IS_PST: 6619 return (pst_info.num_zr () > NUM_FP_ARG_REGS 6620 || pst_info.num_pr () > NUM_PR_ARG_REGS); 6621 6622 case pure_scalable_type_info::DOESNT_MATTER: 6623 gcc_assert (aarch64_return_in_memory_1 (type)); 6624 return true; 6625 6626 case pure_scalable_type_info::NO_ABI_IDENTITY: 6627 case pure_scalable_type_info::ISNT_PST: 6628 return aarch64_return_in_memory_1 (type); 6629 } 6630 gcc_unreachable (); 6631 } 6632 6633 static bool 6634 aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode, 6635 const_tree type, int *nregs) 6636 { 6637 CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v); 6638 return aarch64_vfp_is_call_or_return_candidate (mode, type, 6639 &pcum->aapcs_vfp_rmode, 6640 nregs, NULL, pcum->silent_p); 6641 } 6642 6643 /* Given MODE and TYPE of a function argument, return the alignment in 6644 bits. The idea is to suppress any stronger alignment requested by 6645 the user and opt for the natural alignment (specified in AAPCS64 \S 6646 4.1). ABI_BREAK_GCC_9 is set to the old alignment if the alignment 6647 was incorrectly calculated in versions of GCC prior to GCC 9. 6648 ABI_BREAK_GCC_13 is set to the old alignment if it was incorrectly 6649 calculated in versions between GCC 9 and GCC 13. If the alignment 6650 might have changed between GCC 13 and GCC 14, ABI_BREAK_GCC_14 6651 is the old GCC 13 alignment, otherwise it is zero. 6652 6653 This is a helper function for local use only. */ 6654 6655 static unsigned int 6656 aarch64_function_arg_alignment (machine_mode mode, const_tree type, 6657 unsigned int *abi_break_gcc_9, 6658 unsigned int *abi_break_gcc_13, 6659 unsigned int *abi_break_gcc_14) 6660 { 6661 *abi_break_gcc_9 = 0; 6662 *abi_break_gcc_13 = 0; 6663 *abi_break_gcc_14 = 0; 6664 if (!type) 6665 return GET_MODE_ALIGNMENT (mode); 6666 6667 if (integer_zerop (TYPE_SIZE (type))) 6668 return 0; 6669 6670 gcc_assert (TYPE_MODE (type) == mode); 6671 6672 if (!AGGREGATE_TYPE_P (type)) 6673 { 6674 /* The ABI alignment is the natural alignment of the type, without 6675 any attributes applied. Normally this is the alignment of the 6676 TYPE_MAIN_VARIANT, but not always; see PR108910 for a counterexample. 6677 For now we just handle the known exceptions explicitly. */ 6678 type = TYPE_MAIN_VARIANT (type); 6679 if (POINTER_TYPE_P (type)) 6680 { 6681 gcc_assert (known_eq (POINTER_SIZE, GET_MODE_BITSIZE (mode))); 6682 return POINTER_SIZE; 6683 } 6684 if (TREE_CODE (type) == ENUMERAL_TYPE && TREE_TYPE (type)) 6685 { 6686 *abi_break_gcc_14 = TYPE_ALIGN (type); 6687 type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); 6688 } 6689 gcc_assert (!TYPE_USER_ALIGN (type)); 6690 return TYPE_ALIGN (type); 6691 } 6692 6693 if (TREE_CODE (type) == ARRAY_TYPE) 6694 return TYPE_ALIGN (TREE_TYPE (type)); 6695 6696 unsigned int alignment = 0; 6697 unsigned int bitfield_alignment_with_packed = 0; 6698 unsigned int bitfield_alignment = 0; 6699 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) 6700 if (TREE_CODE (field) == FIELD_DECL) 6701 { 6702 /* Note that we explicitly consider zero-sized fields here, 6703 even though they don't map to AAPCS64 machine types. 6704 For example, in: 6705 6706 struct __attribute__((aligned(8))) empty {}; 6707 6708 struct s { 6709 [[no_unique_address]] empty e; 6710 int x; 6711 }; 6712 6713 "s" contains only one Fundamental Data Type (the int field) 6714 but gains 8-byte alignment and size thanks to "e". */ 6715 alignment = std::max (alignment, DECL_ALIGN (field)); 6716 if (DECL_BIT_FIELD_TYPE (field)) 6717 { 6718 /* Take the bit-field type's alignment into account only 6719 if the user didn't reduce this field's alignment with 6720 the packed attribute. */ 6721 if (!DECL_PACKED (field)) 6722 bitfield_alignment 6723 = std::max (bitfield_alignment, 6724 TYPE_ALIGN (DECL_BIT_FIELD_TYPE (field))); 6725 6726 /* Compute the alignment even if the bit-field is 6727 packed, so that we can emit a warning in case the 6728 alignment changed between GCC versions. */ 6729 bitfield_alignment_with_packed 6730 = std::max (bitfield_alignment_with_packed, 6731 TYPE_ALIGN (DECL_BIT_FIELD_TYPE (field))); 6732 } 6733 } 6734 6735 /* Emit a warning if the alignment is different when taking the 6736 'packed' attribute into account. */ 6737 if (bitfield_alignment != bitfield_alignment_with_packed 6738 && bitfield_alignment_with_packed > alignment) 6739 *abi_break_gcc_13 = bitfield_alignment_with_packed; 6740 6741 if (bitfield_alignment > alignment) 6742 { 6743 *abi_break_gcc_9 = alignment; 6744 return bitfield_alignment; 6745 } 6746 6747 return alignment; 6748 } 6749 6750 /* Return true if TYPE describes a _BitInt(N) or an angreggate that uses the 6751 _BitInt(N) type. These include ARRAY_TYPE's with an element that is a 6752 _BitInt(N) or an aggregate that uses it, and a RECORD_TYPE or a UNION_TYPE 6753 with a field member that is a _BitInt(N) or an aggregate that uses it. 6754 Return false otherwise. */ 6755 6756 static bool 6757 bitint_or_aggr_of_bitint_p (tree type) 6758 { 6759 if (!type) 6760 return false; 6761 6762 if (TREE_CODE (type) == BITINT_TYPE) 6763 return true; 6764 6765 /* If ARRAY_TYPE, check it's element type. */ 6766 if (TREE_CODE (type) == ARRAY_TYPE) 6767 return bitint_or_aggr_of_bitint_p (TREE_TYPE (type)); 6768 6769 /* If RECORD_TYPE or UNION_TYPE, check the fields' types. */ 6770 if (RECORD_OR_UNION_TYPE_P (type)) 6771 for (tree field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) 6772 { 6773 if (TREE_CODE (field) != FIELD_DECL) 6774 continue; 6775 if (bitint_or_aggr_of_bitint_p (TREE_TYPE (field))) 6776 return true; 6777 } 6778 return false; 6779 } 6780 6781 /* Layout a function argument according to the AAPCS64 rules. The rule 6782 numbers refer to the rule numbers in the AAPCS64. ORIG_MODE is the 6783 mode that was originally given to us by the target hook, whereas the 6784 mode in ARG might be the result of replacing partial SVE modes with 6785 the equivalent integer mode. */ 6786 6787 static void 6788 aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) 6789 { 6790 CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v); 6791 tree type = arg.type; 6792 machine_mode mode = arg.mode; 6793 int ncrn, nvrn, nregs; 6794 bool allocate_ncrn, allocate_nvrn; 6795 HOST_WIDE_INT size; 6796 unsigned int abi_break_gcc_9; 6797 unsigned int abi_break_gcc_13; 6798 unsigned int abi_break_gcc_14; 6799 6800 /* We need to do this once per argument. */ 6801 if (pcum->aapcs_arg_processed) 6802 return; 6803 6804 bool warn_pcs_change 6805 = (warn_psabi 6806 && !pcum->silent_p 6807 && (currently_expanding_function_start 6808 || currently_expanding_gimple_stmt)); 6809 6810 /* HFAs and HVAs can have an alignment greater than 16 bytes. For example: 6811 6812 typedef struct foo { 6813 __Int8x16_t foo[2] __attribute__((aligned(32))); 6814 } foo; 6815 6816 is still a HVA despite its larger-than-normal alignment. 6817 However, such over-aligned HFAs and HVAs are guaranteed to have 6818 no padding. 6819 6820 If we exclude HFAs and HVAs from the discussion below, then there 6821 are several things to note: 6822 6823 - Both the C and AAPCS64 interpretations of a type's alignment should 6824 give a value that is no greater than the type's size. 6825 6826 - Types bigger than 16 bytes are passed indirectly. 6827 6828 - If an argument of type T is passed indirectly, TYPE and MODE describe 6829 a pointer to T rather than T iself. 6830 6831 It follows that the AAPCS64 alignment of TYPE must be no greater 6832 than 16 bytes. 6833 6834 Versions prior to GCC 9.1 ignored a bitfield's underlying type 6835 and so could calculate an alignment that was too small. If this 6836 happened for TYPE then ABI_BREAK_GCC_9 is this older, too-small alignment. 6837 6838 Although GCC 9.1 fixed that bug, it introduced a different one: 6839 it would consider the alignment of a bitfield's underlying type even 6840 if the field was packed (which should have the effect of overriding 6841 the alignment of the underlying type). This was fixed in GCC 13.1. 6842 6843 As a result of this bug, GCC 9 to GCC 12 could calculate an alignment 6844 that was too big. If this happened for TYPE, ABI_BREAK_GCC_13 is 6845 this older, too-big alignment. 6846 6847 Also, the fact that GCC 9 to GCC 12 considered irrelevant 6848 alignments meant they could calculate type alignments that were 6849 bigger than the type's size, contrary to the assumption above. 6850 The handling of register arguments was nevertheless (and justifiably) 6851 written to follow the assumption that the alignment can never be 6852 greater than the size. The same was not true for stack arguments; 6853 their alignment was instead handled by MIN bounds in 6854 aarch64_function_arg_boundary. 6855 6856 The net effect is that, if GCC 9 to GCC 12 incorrectly calculated 6857 an alignment of more than 16 bytes for TYPE then: 6858 6859 - If the argument was passed in registers, these GCC versions 6860 would treat the alignment as though it was *less than* 16 bytes. 6861 6862 - If the argument was passed on the stack, these GCC versions 6863 would treat the alignment as though it was *equal to* 16 bytes. 6864 6865 Both behaviors were wrong, but in different cases. */ 6866 6867 pcum->aapcs_arg_processed = true; 6868 6869 pure_scalable_type_info pst_info; 6870 if (type && pst_info.analyze_registers (type)) 6871 { 6872 /* aarch64_function_arg_alignment has never had an effect on 6873 this case. */ 6874 6875 /* The PCS says that it is invalid to pass an SVE value to an 6876 unprototyped function. There is no ABI-defined location we 6877 can return in this case, so we have no real choice but to raise 6878 an error immediately, even though this is only a query function. */ 6879 if (arg.named && pcum->pcs_variant != ARM_PCS_SVE) 6880 { 6881 gcc_assert (!pcum->silent_p); 6882 error ("SVE type %qT cannot be passed to an unprototyped function", 6883 arg.type); 6884 /* Avoid repeating the message, and avoid tripping the assert 6885 below. */ 6886 pcum->pcs_variant = ARM_PCS_SVE; 6887 } 6888 6889 /* We would have converted the argument into pass-by-reference 6890 form if it didn't fit in registers. */ 6891 pcum->aapcs_nextnvrn = pcum->aapcs_nvrn + pst_info.num_zr (); 6892 pcum->aapcs_nextnprn = pcum->aapcs_nprn + pst_info.num_pr (); 6893 gcc_assert (arg.named 6894 && pcum->pcs_variant == ARM_PCS_SVE 6895 && pcum->aapcs_nextnvrn <= NUM_FP_ARG_REGS 6896 && pcum->aapcs_nextnprn <= NUM_PR_ARG_REGS); 6897 pcum->aapcs_reg = pst_info.get_rtx (mode, V0_REGNUM + pcum->aapcs_nvrn, 6898 P0_REGNUM + pcum->aapcs_nprn); 6899 return; 6900 } 6901 6902 /* Generic vectors that map to full SVE modes with -msve-vector-bits=N 6903 are passed by reference, not by value. */ 6904 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 6905 bool sve_p = (vec_flags & VEC_ANY_SVE); 6906 if (sve_p) 6907 /* Vector types can acquire a partial SVE mode using things like 6908 __attribute__((vector_size(N))), and this is potentially useful. 6909 However, the choice of mode doesn't affect the type's ABI 6910 identity, so we should treat the types as though they had 6911 the associated integer mode, just like they did before SVE 6912 was introduced. 6913 6914 We know that the vector must be 128 bits or smaller, 6915 otherwise we'd have passed it in memory instead. */ 6916 gcc_assert (type 6917 && (aarch64_some_values_include_pst_objects_p (type) 6918 || (vec_flags & VEC_PARTIAL))); 6919 6920 /* Size in bytes, rounded to the nearest multiple of 8 bytes. */ 6921 if (type) 6922 size = int_size_in_bytes (type); 6923 else 6924 /* No frontends can create types with variable-sized modes, so we 6925 shouldn't be asked to pass or return them. */ 6926 size = GET_MODE_SIZE (mode).to_constant (); 6927 size = ROUND_UP (size, UNITS_PER_WORD); 6928 6929 allocate_ncrn = (type) ? !(FLOAT_TYPE_P (type)) : !FLOAT_MODE_P (mode); 6930 allocate_nvrn = aarch64_vfp_is_call_candidate (pcum_v, 6931 mode, 6932 type, 6933 &nregs); 6934 gcc_assert (!sve_p || !allocate_nvrn); 6935 6936 unsigned int alignment 6937 = aarch64_function_arg_alignment (mode, type, &abi_break_gcc_9, 6938 &abi_break_gcc_13, &abi_break_gcc_14); 6939 6940 gcc_assert ((allocate_nvrn || alignment <= 16 * BITS_PER_UNIT) 6941 && (!alignment || abi_break_gcc_9 < alignment) 6942 && (!abi_break_gcc_13 || alignment < abi_break_gcc_13)); 6943 6944 /* _BitInt(N) was only added in GCC 14. */ 6945 bool warn_pcs_change_le_gcc14 6946 = warn_pcs_change && !bitint_or_aggr_of_bitint_p (type); 6947 6948 /* allocate_ncrn may be false-positive, but allocate_nvrn is quite reliable. 6949 The following code thus handles passing by SIMD/FP registers first. */ 6950 6951 nvrn = pcum->aapcs_nvrn; 6952 6953 /* C1 - C5 for floating point, homogenous floating point aggregates (HFA) 6954 and homogenous short-vector aggregates (HVA). */ 6955 if (allocate_nvrn) 6956 { 6957 /* aarch64_function_arg_alignment has never had an effect on 6958 this case. */ 6959 if (!pcum->silent_p && !TARGET_FLOAT) 6960 aarch64_err_no_fpadvsimd (mode); 6961 6962 if (nvrn + nregs <= NUM_FP_ARG_REGS) 6963 { 6964 pcum->aapcs_nextnvrn = nvrn + nregs; 6965 if (!aarch64_composite_type_p (type, mode)) 6966 { 6967 gcc_assert (nregs == 1); 6968 pcum->aapcs_reg = gen_rtx_REG (mode, V0_REGNUM + nvrn); 6969 } 6970 else if (aarch64_advsimd_full_struct_mode_p (mode) 6971 && known_eq (GET_MODE_SIZE (pcum->aapcs_vfp_rmode), 16)) 6972 pcum->aapcs_reg = gen_rtx_REG (mode, V0_REGNUM + nvrn); 6973 else if (aarch64_advsimd_partial_struct_mode_p (mode) 6974 && known_eq (GET_MODE_SIZE (pcum->aapcs_vfp_rmode), 8)) 6975 pcum->aapcs_reg = gen_rtx_REG (mode, V0_REGNUM + nvrn); 6976 else 6977 { 6978 rtx par; 6979 int i; 6980 par = gen_rtx_PARALLEL (mode, rtvec_alloc (nregs)); 6981 for (i = 0; i < nregs; i++) 6982 { 6983 rtx tmp = gen_rtx_REG (pcum->aapcs_vfp_rmode, 6984 V0_REGNUM + nvrn + i); 6985 rtx offset = gen_int_mode 6986 (i * GET_MODE_SIZE (pcum->aapcs_vfp_rmode), Pmode); 6987 tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, offset); 6988 XVECEXP (par, 0, i) = tmp; 6989 } 6990 pcum->aapcs_reg = par; 6991 } 6992 return; 6993 } 6994 else 6995 { 6996 /* C.3 NSRN is set to 8. */ 6997 pcum->aapcs_nextnvrn = NUM_FP_ARG_REGS; 6998 goto on_stack; 6999 } 7000 } 7001 7002 ncrn = pcum->aapcs_ncrn; 7003 nregs = size / UNITS_PER_WORD; 7004 7005 /* C6 - C9. though the sign and zero extension semantics are 7006 handled elsewhere. This is the case where the argument fits 7007 entirely general registers. */ 7008 if (allocate_ncrn && (ncrn + nregs <= NUM_ARG_REGS)) 7009 { 7010 gcc_assert (nregs == 0 || nregs == 1 || nregs == 2); 7011 7012 /* C.8 if the argument has an alignment of 16 then the NGRN is 7013 rounded up to the next even number. */ 7014 if (nregs == 2 7015 && ncrn % 2) 7016 { 7017 /* Emit a warning if the alignment changed when taking the 7018 'packed' attribute into account. */ 7019 if (warn_pcs_change_le_gcc14 7020 && abi_break_gcc_13 7021 && ((abi_break_gcc_13 == 16 * BITS_PER_UNIT) 7022 != (alignment == 16 * BITS_PER_UNIT))) 7023 inform (input_location, "parameter passing for argument of type " 7024 "%qT changed in GCC 13.1", type); 7025 7026 if (warn_pcs_change_le_gcc14 7027 && abi_break_gcc_14 7028 && ((abi_break_gcc_14 == 16 * BITS_PER_UNIT) 7029 != (alignment == 16 * BITS_PER_UNIT))) 7030 inform (input_location, "parameter passing for argument of type " 7031 "%qT changed in GCC 14.1", type); 7032 7033 /* The == 16 * BITS_PER_UNIT instead of >= 16 * BITS_PER_UNIT 7034 comparison is there because for > 16 * BITS_PER_UNIT 7035 alignment nregs should be > 2 and therefore it should be 7036 passed by reference rather than value. */ 7037 if (alignment == 16 * BITS_PER_UNIT) 7038 { 7039 if (warn_pcs_change_le_gcc14 7040 && abi_break_gcc_9) 7041 inform (input_location, "parameter passing for argument of type " 7042 "%qT changed in GCC 9.1", type); 7043 ++ncrn; 7044 gcc_assert (ncrn + nregs <= NUM_ARG_REGS); 7045 } 7046 } 7047 7048 /* If an argument with an SVE mode needs to be shifted up to the 7049 high part of the register, treat it as though it had an integer mode. 7050 Using the normal (parallel [...]) would suppress the shifting. */ 7051 if (sve_p 7052 && BYTES_BIG_ENDIAN 7053 && maybe_ne (GET_MODE_SIZE (mode), nregs * UNITS_PER_WORD) 7054 && aarch64_pad_reg_upward (mode, type, false)) 7055 { 7056 mode = int_mode_for_mode (mode).require (); 7057 sve_p = false; 7058 } 7059 7060 /* NREGS can be 0 when e.g. an empty structure is to be passed. 7061 A reg is still generated for it, but the caller should be smart 7062 enough not to use it. */ 7063 if (nregs == 0 7064 || (nregs == 1 && !sve_p) 7065 || GET_MODE_CLASS (mode) == MODE_INT) 7066 pcum->aapcs_reg = gen_rtx_REG (mode, R0_REGNUM + ncrn); 7067 else 7068 { 7069 rtx par; 7070 int i; 7071 7072 par = gen_rtx_PARALLEL (mode, rtvec_alloc (nregs)); 7073 for (i = 0; i < nregs; i++) 7074 { 7075 scalar_int_mode reg_mode = word_mode; 7076 if (nregs == 1) 7077 reg_mode = int_mode_for_mode (mode).require (); 7078 rtx tmp = gen_rtx_REG (reg_mode, R0_REGNUM + ncrn + i); 7079 tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, 7080 GEN_INT (i * UNITS_PER_WORD)); 7081 XVECEXP (par, 0, i) = tmp; 7082 } 7083 pcum->aapcs_reg = par; 7084 } 7085 7086 pcum->aapcs_nextncrn = ncrn + nregs; 7087 return; 7088 } 7089 7090 /* C.11 */ 7091 pcum->aapcs_nextncrn = NUM_ARG_REGS; 7092 7093 /* The argument is passed on stack; record the needed number of words for 7094 this argument and align the total size if necessary. */ 7095 on_stack: 7096 pcum->aapcs_stack_words = size / UNITS_PER_WORD; 7097 7098 if (warn_pcs_change_le_gcc14 7099 && abi_break_gcc_13 7100 && ((abi_break_gcc_13 >= 16 * BITS_PER_UNIT) 7101 != (alignment >= 16 * BITS_PER_UNIT))) 7102 inform (input_location, "parameter passing for argument of type " 7103 "%qT changed in GCC 13.1", type); 7104 7105 if (warn_pcs_change_le_gcc14 7106 && abi_break_gcc_14 7107 && ((abi_break_gcc_14 >= 16 * BITS_PER_UNIT) 7108 != (alignment >= 16 * BITS_PER_UNIT))) 7109 inform (input_location, "parameter passing for argument of type " 7110 "%qT changed in GCC 14.1", type); 7111 7112 if (alignment == 16 * BITS_PER_UNIT) 7113 { 7114 int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD); 7115 if (pcum->aapcs_stack_size != new_size) 7116 { 7117 if (warn_pcs_change_le_gcc14 7118 && abi_break_gcc_9) 7119 inform (input_location, "parameter passing for argument of type " 7120 "%qT changed in GCC 9.1", type); 7121 pcum->aapcs_stack_size = new_size; 7122 } 7123 } 7124 return; 7125 } 7126 7127 /* Add the current argument register to the set of those that need 7128 to be saved and restored around a change to PSTATE.SM. */ 7129 7130 static void 7131 aarch64_record_sme_mode_switch_args (CUMULATIVE_ARGS *pcum) 7132 { 7133 subrtx_var_iterator::array_type array; 7134 FOR_EACH_SUBRTX_VAR (iter, array, pcum->aapcs_reg, NONCONST) 7135 { 7136 rtx x = *iter; 7137 if (REG_P (x) && (FP_REGNUM_P (REGNO (x)) || PR_REGNUM_P (REGNO (x)))) 7138 { 7139 unsigned int i = pcum->num_sme_mode_switch_args++; 7140 gcc_assert (i < ARRAY_SIZE (pcum->sme_mode_switch_args)); 7141 pcum->sme_mode_switch_args[i] = x; 7142 } 7143 } 7144 } 7145 7146 /* Return a parallel that contains all the registers that need to be 7147 saved around a change to PSTATE.SM. Return const0_rtx if there is 7148 no such mode switch, or if no registers need to be saved. */ 7149 7150 static rtx 7151 aarch64_finish_sme_mode_switch_args (CUMULATIVE_ARGS *pcum) 7152 { 7153 if (!pcum->num_sme_mode_switch_args) 7154 return const0_rtx; 7155 7156 auto argvec = gen_rtvec_v (pcum->num_sme_mode_switch_args, 7157 pcum->sme_mode_switch_args); 7158 return gen_rtx_PARALLEL (VOIDmode, argvec); 7159 } 7160 7161 /* Implement TARGET_FUNCTION_ARG. */ 7162 7163 static rtx 7164 aarch64_function_arg (cumulative_args_t pcum_v, const function_arg_info &arg) 7165 { 7166 CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v); 7167 gcc_assert (pcum->pcs_variant == ARM_PCS_AAPCS64 7168 || pcum->pcs_variant == ARM_PCS_SIMD 7169 || pcum->pcs_variant == ARM_PCS_SVE); 7170 7171 if (arg.end_marker_p ()) 7172 { 7173 rtx abi_cookie = aarch64_gen_callee_cookie (pcum->isa_mode, 7174 pcum->pcs_variant); 7175 rtx sme_mode_switch_args = aarch64_finish_sme_mode_switch_args (pcum); 7176 rtx shared_za_flags = gen_int_mode (pcum->shared_za_flags, SImode); 7177 rtx shared_zt0_flags = gen_int_mode (pcum->shared_zt0_flags, SImode); 7178 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec (4, abi_cookie, 7179 sme_mode_switch_args, 7180 shared_za_flags, 7181 shared_zt0_flags)); 7182 } 7183 7184 aarch64_layout_arg (pcum_v, arg); 7185 return pcum->aapcs_reg; 7186 } 7187 7188 void 7189 aarch64_init_cumulative_args (CUMULATIVE_ARGS *pcum, 7190 const_tree fntype, 7191 rtx libname ATTRIBUTE_UNUSED, 7192 const_tree fndecl, 7193 unsigned n_named ATTRIBUTE_UNUSED, 7194 bool silent_p) 7195 { 7196 pcum->aapcs_ncrn = 0; 7197 pcum->aapcs_nvrn = 0; 7198 pcum->aapcs_nprn = 0; 7199 pcum->aapcs_nextncrn = 0; 7200 pcum->aapcs_nextnvrn = 0; 7201 pcum->aapcs_nextnprn = 0; 7202 if (fntype) 7203 { 7204 pcum->pcs_variant = (arm_pcs) fntype_abi (fntype).id (); 7205 pcum->isa_mode = aarch64_fntype_isa_mode (fntype); 7206 } 7207 else 7208 { 7209 pcum->pcs_variant = ARM_PCS_AAPCS64; 7210 pcum->isa_mode = AARCH64_FL_DEFAULT_ISA_MODE; 7211 } 7212 pcum->aapcs_reg = NULL_RTX; 7213 pcum->aapcs_arg_processed = false; 7214 pcum->aapcs_stack_words = 0; 7215 pcum->aapcs_stack_size = 0; 7216 pcum->silent_p = silent_p; 7217 pcum->shared_za_flags 7218 = (fntype ? aarch64_fntype_shared_flags (fntype, "za") : 0U); 7219 pcum->shared_zt0_flags 7220 = (fntype ? aarch64_fntype_shared_flags (fntype, "zt0") : 0U); 7221 pcum->num_sme_mode_switch_args = 0; 7222 7223 if (!silent_p 7224 && !TARGET_FLOAT 7225 && fntype && fntype != error_mark_node) 7226 { 7227 const_tree type = TREE_TYPE (fntype); 7228 machine_mode mode ATTRIBUTE_UNUSED; /* To pass pointer as argument. */ 7229 int nregs ATTRIBUTE_UNUSED; /* Likewise. */ 7230 if (aarch64_vfp_is_call_or_return_candidate (TYPE_MODE (type), type, 7231 &mode, &nregs, NULL, false)) 7232 aarch64_err_no_fpadvsimd (TYPE_MODE (type)); 7233 } 7234 7235 if (!silent_p 7236 && !TARGET_SVE 7237 && pcum->pcs_variant == ARM_PCS_SVE) 7238 { 7239 /* We can't gracefully recover at this point, so make this a 7240 fatal error. */ 7241 if (fndecl) 7242 fatal_error (input_location, "%qE requires the SVE ISA extension", 7243 fndecl); 7244 else 7245 fatal_error (input_location, "calls to functions of type %qT require" 7246 " the SVE ISA extension", fntype); 7247 } 7248 } 7249 7250 static void 7251 aarch64_function_arg_advance (cumulative_args_t pcum_v, 7252 const function_arg_info &arg) 7253 { 7254 CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v); 7255 if (pcum->pcs_variant == ARM_PCS_AAPCS64 7256 || pcum->pcs_variant == ARM_PCS_SIMD 7257 || pcum->pcs_variant == ARM_PCS_SVE) 7258 { 7259 aarch64_layout_arg (pcum_v, arg); 7260 gcc_assert ((pcum->aapcs_reg != NULL_RTX) 7261 != (pcum->aapcs_stack_words != 0)); 7262 if (pcum->aapcs_reg 7263 && aarch64_call_switches_pstate_sm (pcum->isa_mode)) 7264 aarch64_record_sme_mode_switch_args (pcum); 7265 7266 pcum->aapcs_arg_processed = false; 7267 pcum->aapcs_ncrn = pcum->aapcs_nextncrn; 7268 pcum->aapcs_nvrn = pcum->aapcs_nextnvrn; 7269 pcum->aapcs_nprn = pcum->aapcs_nextnprn; 7270 pcum->aapcs_stack_size += pcum->aapcs_stack_words; 7271 pcum->aapcs_stack_words = 0; 7272 pcum->aapcs_reg = NULL_RTX; 7273 } 7274 } 7275 7276 bool 7277 aarch64_function_arg_regno_p (unsigned regno) 7278 { 7279 return ((GP_REGNUM_P (regno) && regno < R0_REGNUM + NUM_ARG_REGS) 7280 || (FP_REGNUM_P (regno) && regno < V0_REGNUM + NUM_FP_ARG_REGS) 7281 || (PR_REGNUM_P (regno) && regno < P0_REGNUM + NUM_PR_ARG_REGS)); 7282 } 7283 7284 /* Implement FUNCTION_ARG_BOUNDARY. Every parameter gets at least 7285 PARM_BOUNDARY bits of alignment, but will be given anything up 7286 to STACK_BOUNDARY bits if the type requires it. This makes sure 7287 that both before and after the layout of each argument, the Next 7288 Stacked Argument Address (NSAA) will have a minimum alignment of 7289 8 bytes. */ 7290 7291 static unsigned int 7292 aarch64_function_arg_boundary (machine_mode mode, const_tree type) 7293 { 7294 unsigned int abi_break_gcc_9; 7295 unsigned int abi_break_gcc_13; 7296 unsigned int abi_break_gcc_14; 7297 unsigned int alignment = aarch64_function_arg_alignment (mode, type, 7298 &abi_break_gcc_9, 7299 &abi_break_gcc_13, 7300 &abi_break_gcc_14); 7301 /* We rely on aarch64_layout_arg and aarch64_gimplify_va_arg_expr 7302 to emit warnings about ABI incompatibility. */ 7303 alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY); 7304 return alignment; 7305 } 7306 7307 /* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE. */ 7308 7309 static fixed_size_mode 7310 aarch64_get_reg_raw_mode (int regno) 7311 { 7312 /* Don't use any non GP registers for __builtin_apply and 7313 __builtin_return if general registers only mode is requested. */ 7314 if (TARGET_GENERAL_REGS_ONLY && !GP_REGNUM_P (regno)) 7315 return as_a <fixed_size_mode> (VOIDmode); 7316 if (TARGET_SVE && FP_REGNUM_P (regno)) 7317 /* Don't use the SVE part of the register for __builtin_apply and 7318 __builtin_return. The SVE registers aren't used by the normal PCS, 7319 so using them there would be a waste of time. The PCS extensions 7320 for SVE types are fundamentally incompatible with the 7321 __builtin_return/__builtin_apply interface. */ 7322 return as_a <fixed_size_mode> (V16QImode); 7323 if (PR_REGNUM_P (regno)) 7324 /* For SVE PR regs, indicate that they should be ignored for 7325 __builtin_apply/__builtin_return. */ 7326 return as_a <fixed_size_mode> (VOIDmode); 7327 return default_get_reg_raw_mode (regno); 7328 } 7329 7330 /* Implement TARGET_FUNCTION_ARG_PADDING. 7331 7332 Small aggregate types are placed in the lowest memory address. 7333 7334 The related parameter passing rules are B.4, C.3, C.5 and C.14. */ 7335 7336 static pad_direction 7337 aarch64_function_arg_padding (machine_mode mode, const_tree type) 7338 { 7339 /* On little-endian targets, the least significant byte of every stack 7340 argument is passed at the lowest byte address of the stack slot. */ 7341 if (!BYTES_BIG_ENDIAN) 7342 return PAD_UPWARD; 7343 7344 /* Otherwise, integral, floating-point and pointer types are padded downward: 7345 the least significant byte of a stack argument is passed at the highest 7346 byte address of the stack slot. */ 7347 if (type 7348 ? (INTEGRAL_TYPE_P (type) || SCALAR_FLOAT_TYPE_P (type) 7349 || POINTER_TYPE_P (type)) 7350 : (SCALAR_INT_MODE_P (mode) || SCALAR_FLOAT_MODE_P (mode))) 7351 return PAD_DOWNWARD; 7352 7353 /* Everything else padded upward, i.e. data in first byte of stack slot. */ 7354 return PAD_UPWARD; 7355 } 7356 7357 /* Similarly, for use by BLOCK_REG_PADDING (MODE, TYPE, FIRST). 7358 7359 It specifies padding for the last (may also be the only) 7360 element of a block move between registers and memory. If 7361 assuming the block is in the memory, padding upward means that 7362 the last element is padded after its highest significant byte, 7363 while in downward padding, the last element is padded at the 7364 its least significant byte side. 7365 7366 Small aggregates and small complex types are always padded 7367 upwards. 7368 7369 We don't need to worry about homogeneous floating-point or 7370 short-vector aggregates; their move is not affected by the 7371 padding direction determined here. Regardless of endianness, 7372 each element of such an aggregate is put in the least 7373 significant bits of a fp/simd register. 7374 7375 Return !BYTES_BIG_ENDIAN if the least significant byte of the 7376 register has useful data, and return the opposite if the most 7377 significant byte does. */ 7378 7379 bool 7380 aarch64_pad_reg_upward (machine_mode mode, const_tree type, 7381 bool first ATTRIBUTE_UNUSED) 7382 { 7383 7384 /* Aside from pure scalable types, small composite types are always 7385 padded upward. */ 7386 if (BYTES_BIG_ENDIAN && aarch64_composite_type_p (type, mode)) 7387 { 7388 HOST_WIDE_INT size; 7389 if (type) 7390 size = int_size_in_bytes (type); 7391 else 7392 /* No frontends can create types with variable-sized modes, so we 7393 shouldn't be asked to pass or return them. */ 7394 size = GET_MODE_SIZE (mode).to_constant (); 7395 if (size < 2 * UNITS_PER_WORD) 7396 { 7397 pure_scalable_type_info pst_info; 7398 if (pst_info.analyze_registers (type)) 7399 return false; 7400 return true; 7401 } 7402 } 7403 7404 /* Otherwise, use the default padding. */ 7405 return !BYTES_BIG_ENDIAN; 7406 } 7407 7408 static scalar_int_mode 7409 aarch64_libgcc_cmp_return_mode (void) 7410 { 7411 return SImode; 7412 } 7413 7414 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP) 7415 7416 /* We use the 12-bit shifted immediate arithmetic instructions so values 7417 must be multiple of (1 << 12), i.e. 4096. */ 7418 #define ARITH_FACTOR 4096 7419 7420 #if (PROBE_INTERVAL % ARITH_FACTOR) != 0 7421 #error Cannot use simple address calculation for stack probing 7422 #endif 7423 7424 /* Emit code to probe a range of stack addresses from FIRST to FIRST+POLY_SIZE, 7425 inclusive. These are offsets from the current stack pointer. */ 7426 7427 static void 7428 aarch64_emit_probe_stack_range (HOST_WIDE_INT first, poly_int64 poly_size) 7429 { 7430 HOST_WIDE_INT size; 7431 if (!poly_size.is_constant (&size)) 7432 { 7433 sorry ("stack probes for SVE frames"); 7434 return; 7435 } 7436 7437 rtx reg1 = gen_rtx_REG (Pmode, PROBE_STACK_FIRST_REGNUM); 7438 7439 /* See the same assertion on PROBE_INTERVAL above. */ 7440 gcc_assert ((first % ARITH_FACTOR) == 0); 7441 7442 /* See if we have a constant small number of probes to generate. If so, 7443 that's the easy case. */ 7444 if (size <= PROBE_INTERVAL) 7445 { 7446 const HOST_WIDE_INT base = ROUND_UP (size, ARITH_FACTOR); 7447 7448 emit_set_insn (reg1, 7449 plus_constant (Pmode, 7450 stack_pointer_rtx, -(first + base))); 7451 emit_stack_probe (plus_constant (Pmode, reg1, base - size)); 7452 } 7453 7454 /* The run-time loop is made up of 8 insns in the generic case while the 7455 compile-time loop is made up of 4+2*(n-2) insns for n # of intervals. */ 7456 else if (size <= 4 * PROBE_INTERVAL) 7457 { 7458 HOST_WIDE_INT i, rem; 7459 7460 emit_set_insn (reg1, 7461 plus_constant (Pmode, 7462 stack_pointer_rtx, 7463 -(first + PROBE_INTERVAL))); 7464 emit_stack_probe (reg1); 7465 7466 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 2 until 7467 it exceeds SIZE. If only two probes are needed, this will not 7468 generate any code. Then probe at FIRST + SIZE. */ 7469 for (i = 2 * PROBE_INTERVAL; i < size; i += PROBE_INTERVAL) 7470 { 7471 emit_set_insn (reg1, 7472 plus_constant (Pmode, reg1, -PROBE_INTERVAL)); 7473 emit_stack_probe (reg1); 7474 } 7475 7476 rem = size - (i - PROBE_INTERVAL); 7477 if (rem > 256) 7478 { 7479 const HOST_WIDE_INT base = ROUND_UP (rem, ARITH_FACTOR); 7480 7481 emit_set_insn (reg1, plus_constant (Pmode, reg1, -base)); 7482 emit_stack_probe (plus_constant (Pmode, reg1, base - rem)); 7483 } 7484 else 7485 emit_stack_probe (plus_constant (Pmode, reg1, -rem)); 7486 } 7487 7488 /* Otherwise, do the same as above, but in a loop. Note that we must be 7489 extra careful with variables wrapping around because we might be at 7490 the very top (or the very bottom) of the address space and we have 7491 to be able to handle this case properly; in particular, we use an 7492 equality test for the loop condition. */ 7493 else 7494 { 7495 rtx reg2 = gen_rtx_REG (Pmode, PROBE_STACK_SECOND_REGNUM); 7496 7497 /* Step 1: round SIZE to the previous multiple of the interval. */ 7498 7499 HOST_WIDE_INT rounded_size = size & -PROBE_INTERVAL; 7500 7501 7502 /* Step 2: compute initial and final value of the loop counter. */ 7503 7504 /* TEST_ADDR = SP + FIRST. */ 7505 emit_set_insn (reg1, 7506 plus_constant (Pmode, stack_pointer_rtx, -first)); 7507 7508 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */ 7509 HOST_WIDE_INT adjustment = - (first + rounded_size); 7510 if (! aarch64_uimm12_shift (adjustment)) 7511 { 7512 aarch64_internal_mov_immediate (reg2, GEN_INT (adjustment), 7513 true, Pmode); 7514 emit_set_insn (reg2, gen_rtx_PLUS (Pmode, stack_pointer_rtx, reg2)); 7515 } 7516 else 7517 emit_set_insn (reg2, 7518 plus_constant (Pmode, stack_pointer_rtx, adjustment)); 7519 7520 /* Step 3: the loop 7521 7522 do 7523 { 7524 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL 7525 probe at TEST_ADDR 7526 } 7527 while (TEST_ADDR != LAST_ADDR) 7528 7529 probes at FIRST + N * PROBE_INTERVAL for values of N from 1 7530 until it is equal to ROUNDED_SIZE. */ 7531 7532 emit_insn (gen_probe_stack_range (reg1, reg1, reg2)); 7533 7534 7535 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time 7536 that SIZE is equal to ROUNDED_SIZE. */ 7537 7538 if (size != rounded_size) 7539 { 7540 HOST_WIDE_INT rem = size - rounded_size; 7541 7542 if (rem > 256) 7543 { 7544 const HOST_WIDE_INT base = ROUND_UP (rem, ARITH_FACTOR); 7545 7546 emit_set_insn (reg2, plus_constant (Pmode, reg2, -base)); 7547 emit_stack_probe (plus_constant (Pmode, reg2, base - rem)); 7548 } 7549 else 7550 emit_stack_probe (plus_constant (Pmode, reg2, -rem)); 7551 } 7552 } 7553 7554 /* Make sure nothing is scheduled before we are done. */ 7555 emit_insn (gen_blockage ()); 7556 } 7557 7558 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are 7559 absolute addresses. */ 7560 7561 const char * 7562 aarch64_output_probe_stack_range (rtx reg1, rtx reg2) 7563 { 7564 static int labelno = 0; 7565 char loop_lab[32]; 7566 rtx xops[2]; 7567 7568 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++); 7569 7570 /* Loop. */ 7571 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab); 7572 7573 HOST_WIDE_INT stack_clash_probe_interval 7574 = 1 << param_stack_clash_protection_guard_size; 7575 7576 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */ 7577 xops[0] = reg1; 7578 HOST_WIDE_INT interval; 7579 if (flag_stack_clash_protection) 7580 interval = stack_clash_probe_interval; 7581 else 7582 interval = PROBE_INTERVAL; 7583 7584 gcc_assert (aarch64_uimm12_shift (interval)); 7585 xops[1] = GEN_INT (interval); 7586 7587 output_asm_insn ("sub\t%0, %0, %1", xops); 7588 7589 /* If doing stack clash protection then we probe up by the ABI specified 7590 amount. We do this because we're dropping full pages at a time in the 7591 loop. But if we're doing non-stack clash probing, probe at SP 0. */ 7592 if (flag_stack_clash_protection) 7593 xops[1] = GEN_INT (STACK_CLASH_CALLER_GUARD); 7594 else 7595 xops[1] = CONST0_RTX (GET_MODE (xops[1])); 7596 7597 /* Probe at TEST_ADDR. If we're inside the loop it is always safe to probe 7598 by this amount for each iteration. */ 7599 output_asm_insn ("str\txzr, [%0, %1]", xops); 7600 7601 /* Test if TEST_ADDR == LAST_ADDR. */ 7602 xops[1] = reg2; 7603 output_asm_insn ("cmp\t%0, %1", xops); 7604 7605 /* Branch. */ 7606 fputs ("\tb.ne\t", asm_out_file); 7607 assemble_name_raw (asm_out_file, loop_lab); 7608 fputc ('\n', asm_out_file); 7609 7610 return ""; 7611 } 7612 7613 /* Emit the probe loop for doing stack clash probes and stack adjustments for 7614 SVE. This emits probes from BASE to BASE - ADJUSTMENT based on a guard size 7615 of GUARD_SIZE. When a probe is emitted it is done at most 7616 MIN_PROBE_THRESHOLD bytes from the current BASE at an interval of 7617 at most MIN_PROBE_THRESHOLD. By the end of this function 7618 BASE = BASE - ADJUSTMENT. */ 7619 7620 const char * 7621 aarch64_output_probe_sve_stack_clash (rtx base, rtx adjustment, 7622 rtx min_probe_threshold, rtx guard_size) 7623 { 7624 /* This function is not allowed to use any instruction generation function 7625 like gen_ and friends. If you do you'll likely ICE during CFG validation, 7626 so instead emit the code you want using output_asm_insn. */ 7627 gcc_assert (flag_stack_clash_protection); 7628 gcc_assert (CONST_INT_P (min_probe_threshold) && CONST_INT_P (guard_size)); 7629 gcc_assert (INTVAL (guard_size) > INTVAL (min_probe_threshold)); 7630 7631 /* The minimum required allocation before the residual requires probing. */ 7632 HOST_WIDE_INT residual_probe_guard = INTVAL (min_probe_threshold); 7633 7634 /* Clamp the value down to the nearest value that can be used with a cmp. */ 7635 residual_probe_guard = aarch64_clamp_to_uimm12_shift (residual_probe_guard); 7636 rtx probe_offset_value_rtx = gen_int_mode (residual_probe_guard, Pmode); 7637 7638 gcc_assert (INTVAL (min_probe_threshold) >= residual_probe_guard); 7639 gcc_assert (aarch64_uimm12_shift (residual_probe_guard)); 7640 7641 static int labelno = 0; 7642 char loop_start_lab[32]; 7643 char loop_end_lab[32]; 7644 rtx xops[2]; 7645 7646 ASM_GENERATE_INTERNAL_LABEL (loop_start_lab, "SVLPSPL", labelno); 7647 ASM_GENERATE_INTERNAL_LABEL (loop_end_lab, "SVLPEND", labelno++); 7648 7649 /* Emit loop start label. */ 7650 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_start_lab); 7651 7652 /* ADJUSTMENT < RESIDUAL_PROBE_GUARD. */ 7653 xops[0] = adjustment; 7654 xops[1] = probe_offset_value_rtx; 7655 output_asm_insn ("cmp\t%0, %1", xops); 7656 7657 /* Branch to end if not enough adjustment to probe. */ 7658 fputs ("\tb.lt\t", asm_out_file); 7659 assemble_name_raw (asm_out_file, loop_end_lab); 7660 fputc ('\n', asm_out_file); 7661 7662 /* BASE = BASE - RESIDUAL_PROBE_GUARD. */ 7663 xops[0] = base; 7664 xops[1] = probe_offset_value_rtx; 7665 output_asm_insn ("sub\t%0, %0, %1", xops); 7666 7667 /* Probe at BASE. */ 7668 xops[1] = const0_rtx; 7669 output_asm_insn ("str\txzr, [%0, %1]", xops); 7670 7671 /* ADJUSTMENT = ADJUSTMENT - RESIDUAL_PROBE_GUARD. */ 7672 xops[0] = adjustment; 7673 xops[1] = probe_offset_value_rtx; 7674 output_asm_insn ("sub\t%0, %0, %1", xops); 7675 7676 /* Branch to start if still more bytes to allocate. */ 7677 fputs ("\tb\t", asm_out_file); 7678 assemble_name_raw (asm_out_file, loop_start_lab); 7679 fputc ('\n', asm_out_file); 7680 7681 /* No probe leave. */ 7682 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_end_lab); 7683 7684 /* BASE = BASE - ADJUSTMENT. */ 7685 xops[0] = base; 7686 xops[1] = adjustment; 7687 output_asm_insn ("sub\t%0, %0, %1", xops); 7688 return ""; 7689 } 7690 7691 /* Determine whether a frame chain needs to be generated. */ 7692 static bool 7693 aarch64_needs_frame_chain (void) 7694 { 7695 if (frame_pointer_needed) 7696 return true; 7697 7698 /* A leaf function cannot have calls or write LR. */ 7699 bool is_leaf = crtl->is_leaf && !df_regs_ever_live_p (LR_REGNUM); 7700 7701 /* Don't use a frame chain in leaf functions if leaf frame pointers 7702 are disabled. */ 7703 if (flag_omit_leaf_frame_pointer && is_leaf) 7704 return false; 7705 7706 return aarch64_use_frame_pointer; 7707 } 7708 7709 /* Return true if the current function should save registers above 7710 the locals area, rather than below it. */ 7711 7712 static bool 7713 aarch64_save_regs_above_locals_p () 7714 { 7715 /* When using stack smash protection, make sure that the canary slot 7716 comes between the locals and the saved registers. Otherwise, 7717 it would be possible for a carefully sized smash attack to change 7718 the saved registers (particularly LR and FP) without reaching the 7719 canary. */ 7720 return crtl->stack_protect_guard; 7721 } 7722 7723 /* Return true if the current function needs to record the incoming 7724 value of PSTATE.SM. */ 7725 static bool 7726 aarch64_need_old_pstate_sm () 7727 { 7728 /* Exit early if the incoming value of PSTATE.SM is known at 7729 compile time. */ 7730 if (aarch64_cfun_incoming_pstate_sm () != 0) 7731 return false; 7732 7733 if (aarch64_cfun_enables_pstate_sm ()) 7734 return true; 7735 7736 /* Non-local goto receivers are entered with PSTATE.SM equal to 0, 7737 but the function needs to return with PSTATE.SM unchanged. */ 7738 if (nonlocal_goto_handler_labels) 7739 return true; 7740 7741 /* Likewise for exception handlers. */ 7742 eh_landing_pad lp; 7743 for (unsigned int i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i) 7744 if (lp && lp->post_landing_pad) 7745 return true; 7746 7747 /* Non-local gotos need to set PSTATE.SM to zero. It's possible to call 7748 streaming-compatible functions without SME being available, so PSTATE.SM 7749 should only be changed if it is currently set to one. */ 7750 if (crtl->has_nonlocal_goto) 7751 return true; 7752 7753 if (cfun->machine->call_switches_pstate_sm) 7754 for (auto insn = get_insns (); insn; insn = NEXT_INSN (insn)) 7755 if (auto *call = dyn_cast<rtx_call_insn *> (insn)) 7756 if (!SIBLING_CALL_P (call)) 7757 { 7758 /* Return true if there is a call to a non-streaming-compatible 7759 function. */ 7760 auto callee_isa_mode = aarch64_insn_callee_isa_mode (call); 7761 if (aarch64_call_switches_pstate_sm (callee_isa_mode)) 7762 return true; 7763 } 7764 return false; 7765 } 7766 7767 /* Mark the registers that need to be saved by the callee and calculate 7768 the size of the callee-saved registers area and frame record (both FP 7769 and LR may be omitted). */ 7770 static void 7771 aarch64_layout_frame (void) 7772 { 7773 unsigned regno, last_fp_reg = INVALID_REGNUM; 7774 machine_mode vector_save_mode = aarch64_reg_save_mode (V8_REGNUM); 7775 poly_int64 vector_save_size = GET_MODE_SIZE (vector_save_mode); 7776 bool frame_related_fp_reg_p = false; 7777 aarch64_frame &frame = cfun->machine->frame; 7778 poly_int64 top_of_locals = -1; 7779 bool enables_pstate_sm = aarch64_cfun_enables_pstate_sm (); 7780 7781 vec_safe_truncate (frame.saved_gprs, 0); 7782 vec_safe_truncate (frame.saved_fprs, 0); 7783 vec_safe_truncate (frame.saved_prs, 0); 7784 7785 frame.emit_frame_chain = aarch64_needs_frame_chain (); 7786 7787 /* Adjust the outgoing arguments size if required. Keep it in sync with what 7788 the mid-end is doing. */ 7789 crtl->outgoing_args_size = STACK_DYNAMIC_OFFSET (cfun); 7790 7791 #define SLOT_NOT_REQUIRED (-2) 7792 #define SLOT_REQUIRED (-1) 7793 7794 frame.wb_push_candidate1 = INVALID_REGNUM; 7795 frame.wb_push_candidate2 = INVALID_REGNUM; 7796 frame.spare_pred_reg = INVALID_REGNUM; 7797 7798 /* First mark all the registers that really need to be saved... */ 7799 for (regno = 0; regno <= LAST_SAVED_REGNUM; regno++) 7800 frame.reg_offset[regno] = SLOT_NOT_REQUIRED; 7801 frame.old_svcr_offset = SLOT_NOT_REQUIRED; 7802 7803 /* ... that includes the eh data registers (if needed)... */ 7804 if (crtl->calls_eh_return) 7805 for (regno = 0; EH_RETURN_DATA_REGNO (regno) != INVALID_REGNUM; regno++) 7806 frame.reg_offset[EH_RETURN_DATA_REGNO (regno)] = SLOT_REQUIRED; 7807 7808 /* ... and any callee saved register that dataflow says is live. */ 7809 for (regno = R0_REGNUM; regno <= R30_REGNUM; regno++) 7810 if (df_regs_ever_live_p (regno) 7811 && !fixed_regs[regno] 7812 && (regno == R30_REGNUM 7813 || !crtl->abi->clobbers_full_reg_p (regno))) 7814 frame.reg_offset[regno] = SLOT_REQUIRED; 7815 7816 for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++) 7817 if ((enables_pstate_sm || df_regs_ever_live_p (regno)) 7818 && !fixed_regs[regno] 7819 && !crtl->abi->clobbers_full_reg_p (regno)) 7820 { 7821 frame.reg_offset[regno] = SLOT_REQUIRED; 7822 last_fp_reg = regno; 7823 if (aarch64_emit_cfi_for_reg_p (regno)) 7824 frame_related_fp_reg_p = true; 7825 } 7826 7827 /* Big-endian SVE frames need a spare predicate register in order 7828 to save Z8-Z15. Decide which register they should use. Prefer 7829 an unused argument register if possible, so that we don't force P4 7830 to be saved unnecessarily. */ 7831 if (frame_related_fp_reg_p 7832 && crtl->abi->id () == ARM_PCS_SVE 7833 && BYTES_BIG_ENDIAN) 7834 { 7835 bitmap live1 = df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun)); 7836 bitmap live2 = df_get_live_in (EXIT_BLOCK_PTR_FOR_FN (cfun)); 7837 for (regno = P0_REGNUM; regno <= P7_REGNUM; regno++) 7838 if (!bitmap_bit_p (live1, regno) && !bitmap_bit_p (live2, regno)) 7839 break; 7840 gcc_assert (regno <= P7_REGNUM); 7841 frame.spare_pred_reg = regno; 7842 df_set_regs_ever_live (regno, true); 7843 } 7844 7845 for (regno = P0_REGNUM; regno <= P15_REGNUM; regno++) 7846 if ((enables_pstate_sm || df_regs_ever_live_p (regno)) 7847 && !fixed_regs[regno] 7848 && !crtl->abi->clobbers_full_reg_p (regno)) 7849 frame.reg_offset[regno] = SLOT_REQUIRED; 7850 7851 bool regs_at_top_p = aarch64_save_regs_above_locals_p (); 7852 7853 poly_int64 offset = crtl->outgoing_args_size; 7854 gcc_assert (multiple_p (offset, STACK_BOUNDARY / BITS_PER_UNIT)); 7855 if (regs_at_top_p) 7856 { 7857 offset += get_frame_size (); 7858 offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); 7859 top_of_locals = offset; 7860 } 7861 frame.bytes_below_saved_regs = offset; 7862 frame.sve_save_and_probe = INVALID_REGNUM; 7863 7864 /* Now assign stack slots for the registers. Start with the predicate 7865 registers, since predicate LDR and STR have a relatively small 7866 offset range. These saves happen below the hard frame pointer. */ 7867 for (regno = P0_REGNUM; regno <= P15_REGNUM; regno++) 7868 if (known_eq (frame.reg_offset[regno], SLOT_REQUIRED)) 7869 { 7870 vec_safe_push (frame.saved_prs, regno); 7871 if (frame.sve_save_and_probe == INVALID_REGNUM) 7872 frame.sve_save_and_probe = regno; 7873 frame.reg_offset[regno] = offset; 7874 offset += BYTES_PER_SVE_PRED; 7875 } 7876 7877 poly_int64 saved_prs_size = offset - frame.bytes_below_saved_regs; 7878 if (maybe_ne (saved_prs_size, 0)) 7879 { 7880 /* If we have any vector registers to save above the predicate registers, 7881 the offset of the vector register save slots need to be a multiple 7882 of the vector size. This lets us use the immediate forms of LDR/STR 7883 (or LD1/ST1 for big-endian). 7884 7885 A vector register is 8 times the size of a predicate register, 7886 and we need to save a maximum of 12 predicate registers, so the 7887 first vector register will be at either #1, MUL VL or #2, MUL VL. 7888 7889 If we don't have any vector registers to save, and we know how 7890 big the predicate save area is, we can just round it up to the 7891 next 16-byte boundary. */ 7892 if (last_fp_reg == INVALID_REGNUM && offset.is_constant ()) 7893 offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); 7894 else 7895 { 7896 if (known_le (saved_prs_size, vector_save_size)) 7897 offset = frame.bytes_below_saved_regs + vector_save_size; 7898 else if (known_le (saved_prs_size, vector_save_size * 2)) 7899 offset = frame.bytes_below_saved_regs + vector_save_size * 2; 7900 else 7901 gcc_unreachable (); 7902 } 7903 } 7904 7905 /* If we need to save any SVE vector registers, add them next. */ 7906 if (last_fp_reg != INVALID_REGNUM && crtl->abi->id () == ARM_PCS_SVE) 7907 for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++) 7908 if (known_eq (frame.reg_offset[regno], SLOT_REQUIRED)) 7909 { 7910 vec_safe_push (frame.saved_fprs, regno); 7911 if (frame.sve_save_and_probe == INVALID_REGNUM) 7912 frame.sve_save_and_probe = regno; 7913 frame.reg_offset[regno] = offset; 7914 offset += vector_save_size; 7915 } 7916 7917 /* OFFSET is now the offset of the hard frame pointer from the bottom 7918 of the callee save area. */ 7919 auto below_hard_fp_saved_regs_size = offset - frame.bytes_below_saved_regs; 7920 bool saves_below_hard_fp_p = maybe_ne (below_hard_fp_saved_regs_size, 0); 7921 gcc_assert (!saves_below_hard_fp_p 7922 || (frame.sve_save_and_probe != INVALID_REGNUM 7923 && known_eq (frame.reg_offset[frame.sve_save_and_probe], 7924 frame.bytes_below_saved_regs))); 7925 7926 frame.bytes_below_hard_fp = offset; 7927 frame.hard_fp_save_and_probe = INVALID_REGNUM; 7928 7929 auto allocate_gpr_slot = [&](unsigned int regno) 7930 { 7931 vec_safe_push (frame.saved_gprs, regno); 7932 frame.reg_offset[regno] = offset; 7933 offset += UNITS_PER_WORD; 7934 }; 7935 7936 if (frame.emit_frame_chain) 7937 { 7938 /* FP and LR are placed in the linkage record. */ 7939 allocate_gpr_slot (R29_REGNUM); 7940 allocate_gpr_slot (R30_REGNUM); 7941 } 7942 else if ((flag_stack_clash_protection || !frame.is_scs_enabled) 7943 && known_eq (frame.reg_offset[R30_REGNUM], SLOT_REQUIRED)) 7944 /* Put the LR save slot first, since it makes a good choice of probe 7945 for stack clash purposes. The idea is that the link register usually 7946 has to be saved before a call anyway, and so we lose little by 7947 stopping it from being individually shrink-wrapped. */ 7948 allocate_gpr_slot (R30_REGNUM); 7949 7950 for (regno = R0_REGNUM; regno <= R30_REGNUM; regno++) 7951 if (known_eq (frame.reg_offset[regno], SLOT_REQUIRED)) 7952 allocate_gpr_slot (regno); 7953 7954 if (aarch64_need_old_pstate_sm ()) 7955 { 7956 frame.old_svcr_offset = offset; 7957 offset += UNITS_PER_WORD; 7958 } 7959 7960 /* If the current function changes the SVE vector length, ensure that the 7961 old value of the DWARF VG register is saved and available in the CFI, 7962 so that outer frames with VL-sized offsets can be processed correctly. */ 7963 if (cfun->machine->call_switches_pstate_sm 7964 || aarch64_cfun_enables_pstate_sm ()) 7965 { 7966 frame.reg_offset[VG_REGNUM] = offset; 7967 offset += UNITS_PER_WORD; 7968 } 7969 7970 poly_int64 max_int_offset = offset; 7971 offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); 7972 bool has_align_gap = maybe_ne (offset, max_int_offset); 7973 7974 for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++) 7975 if (known_eq (frame.reg_offset[regno], SLOT_REQUIRED)) 7976 { 7977 vec_safe_push (frame.saved_fprs, regno); 7978 /* If there is an alignment gap between integer and fp callee-saves, 7979 allocate the last fp register to it if possible. */ 7980 if (regno == last_fp_reg 7981 && has_align_gap 7982 && known_eq (vector_save_size, 8) 7983 && multiple_p (offset, 16)) 7984 { 7985 frame.reg_offset[regno] = max_int_offset; 7986 break; 7987 } 7988 7989 frame.reg_offset[regno] = offset; 7990 offset += vector_save_size; 7991 } 7992 7993 offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); 7994 auto saved_regs_size = offset - frame.bytes_below_saved_regs; 7995 7996 array_slice<unsigned int> push_regs = (!vec_safe_is_empty (frame.saved_gprs) 7997 ? frame.saved_gprs 7998 : frame.saved_fprs); 7999 if (!push_regs.empty () 8000 && known_eq (frame.reg_offset[push_regs[0]], frame.bytes_below_hard_fp)) 8001 { 8002 frame.hard_fp_save_and_probe = push_regs[0]; 8003 frame.wb_push_candidate1 = push_regs[0]; 8004 if (push_regs.size () > 1) 8005 frame.wb_push_candidate2 = push_regs[1]; 8006 } 8007 8008 /* With stack-clash, a register must be saved in non-leaf functions. 8009 The saving of the bottommost register counts as an implicit probe, 8010 which allows us to maintain the invariant described in the comment 8011 at expand_prologue. */ 8012 gcc_assert (crtl->is_leaf || maybe_ne (saved_regs_size, 0)); 8013 8014 if (!regs_at_top_p) 8015 { 8016 offset += get_frame_size (); 8017 offset = aligned_upper_bound (offset, STACK_BOUNDARY / BITS_PER_UNIT); 8018 top_of_locals = offset; 8019 } 8020 offset += frame.saved_varargs_size; 8021 gcc_assert (multiple_p (offset, STACK_BOUNDARY / BITS_PER_UNIT)); 8022 frame.frame_size = offset; 8023 8024 frame.bytes_above_hard_fp = frame.frame_size - frame.bytes_below_hard_fp; 8025 gcc_assert (known_ge (top_of_locals, 0)); 8026 frame.bytes_above_locals = frame.frame_size - top_of_locals; 8027 8028 frame.initial_adjust = 0; 8029 frame.final_adjust = 0; 8030 frame.callee_adjust = 0; 8031 frame.sve_callee_adjust = 0; 8032 8033 frame.wb_pop_candidate1 = frame.wb_push_candidate1; 8034 frame.wb_pop_candidate2 = frame.wb_push_candidate2; 8035 8036 /* Shadow call stack only deals with functions where the LR is pushed 8037 onto the stack and without specifying the "no_sanitize" attribute 8038 with the argument "shadow-call-stack". */ 8039 frame.is_scs_enabled 8040 = (!crtl->calls_eh_return 8041 && sanitize_flags_p (SANITIZE_SHADOW_CALL_STACK) 8042 && known_ge (frame.reg_offset[LR_REGNUM], 0)); 8043 8044 /* When shadow call stack is enabled, the scs_pop in the epilogue will 8045 restore x30, and we don't need to pop x30 again in the traditional 8046 way. Pop candidates record the registers that need to be popped 8047 eventually. */ 8048 if (frame.is_scs_enabled) 8049 { 8050 if (frame.wb_pop_candidate2 == R30_REGNUM) 8051 frame.wb_pop_candidate2 = INVALID_REGNUM; 8052 else if (frame.wb_pop_candidate1 == R30_REGNUM) 8053 frame.wb_pop_candidate1 = INVALID_REGNUM; 8054 } 8055 8056 /* If candidate2 is INVALID_REGNUM, we need to adjust max_push_offset to 8057 256 to ensure that the offset meets the requirements of emit_move_insn. 8058 Similarly, if candidate1 is INVALID_REGNUM, we need to set 8059 max_push_offset to 0, because no registers are popped at this time, 8060 so callee_adjust cannot be adjusted. */ 8061 HOST_WIDE_INT max_push_offset = 0; 8062 if (frame.wb_pop_candidate1 != INVALID_REGNUM) 8063 { 8064 if (frame.wb_pop_candidate2 != INVALID_REGNUM) 8065 max_push_offset = 512; 8066 else 8067 max_push_offset = 256; 8068 } 8069 8070 HOST_WIDE_INT const_size, const_below_saved_regs, const_above_fp; 8071 HOST_WIDE_INT const_saved_regs_size; 8072 if (known_eq (saved_regs_size, 0)) 8073 frame.initial_adjust = frame.frame_size; 8074 else if (frame.frame_size.is_constant (&const_size) 8075 && const_size < max_push_offset 8076 && known_eq (frame.bytes_above_hard_fp, const_size)) 8077 { 8078 /* Simple, small frame with no data below the saved registers. 8079 8080 stp reg1, reg2, [sp, -frame_size]! 8081 stp reg3, reg4, [sp, 16] */ 8082 frame.callee_adjust = const_size; 8083 } 8084 else if (frame.bytes_below_saved_regs.is_constant (&const_below_saved_regs) 8085 && saved_regs_size.is_constant (&const_saved_regs_size) 8086 && const_below_saved_regs + const_saved_regs_size < 512 8087 /* We could handle this case even with data below the saved 8088 registers, provided that that data left us with valid offsets 8089 for all predicate and vector save slots. It's such a rare 8090 case that it hardly seems worth the effort though. */ 8091 && (!saves_below_hard_fp_p || const_below_saved_regs == 0) 8092 && !(cfun->calls_alloca 8093 && frame.bytes_above_hard_fp.is_constant (&const_above_fp) 8094 && const_above_fp < max_push_offset)) 8095 { 8096 /* Frame with small area below the saved registers: 8097 8098 sub sp, sp, frame_size 8099 stp reg1, reg2, [sp, bytes_below_saved_regs] 8100 stp reg3, reg4, [sp, bytes_below_saved_regs + 16] */ 8101 frame.initial_adjust = frame.frame_size; 8102 } 8103 else if (saves_below_hard_fp_p 8104 && known_eq (saved_regs_size, below_hard_fp_saved_regs_size)) 8105 { 8106 /* Frame in which all saves are SVE saves: 8107 8108 sub sp, sp, frame_size - bytes_below_saved_regs 8109 save SVE registers relative to SP 8110 sub sp, sp, bytes_below_saved_regs */ 8111 frame.initial_adjust = frame.frame_size - frame.bytes_below_saved_regs; 8112 frame.final_adjust = frame.bytes_below_saved_regs; 8113 } 8114 else if (frame.wb_push_candidate1 != INVALID_REGNUM 8115 && frame.bytes_above_hard_fp.is_constant (&const_above_fp) 8116 && const_above_fp < max_push_offset) 8117 { 8118 /* Frame with large area below the saved registers, or with SVE saves, 8119 but with a small area above: 8120 8121 stp reg1, reg2, [sp, -hard_fp_offset]! 8122 stp reg3, reg4, [sp, 16] 8123 [sub sp, sp, below_hard_fp_saved_regs_size] 8124 [save SVE registers relative to SP] 8125 sub sp, sp, bytes_below_saved_regs */ 8126 frame.callee_adjust = const_above_fp; 8127 frame.sve_callee_adjust = below_hard_fp_saved_regs_size; 8128 frame.final_adjust = frame.bytes_below_saved_regs; 8129 } 8130 else 8131 { 8132 /* General case: 8133 8134 sub sp, sp, hard_fp_offset 8135 stp x29, x30, [sp, 0] 8136 add x29, sp, 0 8137 stp reg3, reg4, [sp, 16] 8138 [sub sp, sp, below_hard_fp_saved_regs_size] 8139 [save SVE registers relative to SP] 8140 sub sp, sp, bytes_below_saved_regs */ 8141 frame.initial_adjust = frame.bytes_above_hard_fp; 8142 frame.sve_callee_adjust = below_hard_fp_saved_regs_size; 8143 frame.final_adjust = frame.bytes_below_saved_regs; 8144 } 8145 8146 /* The frame is allocated in pieces, with each non-final piece 8147 including a register save at offset 0 that acts as a probe for 8148 the following piece. In addition, the save of the bottommost register 8149 acts as a probe for callees and allocas. Roll back any probes that 8150 aren't needed. 8151 8152 A probe isn't needed if it is associated with the final allocation 8153 (including callees and allocas) that happens before the epilogue is 8154 executed. */ 8155 if (crtl->is_leaf 8156 && !cfun->calls_alloca 8157 && known_eq (frame.final_adjust, 0)) 8158 { 8159 if (maybe_ne (frame.sve_callee_adjust, 0)) 8160 frame.sve_save_and_probe = INVALID_REGNUM; 8161 else 8162 frame.hard_fp_save_and_probe = INVALID_REGNUM; 8163 } 8164 8165 /* Make sure the individual adjustments add up to the full frame size. */ 8166 gcc_assert (known_eq (frame.initial_adjust 8167 + frame.callee_adjust 8168 + frame.sve_callee_adjust 8169 + frame.final_adjust, frame.frame_size)); 8170 8171 if (frame.callee_adjust == 0) 8172 { 8173 /* We've decided not to do a "real" push and pop. However, 8174 setting up the frame chain is treated as being essentially 8175 a multi-instruction push. */ 8176 frame.wb_pop_candidate1 = frame.wb_pop_candidate2 = INVALID_REGNUM; 8177 if (!frame.emit_frame_chain) 8178 frame.wb_push_candidate1 = frame.wb_push_candidate2 = INVALID_REGNUM; 8179 } 8180 8181 frame.laid_out = true; 8182 } 8183 8184 /* Return true if the register REGNO is saved on entry to 8185 the current function. */ 8186 8187 static bool 8188 aarch64_register_saved_on_entry (int regno) 8189 { 8190 return known_ge (cfun->machine->frame.reg_offset[regno], 0); 8191 } 8192 8193 /* Push the register number REGNO of mode MODE to the stack with write-back 8194 adjusting the stack by ADJUSTMENT. */ 8195 8196 static void 8197 aarch64_pushwb_single_reg (machine_mode mode, unsigned regno, 8198 HOST_WIDE_INT adjustment) 8199 { 8200 rtx base_rtx = stack_pointer_rtx; 8201 rtx insn, reg, mem; 8202 8203 reg = gen_rtx_REG (mode, regno); 8204 mem = gen_rtx_PRE_MODIFY (Pmode, base_rtx, 8205 plus_constant (Pmode, base_rtx, -adjustment)); 8206 mem = gen_frame_mem (mode, mem); 8207 8208 insn = emit_move_insn (mem, reg); 8209 RTX_FRAME_RELATED_P (insn) = 1; 8210 } 8211 8212 /* Generate and return an instruction to store the pair of registers 8213 REG and REG2 of mode MODE to location BASE with write-back adjusting 8214 the stack location BASE by ADJUSTMENT. */ 8215 8216 static rtx 8217 aarch64_gen_storewb_pair (machine_mode mode, rtx base, rtx reg, rtx reg2, 8218 HOST_WIDE_INT adjustment) 8219 { 8220 rtx new_base = plus_constant (Pmode, base, -adjustment); 8221 rtx mem = gen_frame_mem (mode, new_base); 8222 rtx mem2 = adjust_address_nv (mem, mode, GET_MODE_SIZE (mode)); 8223 8224 return gen_rtx_PARALLEL (VOIDmode, 8225 gen_rtvec (3, 8226 gen_rtx_SET (base, new_base), 8227 gen_rtx_SET (mem, reg), 8228 gen_rtx_SET (mem2, reg2))); 8229 } 8230 8231 /* Push registers numbered REGNO1 and REGNO2 to the stack, adjusting the 8232 stack pointer by ADJUSTMENT. */ 8233 8234 static void 8235 aarch64_push_regs (unsigned regno1, unsigned regno2, HOST_WIDE_INT adjustment) 8236 { 8237 rtx_insn *insn; 8238 machine_mode mode = aarch64_reg_save_mode (regno1); 8239 8240 if (regno2 == INVALID_REGNUM) 8241 return aarch64_pushwb_single_reg (mode, regno1, adjustment); 8242 8243 rtx reg1 = gen_rtx_REG (mode, regno1); 8244 rtx reg2 = gen_rtx_REG (mode, regno2); 8245 8246 insn = emit_insn (aarch64_gen_storewb_pair (mode, stack_pointer_rtx, reg1, 8247 reg2, adjustment)); 8248 RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 2)) = 1; 8249 RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 1)) = 1; 8250 RTX_FRAME_RELATED_P (insn) = 1; 8251 } 8252 8253 /* Load the pair of register REG, REG2 of mode MODE from stack location BASE, 8254 adjusting it by ADJUSTMENT afterwards. */ 8255 8256 static rtx 8257 aarch64_gen_loadwb_pair (machine_mode mode, rtx base, rtx reg, rtx reg2, 8258 HOST_WIDE_INT adjustment) 8259 { 8260 rtx mem = gen_frame_mem (mode, base); 8261 rtx mem2 = adjust_address_nv (mem, mode, GET_MODE_SIZE (mode)); 8262 rtx new_base = plus_constant (Pmode, base, adjustment); 8263 8264 return gen_rtx_PARALLEL (VOIDmode, 8265 gen_rtvec (3, 8266 gen_rtx_SET (base, new_base), 8267 gen_rtx_SET (reg, mem), 8268 gen_rtx_SET (reg2, mem2))); 8269 } 8270 8271 /* Pop the two registers numbered REGNO1, REGNO2 from the stack, adjusting it 8272 afterwards by ADJUSTMENT and writing the appropriate REG_CFA_RESTORE notes 8273 into CFI_OPS. */ 8274 8275 static void 8276 aarch64_pop_regs (unsigned regno1, unsigned regno2, HOST_WIDE_INT adjustment, 8277 rtx *cfi_ops) 8278 { 8279 machine_mode mode = aarch64_reg_save_mode (regno1); 8280 rtx reg1 = gen_rtx_REG (mode, regno1); 8281 8282 *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg1, *cfi_ops); 8283 8284 if (regno2 == INVALID_REGNUM) 8285 { 8286 rtx mem = plus_constant (Pmode, stack_pointer_rtx, adjustment); 8287 mem = gen_rtx_POST_MODIFY (Pmode, stack_pointer_rtx, mem); 8288 emit_move_insn (reg1, gen_frame_mem (mode, mem)); 8289 } 8290 else 8291 { 8292 rtx reg2 = gen_rtx_REG (mode, regno2); 8293 *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg2, *cfi_ops); 8294 emit_insn (aarch64_gen_loadwb_pair (mode, stack_pointer_rtx, reg1, 8295 reg2, adjustment)); 8296 } 8297 } 8298 8299 /* Given an ldp/stp register operand mode MODE, return a suitable mode to use 8300 for a mem rtx representing the entire pair. */ 8301 8302 static machine_mode 8303 aarch64_pair_mode_for_mode (machine_mode mode) 8304 { 8305 if (known_eq (GET_MODE_SIZE (mode), 4)) 8306 return V2x4QImode; 8307 else if (known_eq (GET_MODE_SIZE (mode), 8)) 8308 return V2x8QImode; 8309 else if (known_eq (GET_MODE_SIZE (mode), 16)) 8310 return V2x16QImode; 8311 else 8312 gcc_unreachable (); 8313 } 8314 8315 /* Given a base mem MEM with mode and address suitable for a single ldp/stp 8316 operand, return an rtx like MEM which instead represents the entire pair. */ 8317 8318 static rtx 8319 aarch64_pair_mem_from_base (rtx mem) 8320 { 8321 auto pair_mode = aarch64_pair_mode_for_mode (GET_MODE (mem)); 8322 mem = adjust_bitfield_address_nv (mem, pair_mode, 0); 8323 gcc_assert (aarch64_mem_pair_lanes_operand (mem, pair_mode)); 8324 return mem; 8325 } 8326 8327 /* Generate and return a store pair instruction to store REG1 and REG2 8328 into memory starting at BASE_MEM. All three rtxes should have modes of the 8329 same size. */ 8330 8331 rtx 8332 aarch64_gen_store_pair (rtx base_mem, rtx reg1, rtx reg2) 8333 { 8334 rtx pair_mem = aarch64_pair_mem_from_base (base_mem); 8335 8336 return gen_rtx_SET (pair_mem, 8337 gen_rtx_UNSPEC (GET_MODE (pair_mem), 8338 gen_rtvec (2, reg1, reg2), 8339 UNSPEC_STP)); 8340 } 8341 8342 /* Generate and return a load pair instruction to load a pair of 8343 registers starting at BASE_MEM into REG1 and REG2. If CODE is 8344 UNKNOWN, all three rtxes should have modes of the same size. 8345 Otherwise, CODE is {SIGN,ZERO}_EXTEND, base_mem should be in SImode, 8346 and REG{1,2} should be in DImode. */ 8347 8348 rtx 8349 aarch64_gen_load_pair (rtx reg1, rtx reg2, rtx base_mem, enum rtx_code code) 8350 { 8351 rtx pair_mem = aarch64_pair_mem_from_base (base_mem); 8352 8353 const bool any_extend_p = (code == ZERO_EXTEND || code == SIGN_EXTEND); 8354 if (any_extend_p) 8355 gcc_checking_assert (GET_MODE (base_mem) == SImode 8356 && GET_MODE (reg1) == DImode 8357 && GET_MODE (reg2) == DImode); 8358 else 8359 gcc_assert (code == UNKNOWN); 8360 8361 rtx unspecs[2] = { 8362 gen_rtx_UNSPEC (any_extend_p ? SImode : GET_MODE (reg1), 8363 gen_rtvec (1, pair_mem), 8364 UNSPEC_LDP_FST), 8365 gen_rtx_UNSPEC (any_extend_p ? SImode : GET_MODE (reg2), 8366 gen_rtvec (1, copy_rtx (pair_mem)), 8367 UNSPEC_LDP_SND) 8368 }; 8369 8370 if (any_extend_p) 8371 for (int i = 0; i < 2; i++) 8372 unspecs[i] = gen_rtx_fmt_e (code, DImode, unspecs[i]); 8373 8374 return gen_rtx_PARALLEL (VOIDmode, 8375 gen_rtvec (2, 8376 gen_rtx_SET (reg1, unspecs[0]), 8377 gen_rtx_SET (reg2, unspecs[1]))); 8378 } 8379 8380 /* Return TRUE if return address signing should be enabled for the current 8381 function, otherwise return FALSE. */ 8382 8383 bool 8384 aarch64_return_address_signing_enabled (void) 8385 { 8386 /* This function should only be called after frame laid out. */ 8387 gcc_assert (cfun->machine->frame.laid_out); 8388 8389 /* If signing scope is AARCH_FUNCTION_NON_LEAF, we only sign a leaf function 8390 if its LR is pushed onto stack. */ 8391 return (aarch_ra_sign_scope == AARCH_FUNCTION_ALL 8392 || (aarch_ra_sign_scope == AARCH_FUNCTION_NON_LEAF 8393 && known_ge (cfun->machine->frame.reg_offset[LR_REGNUM], 0))); 8394 } 8395 8396 /* Only used by the arm backend. */ 8397 void aarch_bti_arch_check (void) 8398 {} 8399 8400 /* Return TRUE if Branch Target Identification Mechanism is enabled. */ 8401 bool 8402 aarch_bti_enabled (void) 8403 { 8404 return (aarch_enable_bti == 1); 8405 } 8406 8407 /* Check if INSN is a BTI J insn. */ 8408 bool 8409 aarch_bti_j_insn_p (rtx_insn *insn) 8410 { 8411 if (!insn || !INSN_P (insn)) 8412 return false; 8413 8414 rtx pat = PATTERN (insn); 8415 return GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == UNSPECV_BTI_J; 8416 } 8417 8418 /* Check if X (or any sub-rtx of X) is a PACIASP/PACIBSP instruction. */ 8419 bool 8420 aarch_pac_insn_p (rtx x) 8421 { 8422 if (!INSN_P (x)) 8423 return false; 8424 8425 subrtx_var_iterator::array_type array; 8426 FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (x), ALL) 8427 { 8428 rtx sub = *iter; 8429 if (sub && GET_CODE (sub) == UNSPEC) 8430 { 8431 int unspec_val = XINT (sub, 1); 8432 switch (unspec_val) 8433 { 8434 case UNSPEC_PACIASP: 8435 case UNSPEC_PACIBSP: 8436 return true; 8437 8438 default: 8439 return false; 8440 } 8441 iter.skip_subrtxes (); 8442 } 8443 } 8444 return false; 8445 } 8446 8447 rtx aarch_gen_bti_c (void) 8448 { 8449 return gen_bti_c (); 8450 } 8451 8452 rtx aarch_gen_bti_j (void) 8453 { 8454 return gen_bti_j (); 8455 } 8456 8457 /* The caller is going to use ST1D or LD1D to save or restore an SVE 8458 register in mode MODE at BASE_RTX + OFFSET, where OFFSET is in 8459 the range [1, 16] * GET_MODE_SIZE (MODE). Prepare for this by: 8460 8461 (1) updating BASE_RTX + OFFSET so that it is a legitimate ST1D 8462 or LD1D address 8463 8464 (2) setting PRED to a valid predicate register for the ST1D or LD1D, 8465 if the variable isn't already nonnull 8466 8467 (1) is needed when OFFSET is in the range [8, 16] * GET_MODE_SIZE (MODE). 8468 Handle this case using a temporary base register that is suitable for 8469 all offsets in that range. Use ANCHOR_REG as this base register if it 8470 is nonnull, otherwise create a new register and store it in ANCHOR_REG. */ 8471 8472 static inline void 8473 aarch64_adjust_sve_callee_save_base (machine_mode mode, rtx &base_rtx, 8474 rtx &anchor_reg, poly_int64 &offset, 8475 rtx &ptrue) 8476 { 8477 if (maybe_ge (offset, 8 * GET_MODE_SIZE (mode))) 8478 { 8479 /* This is the maximum valid offset of the anchor from the base. 8480 Lower values would be valid too. */ 8481 poly_int64 anchor_offset = 16 * GET_MODE_SIZE (mode); 8482 if (!anchor_reg) 8483 { 8484 anchor_reg = gen_rtx_REG (Pmode, STACK_CLASH_SVE_CFA_REGNUM); 8485 emit_insn (gen_add3_insn (anchor_reg, base_rtx, 8486 gen_int_mode (anchor_offset, Pmode))); 8487 } 8488 base_rtx = anchor_reg; 8489 offset -= anchor_offset; 8490 } 8491 if (!ptrue) 8492 { 8493 int pred_reg = cfun->machine->frame.spare_pred_reg; 8494 emit_move_insn (gen_rtx_REG (VNx16BImode, pred_reg), 8495 CONSTM1_RTX (VNx16BImode)); 8496 ptrue = gen_rtx_REG (VNx2BImode, pred_reg); 8497 } 8498 } 8499 8500 /* Add a REG_CFA_EXPRESSION note to INSN to say that register REG 8501 is saved at BASE + OFFSET. */ 8502 8503 static void 8504 aarch64_add_cfa_expression (rtx_insn *insn, rtx reg, 8505 rtx base, poly_int64 offset) 8506 { 8507 rtx mem = gen_frame_mem (GET_MODE (reg), 8508 plus_constant (Pmode, base, offset)); 8509 add_reg_note (insn, REG_CFA_EXPRESSION, gen_rtx_SET (mem, reg)); 8510 } 8511 8512 /* Emit code to save the callee-saved registers in REGS. Skip any 8513 write-back candidates if SKIP_WB is true, otherwise consider only 8514 write-back candidates. 8515 8516 The stack pointer is currently BYTES_BELOW_SP bytes above the bottom 8517 of the static frame. HARD_FP_VALID_P is true if the hard frame pointer 8518 has been set up. */ 8519 8520 static void 8521 aarch64_save_callee_saves (poly_int64 bytes_below_sp, 8522 array_slice<unsigned int> regs, bool skip_wb, 8523 bool hard_fp_valid_p) 8524 { 8525 aarch64_frame &frame = cfun->machine->frame; 8526 rtx_insn *insn; 8527 rtx anchor_reg = NULL_RTX, ptrue = NULL_RTX; 8528 8529 auto skip_save_p = [&](unsigned int regno) 8530 { 8531 if (cfun->machine->reg_is_wrapped_separately[regno]) 8532 return true; 8533 8534 if (skip_wb == (regno == frame.wb_push_candidate1 8535 || regno == frame.wb_push_candidate2)) 8536 return true; 8537 8538 return false; 8539 }; 8540 8541 for (unsigned int i = 0; i < regs.size (); ++i) 8542 { 8543 unsigned int regno = regs[i]; 8544 poly_int64 offset; 8545 bool frame_related_p = aarch64_emit_cfi_for_reg_p (regno); 8546 8547 if (skip_save_p (regno)) 8548 continue; 8549 8550 machine_mode mode = aarch64_reg_save_mode (regno); 8551 rtx reg = gen_rtx_REG (mode, regno); 8552 rtx move_src = reg; 8553 offset = frame.reg_offset[regno] - bytes_below_sp; 8554 if (regno == VG_REGNUM) 8555 { 8556 move_src = gen_rtx_REG (DImode, IP0_REGNUM); 8557 emit_move_insn (move_src, gen_int_mode (aarch64_sve_vg, DImode)); 8558 } 8559 rtx base_rtx = stack_pointer_rtx; 8560 poly_int64 sp_offset = offset; 8561 8562 HOST_WIDE_INT const_offset; 8563 if (mode == VNx2DImode && BYTES_BIG_ENDIAN) 8564 aarch64_adjust_sve_callee_save_base (mode, base_rtx, anchor_reg, 8565 offset, ptrue); 8566 else if (GP_REGNUM_P (REGNO (reg)) 8567 && (!offset.is_constant (&const_offset) || const_offset >= 512)) 8568 { 8569 poly_int64 fp_offset = frame.bytes_below_hard_fp - bytes_below_sp; 8570 if (hard_fp_valid_p) 8571 base_rtx = hard_frame_pointer_rtx; 8572 else 8573 { 8574 if (!anchor_reg) 8575 { 8576 anchor_reg = gen_rtx_REG (Pmode, STACK_CLASH_SVE_CFA_REGNUM); 8577 emit_insn (gen_add3_insn (anchor_reg, base_rtx, 8578 gen_int_mode (fp_offset, Pmode))); 8579 } 8580 base_rtx = anchor_reg; 8581 } 8582 offset -= fp_offset; 8583 } 8584 rtx mem = gen_frame_mem (mode, plus_constant (Pmode, base_rtx, offset)); 8585 rtx cfi_mem = gen_frame_mem (mode, plus_constant (Pmode, 8586 stack_pointer_rtx, 8587 sp_offset)); 8588 rtx cfi_set = gen_rtx_SET (cfi_mem, reg); 8589 bool need_cfi_note_p = (base_rtx != stack_pointer_rtx); 8590 8591 unsigned int regno2; 8592 if (!aarch64_sve_mode_p (mode) 8593 && reg == move_src 8594 && i + 1 < regs.size () 8595 && (regno2 = regs[i + 1], !skip_save_p (regno2)) 8596 && known_eq (GET_MODE_SIZE (mode), 8597 frame.reg_offset[regno2] - frame.reg_offset[regno])) 8598 { 8599 rtx reg2 = gen_rtx_REG (mode, regno2); 8600 8601 offset += GET_MODE_SIZE (mode); 8602 insn = emit_insn (aarch64_gen_store_pair (mem, reg, reg2)); 8603 8604 rtx cfi_mem2 8605 = gen_frame_mem (mode, 8606 plus_constant (Pmode, 8607 stack_pointer_rtx, 8608 sp_offset + GET_MODE_SIZE (mode))); 8609 rtx cfi_set2 = gen_rtx_SET (cfi_mem2, reg2); 8610 8611 /* The first part of a frame-related parallel insn is always 8612 assumed to be relevant to the frame calculations; 8613 subsequent parts, are only frame-related if 8614 explicitly marked. */ 8615 if (aarch64_emit_cfi_for_reg_p (regno2)) 8616 RTX_FRAME_RELATED_P (cfi_set2) = 1; 8617 8618 /* Add a REG_FRAME_RELATED_EXPR note since the unspec 8619 representation of stp cannot be understood directly by 8620 dwarf2cfi. */ 8621 rtx par = gen_rtx_PARALLEL (VOIDmode, 8622 gen_rtvec (2, cfi_set, cfi_set2)); 8623 add_reg_note (insn, REG_FRAME_RELATED_EXPR, par); 8624 8625 regno = regno2; 8626 ++i; 8627 } 8628 else 8629 { 8630 if (mode == VNx2DImode && BYTES_BIG_ENDIAN) 8631 { 8632 insn = emit_insn (gen_aarch64_pred_mov (mode, mem, 8633 ptrue, move_src)); 8634 need_cfi_note_p = true; 8635 } 8636 else if (aarch64_sve_mode_p (mode)) 8637 insn = emit_insn (gen_rtx_SET (mem, move_src)); 8638 else 8639 insn = emit_move_insn (mem, move_src); 8640 8641 if (frame_related_p && (need_cfi_note_p || move_src != reg)) 8642 add_reg_note (insn, REG_FRAME_RELATED_EXPR, cfi_set); 8643 } 8644 8645 RTX_FRAME_RELATED_P (insn) = frame_related_p; 8646 8647 /* Emit a fake instruction to indicate that the VG save slot has 8648 been initialized. */ 8649 if (regno == VG_REGNUM) 8650 emit_insn (gen_aarch64_old_vg_saved (move_src, mem)); 8651 } 8652 } 8653 8654 /* Emit code to restore the callee registers in REGS, ignoring pop candidates 8655 and any other registers that are handled separately. Write the appropriate 8656 REG_CFA_RESTORE notes into CFI_OPS. 8657 8658 The stack pointer is currently BYTES_BELOW_SP bytes above the bottom 8659 of the static frame. */ 8660 8661 static void 8662 aarch64_restore_callee_saves (poly_int64 bytes_below_sp, 8663 array_slice<unsigned int> regs, rtx *cfi_ops) 8664 { 8665 aarch64_frame &frame = cfun->machine->frame; 8666 poly_int64 offset; 8667 rtx anchor_reg = NULL_RTX, ptrue = NULL_RTX; 8668 8669 auto skip_restore_p = [&](unsigned int regno) 8670 { 8671 if (cfun->machine->reg_is_wrapped_separately[regno]) 8672 return true; 8673 8674 if (regno == frame.wb_pop_candidate1 8675 || regno == frame.wb_pop_candidate2) 8676 return true; 8677 8678 /* The shadow call stack code restores LR separately. */ 8679 if (frame.is_scs_enabled && regno == LR_REGNUM) 8680 return true; 8681 8682 return false; 8683 }; 8684 8685 for (unsigned int i = 0; i < regs.size (); ++i) 8686 { 8687 unsigned int regno = regs[i]; 8688 bool frame_related_p = aarch64_emit_cfi_for_reg_p (regno); 8689 if (skip_restore_p (regno)) 8690 continue; 8691 8692 machine_mode mode = aarch64_reg_save_mode (regno); 8693 rtx reg = gen_rtx_REG (mode, regno); 8694 offset = frame.reg_offset[regno] - bytes_below_sp; 8695 rtx base_rtx = stack_pointer_rtx; 8696 if (mode == VNx2DImode && BYTES_BIG_ENDIAN) 8697 aarch64_adjust_sve_callee_save_base (mode, base_rtx, anchor_reg, 8698 offset, ptrue); 8699 rtx mem = gen_frame_mem (mode, plus_constant (Pmode, base_rtx, offset)); 8700 8701 unsigned int regno2; 8702 if (!aarch64_sve_mode_p (mode) 8703 && i + 1 < regs.size () 8704 && (regno2 = regs[i + 1], !skip_restore_p (regno2)) 8705 && known_eq (GET_MODE_SIZE (mode), 8706 frame.reg_offset[regno2] - frame.reg_offset[regno])) 8707 { 8708 rtx reg2 = gen_rtx_REG (mode, regno2); 8709 8710 offset += GET_MODE_SIZE (mode); 8711 emit_insn (aarch64_gen_load_pair (reg, reg2, mem)); 8712 8713 *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg2, *cfi_ops); 8714 regno = regno2; 8715 ++i; 8716 } 8717 else if (mode == VNx2DImode && BYTES_BIG_ENDIAN) 8718 emit_insn (gen_aarch64_pred_mov (mode, reg, ptrue, mem)); 8719 else if (aarch64_sve_mode_p (mode)) 8720 emit_insn (gen_rtx_SET (reg, mem)); 8721 else 8722 emit_move_insn (reg, mem); 8723 if (frame_related_p) 8724 *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg, *cfi_ops); 8725 } 8726 } 8727 8728 /* Return true if OFFSET is a signed 4-bit value multiplied by the size 8729 of MODE. */ 8730 8731 static inline bool 8732 offset_4bit_signed_scaled_p (machine_mode mode, poly_int64 offset) 8733 { 8734 HOST_WIDE_INT multiple; 8735 return (constant_multiple_p (offset, GET_MODE_SIZE (mode), &multiple) 8736 && IN_RANGE (multiple, -8, 7)); 8737 } 8738 8739 /* Return true if OFFSET is a signed 6-bit value multiplied by the size 8740 of MODE. */ 8741 8742 static inline bool 8743 offset_6bit_signed_scaled_p (machine_mode mode, poly_int64 offset) 8744 { 8745 HOST_WIDE_INT multiple; 8746 return (constant_multiple_p (offset, GET_MODE_SIZE (mode), &multiple) 8747 && IN_RANGE (multiple, -32, 31)); 8748 } 8749 8750 /* Return true if OFFSET is an unsigned 6-bit value multiplied by the size 8751 of MODE. */ 8752 8753 static inline bool 8754 offset_6bit_unsigned_scaled_p (machine_mode mode, poly_int64 offset) 8755 { 8756 HOST_WIDE_INT multiple; 8757 return (constant_multiple_p (offset, GET_MODE_SIZE (mode), &multiple) 8758 && IN_RANGE (multiple, 0, 63)); 8759 } 8760 8761 /* Return true if OFFSET is a signed 7-bit value multiplied by the size 8762 of MODE. */ 8763 8764 bool 8765 aarch64_offset_7bit_signed_scaled_p (machine_mode mode, poly_int64 offset) 8766 { 8767 HOST_WIDE_INT multiple; 8768 return (constant_multiple_p (offset, GET_MODE_SIZE (mode), &multiple) 8769 && IN_RANGE (multiple, -64, 63)); 8770 } 8771 8772 /* Return true if OFFSET is a signed 9-bit value. */ 8773 8774 bool 8775 aarch64_offset_9bit_signed_unscaled_p (machine_mode mode ATTRIBUTE_UNUSED, 8776 poly_int64 offset) 8777 { 8778 HOST_WIDE_INT const_offset; 8779 return (offset.is_constant (&const_offset) 8780 && IN_RANGE (const_offset, -256, 255)); 8781 } 8782 8783 /* Return true if OFFSET is a signed 9-bit value multiplied by the size 8784 of MODE. */ 8785 8786 static inline bool 8787 offset_9bit_signed_scaled_p (machine_mode mode, poly_int64 offset) 8788 { 8789 HOST_WIDE_INT multiple; 8790 return (constant_multiple_p (offset, GET_MODE_SIZE (mode), &multiple) 8791 && IN_RANGE (multiple, -256, 255)); 8792 } 8793 8794 /* Return true if OFFSET is an unsigned 12-bit value multiplied by the size 8795 of MODE. */ 8796 8797 static inline bool 8798 offset_12bit_unsigned_scaled_p (machine_mode mode, poly_int64 offset) 8799 { 8800 HOST_WIDE_INT multiple; 8801 return (constant_multiple_p (offset, GET_MODE_SIZE (mode), &multiple) 8802 && IN_RANGE (multiple, 0, 4095)); 8803 } 8804 8805 /* Implement TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS. */ 8806 8807 static sbitmap 8808 aarch64_get_separate_components (void) 8809 { 8810 aarch64_frame &frame = cfun->machine->frame; 8811 sbitmap components = sbitmap_alloc (LAST_SAVED_REGNUM + 1); 8812 bitmap_clear (components); 8813 8814 /* The registers we need saved to the frame. */ 8815 bool enables_pstate_sm = aarch64_cfun_enables_pstate_sm (); 8816 for (unsigned regno = 0; regno <= LAST_SAVED_REGNUM; regno++) 8817 if (aarch64_register_saved_on_entry (regno)) 8818 { 8819 /* Disallow shrink wrapping for registers that will be clobbered 8820 by an SMSTART SM in the prologue. */ 8821 if (enables_pstate_sm 8822 && (FP_REGNUM_P (regno) || PR_REGNUM_P (regno))) 8823 continue; 8824 8825 /* Punt on saves and restores that use ST1D and LD1D. We could 8826 try to be smarter, but it would involve making sure that the 8827 spare predicate register itself is safe to use at the save 8828 and restore points. Also, when a frame pointer is being used, 8829 the slots are often out of reach of ST1D and LD1D anyway. */ 8830 machine_mode mode = aarch64_reg_save_mode (regno); 8831 if (mode == VNx2DImode && BYTES_BIG_ENDIAN) 8832 continue; 8833 8834 poly_int64 offset = frame.reg_offset[regno]; 8835 8836 /* Get the offset relative to the register we'll use. */ 8837 if (frame_pointer_needed) 8838 offset -= frame.bytes_below_hard_fp; 8839 8840 /* Check that we can access the stack slot of the register with one 8841 direct load with no adjustments needed. */ 8842 if (aarch64_sve_mode_p (mode) 8843 ? offset_9bit_signed_scaled_p (mode, offset) 8844 : offset_12bit_unsigned_scaled_p (mode, offset)) 8845 bitmap_set_bit (components, regno); 8846 } 8847 8848 /* Don't mess with the hard frame pointer. */ 8849 if (frame_pointer_needed) 8850 bitmap_clear_bit (components, HARD_FRAME_POINTER_REGNUM); 8851 8852 /* If the spare predicate register used by big-endian SVE code 8853 is call-preserved, it must be saved in the main prologue 8854 before any saves that use it. */ 8855 if (frame.spare_pred_reg != INVALID_REGNUM) 8856 bitmap_clear_bit (components, frame.spare_pred_reg); 8857 8858 unsigned reg1 = frame.wb_push_candidate1; 8859 unsigned reg2 = frame.wb_push_candidate2; 8860 /* If registers have been chosen to be stored/restored with 8861 writeback don't interfere with them to avoid having to output explicit 8862 stack adjustment instructions. */ 8863 if (reg2 != INVALID_REGNUM) 8864 bitmap_clear_bit (components, reg2); 8865 if (reg1 != INVALID_REGNUM) 8866 bitmap_clear_bit (components, reg1); 8867 8868 bitmap_clear_bit (components, LR_REGNUM); 8869 bitmap_clear_bit (components, SP_REGNUM); 8870 if (flag_stack_clash_protection) 8871 { 8872 if (frame.sve_save_and_probe != INVALID_REGNUM) 8873 bitmap_clear_bit (components, frame.sve_save_and_probe); 8874 if (frame.hard_fp_save_and_probe != INVALID_REGNUM) 8875 bitmap_clear_bit (components, frame.hard_fp_save_and_probe); 8876 } 8877 8878 /* The VG save sequence needs a temporary GPR. Punt for now on trying 8879 to find one. */ 8880 bitmap_clear_bit (components, VG_REGNUM); 8881 8882 return components; 8883 } 8884 8885 /* Implement TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB. */ 8886 8887 static sbitmap 8888 aarch64_components_for_bb (basic_block bb) 8889 { 8890 bitmap in = DF_LIVE_IN (bb); 8891 bitmap gen = &DF_LIVE_BB_INFO (bb)->gen; 8892 bitmap kill = &DF_LIVE_BB_INFO (bb)->kill; 8893 8894 sbitmap components = sbitmap_alloc (LAST_SAVED_REGNUM + 1); 8895 bitmap_clear (components); 8896 8897 /* Clobbered registers don't generate values in any meaningful sense, 8898 since nothing after the clobber can rely on their value. And we can't 8899 say that partially-clobbered registers are unconditionally killed, 8900 because whether they're killed or not depends on the mode of the 8901 value they're holding. Thus partially call-clobbered registers 8902 appear in neither the kill set nor the gen set. 8903 8904 Check manually for any calls that clobber more of a register than the 8905 current function can. */ 8906 function_abi_aggregator callee_abis; 8907 rtx_insn *insn; 8908 FOR_BB_INSNS (bb, insn) 8909 if (CALL_P (insn)) 8910 callee_abis.note_callee_abi (insn_callee_abi (insn)); 8911 HARD_REG_SET extra_caller_saves = callee_abis.caller_save_regs (*crtl->abi); 8912 8913 /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets. */ 8914 for (unsigned regno = 0; regno <= LAST_SAVED_REGNUM; regno++) 8915 if (!fixed_regs[regno] 8916 && !crtl->abi->clobbers_full_reg_p (regno) 8917 && (TEST_HARD_REG_BIT (extra_caller_saves, regno) 8918 || bitmap_bit_p (in, regno) 8919 || bitmap_bit_p (gen, regno) 8920 || bitmap_bit_p (kill, regno))) 8921 { 8922 bitmap_set_bit (components, regno); 8923 8924 /* If there is a callee-save at an adjacent offset, add it too 8925 to increase the use of LDP/STP. */ 8926 poly_int64 offset = cfun->machine->frame.reg_offset[regno]; 8927 unsigned regno2 = multiple_p (offset, 16) ? regno + 1 : regno - 1; 8928 8929 if (regno2 <= LAST_SAVED_REGNUM) 8930 { 8931 poly_int64 offset2 = cfun->machine->frame.reg_offset[regno2]; 8932 if (regno < regno2 8933 ? known_eq (offset + 8, offset2) 8934 : multiple_p (offset2, 16) && known_eq (offset2 + 8, offset)) 8935 bitmap_set_bit (components, regno2); 8936 } 8937 } 8938 8939 return components; 8940 } 8941 8942 /* Implement TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS. 8943 Nothing to do for aarch64. */ 8944 8945 static void 8946 aarch64_disqualify_components (sbitmap, edge, sbitmap, bool) 8947 { 8948 } 8949 8950 /* Return the next set bit in BMP from START onwards. Return the total number 8951 of bits in BMP if no set bit is found at or after START. */ 8952 8953 static unsigned int 8954 aarch64_get_next_set_bit (sbitmap bmp, unsigned int start) 8955 { 8956 unsigned int nbits = SBITMAP_SIZE (bmp); 8957 if (start == nbits) 8958 return start; 8959 8960 gcc_assert (start < nbits); 8961 for (unsigned int i = start; i < nbits; i++) 8962 if (bitmap_bit_p (bmp, i)) 8963 return i; 8964 8965 return nbits; 8966 } 8967 8968 /* Do the work for aarch64_emit_prologue_components and 8969 aarch64_emit_epilogue_components. COMPONENTS is the bitmap of registers 8970 to save/restore, PROLOGUE_P indicates whether to emit the prologue sequence 8971 for these components or the epilogue sequence. That is, it determines 8972 whether we should emit stores or loads and what kind of CFA notes to attach 8973 to the insns. Otherwise the logic for the two sequences is very 8974 similar. */ 8975 8976 static void 8977 aarch64_process_components (sbitmap components, bool prologue_p) 8978 { 8979 aarch64_frame &frame = cfun->machine->frame; 8980 rtx ptr_reg = gen_rtx_REG (Pmode, frame_pointer_needed 8981 ? HARD_FRAME_POINTER_REGNUM 8982 : STACK_POINTER_REGNUM); 8983 8984 unsigned last_regno = SBITMAP_SIZE (components); 8985 unsigned regno = aarch64_get_next_set_bit (components, R0_REGNUM); 8986 rtx_insn *insn = NULL; 8987 8988 while (regno != last_regno) 8989 { 8990 bool frame_related_p = aarch64_emit_cfi_for_reg_p (regno); 8991 machine_mode mode = aarch64_reg_save_mode (regno); 8992 8993 rtx reg = gen_rtx_REG (mode, regno); 8994 poly_int64 offset = frame.reg_offset[regno]; 8995 if (frame_pointer_needed) 8996 offset -= frame.bytes_below_hard_fp; 8997 8998 rtx addr = plus_constant (Pmode, ptr_reg, offset); 8999 rtx mem = gen_frame_mem (mode, addr); 9000 9001 rtx set = prologue_p ? gen_rtx_SET (mem, reg) : gen_rtx_SET (reg, mem); 9002 unsigned regno2 = aarch64_get_next_set_bit (components, regno + 1); 9003 /* No more registers to handle after REGNO. 9004 Emit a single save/restore and exit. */ 9005 if (regno2 == last_regno) 9006 { 9007 insn = emit_insn (set); 9008 if (frame_related_p) 9009 { 9010 RTX_FRAME_RELATED_P (insn) = 1; 9011 if (prologue_p) 9012 add_reg_note (insn, REG_CFA_OFFSET, copy_rtx (set)); 9013 else 9014 add_reg_note (insn, REG_CFA_RESTORE, reg); 9015 } 9016 break; 9017 } 9018 9019 poly_int64 offset2 = frame.reg_offset[regno2]; 9020 /* The next register is not of the same class or its offset is not 9021 mergeable with the current one into a pair. */ 9022 if (aarch64_sve_mode_p (mode) 9023 || !satisfies_constraint_Ump (mem) 9024 || GP_REGNUM_P (regno) != GP_REGNUM_P (regno2) 9025 || (crtl->abi->id () == ARM_PCS_SIMD && FP_REGNUM_P (regno)) 9026 || maybe_ne ((offset2 - frame.reg_offset[regno]), 9027 GET_MODE_SIZE (mode))) 9028 { 9029 insn = emit_insn (set); 9030 if (frame_related_p) 9031 { 9032 RTX_FRAME_RELATED_P (insn) = 1; 9033 if (prologue_p) 9034 add_reg_note (insn, REG_CFA_OFFSET, copy_rtx (set)); 9035 else 9036 add_reg_note (insn, REG_CFA_RESTORE, reg); 9037 } 9038 9039 regno = regno2; 9040 continue; 9041 } 9042 9043 bool frame_related2_p = aarch64_emit_cfi_for_reg_p (regno2); 9044 9045 /* REGNO2 can be saved/restored in a pair with REGNO. */ 9046 rtx reg2 = gen_rtx_REG (mode, regno2); 9047 if (frame_pointer_needed) 9048 offset2 -= frame.bytes_below_hard_fp; 9049 rtx addr2 = plus_constant (Pmode, ptr_reg, offset2); 9050 rtx mem2 = gen_frame_mem (mode, addr2); 9051 rtx set2 = prologue_p ? gen_rtx_SET (mem2, reg2) 9052 : gen_rtx_SET (reg2, mem2); 9053 9054 if (prologue_p) 9055 insn = emit_insn (aarch64_gen_store_pair (mem, reg, reg2)); 9056 else 9057 insn = emit_insn (aarch64_gen_load_pair (reg, reg2, mem)); 9058 9059 if (frame_related_p || frame_related2_p) 9060 { 9061 RTX_FRAME_RELATED_P (insn) = 1; 9062 if (prologue_p) 9063 { 9064 if (frame_related_p) 9065 add_reg_note (insn, REG_CFA_OFFSET, set); 9066 if (frame_related2_p) 9067 add_reg_note (insn, REG_CFA_OFFSET, set2); 9068 } 9069 else 9070 { 9071 if (frame_related_p) 9072 add_reg_note (insn, REG_CFA_RESTORE, reg); 9073 if (frame_related2_p) 9074 add_reg_note (insn, REG_CFA_RESTORE, reg2); 9075 } 9076 } 9077 9078 regno = aarch64_get_next_set_bit (components, regno2 + 1); 9079 } 9080 } 9081 9082 /* Implement TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS. */ 9083 9084 static void 9085 aarch64_emit_prologue_components (sbitmap components) 9086 { 9087 aarch64_process_components (components, true); 9088 } 9089 9090 /* Implement TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS. */ 9091 9092 static void 9093 aarch64_emit_epilogue_components (sbitmap components) 9094 { 9095 aarch64_process_components (components, false); 9096 } 9097 9098 /* Implement TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS. */ 9099 9100 static void 9101 aarch64_set_handled_components (sbitmap components) 9102 { 9103 for (unsigned regno = 0; regno <= LAST_SAVED_REGNUM; regno++) 9104 if (bitmap_bit_p (components, regno)) 9105 cfun->machine->reg_is_wrapped_separately[regno] = true; 9106 } 9107 9108 /* On AArch64 we have an ABI defined safe buffer. This constant is used to 9109 determining the probe offset for alloca. */ 9110 9111 static HOST_WIDE_INT 9112 aarch64_stack_clash_protection_alloca_probe_range (void) 9113 { 9114 return STACK_CLASH_CALLER_GUARD; 9115 } 9116 9117 /* Emit a stack tie that acts as a scheduling barrier for all previous and 9118 subsequent memory accesses and that requires the stack pointer and REG 9119 to have their current values. REG can be stack_pointer_rtx if no 9120 other register's value needs to be fixed. */ 9121 9122 static void 9123 aarch64_emit_stack_tie (rtx reg) 9124 { 9125 emit_insn (gen_stack_tie (reg, gen_int_mode (REGNO (reg), DImode))); 9126 } 9127 9128 /* Allocate POLY_SIZE bytes of stack space using TEMP1 and TEMP2 as scratch 9129 registers, given that the stack pointer is currently BYTES_BELOW_SP bytes 9130 above the bottom of the static frame. 9131 9132 If POLY_SIZE is not large enough to require a probe this function will only 9133 adjust the stack. When allocating the stack space FRAME_RELATED_P is then 9134 used to indicate if the allocation is frame related. FINAL_ADJUSTMENT_P 9135 indicates whether we are allocating the area below the saved registers. 9136 If we are then we ensure that any allocation larger than the ABI defined 9137 buffer needs a probe so that the invariant of having a 1KB buffer is 9138 maintained. 9139 9140 We emit barriers after each stack adjustment to prevent optimizations from 9141 breaking the invariant that we never drop the stack more than a page. This 9142 invariant is needed to make it easier to correctly handle asynchronous 9143 events, e.g. if we were to allow the stack to be dropped by more than a page 9144 and then have multiple probes up and we take a signal somewhere in between 9145 then the signal handler doesn't know the state of the stack and can make no 9146 assumptions about which pages have been probed. 9147 9148 FORCE_ISA_MODE is AARCH64_FL_SM_ON if any variable component of POLY_SIZE 9149 is measured relative to the SME vector length instead of the current 9150 prevailing vector length. It is 0 otherwise. */ 9151 9152 static void 9153 aarch64_allocate_and_probe_stack_space (rtx temp1, rtx temp2, 9154 poly_int64 poly_size, 9155 poly_int64 bytes_below_sp, 9156 aarch64_feature_flags force_isa_mode, 9157 bool frame_related_p, 9158 bool final_adjustment_p) 9159 { 9160 aarch64_frame &frame = cfun->machine->frame; 9161 HOST_WIDE_INT guard_size 9162 = 1 << param_stack_clash_protection_guard_size; 9163 HOST_WIDE_INT guard_used_by_caller = STACK_CLASH_CALLER_GUARD; 9164 HOST_WIDE_INT byte_sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT; 9165 gcc_assert (multiple_p (poly_size, byte_sp_alignment)); 9166 HOST_WIDE_INT min_probe_threshold 9167 = (final_adjustment_p 9168 ? guard_used_by_caller + byte_sp_alignment 9169 : guard_size - guard_used_by_caller); 9170 poly_int64 frame_size = frame.frame_size; 9171 9172 /* We should always have a positive probe threshold. */ 9173 gcc_assert (min_probe_threshold > 0); 9174 9175 if (flag_stack_clash_protection && !final_adjustment_p) 9176 { 9177 poly_int64 initial_adjust = frame.initial_adjust; 9178 poly_int64 sve_callee_adjust = frame.sve_callee_adjust; 9179 poly_int64 final_adjust = frame.final_adjust; 9180 9181 if (known_eq (frame_size, 0)) 9182 { 9183 dump_stack_clash_frame_info (NO_PROBE_NO_FRAME, false); 9184 } 9185 else if (known_lt (initial_adjust + sve_callee_adjust, 9186 guard_size - guard_used_by_caller) 9187 && known_lt (final_adjust, guard_used_by_caller)) 9188 { 9189 dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true); 9190 } 9191 } 9192 9193 /* If SIZE is not large enough to require probing, just adjust the stack and 9194 exit. */ 9195 if (known_lt (poly_size, min_probe_threshold) 9196 || !flag_stack_clash_protection) 9197 { 9198 aarch64_sub_sp (temp1, temp2, poly_size, force_isa_mode, 9199 frame_related_p); 9200 return; 9201 } 9202 9203 HOST_WIDE_INT size; 9204 /* Handle the SVE non-constant case first. */ 9205 if (!poly_size.is_constant (&size)) 9206 { 9207 if (dump_file) 9208 { 9209 fprintf (dump_file, "Stack clash SVE prologue: "); 9210 print_dec (poly_size, dump_file); 9211 fprintf (dump_file, " bytes, dynamic probing will be required.\n"); 9212 } 9213 9214 /* First calculate the amount of bytes we're actually spilling. */ 9215 aarch64_add_offset (Pmode, temp1, CONST0_RTX (Pmode), 9216 poly_size, temp1, temp2, force_isa_mode, 9217 false, true); 9218 9219 auto initial_cfa_offset = frame.frame_size - bytes_below_sp; 9220 auto final_cfa_offset = initial_cfa_offset + poly_size; 9221 if (frame_related_p) 9222 { 9223 /* This is done to provide unwinding information for the stack 9224 adjustments we're about to do, however to prevent the optimizers 9225 from removing the R11 move and leaving the CFA note (which would be 9226 very wrong) we tie the old and new stack pointer together. 9227 The tie will expand to nothing but the optimizers will not touch 9228 the instruction. */ 9229 rtx stack_ptr_copy = gen_rtx_REG (Pmode, STACK_CLASH_SVE_CFA_REGNUM); 9230 auto *insn = emit_move_insn (stack_ptr_copy, stack_pointer_rtx); 9231 aarch64_emit_stack_tie (stack_ptr_copy); 9232 9233 /* We want the CFA independent of the stack pointer for the 9234 duration of the loop. */ 9235 add_reg_note (insn, REG_CFA_DEF_CFA, 9236 plus_constant (Pmode, stack_ptr_copy, 9237 initial_cfa_offset)); 9238 RTX_FRAME_RELATED_P (insn) = 1; 9239 } 9240 9241 rtx probe_const = gen_int_mode (min_probe_threshold, Pmode); 9242 rtx guard_const = gen_int_mode (guard_size, Pmode); 9243 9244 auto *insn 9245 = emit_insn (gen_probe_sve_stack_clash (Pmode, stack_pointer_rtx, 9246 stack_pointer_rtx, temp1, 9247 probe_const, guard_const)); 9248 9249 /* Now reset the CFA register if needed. */ 9250 if (frame_related_p) 9251 { 9252 add_reg_note (insn, REG_CFA_DEF_CFA, 9253 plus_constant (Pmode, stack_pointer_rtx, 9254 final_cfa_offset)); 9255 RTX_FRAME_RELATED_P (insn) = 1; 9256 } 9257 9258 return; 9259 } 9260 9261 if (dump_file) 9262 fprintf (dump_file, 9263 "Stack clash AArch64 prologue: " HOST_WIDE_INT_PRINT_DEC 9264 " bytes, probing will be required.\n", size); 9265 9266 /* Round size to the nearest multiple of guard_size, and calculate the 9267 residual as the difference between the original size and the rounded 9268 size. */ 9269 HOST_WIDE_INT rounded_size = ROUND_DOWN (size, guard_size); 9270 HOST_WIDE_INT residual = size - rounded_size; 9271 9272 /* We can handle a small number of allocations/probes inline. Otherwise 9273 punt to a loop. */ 9274 if (rounded_size <= STACK_CLASH_MAX_UNROLL_PAGES * guard_size) 9275 { 9276 for (HOST_WIDE_INT i = 0; i < rounded_size; i += guard_size) 9277 { 9278 aarch64_sub_sp (NULL, temp2, guard_size, force_isa_mode, true); 9279 emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, 9280 guard_used_by_caller)); 9281 emit_insn (gen_blockage ()); 9282 } 9283 dump_stack_clash_frame_info (PROBE_INLINE, size != rounded_size); 9284 } 9285 else 9286 { 9287 /* Compute the ending address. */ 9288 aarch64_add_offset (Pmode, temp1, stack_pointer_rtx, -rounded_size, 9289 temp1, NULL, force_isa_mode, false, true); 9290 rtx_insn *insn = get_last_insn (); 9291 9292 /* For the initial allocation, we don't have a frame pointer 9293 set up, so we always need CFI notes. If we're doing the 9294 final allocation, then we may have a frame pointer, in which 9295 case it is the CFA, otherwise we need CFI notes. 9296 9297 We can determine which allocation we are doing by looking at 9298 the value of FRAME_RELATED_P since the final allocations are not 9299 frame related. */ 9300 auto cfa_offset = frame.frame_size - (bytes_below_sp - rounded_size); 9301 if (frame_related_p) 9302 { 9303 /* We want the CFA independent of the stack pointer for the 9304 duration of the loop. */ 9305 add_reg_note (insn, REG_CFA_DEF_CFA, 9306 plus_constant (Pmode, temp1, cfa_offset)); 9307 RTX_FRAME_RELATED_P (insn) = 1; 9308 } 9309 9310 /* This allocates and probes the stack. Note that this re-uses some of 9311 the existing Ada stack protection code. However we are guaranteed not 9312 to enter the non loop or residual branches of that code. 9313 9314 The non-loop part won't be entered because if our allocation amount 9315 doesn't require a loop, the case above would handle it. 9316 9317 The residual amount won't be entered because TEMP1 is a mutliple of 9318 the allocation size. The residual will always be 0. As such, the only 9319 part we are actually using from that code is the loop setup. The 9320 actual probing is done in aarch64_output_probe_stack_range. */ 9321 insn = emit_insn (gen_probe_stack_range (stack_pointer_rtx, 9322 stack_pointer_rtx, temp1)); 9323 9324 /* Now reset the CFA register if needed. */ 9325 if (frame_related_p) 9326 { 9327 add_reg_note (insn, REG_CFA_DEF_CFA, 9328 plus_constant (Pmode, stack_pointer_rtx, cfa_offset)); 9329 RTX_FRAME_RELATED_P (insn) = 1; 9330 } 9331 9332 emit_insn (gen_blockage ()); 9333 dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size); 9334 } 9335 9336 /* Handle any residuals. Residuals of at least MIN_PROBE_THRESHOLD have to 9337 be probed. This maintains the requirement that each page is probed at 9338 least once. For initial probing we probe only if the allocation is 9339 more than GUARD_SIZE - buffer, and below the saved registers we probe 9340 if the amount is larger than buffer. GUARD_SIZE - buffer + buffer == 9341 GUARD_SIZE. This works that for any allocation that is large enough to 9342 trigger a probe here, we'll have at least one, and if they're not large 9343 enough for this code to emit anything for them, The page would have been 9344 probed by the saving of FP/LR either by this function or any callees. If 9345 we don't have any callees then we won't have more stack adjustments and so 9346 are still safe. */ 9347 if (residual) 9348 { 9349 gcc_assert (guard_used_by_caller + byte_sp_alignment <= size); 9350 9351 /* If we're doing final adjustments, and we've done any full page 9352 allocations then any residual needs to be probed. */ 9353 if (final_adjustment_p && rounded_size != 0) 9354 min_probe_threshold = 0; 9355 9356 aarch64_sub_sp (temp1, temp2, residual, force_isa_mode, frame_related_p); 9357 if (residual >= min_probe_threshold) 9358 { 9359 if (dump_file) 9360 fprintf (dump_file, 9361 "Stack clash AArch64 prologue residuals: " 9362 HOST_WIDE_INT_PRINT_DEC " bytes, probing will be required." 9363 "\n", residual); 9364 9365 emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx, 9366 guard_used_by_caller)); 9367 emit_insn (gen_blockage ()); 9368 } 9369 } 9370 } 9371 9372 /* Implement TARGET_EXTRA_LIVE_ON_ENTRY. */ 9373 9374 void 9375 aarch64_extra_live_on_entry (bitmap regs) 9376 { 9377 if (TARGET_ZA) 9378 { 9379 bitmap_set_bit (regs, LOWERING_REGNUM); 9380 bitmap_set_bit (regs, SME_STATE_REGNUM); 9381 bitmap_set_bit (regs, TPIDR2_SETUP_REGNUM); 9382 bitmap_set_bit (regs, ZA_FREE_REGNUM); 9383 bitmap_set_bit (regs, ZA_SAVED_REGNUM); 9384 9385 /* The only time ZA can't have live contents on entry is when 9386 the function explicitly treats it as a pure output. */ 9387 auto za_flags = aarch64_cfun_shared_flags ("za"); 9388 if (za_flags != (AARCH64_STATE_SHARED | AARCH64_STATE_OUT)) 9389 bitmap_set_bit (regs, ZA_REGNUM); 9390 9391 /* Since ZT0 is call-clobbered, it is only live on input if 9392 it is explicitly shared, and is not a pure output. */ 9393 auto zt0_flags = aarch64_cfun_shared_flags ("zt0"); 9394 if (zt0_flags != 0 9395 && zt0_flags != (AARCH64_STATE_SHARED | AARCH64_STATE_OUT)) 9396 bitmap_set_bit (regs, ZT0_REGNUM); 9397 } 9398 } 9399 9400 /* Return 1 if the register is used by the epilogue. We need to say the 9401 return register is used, but only after epilogue generation is complete. 9402 Note that in the case of sibcalls, the values "used by the epilogue" are 9403 considered live at the start of the called function. */ 9404 9405 int 9406 aarch64_epilogue_uses (int regno) 9407 { 9408 if (epilogue_completed) 9409 { 9410 if (regno == LR_REGNUM) 9411 return 1; 9412 } 9413 if (regno == LOWERING_REGNUM && TARGET_ZA) 9414 return 1; 9415 if (regno == SME_STATE_REGNUM && TARGET_ZA) 9416 return 1; 9417 if (regno == TPIDR2_SETUP_REGNUM && TARGET_ZA) 9418 return 1; 9419 /* If the function shares SME state with its caller, ensure that that 9420 data is not in the lazy save buffer on exit. */ 9421 if (regno == ZA_SAVED_REGNUM && aarch64_cfun_incoming_pstate_za () != 0) 9422 return 1; 9423 if (regno == ZA_REGNUM && aarch64_cfun_shared_flags ("za") != 0) 9424 return 1; 9425 if (regno == ZT0_REGNUM && aarch64_cfun_shared_flags ("zt0") != 0) 9426 return 1; 9427 return 0; 9428 } 9429 9430 /* Implement TARGET_USE_LATE_PROLOGUE_EPILOGUE. */ 9431 9432 static bool 9433 aarch64_use_late_prologue_epilogue () 9434 { 9435 return aarch64_cfun_enables_pstate_sm (); 9436 } 9437 9438 /* The current function's frame has a save slot for the incoming state 9439 of SVCR. Return a legitimate memory for the slot, based on the hard 9440 frame pointer. */ 9441 9442 static rtx 9443 aarch64_old_svcr_mem () 9444 { 9445 gcc_assert (frame_pointer_needed 9446 && known_ge (cfun->machine->frame.old_svcr_offset, 0)); 9447 rtx base = hard_frame_pointer_rtx; 9448 poly_int64 offset = (0 9449 /* hard fp -> bottom of frame. */ 9450 - cfun->machine->frame.bytes_below_hard_fp 9451 /* bottom of frame -> save slot. */ 9452 + cfun->machine->frame.old_svcr_offset); 9453 return gen_frame_mem (DImode, plus_constant (Pmode, base, offset)); 9454 } 9455 9456 /* The current function's frame has a save slot for the incoming state 9457 of SVCR. Load the slot into register REGNO and return the register. */ 9458 9459 static rtx 9460 aarch64_read_old_svcr (unsigned int regno) 9461 { 9462 rtx svcr = gen_rtx_REG (DImode, regno); 9463 emit_move_insn (svcr, aarch64_old_svcr_mem ()); 9464 return svcr; 9465 } 9466 9467 /* Like the rtx version of aarch64_guard_switch_pstate_sm, but first 9468 load the incoming value of SVCR from its save slot into temporary 9469 register REGNO. */ 9470 9471 static rtx_insn * 9472 aarch64_guard_switch_pstate_sm (unsigned int regno, 9473 aarch64_feature_flags local_mode) 9474 { 9475 rtx old_svcr = aarch64_read_old_svcr (regno); 9476 return aarch64_guard_switch_pstate_sm (old_svcr, local_mode); 9477 } 9478 9479 /* AArch64 stack frames generated by this compiler look like: 9480 9481 +-------------------------------+ 9482 | | 9483 | incoming stack arguments | 9484 | | 9485 +-------------------------------+ 9486 | | <-- incoming stack pointer (aligned) 9487 | callee-allocated save area | 9488 | for register varargs | 9489 | | 9490 +-------------------------------+ 9491 | local variables (1) | <-- frame_pointer_rtx 9492 | | 9493 +-------------------------------+ 9494 | padding (1) | 9495 +-------------------------------+ 9496 | callee-saved registers | 9497 +-------------------------------+ 9498 | LR' | 9499 +-------------------------------+ 9500 | FP' | 9501 +-------------------------------+ <-- hard_frame_pointer_rtx (aligned) 9502 | SVE vector registers | 9503 +-------------------------------+ 9504 | SVE predicate registers | 9505 +-------------------------------+ 9506 | local variables (2) | 9507 +-------------------------------+ 9508 | padding (2) | 9509 +-------------------------------+ 9510 | dynamic allocation | 9511 +-------------------------------+ 9512 | padding | 9513 +-------------------------------+ 9514 | outgoing stack arguments | <-- arg_pointer 9515 | | 9516 +-------------------------------+ 9517 | | <-- stack_pointer_rtx (aligned) 9518 9519 The regions marked (1) and (2) are mutually exclusive. (2) is used 9520 when aarch64_save_regs_above_locals_p is true. 9521 9522 Dynamic stack allocations via alloca() decrease stack_pointer_rtx 9523 but leave frame_pointer_rtx and hard_frame_pointer_rtx 9524 unchanged. 9525 9526 By default for stack-clash we assume the guard is at least 64KB, but this 9527 value is configurable to either 4KB or 64KB. We also force the guard size to 9528 be the same as the probing interval and both values are kept in sync. 9529 9530 With those assumptions the callee can allocate up to 63KB (or 3KB depending 9531 on the guard size) of stack space without probing. 9532 9533 When probing is needed, we emit a probe at the start of the prologue 9534 and every PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE bytes thereafter. 9535 9536 We can also use register saves as probes. These are stored in 9537 sve_save_and_probe and hard_fp_save_and_probe. 9538 9539 For outgoing arguments we probe if the size is larger than 1KB, such that 9540 the ABI specified buffer is maintained for the next callee. 9541 9542 The following registers are reserved during frame layout and should not be 9543 used for any other purpose: 9544 9545 - r11: Used by stack clash protection when SVE is enabled, and also 9546 as an anchor register when saving and restoring registers 9547 - r12(EP0) and r13(EP1): Used as temporaries for stack adjustment. 9548 - r14 and r15: Used for speculation tracking. 9549 - r16(IP0), r17(IP1): Used by indirect tailcalls. 9550 - r30(LR), r29(FP): Used by standard frame layout. 9551 9552 These registers must be avoided in frame layout related code unless the 9553 explicit intention is to interact with one of the features listed above. */ 9554 9555 /* Generate the prologue instructions for entry into a function. 9556 Establish the stack frame by decreasing the stack pointer with a 9557 properly calculated size and, if necessary, create a frame record 9558 filled with the values of LR and previous frame pointer. The 9559 current FP is also set up if it is in use. */ 9560 9561 void 9562 aarch64_expand_prologue (void) 9563 { 9564 aarch64_frame &frame = cfun->machine->frame; 9565 poly_int64 frame_size = frame.frame_size; 9566 poly_int64 initial_adjust = frame.initial_adjust; 9567 HOST_WIDE_INT callee_adjust = frame.callee_adjust; 9568 poly_int64 final_adjust = frame.final_adjust; 9569 poly_int64 sve_callee_adjust = frame.sve_callee_adjust; 9570 unsigned reg1 = frame.wb_push_candidate1; 9571 unsigned reg2 = frame.wb_push_candidate2; 9572 bool emit_frame_chain = frame.emit_frame_chain; 9573 rtx_insn *insn; 9574 aarch64_feature_flags force_isa_mode = 0; 9575 if (aarch64_cfun_enables_pstate_sm ()) 9576 force_isa_mode = AARCH64_FL_SM_ON; 9577 9578 if (flag_stack_clash_protection 9579 && known_eq (callee_adjust, 0) 9580 && known_lt (frame.reg_offset[VG_REGNUM], 0)) 9581 { 9582 /* Fold the SVE allocation into the initial allocation. 9583 We don't do this in aarch64_layout_arg to avoid pessimizing 9584 the epilogue code. */ 9585 initial_adjust += sve_callee_adjust; 9586 sve_callee_adjust = 0; 9587 } 9588 9589 /* Sign return address for functions. */ 9590 if (aarch64_return_address_signing_enabled ()) 9591 { 9592 switch (aarch64_ra_sign_key) 9593 { 9594 case AARCH64_KEY_A: 9595 insn = emit_insn (gen_paciasp ()); 9596 break; 9597 case AARCH64_KEY_B: 9598 insn = emit_insn (gen_pacibsp ()); 9599 break; 9600 default: 9601 gcc_unreachable (); 9602 } 9603 add_reg_note (insn, REG_CFA_TOGGLE_RA_MANGLE, const0_rtx); 9604 RTX_FRAME_RELATED_P (insn) = 1; 9605 } 9606 9607 /* Push return address to shadow call stack. */ 9608 if (frame.is_scs_enabled) 9609 emit_insn (gen_scs_push ()); 9610 9611 if (flag_stack_usage_info) 9612 current_function_static_stack_size = constant_lower_bound (frame_size); 9613 9614 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK) 9615 { 9616 if (crtl->is_leaf && !cfun->calls_alloca) 9617 { 9618 if (maybe_gt (frame_size, PROBE_INTERVAL) 9619 && maybe_gt (frame_size, get_stack_check_protect ())) 9620 aarch64_emit_probe_stack_range (get_stack_check_protect (), 9621 (frame_size 9622 - get_stack_check_protect ())); 9623 } 9624 else if (maybe_gt (frame_size, 0)) 9625 aarch64_emit_probe_stack_range (get_stack_check_protect (), frame_size); 9626 } 9627 9628 rtx tmp0_rtx = gen_rtx_REG (Pmode, EP0_REGNUM); 9629 rtx tmp1_rtx = gen_rtx_REG (Pmode, EP1_REGNUM); 9630 9631 /* In theory we should never have both an initial adjustment 9632 and a callee save adjustment. Verify that is the case since the 9633 code below does not handle it for -fstack-clash-protection. */ 9634 gcc_assert (known_eq (initial_adjust, 0) || callee_adjust == 0); 9635 9636 /* The offset of the current SP from the bottom of the static frame. */ 9637 poly_int64 bytes_below_sp = frame_size; 9638 9639 /* Will only probe if the initial adjustment is larger than the guard 9640 less the amount of the guard reserved for use by the caller's 9641 outgoing args. */ 9642 aarch64_allocate_and_probe_stack_space (tmp0_rtx, tmp1_rtx, initial_adjust, 9643 bytes_below_sp, force_isa_mode, 9644 true, false); 9645 bytes_below_sp -= initial_adjust; 9646 9647 if (callee_adjust != 0) 9648 { 9649 aarch64_push_regs (reg1, reg2, callee_adjust); 9650 bytes_below_sp -= callee_adjust; 9651 } 9652 9653 if (emit_frame_chain) 9654 { 9655 /* The offset of the frame chain record (if any) from the current SP. */ 9656 poly_int64 chain_offset = (initial_adjust + callee_adjust 9657 - frame.bytes_above_hard_fp); 9658 gcc_assert (known_ge (chain_offset, 0)); 9659 9660 gcc_assert (reg1 == R29_REGNUM && reg2 == R30_REGNUM); 9661 if (callee_adjust == 0) 9662 aarch64_save_callee_saves (bytes_below_sp, frame.saved_gprs, 9663 false, false); 9664 else 9665 gcc_assert (known_eq (chain_offset, 0)); 9666 aarch64_add_offset (Pmode, hard_frame_pointer_rtx, 9667 stack_pointer_rtx, chain_offset, 9668 tmp1_rtx, tmp0_rtx, force_isa_mode, 9669 frame_pointer_needed); 9670 if (frame_pointer_needed && !frame_size.is_constant ()) 9671 { 9672 /* Variable-sized frames need to describe the save slot 9673 address using DW_CFA_expression rather than DW_CFA_offset. 9674 This means that, without taking further action, the 9675 locations of the registers that we've already saved would 9676 remain based on the stack pointer even after we redefine 9677 the CFA based on the frame pointer. We therefore need new 9678 DW_CFA_expressions to re-express the save slots with addresses 9679 based on the frame pointer. */ 9680 rtx_insn *insn = get_last_insn (); 9681 gcc_assert (RTX_FRAME_RELATED_P (insn)); 9682 9683 /* Add an explicit CFA definition if this was previously 9684 implicit. */ 9685 if (!find_reg_note (insn, REG_CFA_ADJUST_CFA, NULL_RTX)) 9686 { 9687 rtx src = plus_constant (Pmode, stack_pointer_rtx, chain_offset); 9688 add_reg_note (insn, REG_CFA_ADJUST_CFA, 9689 gen_rtx_SET (hard_frame_pointer_rtx, src)); 9690 } 9691 9692 /* Change the save slot expressions for the registers that 9693 we've already saved. */ 9694 aarch64_add_cfa_expression (insn, regno_reg_rtx[reg2], 9695 hard_frame_pointer_rtx, UNITS_PER_WORD); 9696 aarch64_add_cfa_expression (insn, regno_reg_rtx[reg1], 9697 hard_frame_pointer_rtx, 0); 9698 } 9699 aarch64_emit_stack_tie (hard_frame_pointer_rtx); 9700 } 9701 9702 aarch64_save_callee_saves (bytes_below_sp, frame.saved_gprs, true, 9703 emit_frame_chain); 9704 if (maybe_ge (frame.reg_offset[VG_REGNUM], 0)) 9705 { 9706 unsigned int saved_regs[] = { VG_REGNUM }; 9707 aarch64_save_callee_saves (bytes_below_sp, saved_regs, true, 9708 emit_frame_chain); 9709 } 9710 if (maybe_ne (sve_callee_adjust, 0)) 9711 { 9712 gcc_assert (!flag_stack_clash_protection 9713 || known_eq (initial_adjust, 0) 9714 /* The VG save isn't shrink-wrapped and so serves as 9715 a probe of the initial allocation. */ 9716 || known_eq (frame.reg_offset[VG_REGNUM], bytes_below_sp)); 9717 aarch64_allocate_and_probe_stack_space (tmp1_rtx, tmp0_rtx, 9718 sve_callee_adjust, 9719 bytes_below_sp, force_isa_mode, 9720 !frame_pointer_needed, false); 9721 bytes_below_sp -= sve_callee_adjust; 9722 } 9723 aarch64_save_callee_saves (bytes_below_sp, frame.saved_prs, true, 9724 emit_frame_chain); 9725 aarch64_save_callee_saves (bytes_below_sp, frame.saved_fprs, true, 9726 emit_frame_chain); 9727 9728 /* We may need to probe the final adjustment if it is larger than the guard 9729 that is assumed by the called. */ 9730 aarch64_allocate_and_probe_stack_space (tmp1_rtx, tmp0_rtx, final_adjust, 9731 bytes_below_sp, force_isa_mode, 9732 !frame_pointer_needed, true); 9733 bytes_below_sp -= final_adjust; 9734 gcc_assert (known_eq (bytes_below_sp, 0)); 9735 if (emit_frame_chain && maybe_ne (final_adjust, 0)) 9736 aarch64_emit_stack_tie (hard_frame_pointer_rtx); 9737 9738 /* Save the incoming value of PSTATE.SM, if required. Code further 9739 down does this for locally-streaming functions. */ 9740 if (known_ge (frame.old_svcr_offset, 0) 9741 && !aarch64_cfun_enables_pstate_sm ()) 9742 { 9743 rtx mem = aarch64_old_svcr_mem (); 9744 MEM_VOLATILE_P (mem) = 1; 9745 if (TARGET_SME) 9746 { 9747 rtx reg = gen_rtx_REG (DImode, IP0_REGNUM); 9748 emit_insn (gen_aarch64_read_svcr (reg)); 9749 emit_move_insn (mem, reg); 9750 } 9751 else 9752 { 9753 rtx old_r0 = NULL_RTX, old_r1 = NULL_RTX; 9754 auto &args = crtl->args.info; 9755 if (args.aapcs_ncrn > 0) 9756 { 9757 old_r0 = gen_rtx_REG (DImode, PROBE_STACK_FIRST_REGNUM); 9758 emit_move_insn (old_r0, gen_rtx_REG (DImode, R0_REGNUM)); 9759 } 9760 if (args.aapcs_ncrn > 1) 9761 { 9762 old_r1 = gen_rtx_REG (DImode, PROBE_STACK_SECOND_REGNUM); 9763 emit_move_insn (old_r1, gen_rtx_REG (DImode, R1_REGNUM)); 9764 } 9765 emit_insn (gen_aarch64_get_sme_state ()); 9766 emit_move_insn (mem, gen_rtx_REG (DImode, R0_REGNUM)); 9767 if (old_r0) 9768 emit_move_insn (gen_rtx_REG (DImode, R0_REGNUM), old_r0); 9769 if (old_r1) 9770 emit_move_insn (gen_rtx_REG (DImode, R1_REGNUM), old_r1); 9771 } 9772 } 9773 9774 /* Enable PSTATE.SM, if required. */ 9775 if (aarch64_cfun_enables_pstate_sm ()) 9776 { 9777 rtx_insn *guard_label = nullptr; 9778 if (known_ge (cfun->machine->frame.old_svcr_offset, 0)) 9779 { 9780 /* The current function is streaming-compatible. Save the 9781 original state of PSTATE.SM. */ 9782 rtx svcr = gen_rtx_REG (DImode, IP0_REGNUM); 9783 emit_insn (gen_aarch64_read_svcr (svcr)); 9784 emit_move_insn (aarch64_old_svcr_mem (), svcr); 9785 guard_label = aarch64_guard_switch_pstate_sm (svcr, 9786 aarch64_isa_flags); 9787 } 9788 aarch64_sme_mode_switch_regs args_switch; 9789 auto &args = crtl->args.info; 9790 for (unsigned int i = 0; i < args.num_sme_mode_switch_args; ++i) 9791 { 9792 rtx x = args.sme_mode_switch_args[i]; 9793 args_switch.add_reg (GET_MODE (x), REGNO (x)); 9794 } 9795 args_switch.emit_prologue (); 9796 emit_insn (gen_aarch64_smstart_sm ()); 9797 args_switch.emit_epilogue (); 9798 if (guard_label) 9799 emit_label (guard_label); 9800 } 9801 } 9802 9803 /* Return TRUE if we can use a simple_return insn. 9804 9805 This function checks whether the callee saved stack is empty, which 9806 means no restore actions are need. The pro_and_epilogue will use 9807 this to check whether shrink-wrapping opt is feasible. */ 9808 9809 bool 9810 aarch64_use_return_insn_p (void) 9811 { 9812 if (!reload_completed) 9813 return false; 9814 9815 if (crtl->profile) 9816 return false; 9817 9818 return known_eq (cfun->machine->frame.frame_size, 0); 9819 } 9820 9821 /* Generate the epilogue instructions for returning from a function. 9822 This is almost exactly the reverse of the prolog sequence, except 9823 that we need to insert barriers to avoid scheduling loads that read 9824 from a deallocated stack, and we optimize the unwind records by 9825 emitting them all together if possible. */ 9826 void 9827 aarch64_expand_epilogue (rtx_call_insn *sibcall) 9828 { 9829 aarch64_frame &frame = cfun->machine->frame; 9830 poly_int64 initial_adjust = frame.initial_adjust; 9831 HOST_WIDE_INT callee_adjust = frame.callee_adjust; 9832 poly_int64 final_adjust = frame.final_adjust; 9833 poly_int64 sve_callee_adjust = frame.sve_callee_adjust; 9834 poly_int64 bytes_below_hard_fp = frame.bytes_below_hard_fp; 9835 unsigned reg1 = frame.wb_pop_candidate1; 9836 unsigned reg2 = frame.wb_pop_candidate2; 9837 rtx cfi_ops = NULL; 9838 rtx_insn *insn; 9839 /* A stack clash protection prologue may not have left EP0_REGNUM or 9840 EP1_REGNUM in a usable state. The same is true for allocations 9841 with an SVE component, since we then need both temporary registers 9842 for each allocation. For stack clash we are in a usable state if 9843 the adjustment is less than GUARD_SIZE - GUARD_USED_BY_CALLER. */ 9844 HOST_WIDE_INT guard_size 9845 = 1 << param_stack_clash_protection_guard_size; 9846 HOST_WIDE_INT guard_used_by_caller = STACK_CLASH_CALLER_GUARD; 9847 aarch64_feature_flags force_isa_mode = 0; 9848 if (aarch64_cfun_enables_pstate_sm ()) 9849 force_isa_mode = AARCH64_FL_SM_ON; 9850 9851 /* We can re-use the registers when: 9852 9853 (a) the deallocation amount is the same as the corresponding 9854 allocation amount (which is false if we combine the initial 9855 and SVE callee save allocations in the prologue); and 9856 9857 (b) the allocation amount doesn't need a probe (which is false 9858 if the amount is guard_size - guard_used_by_caller or greater). 9859 9860 In such situations the register should remain live with the correct 9861 value. */ 9862 bool can_inherit_p = (initial_adjust.is_constant () 9863 && final_adjust.is_constant () 9864 && (!flag_stack_clash_protection 9865 || (known_lt (initial_adjust, 9866 guard_size - guard_used_by_caller) 9867 && known_eq (sve_callee_adjust, 0)))); 9868 9869 /* We need to add memory barrier to prevent read from deallocated stack. */ 9870 bool need_barrier_p 9871 = maybe_ne (get_frame_size () 9872 + frame.saved_varargs_size, 0); 9873 9874 /* Reset PSTATE.SM, if required. */ 9875 if (aarch64_cfun_enables_pstate_sm ()) 9876 { 9877 rtx_insn *guard_label = nullptr; 9878 if (known_ge (cfun->machine->frame.old_svcr_offset, 0)) 9879 guard_label = aarch64_guard_switch_pstate_sm (IP0_REGNUM, 9880 aarch64_isa_flags); 9881 aarch64_sme_mode_switch_regs return_switch; 9882 if (sibcall) 9883 return_switch.add_call_args (sibcall); 9884 else if (crtl->return_rtx && REG_P (crtl->return_rtx)) 9885 return_switch.add_reg (GET_MODE (crtl->return_rtx), 9886 REGNO (crtl->return_rtx)); 9887 return_switch.emit_prologue (); 9888 emit_insn (gen_aarch64_smstop_sm ()); 9889 return_switch.emit_epilogue (); 9890 if (guard_label) 9891 emit_label (guard_label); 9892 } 9893 9894 /* Emit a barrier to prevent loads from a deallocated stack. */ 9895 if (maybe_gt (final_adjust, crtl->outgoing_args_size) 9896 || cfun->calls_alloca 9897 || crtl->calls_eh_return) 9898 { 9899 aarch64_emit_stack_tie (stack_pointer_rtx); 9900 need_barrier_p = false; 9901 } 9902 9903 /* Restore the stack pointer from the frame pointer if it may not 9904 be the same as the stack pointer. */ 9905 rtx tmp0_rtx = gen_rtx_REG (Pmode, EP0_REGNUM); 9906 rtx tmp1_rtx = gen_rtx_REG (Pmode, EP1_REGNUM); 9907 if (frame_pointer_needed 9908 && (maybe_ne (final_adjust, 0) || cfun->calls_alloca)) 9909 /* If writeback is used when restoring callee-saves, the CFA 9910 is restored on the instruction doing the writeback. */ 9911 aarch64_add_offset (Pmode, stack_pointer_rtx, 9912 hard_frame_pointer_rtx, 9913 -bytes_below_hard_fp + final_adjust, 9914 tmp1_rtx, tmp0_rtx, force_isa_mode, 9915 callee_adjust == 0); 9916 else 9917 /* The case where we need to re-use the register here is very rare, so 9918 avoid the complicated condition and just always emit a move if the 9919 immediate doesn't fit. */ 9920 aarch64_add_sp (tmp1_rtx, tmp0_rtx, final_adjust, force_isa_mode, true); 9921 9922 /* Restore the vector registers before the predicate registers, 9923 so that we can use P4 as a temporary for big-endian SVE frames. */ 9924 aarch64_restore_callee_saves (final_adjust, frame.saved_fprs, &cfi_ops); 9925 aarch64_restore_callee_saves (final_adjust, frame.saved_prs, &cfi_ops); 9926 if (maybe_ne (sve_callee_adjust, 0)) 9927 aarch64_add_sp (NULL_RTX, NULL_RTX, sve_callee_adjust, 9928 force_isa_mode, true); 9929 9930 /* When shadow call stack is enabled, the scs_pop in the epilogue will 9931 restore x30, we don't need to restore x30 again in the traditional 9932 way. */ 9933 aarch64_restore_callee_saves (final_adjust + sve_callee_adjust, 9934 frame.saved_gprs, &cfi_ops); 9935 9936 if (need_barrier_p) 9937 aarch64_emit_stack_tie (stack_pointer_rtx); 9938 9939 if (callee_adjust != 0) 9940 aarch64_pop_regs (reg1, reg2, callee_adjust, &cfi_ops); 9941 9942 /* If we have no register restore information, the CFA must have been 9943 defined in terms of the stack pointer since the end of the prologue. */ 9944 gcc_assert (cfi_ops || !frame_pointer_needed); 9945 9946 if (cfi_ops && (callee_adjust != 0 || maybe_gt (initial_adjust, 65536))) 9947 { 9948 /* Emit delayed restores and set the CFA to be SP + initial_adjust. */ 9949 insn = get_last_insn (); 9950 rtx new_cfa = plus_constant (Pmode, stack_pointer_rtx, initial_adjust); 9951 REG_NOTES (insn) = alloc_reg_note (REG_CFA_DEF_CFA, new_cfa, cfi_ops); 9952 RTX_FRAME_RELATED_P (insn) = 1; 9953 cfi_ops = NULL; 9954 } 9955 9956 /* Liveness of EP0_REGNUM can not be trusted across function calls either, so 9957 add restriction on emit_move optimization to leaf functions. */ 9958 aarch64_add_sp (tmp0_rtx, tmp1_rtx, initial_adjust, force_isa_mode, 9959 (!can_inherit_p || !crtl->is_leaf 9960 || df_regs_ever_live_p (EP0_REGNUM))); 9961 9962 if (cfi_ops) 9963 { 9964 /* Emit delayed restores and reset the CFA to be SP. */ 9965 insn = get_last_insn (); 9966 cfi_ops = alloc_reg_note (REG_CFA_DEF_CFA, stack_pointer_rtx, cfi_ops); 9967 REG_NOTES (insn) = cfi_ops; 9968 RTX_FRAME_RELATED_P (insn) = 1; 9969 } 9970 9971 /* Pop return address from shadow call stack. */ 9972 if (frame.is_scs_enabled) 9973 { 9974 machine_mode mode = aarch64_reg_save_mode (R30_REGNUM); 9975 rtx reg = gen_rtx_REG (mode, R30_REGNUM); 9976 9977 insn = emit_insn (gen_scs_pop ()); 9978 add_reg_note (insn, REG_CFA_RESTORE, reg); 9979 RTX_FRAME_RELATED_P (insn) = 1; 9980 } 9981 9982 /* Stack adjustment for exception handler. */ 9983 if (crtl->calls_eh_return && !sibcall) 9984 { 9985 /* If the EH_RETURN_TAKEN_RTX flag is set then we need 9986 to unwind the stack and jump to the handler, otherwise 9987 skip this eh_return logic and continue with normal 9988 return after the label. We have already reset the CFA 9989 to be SP; letting the CFA move during this adjustment 9990 is just as correct as retaining the CFA from the body 9991 of the function. Therefore, do nothing special. */ 9992 rtx_code_label *label = gen_label_rtx (); 9993 rtx x = aarch64_gen_compare_zero_and_branch (EQ, EH_RETURN_TAKEN_RTX, 9994 label); 9995 rtx jump = emit_jump_insn (x); 9996 JUMP_LABEL (jump) = label; 9997 LABEL_NUSES (label)++; 9998 emit_insn (gen_add2_insn (stack_pointer_rtx, 9999 EH_RETURN_STACKADJ_RTX)); 10000 emit_jump_insn (gen_indirect_jump (EH_RETURN_HANDLER_RTX)); 10001 emit_barrier (); 10002 emit_label (label); 10003 } 10004 10005 /* We prefer to emit the combined return/authenticate instruction RETAA, 10006 however there are three cases in which we must instead emit an explicit 10007 authentication instruction. 10008 10009 1) Sibcalls don't return in a normal way, so if we're about to call one 10010 we must authenticate. 10011 10012 2) The RETAA instruction is not available without FEAT_PAuth, so if we 10013 are generating code for !TARGET_PAUTH we can't use it and must 10014 explicitly authenticate. 10015 */ 10016 if (aarch64_return_address_signing_enabled () 10017 && (sibcall || !TARGET_PAUTH)) 10018 { 10019 switch (aarch64_ra_sign_key) 10020 { 10021 case AARCH64_KEY_A: 10022 insn = emit_insn (gen_autiasp ()); 10023 break; 10024 case AARCH64_KEY_B: 10025 insn = emit_insn (gen_autibsp ()); 10026 break; 10027 default: 10028 gcc_unreachable (); 10029 } 10030 add_reg_note (insn, REG_CFA_TOGGLE_RA_MANGLE, const0_rtx); 10031 RTX_FRAME_RELATED_P (insn) = 1; 10032 } 10033 10034 emit_use (gen_rtx_REG (DImode, LR_REGNUM)); 10035 if (!sibcall) 10036 emit_jump_insn (ret_rtx); 10037 } 10038 10039 /* Output code to add DELTA to the first argument, and then jump 10040 to FUNCTION. Used for C++ multiple inheritance. */ 10041 static void 10042 aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, 10043 HOST_WIDE_INT delta, 10044 HOST_WIDE_INT vcall_offset, 10045 tree function) 10046 { 10047 /* The this pointer is always in x0. Note that this differs from 10048 Arm where the this pointer maybe bumped to r1 if r0 is required 10049 to return a pointer to an aggregate. On AArch64 a result value 10050 pointer will be in x8. */ 10051 int this_regno = R0_REGNUM; 10052 rtx this_rtx, temp0, temp1, addr, funexp; 10053 rtx_insn *insn; 10054 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk)); 10055 10056 if (aarch_bti_enabled ()) 10057 emit_insn (gen_bti_c()); 10058 10059 reload_completed = 1; 10060 emit_note (NOTE_INSN_PROLOGUE_END); 10061 10062 this_rtx = gen_rtx_REG (Pmode, this_regno); 10063 temp0 = gen_rtx_REG (Pmode, EP0_REGNUM); 10064 temp1 = gen_rtx_REG (Pmode, EP1_REGNUM); 10065 10066 if (vcall_offset == 0) 10067 aarch64_add_offset (Pmode, this_rtx, this_rtx, delta, temp1, temp0, 10068 0, false); 10069 else 10070 { 10071 gcc_assert ((vcall_offset & (POINTER_BYTES - 1)) == 0); 10072 10073 addr = this_rtx; 10074 if (delta != 0) 10075 { 10076 if (delta >= -256 && delta < 256) 10077 addr = gen_rtx_PRE_MODIFY (Pmode, this_rtx, 10078 plus_constant (Pmode, this_rtx, delta)); 10079 else 10080 aarch64_add_offset (Pmode, this_rtx, this_rtx, delta, 10081 temp1, temp0, 0, false); 10082 } 10083 10084 if (Pmode == ptr_mode) 10085 aarch64_emit_move (temp0, gen_rtx_MEM (ptr_mode, addr)); 10086 else 10087 aarch64_emit_move (temp0, 10088 gen_rtx_ZERO_EXTEND (Pmode, 10089 gen_rtx_MEM (ptr_mode, addr))); 10090 10091 if (vcall_offset >= -256 && vcall_offset < 4096 * POINTER_BYTES) 10092 addr = plus_constant (Pmode, temp0, vcall_offset); 10093 else 10094 { 10095 aarch64_internal_mov_immediate (temp1, GEN_INT (vcall_offset), true, 10096 Pmode); 10097 addr = gen_rtx_PLUS (Pmode, temp0, temp1); 10098 } 10099 10100 if (Pmode == ptr_mode) 10101 aarch64_emit_move (temp1, gen_rtx_MEM (ptr_mode,addr)); 10102 else 10103 aarch64_emit_move (temp1, 10104 gen_rtx_SIGN_EXTEND (Pmode, 10105 gen_rtx_MEM (ptr_mode, addr))); 10106 10107 emit_insn (gen_add2_insn (this_rtx, temp1)); 10108 } 10109 10110 /* Generate a tail call to the target function. */ 10111 if (!TREE_USED (function)) 10112 { 10113 assemble_external (function); 10114 TREE_USED (function) = 1; 10115 } 10116 funexp = XEXP (DECL_RTL (function), 0); 10117 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp); 10118 auto isa_mode = aarch64_fntype_isa_mode (TREE_TYPE (function)); 10119 auto pcs_variant = arm_pcs (fndecl_abi (function).id ()); 10120 rtx callee_abi = aarch64_gen_callee_cookie (isa_mode, pcs_variant); 10121 insn = emit_call_insn (gen_sibcall (funexp, const0_rtx, callee_abi)); 10122 SIBLING_CALL_P (insn) = 1; 10123 10124 insn = get_insns (); 10125 shorten_branches (insn); 10126 10127 assemble_start_function (thunk, fnname); 10128 final_start_function (insn, file, 1); 10129 final (insn, file, 1); 10130 final_end_function (); 10131 assemble_end_function (thunk, fnname); 10132 10133 /* Stop pretending to be a post-reload pass. */ 10134 reload_completed = 0; 10135 } 10136 10137 static bool 10138 aarch64_tls_referenced_p (rtx x) 10139 { 10140 if (!TARGET_HAVE_TLS) 10141 return false; 10142 subrtx_iterator::array_type array; 10143 FOR_EACH_SUBRTX (iter, array, x, ALL) 10144 { 10145 const_rtx x = *iter; 10146 if (SYMBOL_REF_P (x) && SYMBOL_REF_TLS_MODEL (x) != 0) 10147 return true; 10148 /* Don't recurse into UNSPEC_TLS looking for TLS symbols; these are 10149 TLS offsets, not real symbol references. */ 10150 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLS) 10151 iter.skip_subrtxes (); 10152 } 10153 return false; 10154 } 10155 10156 10157 static bool 10158 aarch64_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x) 10159 { 10160 if (GET_CODE (x) == HIGH) 10161 return true; 10162 10163 /* There's no way to calculate VL-based values using relocations. */ 10164 subrtx_iterator::array_type array; 10165 HOST_WIDE_INT factor; 10166 FOR_EACH_SUBRTX (iter, array, x, ALL) 10167 if (GET_CODE (*iter) == CONST_POLY_INT 10168 || aarch64_sme_vq_unspec_p (x, &factor)) 10169 return true; 10170 10171 poly_int64 offset; 10172 rtx base = strip_offset_and_salt (x, &offset); 10173 if (SYMBOL_REF_P (base) || LABEL_REF_P (base)) 10174 { 10175 /* We checked for POLY_INT_CST offsets above. */ 10176 if (aarch64_classify_symbol (base, offset.to_constant ()) 10177 != SYMBOL_FORCE_TO_MEM) 10178 return true; 10179 else 10180 /* Avoid generating a 64-bit relocation in ILP32; leave 10181 to aarch64_expand_mov_immediate to handle it properly. */ 10182 return mode != ptr_mode; 10183 } 10184 10185 return aarch64_tls_referenced_p (x); 10186 } 10187 10188 /* Implement TARGET_CASE_VALUES_THRESHOLD. 10189 The expansion for a table switch is quite expensive due to the number 10190 of instructions, the table lookup and hard to predict indirect jump. 10191 When optimizing for speed, and -O3 enabled, use the per-core tuning if 10192 set, otherwise use tables for >= 11 cases as a tradeoff between size and 10193 performance. When optimizing for size, use 8 for smallest codesize. */ 10194 10195 static unsigned int 10196 aarch64_case_values_threshold (void) 10197 { 10198 /* Use the specified limit for the number of cases before using jump 10199 tables at higher optimization levels. */ 10200 if (optimize > 2 10201 && aarch64_tune_params.max_case_values != 0) 10202 return aarch64_tune_params.max_case_values; 10203 else 10204 return optimize_size ? 8 : 11; 10205 } 10206 10207 /* Return true if register REGNO is a valid index register. 10208 STRICT_P is true if REG_OK_STRICT is in effect. */ 10209 10210 bool 10211 aarch64_regno_ok_for_index_p (int regno, bool strict_p) 10212 { 10213 if (!HARD_REGISTER_NUM_P (regno)) 10214 { 10215 if (!strict_p) 10216 return true; 10217 10218 if (!reg_renumber) 10219 return false; 10220 10221 regno = reg_renumber[regno]; 10222 } 10223 return GP_REGNUM_P (regno); 10224 } 10225 10226 /* Return true if register REGNO is a valid base register for mode MODE. 10227 STRICT_P is true if REG_OK_STRICT is in effect. */ 10228 10229 bool 10230 aarch64_regno_ok_for_base_p (int regno, bool strict_p) 10231 { 10232 if (!HARD_REGISTER_NUM_P (regno)) 10233 { 10234 if (!strict_p) 10235 return true; 10236 10237 if (!reg_renumber) 10238 return false; 10239 10240 regno = reg_renumber[regno]; 10241 } 10242 10243 /* The fake registers will be eliminated to either the stack or 10244 hard frame pointer, both of which are usually valid base registers. 10245 Reload deals with the cases where the eliminated form isn't valid. */ 10246 return (GP_REGNUM_P (regno) 10247 || regno == SP_REGNUM 10248 || regno == FRAME_POINTER_REGNUM 10249 || regno == ARG_POINTER_REGNUM); 10250 } 10251 10252 /* Return true if X is a valid base register for mode MODE. 10253 STRICT_P is true if REG_OK_STRICT is in effect. */ 10254 10255 static bool 10256 aarch64_base_register_rtx_p (rtx x, bool strict_p) 10257 { 10258 if (!strict_p 10259 && SUBREG_P (x) 10260 && contains_reg_of_mode[GENERAL_REGS][GET_MODE (SUBREG_REG (x))]) 10261 x = SUBREG_REG (x); 10262 10263 return (REG_P (x) && aarch64_regno_ok_for_base_p (REGNO (x), strict_p)); 10264 } 10265 10266 /* Return true if address offset is a valid index. If it is, fill in INFO 10267 appropriately. STRICT_P is true if REG_OK_STRICT is in effect. */ 10268 10269 static bool 10270 aarch64_classify_index (struct aarch64_address_info *info, rtx x, 10271 machine_mode mode, bool strict_p) 10272 { 10273 enum aarch64_address_type type; 10274 rtx index; 10275 int shift; 10276 10277 /* (reg:P) */ 10278 if ((REG_P (x) || SUBREG_P (x)) 10279 && GET_MODE (x) == Pmode) 10280 { 10281 type = ADDRESS_REG_REG; 10282 index = x; 10283 shift = 0; 10284 } 10285 /* (sign_extend:DI (reg:SI)) */ 10286 else if ((GET_CODE (x) == SIGN_EXTEND 10287 || GET_CODE (x) == ZERO_EXTEND) 10288 && GET_MODE (x) == DImode 10289 && GET_MODE (XEXP (x, 0)) == SImode) 10290 { 10291 type = (GET_CODE (x) == SIGN_EXTEND) 10292 ? ADDRESS_REG_SXTW : ADDRESS_REG_UXTW; 10293 index = XEXP (x, 0); 10294 shift = 0; 10295 } 10296 /* (mult:DI (sign_extend:DI (reg:SI)) (const_int scale)) */ 10297 else if (GET_CODE (x) == MULT 10298 && (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND 10299 || GET_CODE (XEXP (x, 0)) == ZERO_EXTEND) 10300 && GET_MODE (XEXP (x, 0)) == DImode 10301 && GET_MODE (XEXP (XEXP (x, 0), 0)) == SImode 10302 && CONST_INT_P (XEXP (x, 1))) 10303 { 10304 type = (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND) 10305 ? ADDRESS_REG_SXTW : ADDRESS_REG_UXTW; 10306 index = XEXP (XEXP (x, 0), 0); 10307 shift = exact_log2 (INTVAL (XEXP (x, 1))); 10308 } 10309 /* (ashift:DI (sign_extend:DI (reg:SI)) (const_int shift)) */ 10310 else if (GET_CODE (x) == ASHIFT 10311 && (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND 10312 || GET_CODE (XEXP (x, 0)) == ZERO_EXTEND) 10313 && GET_MODE (XEXP (x, 0)) == DImode 10314 && GET_MODE (XEXP (XEXP (x, 0), 0)) == SImode 10315 && CONST_INT_P (XEXP (x, 1))) 10316 { 10317 type = (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND) 10318 ? ADDRESS_REG_SXTW : ADDRESS_REG_UXTW; 10319 index = XEXP (XEXP (x, 0), 0); 10320 shift = INTVAL (XEXP (x, 1)); 10321 } 10322 /* (and:DI (mult:DI (reg:DI) (const_int scale)) 10323 (const_int 0xffffffff<<shift)) */ 10324 else if (GET_CODE (x) == AND 10325 && GET_MODE (x) == DImode 10326 && GET_CODE (XEXP (x, 0)) == MULT 10327 && GET_MODE (XEXP (XEXP (x, 0), 0)) == DImode 10328 && CONST_INT_P (XEXP (XEXP (x, 0), 1)) 10329 && CONST_INT_P (XEXP (x, 1))) 10330 { 10331 type = ADDRESS_REG_UXTW; 10332 index = XEXP (XEXP (x, 0), 0); 10333 shift = exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1))); 10334 /* Avoid undefined code dealing with shift being -1. */ 10335 if (shift != -1 10336 && INTVAL (XEXP (x, 1)) != (HOST_WIDE_INT)0xffffffff << shift) 10337 shift = -1; 10338 } 10339 /* (and:DI (ashift:DI (reg:DI) (const_int shift)) 10340 (const_int 0xffffffff<<shift)) */ 10341 else if (GET_CODE (x) == AND 10342 && GET_MODE (x) == DImode 10343 && GET_CODE (XEXP (x, 0)) == ASHIFT 10344 && GET_MODE (XEXP (XEXP (x, 0), 0)) == DImode 10345 && CONST_INT_P (XEXP (XEXP (x, 0), 1)) 10346 && CONST_INT_P (XEXP (x, 1))) 10347 { 10348 type = ADDRESS_REG_UXTW; 10349 index = XEXP (XEXP (x, 0), 0); 10350 shift = INTVAL (XEXP (XEXP (x, 0), 1)); 10351 if (INTVAL (XEXP (x, 1)) != (HOST_WIDE_INT)0xffffffff << shift) 10352 shift = -1; 10353 } 10354 /* (mult:P (reg:P) (const_int scale)) */ 10355 else if (GET_CODE (x) == MULT 10356 && GET_MODE (x) == Pmode 10357 && GET_MODE (XEXP (x, 0)) == Pmode 10358 && CONST_INT_P (XEXP (x, 1))) 10359 { 10360 type = ADDRESS_REG_REG; 10361 index = XEXP (x, 0); 10362 shift = exact_log2 (INTVAL (XEXP (x, 1))); 10363 } 10364 /* (ashift:P (reg:P) (const_int shift)) */ 10365 else if (GET_CODE (x) == ASHIFT 10366 && GET_MODE (x) == Pmode 10367 && GET_MODE (XEXP (x, 0)) == Pmode 10368 && CONST_INT_P (XEXP (x, 1))) 10369 { 10370 type = ADDRESS_REG_REG; 10371 index = XEXP (x, 0); 10372 shift = INTVAL (XEXP (x, 1)); 10373 } 10374 else 10375 return false; 10376 10377 if (!strict_p 10378 && SUBREG_P (index) 10379 && contains_reg_of_mode[GENERAL_REGS][GET_MODE (SUBREG_REG (index))]) 10380 index = SUBREG_REG (index); 10381 10382 if (aarch64_sve_data_mode_p (mode) || mode == VNx1TImode) 10383 { 10384 if (type != ADDRESS_REG_REG 10385 || (1 << shift) != GET_MODE_UNIT_SIZE (mode)) 10386 return false; 10387 } 10388 else 10389 { 10390 if (shift != 0 10391 && !(IN_RANGE (shift, 1, 3) 10392 && known_eq (1 << shift, GET_MODE_SIZE (mode)))) 10393 return false; 10394 } 10395 10396 if (REG_P (index) 10397 && aarch64_regno_ok_for_index_p (REGNO (index), strict_p)) 10398 { 10399 info->type = type; 10400 info->offset = index; 10401 info->shift = shift; 10402 return true; 10403 } 10404 10405 return false; 10406 } 10407 10408 /* Return true if MODE is one of the modes for which we 10409 support LDP/STP operations. */ 10410 10411 static bool 10412 aarch64_mode_valid_for_sched_fusion_p (machine_mode mode) 10413 { 10414 return mode == SImode || mode == DImode 10415 || mode == SFmode || mode == DFmode 10416 || mode == SDmode || mode == DDmode 10417 || (aarch64_vector_mode_supported_p (mode) 10418 && (known_eq (GET_MODE_SIZE (mode), 8) 10419 || (known_eq (GET_MODE_SIZE (mode), 16) 10420 && (aarch64_tune_params.extra_tuning_flags 10421 & AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS) == 0))); 10422 } 10423 10424 /* Return true if REGNO is a virtual pointer register, or an eliminable 10425 "soft" frame register. Like REGNO_PTR_FRAME_P except that we don't 10426 include stack_pointer or hard_frame_pointer. */ 10427 static bool 10428 virt_or_elim_regno_p (unsigned regno) 10429 { 10430 return ((regno >= FIRST_VIRTUAL_REGISTER 10431 && regno <= LAST_VIRTUAL_POINTER_REGISTER) 10432 || regno == FRAME_POINTER_REGNUM 10433 || regno == ARG_POINTER_REGNUM); 10434 } 10435 10436 /* Return true if X is a valid address of type TYPE for machine mode MODE. 10437 If it is, fill in INFO appropriately. STRICT_P is true if 10438 REG_OK_STRICT is in effect. */ 10439 10440 bool 10441 aarch64_classify_address (struct aarch64_address_info *info, 10442 rtx x, machine_mode mode, bool strict_p, 10443 aarch64_addr_query_type type) 10444 { 10445 enum rtx_code code = GET_CODE (x); 10446 rtx op0, op1; 10447 poly_int64 offset; 10448 10449 HOST_WIDE_INT const_size; 10450 10451 /* Whether a vector mode is partial doesn't affect address legitimacy. 10452 Partial vectors like VNx8QImode allow the same indexed addressing 10453 mode and MUL VL addressing mode as full vectors like VNx16QImode; 10454 in both cases, MUL VL counts multiples of GET_MODE_SIZE. */ 10455 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 10456 vec_flags &= ~VEC_PARTIAL; 10457 10458 /* On BE, we use load/store pair for all large int mode load/stores. 10459 TI/TF/TDmode may also use a load/store pair. */ 10460 bool advsimd_struct_p = (vec_flags == (VEC_ADVSIMD | VEC_STRUCT)); 10461 bool load_store_pair_p = (type == ADDR_QUERY_LDP_STP 10462 || type == ADDR_QUERY_LDP_STP_N 10463 || mode == TImode 10464 || mode == TFmode 10465 || mode == TDmode 10466 || ((!TARGET_SIMD || BYTES_BIG_ENDIAN) 10467 && advsimd_struct_p)); 10468 /* If we are dealing with ADDR_QUERY_LDP_STP_N that means the incoming mode 10469 corresponds to the actual size of the memory being loaded/stored and the 10470 mode of the corresponding addressing mode is half of that. */ 10471 if (type == ADDR_QUERY_LDP_STP_N) 10472 { 10473 if (known_eq (GET_MODE_SIZE (mode), 32)) 10474 mode = V16QImode; 10475 else if (known_eq (GET_MODE_SIZE (mode), 16)) 10476 mode = DFmode; 10477 else if (known_eq (GET_MODE_SIZE (mode), 8)) 10478 mode = SFmode; 10479 else 10480 return false; 10481 10482 /* This isn't really an Advanced SIMD struct mode, but a mode 10483 used to represent the complete mem in a load/store pair. */ 10484 advsimd_struct_p = false; 10485 } 10486 10487 bool allow_reg_index_p = (!load_store_pair_p 10488 && ((vec_flags == 0 10489 && known_lt (GET_MODE_SIZE (mode), 16)) 10490 || vec_flags == VEC_ADVSIMD 10491 || vec_flags & VEC_SVE_DATA 10492 || mode == VNx1TImode)); 10493 10494 /* For SVE, only accept [Rn], [Rn, #offset, MUL VL] and [Rn, Rm, LSL #shift]. 10495 The latter is not valid for SVE predicates, and that's rejected through 10496 allow_reg_index_p above. */ 10497 if ((vec_flags & (VEC_SVE_DATA | VEC_SVE_PRED)) != 0 10498 && (code != REG && code != PLUS)) 10499 return false; 10500 10501 /* On LE, for AdvSIMD, don't support anything other than POST_INC or 10502 REG addressing. */ 10503 if (advsimd_struct_p 10504 && TARGET_SIMD 10505 && !BYTES_BIG_ENDIAN 10506 && (code != POST_INC && code != REG)) 10507 return false; 10508 10509 gcc_checking_assert (GET_MODE (x) == VOIDmode 10510 || SCALAR_INT_MODE_P (GET_MODE (x))); 10511 10512 switch (code) 10513 { 10514 case REG: 10515 case SUBREG: 10516 info->type = ADDRESS_REG_IMM; 10517 info->base = x; 10518 info->offset = const0_rtx; 10519 info->const_offset = 0; 10520 return aarch64_base_register_rtx_p (x, strict_p); 10521 10522 case PLUS: 10523 op0 = XEXP (x, 0); 10524 op1 = XEXP (x, 1); 10525 10526 if (! strict_p 10527 && REG_P (op0) 10528 && virt_or_elim_regno_p (REGNO (op0)) 10529 && poly_int_rtx_p (op1, &offset)) 10530 { 10531 info->type = ADDRESS_REG_IMM; 10532 info->base = op0; 10533 info->offset = op1; 10534 info->const_offset = offset; 10535 10536 return true; 10537 } 10538 10539 if (maybe_ne (GET_MODE_SIZE (mode), 0) 10540 && aarch64_base_register_rtx_p (op0, strict_p) 10541 && poly_int_rtx_p (op1, &offset)) 10542 { 10543 info->type = ADDRESS_REG_IMM; 10544 info->base = op0; 10545 info->offset = op1; 10546 info->const_offset = offset; 10547 10548 /* TImode, TFmode and TDmode values are allowed in both pairs of X 10549 registers and individual Q registers. The available 10550 address modes are: 10551 X,X: 7-bit signed scaled offset 10552 Q: 9-bit signed offset 10553 We conservatively require an offset representable in either mode. 10554 When performing the check for pairs of X registers i.e. LDP/STP 10555 pass down DImode since that is the natural size of the LDP/STP 10556 instruction memory accesses. */ 10557 if (mode == TImode || mode == TFmode || mode == TDmode) 10558 return (aarch64_offset_7bit_signed_scaled_p (DImode, offset) 10559 && (aarch64_offset_9bit_signed_unscaled_p (mode, offset) 10560 || offset_12bit_unsigned_scaled_p (mode, offset))); 10561 10562 if (mode == V8DImode) 10563 return (aarch64_offset_7bit_signed_scaled_p (DImode, offset) 10564 && aarch64_offset_7bit_signed_scaled_p (DImode, offset + 48)); 10565 10566 /* A 7bit offset check because OImode will emit a ldp/stp 10567 instruction (only !TARGET_SIMD or big endian will get here). 10568 For ldp/stp instructions, the offset is scaled for the size of a 10569 single element of the pair. */ 10570 if (aarch64_advsimd_partial_struct_mode_p (mode) 10571 && known_eq (GET_MODE_SIZE (mode), 16)) 10572 return aarch64_offset_7bit_signed_scaled_p (DImode, offset); 10573 if (aarch64_advsimd_full_struct_mode_p (mode) 10574 && known_eq (GET_MODE_SIZE (mode), 32)) 10575 return aarch64_offset_7bit_signed_scaled_p (TImode, offset); 10576 10577 /* Three 9/12 bit offsets checks because CImode will emit three 10578 ldr/str instructions (only !TARGET_SIMD or big endian will 10579 get here). */ 10580 if (aarch64_advsimd_partial_struct_mode_p (mode) 10581 && known_eq (GET_MODE_SIZE (mode), 24)) 10582 return (aarch64_offset_7bit_signed_scaled_p (DImode, offset) 10583 && (aarch64_offset_9bit_signed_unscaled_p (DImode, 10584 offset + 16) 10585 || offset_12bit_unsigned_scaled_p (DImode, 10586 offset + 16))); 10587 if (aarch64_advsimd_full_struct_mode_p (mode) 10588 && known_eq (GET_MODE_SIZE (mode), 48)) 10589 return (aarch64_offset_7bit_signed_scaled_p (TImode, offset) 10590 && (aarch64_offset_9bit_signed_unscaled_p (TImode, 10591 offset + 32) 10592 || offset_12bit_unsigned_scaled_p (TImode, 10593 offset + 32))); 10594 10595 /* Two 7bit offsets checks because XImode will emit two ldp/stp 10596 instructions (only big endian will get here). */ 10597 if (aarch64_advsimd_partial_struct_mode_p (mode) 10598 && known_eq (GET_MODE_SIZE (mode), 32)) 10599 return (aarch64_offset_7bit_signed_scaled_p (DImode, offset) 10600 && aarch64_offset_7bit_signed_scaled_p (DImode, 10601 offset + 16)); 10602 if (aarch64_advsimd_full_struct_mode_p (mode) 10603 && known_eq (GET_MODE_SIZE (mode), 64)) 10604 return (aarch64_offset_7bit_signed_scaled_p (TImode, offset) 10605 && aarch64_offset_7bit_signed_scaled_p (TImode, 10606 offset + 32)); 10607 10608 /* Make "m" use the LD1 offset range for SVE data modes, so 10609 that pre-RTL optimizers like ivopts will work to that 10610 instead of the wider LDR/STR range. */ 10611 if (vec_flags == VEC_SVE_DATA || mode == VNx1TImode) 10612 return (type == ADDR_QUERY_M 10613 ? offset_4bit_signed_scaled_p (mode, offset) 10614 : offset_9bit_signed_scaled_p (mode, offset)); 10615 10616 if (vec_flags == (VEC_SVE_DATA | VEC_STRUCT)) 10617 { 10618 poly_int64 end_offset = (offset 10619 + GET_MODE_SIZE (mode) 10620 - BYTES_PER_SVE_VECTOR); 10621 return (type == ADDR_QUERY_M 10622 ? offset_4bit_signed_scaled_p (mode, offset) 10623 : (offset_9bit_signed_scaled_p (SVE_BYTE_MODE, offset) 10624 && offset_9bit_signed_scaled_p (SVE_BYTE_MODE, 10625 end_offset))); 10626 } 10627 10628 if (vec_flags == VEC_SVE_PRED) 10629 return offset_9bit_signed_scaled_p (mode, offset); 10630 10631 if (vec_flags == (VEC_SVE_PRED | VEC_STRUCT)) 10632 { 10633 poly_int64 end_offset = (offset 10634 + GET_MODE_SIZE (mode) 10635 - BYTES_PER_SVE_PRED); 10636 return (offset_9bit_signed_scaled_p (VNx16BImode, end_offset) 10637 && offset_9bit_signed_scaled_p (VNx16BImode, offset)); 10638 } 10639 10640 if (load_store_pair_p) 10641 return ((known_eq (GET_MODE_SIZE (mode), 4) 10642 || known_eq (GET_MODE_SIZE (mode), 8) 10643 || known_eq (GET_MODE_SIZE (mode), 16)) 10644 && aarch64_offset_7bit_signed_scaled_p (mode, offset)); 10645 else 10646 return (aarch64_offset_9bit_signed_unscaled_p (mode, offset) 10647 || offset_12bit_unsigned_scaled_p (mode, offset)); 10648 } 10649 10650 if (allow_reg_index_p) 10651 { 10652 /* Look for base + (scaled/extended) index register. */ 10653 if (aarch64_base_register_rtx_p (op0, strict_p) 10654 && aarch64_classify_index (info, op1, mode, strict_p)) 10655 { 10656 info->base = op0; 10657 return true; 10658 } 10659 if (aarch64_base_register_rtx_p (op1, strict_p) 10660 && aarch64_classify_index (info, op0, mode, strict_p)) 10661 { 10662 info->base = op1; 10663 return true; 10664 } 10665 } 10666 10667 return false; 10668 10669 case POST_INC: 10670 case POST_DEC: 10671 case PRE_INC: 10672 case PRE_DEC: 10673 info->type = ADDRESS_REG_WB; 10674 info->base = XEXP (x, 0); 10675 info->offset = NULL_RTX; 10676 return aarch64_base_register_rtx_p (info->base, strict_p); 10677 10678 case POST_MODIFY: 10679 case PRE_MODIFY: 10680 info->type = ADDRESS_REG_WB; 10681 info->base = XEXP (x, 0); 10682 if (GET_CODE (XEXP (x, 1)) == PLUS 10683 && poly_int_rtx_p (XEXP (XEXP (x, 1), 1), &offset) 10684 && rtx_equal_p (XEXP (XEXP (x, 1), 0), info->base) 10685 && aarch64_base_register_rtx_p (info->base, strict_p)) 10686 { 10687 info->offset = XEXP (XEXP (x, 1), 1); 10688 info->const_offset = offset; 10689 10690 /* TImode, TFmode and TDmode values are allowed in both pairs of X 10691 registers and individual Q registers. The available 10692 address modes are: 10693 X,X: 7-bit signed scaled offset 10694 Q: 9-bit signed offset 10695 We conservatively require an offset representable in either mode. 10696 */ 10697 if (mode == TImode || mode == TFmode || mode == TDmode) 10698 return (aarch64_offset_7bit_signed_scaled_p (mode, offset) 10699 && aarch64_offset_9bit_signed_unscaled_p (mode, offset)); 10700 10701 if (load_store_pair_p) 10702 return ((known_eq (GET_MODE_SIZE (mode), 4) 10703 || known_eq (GET_MODE_SIZE (mode), 8) 10704 || known_eq (GET_MODE_SIZE (mode), 16)) 10705 && aarch64_offset_7bit_signed_scaled_p (mode, offset)); 10706 else 10707 return aarch64_offset_9bit_signed_unscaled_p (mode, offset); 10708 } 10709 return false; 10710 10711 case CONST: 10712 case SYMBOL_REF: 10713 case LABEL_REF: 10714 /* load literal: pc-relative constant pool entry. Only supported 10715 for SI mode or larger. */ 10716 info->type = ADDRESS_SYMBOLIC; 10717 10718 if (!load_store_pair_p 10719 && GET_MODE_SIZE (mode).is_constant (&const_size) 10720 && const_size >= 4) 10721 { 10722 poly_int64 offset; 10723 rtx sym = strip_offset_and_salt (x, &offset); 10724 return ((LABEL_REF_P (sym) 10725 || (SYMBOL_REF_P (sym) 10726 && CONSTANT_POOL_ADDRESS_P (sym) 10727 && aarch64_pcrelative_literal_loads))); 10728 } 10729 return false; 10730 10731 case LO_SUM: 10732 info->type = ADDRESS_LO_SUM; 10733 info->base = XEXP (x, 0); 10734 info->offset = XEXP (x, 1); 10735 if (allow_reg_index_p 10736 && aarch64_base_register_rtx_p (info->base, strict_p)) 10737 { 10738 poly_int64 offset; 10739 HOST_WIDE_INT const_offset; 10740 rtx sym = strip_offset_and_salt (info->offset, &offset); 10741 if (SYMBOL_REF_P (sym) 10742 && offset.is_constant (&const_offset) 10743 && (aarch64_classify_symbol (sym, const_offset) 10744 == SYMBOL_SMALL_ABSOLUTE)) 10745 { 10746 /* The symbol and offset must be aligned to the access size. */ 10747 unsigned int align; 10748 10749 if (CONSTANT_POOL_ADDRESS_P (sym)) 10750 align = GET_MODE_ALIGNMENT (get_pool_mode (sym)); 10751 else if (TREE_CONSTANT_POOL_ADDRESS_P (sym)) 10752 { 10753 tree exp = SYMBOL_REF_DECL (sym); 10754 align = TYPE_ALIGN (TREE_TYPE (exp)); 10755 align = aarch64_constant_alignment (exp, align); 10756 } 10757 else if (SYMBOL_REF_DECL (sym)) 10758 align = DECL_ALIGN (SYMBOL_REF_DECL (sym)); 10759 else if (SYMBOL_REF_HAS_BLOCK_INFO_P (sym) 10760 && SYMBOL_REF_BLOCK (sym) != NULL) 10761 align = SYMBOL_REF_BLOCK (sym)->alignment; 10762 else 10763 align = BITS_PER_UNIT; 10764 10765 poly_int64 ref_size = GET_MODE_SIZE (mode); 10766 if (known_eq (ref_size, 0)) 10767 ref_size = GET_MODE_SIZE (DImode); 10768 10769 return (multiple_p (const_offset, ref_size) 10770 && multiple_p (align / BITS_PER_UNIT, ref_size)); 10771 } 10772 } 10773 return false; 10774 10775 default: 10776 return false; 10777 } 10778 } 10779 10780 /* Return true if the address X is valid for a PRFM instruction. 10781 STRICT_P is true if we should do strict checking with 10782 aarch64_classify_address. */ 10783 10784 bool 10785 aarch64_address_valid_for_prefetch_p (rtx x, bool strict_p) 10786 { 10787 struct aarch64_address_info addr; 10788 10789 /* PRFM accepts the same addresses as DImode... */ 10790 bool res = aarch64_classify_address (&addr, x, DImode, strict_p); 10791 if (!res) 10792 return false; 10793 10794 /* ... except writeback forms. */ 10795 return addr.type != ADDRESS_REG_WB; 10796 } 10797 10798 bool 10799 aarch64_symbolic_address_p (rtx x) 10800 { 10801 poly_int64 offset; 10802 x = strip_offset_and_salt (x, &offset); 10803 return SYMBOL_REF_P (x) || LABEL_REF_P (x); 10804 } 10805 10806 /* Classify the base of symbolic expression X. */ 10807 10808 enum aarch64_symbol_type 10809 aarch64_classify_symbolic_expression (rtx x) 10810 { 10811 rtx offset; 10812 10813 split_const (x, &x, &offset); 10814 return aarch64_classify_symbol (x, INTVAL (offset)); 10815 } 10816 10817 10818 /* Return TRUE if X is a legitimate address for accessing memory in 10819 mode MODE. */ 10820 static bool 10821 aarch64_legitimate_address_hook_p (machine_mode mode, rtx x, bool strict_p, 10822 code_helper = ERROR_MARK) 10823 { 10824 struct aarch64_address_info addr; 10825 10826 return aarch64_classify_address (&addr, x, mode, strict_p); 10827 } 10828 10829 /* Return TRUE if X is a legitimate address of type TYPE for accessing 10830 memory in mode MODE. STRICT_P is true if REG_OK_STRICT is in effect. */ 10831 bool 10832 aarch64_legitimate_address_p (machine_mode mode, rtx x, bool strict_p, 10833 aarch64_addr_query_type type) 10834 { 10835 struct aarch64_address_info addr; 10836 10837 return aarch64_classify_address (&addr, x, mode, strict_p, type); 10838 } 10839 10840 /* Implement TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT. */ 10841 10842 static bool 10843 aarch64_legitimize_address_displacement (rtx *offset1, rtx *offset2, 10844 poly_int64 orig_offset, 10845 machine_mode mode) 10846 { 10847 HOST_WIDE_INT size; 10848 if (GET_MODE_SIZE (mode).is_constant (&size)) 10849 { 10850 HOST_WIDE_INT const_offset, second_offset; 10851 10852 /* A general SVE offset is A * VQ + B. Remove the A component from 10853 coefficient 0 in order to get the constant B. */ 10854 const_offset = orig_offset.coeffs[0] - orig_offset.coeffs[1]; 10855 10856 /* Split an out-of-range address displacement into a base and 10857 offset. Use 4KB range for 1- and 2-byte accesses and a 16KB 10858 range otherwise to increase opportunities for sharing the base 10859 address of different sizes. Unaligned accesses use the signed 10860 9-bit range, TImode/TFmode/TDmode use the intersection of signed 10861 scaled 7-bit and signed 9-bit offset. */ 10862 if (mode == TImode || mode == TFmode || mode == TDmode) 10863 second_offset = ((const_offset + 0x100) & 0x1f8) - 0x100; 10864 else if ((const_offset & (size - 1)) != 0) 10865 second_offset = ((const_offset + 0x100) & 0x1ff) - 0x100; 10866 else 10867 second_offset = const_offset & (size < 4 ? 0xfff : 0x3ffc); 10868 10869 if (second_offset == 0 || known_eq (orig_offset, second_offset)) 10870 return false; 10871 10872 /* Split the offset into second_offset and the rest. */ 10873 *offset1 = gen_int_mode (orig_offset - second_offset, Pmode); 10874 *offset2 = gen_int_mode (second_offset, Pmode); 10875 return true; 10876 } 10877 else 10878 { 10879 /* Get the mode we should use as the basis of the range. For structure 10880 modes this is the mode of one vector. */ 10881 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 10882 machine_mode step_mode 10883 = (vec_flags & VEC_STRUCT) != 0 ? SVE_BYTE_MODE : mode; 10884 10885 /* Get the "mul vl" multiplier we'd like to use. */ 10886 HOST_WIDE_INT factor = GET_MODE_SIZE (step_mode).coeffs[1]; 10887 HOST_WIDE_INT vnum = orig_offset.coeffs[1] / factor; 10888 if (vec_flags & VEC_SVE_DATA) 10889 /* LDR supports a 9-bit range, but the move patterns for 10890 structure modes require all vectors to be in range of the 10891 same base. The simplest way of accomodating that while still 10892 promoting reuse of anchor points between different modes is 10893 to use an 8-bit range unconditionally. */ 10894 vnum = ((vnum + 128) & 255) - 128; 10895 else 10896 /* Predicates are only handled singly, so we might as well use 10897 the full range. */ 10898 vnum = ((vnum + 256) & 511) - 256; 10899 if (vnum == 0) 10900 return false; 10901 10902 /* Convert the "mul vl" multiplier into a byte offset. */ 10903 poly_int64 second_offset = GET_MODE_SIZE (step_mode) * vnum; 10904 if (known_eq (second_offset, orig_offset)) 10905 return false; 10906 10907 /* Split the offset into second_offset and the rest. */ 10908 *offset1 = gen_int_mode (orig_offset - second_offset, Pmode); 10909 *offset2 = gen_int_mode (second_offset, Pmode); 10910 return true; 10911 } 10912 } 10913 10914 /* Return the binary representation of floating point constant VALUE in INTVAL. 10915 If the value cannot be converted, return false without setting INTVAL. 10916 The conversion is done in the given MODE. */ 10917 bool 10918 aarch64_reinterpret_float_as_int (rtx value, unsigned HOST_WIDE_INT *intval) 10919 { 10920 10921 /* We make a general exception for 0. */ 10922 if (aarch64_float_const_zero_rtx_p (value)) 10923 { 10924 *intval = 0; 10925 return true; 10926 } 10927 10928 scalar_float_mode mode; 10929 if (!CONST_DOUBLE_P (value) 10930 || !is_a <scalar_float_mode> (GET_MODE (value), &mode) 10931 || GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT 10932 /* Only support up to DF mode. */ 10933 || GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (DFmode)) 10934 return false; 10935 10936 unsigned HOST_WIDE_INT ival = 0; 10937 10938 long res[2]; 10939 real_to_target (res, 10940 CONST_DOUBLE_REAL_VALUE (value), 10941 REAL_MODE_FORMAT (mode)); 10942 10943 if (mode == DFmode || mode == DDmode) 10944 { 10945 int order = BYTES_BIG_ENDIAN ? 1 : 0; 10946 ival = zext_hwi (res[order], 32); 10947 ival |= (zext_hwi (res[1 - order], 32) << 32); 10948 } 10949 else 10950 ival = zext_hwi (res[0], 32); 10951 10952 *intval = ival; 10953 return true; 10954 } 10955 10956 /* Return TRUE if rtx X is an immediate constant that can be moved using a 10957 single MOV(+MOVK) followed by an FMOV. */ 10958 bool 10959 aarch64_float_const_rtx_p (rtx x) 10960 { 10961 machine_mode mode = GET_MODE (x); 10962 if (mode == VOIDmode) 10963 return false; 10964 10965 /* Determine whether it's cheaper to write float constants as 10966 mov/movk pairs over ldr/adrp pairs. */ 10967 unsigned HOST_WIDE_INT ival; 10968 10969 if (CONST_DOUBLE_P (x) 10970 && SCALAR_FLOAT_MODE_P (mode) 10971 && aarch64_reinterpret_float_as_int (x, &ival)) 10972 { 10973 machine_mode imode = known_eq (GET_MODE_SIZE (mode), 8) ? DImode : SImode; 10974 int num_instr = aarch64_internal_mov_immediate 10975 (NULL_RTX, gen_int_mode (ival, imode), false, imode); 10976 return num_instr < 3; 10977 } 10978 10979 return false; 10980 } 10981 10982 /* Return TRUE if rtx X is immediate constant 0.0 (but not in Decimal 10983 Floating Point). */ 10984 bool 10985 aarch64_float_const_zero_rtx_p (rtx x) 10986 { 10987 /* 0.0 in Decimal Floating Point cannot be represented by #0 or 10988 zr as our callers expect, so no need to check the actual 10989 value if X is of Decimal Floating Point type. */ 10990 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_DECIMAL_FLOAT) 10991 return false; 10992 10993 if (REAL_VALUE_MINUS_ZERO (*CONST_DOUBLE_REAL_VALUE (x))) 10994 return !HONOR_SIGNED_ZEROS (GET_MODE (x)); 10995 return real_equal (CONST_DOUBLE_REAL_VALUE (x), &dconst0); 10996 } 10997 10998 /* Return true if X is any kind of constant zero rtx. */ 10999 11000 bool 11001 aarch64_const_zero_rtx_p (rtx x) 11002 { 11003 return (x == CONST0_RTX (GET_MODE (x)) 11004 || (CONST_DOUBLE_P (x) && aarch64_float_const_zero_rtx_p (x))); 11005 } 11006 11007 /* Return TRUE if rtx X is immediate constant that fits in a single 11008 MOVI immediate operation. */ 11009 bool 11010 aarch64_can_const_movi_rtx_p (rtx x, machine_mode mode) 11011 { 11012 if (!TARGET_SIMD) 11013 return false; 11014 11015 machine_mode vmode; 11016 scalar_int_mode imode; 11017 unsigned HOST_WIDE_INT ival; 11018 11019 if (CONST_DOUBLE_P (x) 11020 && SCALAR_FLOAT_MODE_P (mode)) 11021 { 11022 if (!aarch64_reinterpret_float_as_int (x, &ival)) 11023 return false; 11024 11025 /* We make a general exception for 0. */ 11026 if (aarch64_float_const_zero_rtx_p (x)) 11027 return true; 11028 11029 imode = int_mode_for_mode (mode).require (); 11030 } 11031 else if (CONST_INT_P (x) 11032 && is_a <scalar_int_mode> (mode, &imode)) 11033 ival = INTVAL (x); 11034 else 11035 return false; 11036 11037 /* use a 64 bit mode for everything except for DI/DF/DD mode, where we use 11038 a 128 bit vector mode. */ 11039 int width = GET_MODE_BITSIZE (imode) == 64 ? 128 : 64; 11040 11041 vmode = aarch64_simd_container_mode (imode, width); 11042 rtx v_op = aarch64_simd_gen_const_vector_dup (vmode, ival); 11043 11044 return aarch64_simd_valid_immediate (v_op, NULL); 11045 } 11046 11047 11048 /* Return the fixed registers used for condition codes. */ 11049 11050 static bool 11051 aarch64_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2) 11052 { 11053 *p1 = CC_REGNUM; 11054 *p2 = INVALID_REGNUM; 11055 return true; 11056 } 11057 11058 /* Return a fresh memory reference to the current function's TPIDR2 block, 11059 creating a block if necessary. */ 11060 11061 static rtx 11062 aarch64_get_tpidr2_block () 11063 { 11064 if (!cfun->machine->tpidr2_block) 11065 /* The TPIDR2 block is 16 bytes in size and must be aligned to a 128-bit 11066 boundary. */ 11067 cfun->machine->tpidr2_block = assign_stack_local (V16QImode, 16, 128); 11068 return copy_rtx (cfun->machine->tpidr2_block); 11069 } 11070 11071 /* Return a fresh register that points to the current function's 11072 TPIDR2 block, creating a block if necessary. */ 11073 11074 static rtx 11075 aarch64_get_tpidr2_ptr () 11076 { 11077 rtx block = aarch64_get_tpidr2_block (); 11078 return force_reg (Pmode, XEXP (block, 0)); 11079 } 11080 11081 /* Emit instructions to allocate a ZA lazy save buffer and initialize the 11082 current function's TPIDR2 block. */ 11083 11084 static void 11085 aarch64_init_tpidr2_block () 11086 { 11087 rtx block = aarch64_get_tpidr2_block (); 11088 11089 /* The ZA save buffer is SVL.B*SVL.B bytes in size. */ 11090 rtx svl_bytes = aarch64_sme_vq_immediate (Pmode, 16, AARCH64_ISA_MODE); 11091 rtx svl_bytes_reg = force_reg (DImode, svl_bytes); 11092 rtx za_size = expand_simple_binop (Pmode, MULT, svl_bytes_reg, 11093 svl_bytes_reg, NULL, 0, OPTAB_LIB_WIDEN); 11094 rtx za_save_buffer = allocate_dynamic_stack_space (za_size, 128, 11095 BITS_PER_UNIT, -1, true); 11096 za_save_buffer = force_reg (Pmode, za_save_buffer); 11097 cfun->machine->za_save_buffer = za_save_buffer; 11098 11099 /* The first word of the block points to the save buffer and the second 11100 word is the number of ZA slices to save. */ 11101 rtx block_0 = adjust_address (block, DImode, 0); 11102 emit_insn (aarch64_gen_store_pair (block_0, za_save_buffer, svl_bytes_reg)); 11103 11104 if (!memory_operand (block, V16QImode)) 11105 block = replace_equiv_address (block, force_reg (Pmode, XEXP (block, 0))); 11106 emit_insn (gen_aarch64_setup_local_tpidr2 (block)); 11107 } 11108 11109 /* Restore the contents of ZA from the lazy save buffer, given that 11110 register TPIDR2_BLOCK points to the current function's TPIDR2 block. 11111 PSTATE.ZA is known to be 0 and TPIDR2_EL0 is known to be null. */ 11112 11113 void 11114 aarch64_restore_za (rtx tpidr2_block) 11115 { 11116 emit_insn (gen_aarch64_smstart_za ()); 11117 if (REGNO (tpidr2_block) != R0_REGNUM) 11118 emit_move_insn (gen_rtx_REG (Pmode, R0_REGNUM), tpidr2_block); 11119 emit_insn (gen_aarch64_tpidr2_restore ()); 11120 } 11121 11122 /* Return the ZT0 save buffer, creating one if necessary. */ 11123 11124 static rtx 11125 aarch64_get_zt0_save_buffer () 11126 { 11127 if (!cfun->machine->zt0_save_buffer) 11128 cfun->machine->zt0_save_buffer = assign_stack_local (V8DImode, 64, 128); 11129 return cfun->machine->zt0_save_buffer; 11130 } 11131 11132 /* Save ZT0 to the current function's save buffer. */ 11133 11134 static void 11135 aarch64_save_zt0 () 11136 { 11137 rtx mem = aarch64_get_zt0_save_buffer (); 11138 mem = replace_equiv_address (mem, force_reg (Pmode, XEXP (mem, 0))); 11139 emit_insn (gen_aarch64_sme_str_zt0 (mem)); 11140 } 11141 11142 /* Restore ZT0 from the current function's save buffer. FROM_LAZY_SAVE_P 11143 is true if the load is happening after a call to a private-ZA function, 11144 false if it can be treated as a normal load. */ 11145 11146 static void 11147 aarch64_restore_zt0 (bool from_lazy_save_p) 11148 { 11149 rtx mem = aarch64_get_zt0_save_buffer (); 11150 mem = replace_equiv_address (mem, force_reg (Pmode, XEXP (mem, 0))); 11151 emit_insn (from_lazy_save_p 11152 ? gen_aarch64_restore_zt0 (mem) 11153 : gen_aarch64_sme_ldr_zt0 (mem)); 11154 } 11155 11156 /* Implement TARGET_START_CALL_ARGS. */ 11157 11158 static void 11159 aarch64_start_call_args (cumulative_args_t ca_v) 11160 { 11161 CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v); 11162 11163 if (!TARGET_SME && (ca->isa_mode & AARCH64_FL_SM_ON)) 11164 { 11165 error ("calling a streaming function requires the ISA extension %qs", 11166 "sme"); 11167 inform (input_location, "you can enable %qs using the command-line" 11168 " option %<-march%>, or by using the %<target%>" 11169 " attribute or pragma", "sme"); 11170 } 11171 11172 if ((ca->shared_za_flags & (AARCH64_STATE_IN | AARCH64_STATE_OUT)) 11173 && !aarch64_cfun_has_state ("za")) 11174 error ("call to a function that shares %qs state from a function" 11175 " that has no %qs state", "za", "za"); 11176 else if ((ca->shared_zt0_flags & (AARCH64_STATE_IN | AARCH64_STATE_OUT)) 11177 && !aarch64_cfun_has_state ("zt0")) 11178 error ("call to a function that shares %qs state from a function" 11179 " that has no %qs state", "zt0", "zt0"); 11180 else if (!TARGET_ZA && (ca->isa_mode & AARCH64_FL_ZA_ON)) 11181 error ("call to a function that shares SME state from a function" 11182 " that has no SME state"); 11183 11184 /* If this is a call to a private ZA function, emit a marker to 11185 indicate where any necessary set-up code could be inserted. 11186 The code itself is inserted by the mode-switching pass. */ 11187 if (TARGET_ZA && !(ca->isa_mode & AARCH64_FL_ZA_ON)) 11188 emit_insn (gen_aarch64_start_private_za_call ()); 11189 11190 /* If this is a call to a shared-ZA function that doesn't share ZT0, 11191 save and restore ZT0 around the call. */ 11192 if (aarch64_cfun_has_state ("zt0") 11193 && (ca->isa_mode & AARCH64_FL_ZA_ON) 11194 && ca->shared_zt0_flags == 0) 11195 aarch64_save_zt0 (); 11196 } 11197 11198 /* This function is used by the call expanders of the machine description. 11199 RESULT is the register in which the result is returned. It's NULL for 11200 "call" and "sibcall". 11201 MEM is the location of the function call. 11202 COOKIE is either: 11203 - a const_int that gives the argument to the call's UNSPEC_CALLEE_ABI. 11204 - a PARALLEL that contains such a const_int as its first element. 11205 The second element is a PARALLEL that lists all the argument 11206 registers that need to be saved and restored around a change 11207 in PSTATE.SM, or const0_rtx if no such switch is needed. 11208 The third and fourth elements are const_ints that contain the 11209 sharing flags for ZA and ZT0 respectively. 11210 SIBCALL indicates whether this function call is normal call or sibling call. 11211 It will generate different pattern accordingly. */ 11212 11213 void 11214 aarch64_expand_call (rtx result, rtx mem, rtx cookie, bool sibcall) 11215 { 11216 rtx call, callee, tmp; 11217 rtvec vec; 11218 machine_mode mode; 11219 11220 rtx callee_abi = cookie; 11221 rtx sme_mode_switch_args = const0_rtx; 11222 unsigned int shared_za_flags = 0; 11223 unsigned int shared_zt0_flags = 0; 11224 if (GET_CODE (cookie) == PARALLEL) 11225 { 11226 callee_abi = XVECEXP (cookie, 0, 0); 11227 sme_mode_switch_args = XVECEXP (cookie, 0, 1); 11228 shared_za_flags = INTVAL (XVECEXP (cookie, 0, 2)); 11229 shared_zt0_flags = INTVAL (XVECEXP (cookie, 0, 3)); 11230 } 11231 11232 gcc_assert (CONST_INT_P (callee_abi)); 11233 auto callee_isa_mode = aarch64_callee_isa_mode (callee_abi); 11234 11235 if (aarch64_cfun_has_state ("za") 11236 && (callee_isa_mode & AARCH64_FL_ZA_ON) 11237 && !shared_za_flags) 11238 { 11239 sorry ("call to a function that shares state other than %qs" 11240 " from a function that has %qs state", "za", "za"); 11241 inform (input_location, "use %<__arm_preserves(\"za\")%> if the" 11242 " callee preserves ZA"); 11243 } 11244 11245 gcc_assert (MEM_P (mem)); 11246 callee = XEXP (mem, 0); 11247 mode = GET_MODE (callee); 11248 gcc_assert (mode == Pmode); 11249 11250 /* Decide if we should generate indirect calls by loading the 11251 address of the callee into a register before performing 11252 the branch-and-link. */ 11253 if (SYMBOL_REF_P (callee) 11254 ? (aarch64_is_long_call_p (callee) 11255 || aarch64_is_noplt_call_p (callee)) 11256 : !REG_P (callee)) 11257 XEXP (mem, 0) = force_reg (mode, callee); 11258 11259 /* Accumulate the return values, including state that is shared via 11260 attributes. */ 11261 auto_vec<rtx, 8> return_values; 11262 if (result) 11263 { 11264 if (GET_CODE (result) == PARALLEL) 11265 for (int i = 0; i < XVECLEN (result, 0); ++i) 11266 return_values.safe_push (XVECEXP (result, 0, i)); 11267 else 11268 return_values.safe_push (result); 11269 } 11270 unsigned int orig_num_return_values = return_values.length (); 11271 if (shared_za_flags & AARCH64_STATE_OUT) 11272 return_values.safe_push (gen_rtx_REG (VNx16BImode, ZA_REGNUM)); 11273 /* When calling private-ZA functions from functions with ZA state, 11274 we want to know whether the call committed a lazy save. */ 11275 if (TARGET_ZA && !shared_za_flags) 11276 return_values.safe_push (gen_rtx_REG (VNx16BImode, ZA_SAVED_REGNUM)); 11277 if (shared_zt0_flags & AARCH64_STATE_OUT) 11278 return_values.safe_push (gen_rtx_REG (V8DImode, ZT0_REGNUM)); 11279 11280 /* Create the new return value, if necessary. */ 11281 if (orig_num_return_values != return_values.length ()) 11282 { 11283 if (return_values.length () == 1) 11284 result = return_values[0]; 11285 else 11286 { 11287 for (rtx &x : return_values) 11288 if (GET_CODE (x) != EXPR_LIST) 11289 x = gen_rtx_EXPR_LIST (VOIDmode, x, const0_rtx); 11290 rtvec v = gen_rtvec_v (return_values.length (), 11291 return_values.address ()); 11292 result = gen_rtx_PARALLEL (VOIDmode, v); 11293 } 11294 } 11295 11296 call = gen_rtx_CALL (VOIDmode, mem, const0_rtx); 11297 11298 if (result != NULL_RTX) 11299 call = gen_rtx_SET (result, call); 11300 11301 if (sibcall) 11302 tmp = ret_rtx; 11303 else 11304 tmp = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNUM)); 11305 11306 callee_abi = gen_rtx_UNSPEC (DImode, gen_rtvec (1, callee_abi), 11307 UNSPEC_CALLEE_ABI); 11308 11309 vec = gen_rtvec (3, call, callee_abi, tmp); 11310 call = gen_rtx_PARALLEL (VOIDmode, vec); 11311 11312 auto call_insn = aarch64_emit_call_insn (call); 11313 11314 /* Check whether the call requires a change to PSTATE.SM. We can't 11315 emit the instructions to change PSTATE.SM yet, since they involve 11316 a change in vector length and a change in instruction set, which 11317 cannot be represented in RTL. 11318 11319 For now, just record which registers will be clobbered and used 11320 by the changes to PSTATE.SM. */ 11321 if (!sibcall && aarch64_call_switches_pstate_sm (callee_isa_mode)) 11322 { 11323 aarch64_sme_mode_switch_regs args_switch; 11324 if (sme_mode_switch_args != const0_rtx) 11325 { 11326 unsigned int num_args = XVECLEN (sme_mode_switch_args, 0); 11327 for (unsigned int i = 0; i < num_args; ++i) 11328 { 11329 rtx x = XVECEXP (sme_mode_switch_args, 0, i); 11330 args_switch.add_reg (GET_MODE (x), REGNO (x)); 11331 } 11332 } 11333 11334 aarch64_sme_mode_switch_regs result_switch; 11335 if (result) 11336 result_switch.add_call_result (call_insn); 11337 11338 unsigned int num_gprs = MAX (args_switch.num_gprs (), 11339 result_switch.num_gprs ()); 11340 for (unsigned int i = 0; i < num_gprs; ++i) 11341 clobber_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), 11342 gen_rtx_REG (DImode, args_switch.FIRST_GPR + i)); 11343 11344 for (int regno = V0_REGNUM; regno < V0_REGNUM + 32; regno += 4) 11345 clobber_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), 11346 gen_rtx_REG (V4x16QImode, regno)); 11347 11348 for (int regno = P0_REGNUM; regno < P0_REGNUM + 16; regno += 1) 11349 clobber_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), 11350 gen_rtx_REG (VNx16BImode, regno)); 11351 11352 /* Ensure that the VG save slot has been initialized. Also emit 11353 an instruction to model the effect of the temporary clobber 11354 of VG, so that the prologue/epilogue pass sees the need to 11355 save the old value. */ 11356 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), 11357 gen_rtx_REG (DImode, VG_REGNUM)); 11358 emit_insn_before (gen_aarch64_update_vg (), call_insn); 11359 11360 cfun->machine->call_switches_pstate_sm = true; 11361 } 11362 11363 /* Add any ZA-related information. 11364 11365 ZA_REGNUM represents the current function's ZA state, rather than 11366 the contents of the ZA register itself. We ensure that the function's 11367 ZA state is preserved by private-ZA call sequences, so the call itself 11368 does not use or clobber ZA_REGNUM. The same thing applies to 11369 ZT0_REGNUM. */ 11370 if (TARGET_ZA) 11371 { 11372 /* The callee requires ZA to be active if the callee is shared-ZA, 11373 otherwise it requires ZA to be dormant or off. The state of ZA is 11374 captured by a combination of SME_STATE_REGNUM, TPIDR2_SETUP_REGNUM, 11375 and ZA_SAVED_REGNUM. */ 11376 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), 11377 gen_rtx_REG (DImode, SME_STATE_REGNUM)); 11378 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), 11379 gen_rtx_REG (DImode, TPIDR2_SETUP_REGNUM)); 11380 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), 11381 gen_rtx_REG (VNx16BImode, ZA_SAVED_REGNUM)); 11382 11383 /* Keep the aarch64_start/end_private_za_call markers live. */ 11384 if (!(callee_isa_mode & AARCH64_FL_ZA_ON)) 11385 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), 11386 gen_rtx_REG (VNx16BImode, LOWERING_REGNUM)); 11387 11388 /* If the callee is a shared-ZA function, record whether it uses the 11389 current value of ZA and ZT0. */ 11390 if (shared_za_flags & AARCH64_STATE_IN) 11391 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), 11392 gen_rtx_REG (VNx16BImode, ZA_REGNUM)); 11393 11394 if (shared_zt0_flags & AARCH64_STATE_IN) 11395 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), 11396 gen_rtx_REG (V8DImode, ZT0_REGNUM)); 11397 } 11398 } 11399 11400 /* Implement TARGET_END_CALL_ARGS. */ 11401 11402 static void 11403 aarch64_end_call_args (cumulative_args_t ca_v) 11404 { 11405 CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v); 11406 11407 /* If this is a call to a private ZA function, emit a marker to 11408 indicate where any necessary restoration code could be inserted. 11409 The code itself is inserted by the mode-switching pass. */ 11410 if (TARGET_ZA && !(ca->isa_mode & AARCH64_FL_ZA_ON)) 11411 emit_insn (gen_aarch64_end_private_za_call ()); 11412 11413 /* If this is a call to a shared-ZA function that doesn't share ZT0, 11414 save and restore ZT0 around the call. */ 11415 if (aarch64_cfun_has_state ("zt0") 11416 && (ca->isa_mode & AARCH64_FL_ZA_ON) 11417 && ca->shared_zt0_flags == 0) 11418 aarch64_restore_zt0 (false); 11419 } 11420 11421 /* Emit call insn with PAT and do aarch64-specific handling. */ 11422 11423 rtx_call_insn * 11424 aarch64_emit_call_insn (rtx pat) 11425 { 11426 auto insn = emit_call_insn (pat); 11427 11428 rtx *fusage = &CALL_INSN_FUNCTION_USAGE (insn); 11429 clobber_reg (fusage, gen_rtx_REG (word_mode, IP0_REGNUM)); 11430 clobber_reg (fusage, gen_rtx_REG (word_mode, IP1_REGNUM)); 11431 return as_a<rtx_call_insn *> (insn); 11432 } 11433 11434 machine_mode 11435 aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y) 11436 { 11437 machine_mode mode_x = GET_MODE (x); 11438 rtx_code code_x = GET_CODE (x); 11439 11440 /* All floating point compares return CCFP if it is an equality 11441 comparison, and CCFPE otherwise. */ 11442 if (GET_MODE_CLASS (mode_x) == MODE_FLOAT) 11443 { 11444 switch (code) 11445 { 11446 case EQ: 11447 case NE: 11448 case UNORDERED: 11449 case ORDERED: 11450 case UNLT: 11451 case UNLE: 11452 case UNGT: 11453 case UNGE: 11454 case UNEQ: 11455 return CCFPmode; 11456 11457 case LT: 11458 case LE: 11459 case GT: 11460 case GE: 11461 case LTGT: 11462 return CCFPEmode; 11463 11464 default: 11465 gcc_unreachable (); 11466 } 11467 } 11468 11469 /* Equality comparisons of short modes against zero can be performed 11470 using the TST instruction with the appropriate bitmask. */ 11471 if (y == const0_rtx && (REG_P (x) || SUBREG_P (x)) 11472 && (code == EQ || code == NE) 11473 && (mode_x == HImode || mode_x == QImode)) 11474 return CC_Zmode; 11475 11476 /* Similarly, comparisons of zero_extends from shorter modes can 11477 be performed using an ANDS with an immediate mask. */ 11478 if (y == const0_rtx && code_x == ZERO_EXTEND 11479 && (mode_x == SImode || mode_x == DImode) 11480 && (GET_MODE (XEXP (x, 0)) == HImode || GET_MODE (XEXP (x, 0)) == QImode) 11481 && (code == EQ || code == NE)) 11482 return CC_Zmode; 11483 11484 /* Zero extracts support equality comparisons. */ 11485 if ((mode_x == SImode || mode_x == DImode) 11486 && y == const0_rtx 11487 && (code_x == ZERO_EXTRACT && CONST_INT_P (XEXP (x, 1)) 11488 && CONST_INT_P (XEXP (x, 2))) 11489 && (code == EQ || code == NE)) 11490 return CC_Zmode; 11491 11492 /* ANDS/BICS/TST support equality and all signed comparisons. */ 11493 if ((mode_x == SImode || mode_x == DImode) 11494 && y == const0_rtx 11495 && (code_x == AND) 11496 && (code == EQ || code == NE || code == LT || code == GE 11497 || code == GT || code == LE)) 11498 return CC_NZVmode; 11499 11500 /* ADDS/SUBS correctly set N and Z flags. */ 11501 if ((mode_x == SImode || mode_x == DImode) 11502 && y == const0_rtx 11503 && (code == EQ || code == NE || code == LT || code == GE) 11504 && (code_x == PLUS || code_x == MINUS || code_x == NEG)) 11505 return CC_NZmode; 11506 11507 /* A compare with a shifted operand. Because of canonicalization, 11508 the comparison will have to be swapped when we emit the assembly 11509 code. */ 11510 if ((mode_x == SImode || mode_x == DImode) 11511 && (REG_P (y) || SUBREG_P (y) || y == const0_rtx) 11512 && (code_x == ASHIFT || code_x == ASHIFTRT 11513 || code_x == LSHIFTRT 11514 || code_x == ZERO_EXTEND || code_x == SIGN_EXTEND)) 11515 return CC_SWPmode; 11516 11517 /* Similarly for a negated operand, but we can only do this for 11518 equalities. */ 11519 if ((mode_x == SImode || mode_x == DImode) 11520 && (REG_P (y) || SUBREG_P (y)) 11521 && (code == EQ || code == NE) 11522 && code_x == NEG) 11523 return CC_Zmode; 11524 11525 /* A test for unsigned overflow from an addition. */ 11526 if ((mode_x == DImode || mode_x == TImode) 11527 && (code == LTU || code == GEU) 11528 && code_x == PLUS 11529 && rtx_equal_p (XEXP (x, 0), y)) 11530 return CC_Cmode; 11531 11532 /* A test for unsigned overflow from an add with carry. */ 11533 if ((mode_x == DImode || mode_x == TImode) 11534 && (code == LTU || code == GEU) 11535 && code_x == PLUS 11536 && CONST_SCALAR_INT_P (y) 11537 && (rtx_mode_t (y, mode_x) 11538 == (wi::shwi (1, mode_x) 11539 << (GET_MODE_BITSIZE (mode_x).to_constant () / 2)))) 11540 return CC_ADCmode; 11541 11542 /* A test for signed overflow. */ 11543 if ((mode_x == DImode || mode_x == TImode) 11544 && code == NE 11545 && code_x == PLUS 11546 && GET_CODE (y) == SIGN_EXTEND) 11547 return CC_Vmode; 11548 11549 /* For everything else, return CCmode. */ 11550 return CCmode; 11551 } 11552 11553 static int 11554 aarch64_get_condition_code_1 (machine_mode, enum rtx_code); 11555 11556 int 11557 aarch64_get_condition_code (rtx x) 11558 { 11559 machine_mode mode = GET_MODE (XEXP (x, 0)); 11560 enum rtx_code comp_code = GET_CODE (x); 11561 11562 if (GET_MODE_CLASS (mode) != MODE_CC) 11563 mode = SELECT_CC_MODE (comp_code, XEXP (x, 0), XEXP (x, 1)); 11564 return aarch64_get_condition_code_1 (mode, comp_code); 11565 } 11566 11567 static int 11568 aarch64_get_condition_code_1 (machine_mode mode, enum rtx_code comp_code) 11569 { 11570 switch (mode) 11571 { 11572 case E_CCFPmode: 11573 case E_CCFPEmode: 11574 switch (comp_code) 11575 { 11576 case GE: return AARCH64_GE; 11577 case GT: return AARCH64_GT; 11578 case LE: return AARCH64_LS; 11579 case LT: return AARCH64_MI; 11580 case NE: return AARCH64_NE; 11581 case EQ: return AARCH64_EQ; 11582 case ORDERED: return AARCH64_VC; 11583 case UNORDERED: return AARCH64_VS; 11584 case UNLT: return AARCH64_LT; 11585 case UNLE: return AARCH64_LE; 11586 case UNGT: return AARCH64_HI; 11587 case UNGE: return AARCH64_PL; 11588 default: return -1; 11589 } 11590 break; 11591 11592 case E_CCmode: 11593 switch (comp_code) 11594 { 11595 case NE: return AARCH64_NE; 11596 case EQ: return AARCH64_EQ; 11597 case GE: return AARCH64_GE; 11598 case GT: return AARCH64_GT; 11599 case LE: return AARCH64_LE; 11600 case LT: return AARCH64_LT; 11601 case GEU: return AARCH64_CS; 11602 case GTU: return AARCH64_HI; 11603 case LEU: return AARCH64_LS; 11604 case LTU: return AARCH64_CC; 11605 default: return -1; 11606 } 11607 break; 11608 11609 case E_CC_SWPmode: 11610 switch (comp_code) 11611 { 11612 case NE: return AARCH64_NE; 11613 case EQ: return AARCH64_EQ; 11614 case GE: return AARCH64_LE; 11615 case GT: return AARCH64_LT; 11616 case LE: return AARCH64_GE; 11617 case LT: return AARCH64_GT; 11618 case GEU: return AARCH64_LS; 11619 case GTU: return AARCH64_CC; 11620 case LEU: return AARCH64_CS; 11621 case LTU: return AARCH64_HI; 11622 default: return -1; 11623 } 11624 break; 11625 11626 case E_CC_NZCmode: 11627 switch (comp_code) 11628 { 11629 case NE: return AARCH64_NE; /* = any */ 11630 case EQ: return AARCH64_EQ; /* = none */ 11631 case GE: return AARCH64_PL; /* = nfrst */ 11632 case LT: return AARCH64_MI; /* = first */ 11633 case GEU: return AARCH64_CS; /* = nlast */ 11634 case GTU: return AARCH64_HI; /* = pmore */ 11635 case LEU: return AARCH64_LS; /* = plast */ 11636 case LTU: return AARCH64_CC; /* = last */ 11637 default: return -1; 11638 } 11639 break; 11640 11641 case E_CC_NZVmode: 11642 switch (comp_code) 11643 { 11644 case NE: return AARCH64_NE; 11645 case EQ: return AARCH64_EQ; 11646 case GE: return AARCH64_PL; 11647 case LT: return AARCH64_MI; 11648 case GT: return AARCH64_GT; 11649 case LE: return AARCH64_LE; 11650 default: return -1; 11651 } 11652 break; 11653 11654 case E_CC_NZmode: 11655 switch (comp_code) 11656 { 11657 case NE: return AARCH64_NE; 11658 case EQ: return AARCH64_EQ; 11659 case GE: return AARCH64_PL; 11660 case LT: return AARCH64_MI; 11661 default: return -1; 11662 } 11663 break; 11664 11665 case E_CC_Zmode: 11666 switch (comp_code) 11667 { 11668 case NE: return AARCH64_NE; 11669 case EQ: return AARCH64_EQ; 11670 default: return -1; 11671 } 11672 break; 11673 11674 case E_CC_Cmode: 11675 switch (comp_code) 11676 { 11677 case LTU: return AARCH64_CS; 11678 case GEU: return AARCH64_CC; 11679 default: return -1; 11680 } 11681 break; 11682 11683 case E_CC_ADCmode: 11684 switch (comp_code) 11685 { 11686 case GEU: return AARCH64_CS; 11687 case LTU: return AARCH64_CC; 11688 default: return -1; 11689 } 11690 break; 11691 11692 case E_CC_Vmode: 11693 switch (comp_code) 11694 { 11695 case NE: return AARCH64_VS; 11696 case EQ: return AARCH64_VC; 11697 default: return -1; 11698 } 11699 break; 11700 11701 default: 11702 return -1; 11703 } 11704 11705 return -1; 11706 } 11707 11708 /* Return true if X is a CONST_INT, CONST_WIDE_INT or a constant vector 11709 duplicate of such constants. If so, store in RET_WI the wide_int 11710 representation of the constant paired with the inner mode of the vector mode 11711 or MODE for scalar X constants. If MODE is not provided then TImode is 11712 used. */ 11713 11714 static bool 11715 aarch64_extract_vec_duplicate_wide_int (rtx x, wide_int *ret_wi, 11716 scalar_mode mode = TImode) 11717 { 11718 rtx elt = unwrap_const_vec_duplicate (x); 11719 if (!CONST_SCALAR_INT_P (elt)) 11720 return false; 11721 scalar_mode smode 11722 = CONST_SCALAR_INT_P (x) ? mode : GET_MODE_INNER (GET_MODE (x)); 11723 *ret_wi = rtx_mode_t (elt, smode); 11724 return true; 11725 } 11726 11727 /* Return true if X is a scalar or a constant vector of integer 11728 immediates that represent the rounding constant used in the fixed-point 11729 arithmetic instructions. 11730 The accepted form of the constant is (1 << (C - 1)) where C is in the range 11731 [1, MODE_WIDTH/2]. */ 11732 11733 bool 11734 aarch64_rnd_imm_p (rtx x) 11735 { 11736 wide_int rnd_cst; 11737 if (!aarch64_extract_vec_duplicate_wide_int (x, &rnd_cst)) 11738 return false; 11739 int log2 = wi::exact_log2 (rnd_cst); 11740 if (log2 < 0) 11741 return false; 11742 return IN_RANGE (log2, 0, rnd_cst.get_precision () / 2 - 1); 11743 } 11744 11745 /* Return true if RND is a constant vector of integer rounding constants 11746 corresponding to a constant vector of shifts, SHIFT. 11747 The relationship should be RND == (1 << (SHIFT - 1)). */ 11748 11749 bool 11750 aarch64_const_vec_rnd_cst_p (rtx rnd, rtx shift) 11751 { 11752 wide_int rnd_cst, shft_cst; 11753 if (!aarch64_extract_vec_duplicate_wide_int (rnd, &rnd_cst) 11754 || !aarch64_extract_vec_duplicate_wide_int (shift, &shft_cst)) 11755 return false; 11756 11757 return rnd_cst == (wi::shwi (1, rnd_cst.get_precision ()) << (shft_cst - 1)); 11758 } 11759 11760 bool 11761 aarch64_const_vec_all_same_in_range_p (rtx x, 11762 HOST_WIDE_INT minval, 11763 HOST_WIDE_INT maxval) 11764 { 11765 rtx elt; 11766 return (const_vec_duplicate_p (x, &elt) 11767 && CONST_INT_P (elt) 11768 && IN_RANGE (INTVAL (elt), minval, maxval)); 11769 } 11770 11771 /* Some constants can't be made using normal mov instructions in Advanced SIMD 11772 but we can still create them in various ways. If the constant in VAL can be 11773 created using alternate methods then if possible then return true and 11774 additionally set TARGET to the rtx for the sequence if TARGET is not NULL. 11775 Otherwise return false if sequence is not possible. */ 11776 11777 bool 11778 aarch64_maybe_generate_simd_constant (rtx target, rtx val, machine_mode mode) 11779 { 11780 wide_int wval; 11781 auto smode = GET_MODE_INNER (mode); 11782 if (!aarch64_extract_vec_duplicate_wide_int (val, &wval, smode)) 11783 return false; 11784 11785 /* For Advanced SIMD we can create an integer with only the top bit set 11786 using fneg (0.0f). */ 11787 if (TARGET_SIMD 11788 && !TARGET_SVE 11789 && smode == DImode 11790 && wi::only_sign_bit_p (wval)) 11791 { 11792 if (!target) 11793 return true; 11794 11795 /* Use the same base type as aarch64_gen_shareable_zero. */ 11796 rtx zero = CONST0_RTX (V4SImode); 11797 emit_move_insn (lowpart_subreg (V4SImode, target, mode), zero); 11798 rtx neg = lowpart_subreg (V2DFmode, target, mode); 11799 emit_insn (gen_negv2df2 (neg, copy_rtx (neg))); 11800 return true; 11801 } 11802 11803 return false; 11804 } 11805 11806 /* Check if the value in VAL with mode MODE can be created using special 11807 instruction sequences. */ 11808 11809 bool aarch64_simd_special_constant_p (rtx val, machine_mode mode) 11810 { 11811 return aarch64_maybe_generate_simd_constant (NULL_RTX, val, mode); 11812 } 11813 11814 bool 11815 aarch64_const_vec_all_same_int_p (rtx x, HOST_WIDE_INT val) 11816 { 11817 return aarch64_const_vec_all_same_in_range_p (x, val, val); 11818 } 11819 11820 /* Return true if VEC is a constant in which every element is in the range 11821 [MINVAL, MAXVAL]. The elements do not need to have the same value. */ 11822 11823 static bool 11824 aarch64_const_vec_all_in_range_p (rtx vec, 11825 HOST_WIDE_INT minval, 11826 HOST_WIDE_INT maxval) 11827 { 11828 if (!CONST_VECTOR_P (vec) 11829 || GET_MODE_CLASS (GET_MODE (vec)) != MODE_VECTOR_INT) 11830 return false; 11831 11832 int nunits; 11833 if (!CONST_VECTOR_STEPPED_P (vec)) 11834 nunits = const_vector_encoded_nelts (vec); 11835 else if (!CONST_VECTOR_NUNITS (vec).is_constant (&nunits)) 11836 return false; 11837 11838 for (int i = 0; i < nunits; i++) 11839 { 11840 rtx vec_elem = CONST_VECTOR_ELT (vec, i); 11841 if (!CONST_INT_P (vec_elem) 11842 || !IN_RANGE (INTVAL (vec_elem), minval, maxval)) 11843 return false; 11844 } 11845 return true; 11846 } 11847 11848 /* N Z C V. */ 11849 #define AARCH64_CC_V 1 11850 #define AARCH64_CC_C (1 << 1) 11851 #define AARCH64_CC_Z (1 << 2) 11852 #define AARCH64_CC_N (1 << 3) 11853 11854 /* N Z C V flags for ccmp. Indexed by AARCH64_COND_CODE. */ 11855 static const int aarch64_nzcv_codes[] = 11856 { 11857 0, /* EQ, Z == 1. */ 11858 AARCH64_CC_Z, /* NE, Z == 0. */ 11859 0, /* CS, C == 1. */ 11860 AARCH64_CC_C, /* CC, C == 0. */ 11861 0, /* MI, N == 1. */ 11862 AARCH64_CC_N, /* PL, N == 0. */ 11863 0, /* VS, V == 1. */ 11864 AARCH64_CC_V, /* VC, V == 0. */ 11865 0, /* HI, C ==1 && Z == 0. */ 11866 AARCH64_CC_C, /* LS, !(C == 1 && Z == 0). */ 11867 AARCH64_CC_V, /* GE, N == V. */ 11868 0, /* LT, N != V. */ 11869 AARCH64_CC_Z, /* GT, Z == 0 && N == V. */ 11870 0, /* LE, !(Z == 0 && N == V). */ 11871 0, /* AL, Any. */ 11872 0 /* NV, Any. */ 11873 }; 11874 11875 /* Print floating-point vector immediate operand X to F, negating it 11876 first if NEGATE is true. Return true on success, false if it isn't 11877 a constant we can handle. */ 11878 11879 static bool 11880 aarch64_print_vector_float_operand (FILE *f, rtx x, bool negate) 11881 { 11882 rtx elt; 11883 11884 if (!const_vec_duplicate_p (x, &elt)) 11885 return false; 11886 11887 REAL_VALUE_TYPE r = *CONST_DOUBLE_REAL_VALUE (elt); 11888 if (negate) 11889 r = real_value_negate (&r); 11890 11891 /* Handle the SVE single-bit immediates specially, since they have a 11892 fixed form in the assembly syntax. */ 11893 if (real_equal (&r, &dconst0)) 11894 asm_fprintf (f, "0.0"); 11895 else if (real_equal (&r, &dconst2)) 11896 asm_fprintf (f, "2.0"); 11897 else if (real_equal (&r, &dconst1)) 11898 asm_fprintf (f, "1.0"); 11899 else if (real_equal (&r, &dconsthalf)) 11900 asm_fprintf (f, "0.5"); 11901 else 11902 { 11903 const int buf_size = 20; 11904 char float_buf[buf_size] = {'\0'}; 11905 real_to_decimal_for_mode (float_buf, &r, buf_size, buf_size, 11906 1, GET_MODE (elt)); 11907 asm_fprintf (f, "%s", float_buf); 11908 } 11909 11910 return true; 11911 } 11912 11913 /* Return the equivalent letter for size. */ 11914 static char 11915 sizetochar (int size) 11916 { 11917 switch (size) 11918 { 11919 case 64: return 'd'; 11920 case 32: return 's'; 11921 case 16: return 'h'; 11922 case 8 : return 'b'; 11923 default: gcc_unreachable (); 11924 } 11925 } 11926 11927 /* Print operand X to file F in a target specific manner according to CODE. 11928 The acceptable formatting commands given by CODE are: 11929 'c': An integer or symbol address without a preceding # 11930 sign. 11931 'C': Take the duplicated element in a vector constant 11932 and print it in hex. 11933 'D': Take the duplicated element in a vector constant 11934 and print it as an unsigned integer, in decimal. 11935 'e': Print the sign/zero-extend size as a character 8->b, 11936 16->h, 32->w. Can also be used for masks: 11937 0xff->b, 0xffff->h, 0xffffffff->w. 11938 'I': If the operand is a duplicated vector constant, 11939 replace it with the duplicated scalar. If the 11940 operand is then a floating-point constant, replace 11941 it with the integer bit representation. Print the 11942 transformed constant as a signed decimal number. 11943 'p': Prints N such that 2^N == X (X must be power of 2 and 11944 const int). 11945 'P': Print the number of non-zero bits in X (a const_int). 11946 'H': Print the higher numbered register of a pair (TImode) 11947 of regs. 11948 'm': Print a condition (eq, ne, etc). 11949 'M': Same as 'm', but invert condition. 11950 'N': Take the duplicated element in a vector constant 11951 and print the negative of it in decimal. 11952 'b/h/s/d/q': Print a scalar FP/SIMD register name. 11953 'Z': Same for SVE registers. ('z' was already taken.) 11954 Note that it is not necessary to use %Z for operands 11955 that have SVE modes. The convention is to use %Z 11956 only for non-SVE (or potentially non-SVE) modes. 11957 'S/T/U/V': Print a FP/SIMD register name for a register list. 11958 The register printed is the FP/SIMD register name 11959 of X + 0/1/2/3 for S/T/U/V. 11960 'R': Print a scalar Integer/FP/SIMD register name + 1. 11961 'X': Print bottom 16 bits of integer constant in hex. 11962 'w/x': Print a general register name or the zero register 11963 (32-bit or 64-bit). 11964 '0': Print a normal operand, if it's a general register, 11965 then we assume DImode. 11966 'k': Print NZCV for conditional compare instructions. 11967 'K': Print a predicate register as pn<N> rather than p<N> 11968 'A': Output address constant representing the first 11969 argument of X, specifying a relocation offset 11970 if appropriate. 11971 'L': Output constant address specified by X 11972 with a relocation offset if appropriate. 11973 'G': Prints address of X, specifying a PC relative 11974 relocation mode if appropriate. 11975 'y': Output address of LDP or STP - this is used for 11976 some LDP/STPs which don't use a PARALLEL in their 11977 pattern (so the mode needs to be adjusted). 11978 'z': Output address of a typical LDP or STP. */ 11979 11980 static void 11981 aarch64_print_operand (FILE *f, rtx x, int code) 11982 { 11983 rtx elt; 11984 switch (code) 11985 { 11986 case 'c': 11987 if (CONST_INT_P (x)) 11988 fprintf (f, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); 11989 else 11990 { 11991 poly_int64 offset; 11992 rtx base = strip_offset_and_salt (x, &offset); 11993 if (SYMBOL_REF_P (base)) 11994 output_addr_const (f, x); 11995 else 11996 output_operand_lossage ("unsupported operand for code '%c'", code); 11997 } 11998 break; 11999 12000 case 'e': 12001 { 12002 x = unwrap_const_vec_duplicate (x); 12003 if (!CONST_INT_P (x)) 12004 { 12005 output_operand_lossage ("invalid operand for '%%%c'", code); 12006 return; 12007 } 12008 12009 HOST_WIDE_INT val = INTVAL (x); 12010 if ((val & ~7) == 8 || val == 0xff) 12011 fputc ('b', f); 12012 else if ((val & ~7) == 16 || val == 0xffff) 12013 fputc ('h', f); 12014 else if ((val & ~7) == 32 || val == 0xffffffff) 12015 fputc ('w', f); 12016 else 12017 { 12018 output_operand_lossage ("invalid operand for '%%%c'", code); 12019 return; 12020 } 12021 } 12022 break; 12023 12024 case 'p': 12025 { 12026 int n; 12027 12028 if (!CONST_INT_P (x) || (n = exact_log2 (INTVAL (x))) < 0) 12029 { 12030 output_operand_lossage ("invalid operand for '%%%c'", code); 12031 return; 12032 } 12033 12034 asm_fprintf (f, "%d", n); 12035 } 12036 break; 12037 12038 case 'P': 12039 if (!CONST_INT_P (x)) 12040 { 12041 output_operand_lossage ("invalid operand for '%%%c'", code); 12042 return; 12043 } 12044 12045 asm_fprintf (f, "%u", popcount_hwi (INTVAL (x))); 12046 break; 12047 12048 case 'H': 12049 if (x == const0_rtx) 12050 { 12051 asm_fprintf (f, "xzr"); 12052 break; 12053 } 12054 12055 if (!REG_P (x) || !GP_REGNUM_P (REGNO (x) + 1)) 12056 { 12057 output_operand_lossage ("invalid operand for '%%%c'", code); 12058 return; 12059 } 12060 12061 asm_fprintf (f, "%s", reg_names [REGNO (x) + 1]); 12062 break; 12063 12064 case 'I': 12065 { 12066 x = aarch64_bit_representation (unwrap_const_vec_duplicate (x)); 12067 if (CONST_INT_P (x)) 12068 asm_fprintf (f, "%wd", INTVAL (x)); 12069 else 12070 { 12071 output_operand_lossage ("invalid operand for '%%%c'", code); 12072 return; 12073 } 12074 break; 12075 } 12076 12077 case 'M': 12078 case 'm': 12079 { 12080 int cond_code; 12081 /* CONST_TRUE_RTX means al/nv (al is the default, don't print it). */ 12082 if (x == const_true_rtx) 12083 { 12084 if (code == 'M') 12085 fputs ("nv", f); 12086 return; 12087 } 12088 12089 if (!COMPARISON_P (x)) 12090 { 12091 output_operand_lossage ("invalid operand for '%%%c'", code); 12092 return; 12093 } 12094 12095 cond_code = aarch64_get_condition_code (x); 12096 gcc_assert (cond_code >= 0); 12097 if (code == 'M') 12098 cond_code = AARCH64_INVERSE_CONDITION_CODE (cond_code); 12099 if (GET_MODE (XEXP (x, 0)) == CC_NZCmode) 12100 fputs (aarch64_sve_condition_codes[cond_code], f); 12101 else 12102 fputs (aarch64_condition_codes[cond_code], f); 12103 } 12104 break; 12105 12106 case 'N': 12107 if (!const_vec_duplicate_p (x, &elt)) 12108 { 12109 output_operand_lossage ("invalid vector constant"); 12110 return; 12111 } 12112 12113 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_VECTOR_INT) 12114 asm_fprintf (f, "%wd", (HOST_WIDE_INT) -UINTVAL (elt)); 12115 else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_VECTOR_FLOAT 12116 && aarch64_print_vector_float_operand (f, x, true)) 12117 ; 12118 else 12119 { 12120 output_operand_lossage ("invalid vector constant"); 12121 return; 12122 } 12123 break; 12124 12125 case 'b': 12126 case 'h': 12127 case 's': 12128 case 'd': 12129 case 'q': 12130 case 'Z': 12131 code = TOLOWER (code); 12132 if (!REG_P (x) || !FP_REGNUM_P (REGNO (x))) 12133 { 12134 output_operand_lossage ("incompatible floating point / vector register operand for '%%%c'", code); 12135 return; 12136 } 12137 asm_fprintf (f, "%c%d", code, REGNO (x) - V0_REGNUM); 12138 break; 12139 12140 case 'S': 12141 case 'T': 12142 case 'U': 12143 case 'V': 12144 if (!REG_P (x) || (!FP_REGNUM_P (REGNO (x)) && !PR_REGNUM_P (REGNO (x)))) 12145 { 12146 output_operand_lossage ("incompatible operand for '%%%c'", code); 12147 return; 12148 } 12149 if (PR_REGNUM_P (REGNO (x))) 12150 asm_fprintf (f, "p%d", REGNO (x) - P0_REGNUM + (code - 'S')); 12151 else 12152 asm_fprintf (f, "%c%d", 12153 aarch64_sve_data_mode_p (GET_MODE (x)) ? 'z' : 'v', 12154 REGNO (x) - V0_REGNUM + (code - 'S')); 12155 break; 12156 12157 case 'R': 12158 if (REG_P (x) && FP_REGNUM_P (REGNO (x)) 12159 && (aarch64_advsimd_partial_struct_mode_p (GET_MODE (x)))) 12160 asm_fprintf (f, "d%d", REGNO (x) - V0_REGNUM + 1); 12161 else if (REG_P (x) && FP_REGNUM_P (REGNO (x))) 12162 asm_fprintf (f, "q%d", REGNO (x) - V0_REGNUM + 1); 12163 else if (REG_P (x) && GP_REGNUM_P (REGNO (x))) 12164 asm_fprintf (f, "x%d", REGNO (x) - R0_REGNUM + 1); 12165 else 12166 output_operand_lossage ("incompatible register operand for '%%%c'", 12167 code); 12168 break; 12169 12170 case 'X': 12171 if (!CONST_INT_P (x)) 12172 { 12173 output_operand_lossage ("invalid operand for '%%%c'", code); 12174 return; 12175 } 12176 asm_fprintf (f, "0x%wx", UINTVAL (x) & 0xffff); 12177 break; 12178 12179 case 'C': 12180 { 12181 /* Print a replicated constant in hex. */ 12182 if (!const_vec_duplicate_p (x, &elt) || !CONST_INT_P (elt)) 12183 { 12184 output_operand_lossage ("invalid operand for '%%%c'", code); 12185 return; 12186 } 12187 scalar_mode inner_mode = GET_MODE_INNER (GET_MODE (x)); 12188 asm_fprintf (f, "0x%wx", UINTVAL (elt) & GET_MODE_MASK (inner_mode)); 12189 } 12190 break; 12191 12192 case 'D': 12193 { 12194 /* Print a replicated constant in decimal, treating it as 12195 unsigned. */ 12196 if (!const_vec_duplicate_p (x, &elt) || !CONST_INT_P (elt)) 12197 { 12198 output_operand_lossage ("invalid operand for '%%%c'", code); 12199 return; 12200 } 12201 scalar_mode inner_mode = GET_MODE_INNER (GET_MODE (x)); 12202 asm_fprintf (f, "%wd", UINTVAL (elt) & GET_MODE_MASK (inner_mode)); 12203 } 12204 break; 12205 12206 case 'w': 12207 case 'x': 12208 if (aarch64_const_zero_rtx_p (x)) 12209 { 12210 asm_fprintf (f, "%czr", code); 12211 break; 12212 } 12213 12214 if (REG_P (x) && GP_REGNUM_P (REGNO (x))) 12215 { 12216 asm_fprintf (f, "%c%d", code, REGNO (x) - R0_REGNUM); 12217 break; 12218 } 12219 12220 if (REG_P (x) && REGNO (x) == SP_REGNUM) 12221 { 12222 asm_fprintf (f, "%ssp", code == 'w' ? "w" : ""); 12223 break; 12224 } 12225 12226 /* Fall through */ 12227 12228 case 0: 12229 if (x == NULL) 12230 { 12231 output_operand_lossage ("missing operand"); 12232 return; 12233 } 12234 12235 switch (GET_CODE (x)) 12236 { 12237 case CONST_STRING: 12238 { 12239 asm_fprintf (f, "%s", XSTR (x, 0)); 12240 break; 12241 } 12242 case REG: 12243 if (aarch64_sve_data_mode_p (GET_MODE (x))) 12244 { 12245 if (REG_NREGS (x) == 1) 12246 asm_fprintf (f, "z%d", REGNO (x) - V0_REGNUM); 12247 else 12248 { 12249 char suffix 12250 = sizetochar (GET_MODE_UNIT_BITSIZE (GET_MODE (x))); 12251 asm_fprintf (f, "{z%d.%c - z%d.%c}", 12252 REGNO (x) - V0_REGNUM, suffix, 12253 END_REGNO (x) - V0_REGNUM - 1, suffix); 12254 } 12255 } 12256 else 12257 asm_fprintf (f, "%s", reg_names [REGNO (x)]); 12258 break; 12259 12260 case MEM: 12261 output_address (GET_MODE (x), XEXP (x, 0)); 12262 break; 12263 12264 case LABEL_REF: 12265 case SYMBOL_REF: 12266 output_addr_const (asm_out_file, x); 12267 break; 12268 12269 case CONST_INT: 12270 asm_fprintf (f, "%wd", INTVAL (x)); 12271 break; 12272 12273 case CONST: 12274 if (!VECTOR_MODE_P (GET_MODE (x))) 12275 { 12276 output_addr_const (asm_out_file, x); 12277 break; 12278 } 12279 /* fall through */ 12280 12281 case CONST_VECTOR: 12282 if (!const_vec_duplicate_p (x, &elt)) 12283 { 12284 output_operand_lossage ("invalid vector constant"); 12285 return; 12286 } 12287 12288 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_VECTOR_INT) 12289 asm_fprintf (f, "%wd", INTVAL (elt)); 12290 else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_VECTOR_FLOAT 12291 && aarch64_print_vector_float_operand (f, x, false)) 12292 ; 12293 else 12294 { 12295 output_operand_lossage ("invalid vector constant"); 12296 return; 12297 } 12298 break; 12299 12300 case CONST_DOUBLE: 12301 /* Since we define TARGET_SUPPORTS_WIDE_INT we shouldn't ever 12302 be getting CONST_DOUBLEs holding integers. */ 12303 gcc_assert (GET_MODE (x) != VOIDmode); 12304 if (aarch64_float_const_zero_rtx_p (x)) 12305 { 12306 fputc ('0', f); 12307 break; 12308 } 12309 else if (aarch64_float_const_representable_p (x)) 12310 { 12311 #define buf_size 20 12312 char float_buf[buf_size] = {'\0'}; 12313 real_to_decimal_for_mode (float_buf, 12314 CONST_DOUBLE_REAL_VALUE (x), 12315 buf_size, buf_size, 12316 1, GET_MODE (x)); 12317 asm_fprintf (asm_out_file, "%s", float_buf); 12318 break; 12319 #undef buf_size 12320 } 12321 output_operand_lossage ("invalid constant"); 12322 return; 12323 default: 12324 output_operand_lossage ("invalid operand"); 12325 return; 12326 } 12327 break; 12328 12329 case 'A': 12330 if (GET_CODE (x) == HIGH) 12331 x = XEXP (x, 0); 12332 12333 switch (aarch64_classify_symbolic_expression (x)) 12334 { 12335 case SYMBOL_SMALL_GOT_4G: 12336 asm_fprintf (asm_out_file, ":got:"); 12337 break; 12338 12339 case SYMBOL_SMALL_TLSGD: 12340 asm_fprintf (asm_out_file, ":tlsgd:"); 12341 break; 12342 12343 case SYMBOL_SMALL_TLSDESC: 12344 asm_fprintf (asm_out_file, ":tlsdesc:"); 12345 break; 12346 12347 case SYMBOL_SMALL_TLSIE: 12348 asm_fprintf (asm_out_file, ":gottprel:"); 12349 break; 12350 12351 case SYMBOL_TLSLE24: 12352 asm_fprintf (asm_out_file, ":tprel:"); 12353 break; 12354 12355 case SYMBOL_TINY_GOT: 12356 gcc_unreachable (); 12357 break; 12358 12359 default: 12360 break; 12361 } 12362 output_addr_const (asm_out_file, x); 12363 break; 12364 12365 case 'L': 12366 switch (aarch64_classify_symbolic_expression (x)) 12367 { 12368 case SYMBOL_SMALL_GOT_4G: 12369 asm_fprintf (asm_out_file, ":got_lo12:"); 12370 break; 12371 12372 case SYMBOL_SMALL_TLSGD: 12373 asm_fprintf (asm_out_file, ":tlsgd_lo12:"); 12374 break; 12375 12376 case SYMBOL_SMALL_TLSDESC: 12377 asm_fprintf (asm_out_file, ":tlsdesc_lo12:"); 12378 break; 12379 12380 case SYMBOL_SMALL_TLSIE: 12381 asm_fprintf (asm_out_file, ":gottprel_lo12:"); 12382 break; 12383 12384 case SYMBOL_TLSLE12: 12385 asm_fprintf (asm_out_file, ":tprel_lo12:"); 12386 break; 12387 12388 case SYMBOL_TLSLE24: 12389 asm_fprintf (asm_out_file, ":tprel_lo12_nc:"); 12390 break; 12391 12392 case SYMBOL_TINY_GOT: 12393 asm_fprintf (asm_out_file, ":got:"); 12394 break; 12395 12396 case SYMBOL_TINY_TLSIE: 12397 asm_fprintf (asm_out_file, ":gottprel:"); 12398 break; 12399 12400 default: 12401 break; 12402 } 12403 output_addr_const (asm_out_file, x); 12404 break; 12405 12406 case 'G': 12407 switch (aarch64_classify_symbolic_expression (x)) 12408 { 12409 case SYMBOL_TLSLE24: 12410 asm_fprintf (asm_out_file, ":tprel_hi12:"); 12411 break; 12412 default: 12413 break; 12414 } 12415 output_addr_const (asm_out_file, x); 12416 break; 12417 12418 case 'k': 12419 { 12420 HOST_WIDE_INT cond_code; 12421 12422 if (!CONST_INT_P (x)) 12423 { 12424 output_operand_lossage ("invalid operand for '%%%c'", code); 12425 return; 12426 } 12427 12428 cond_code = INTVAL (x); 12429 gcc_assert (cond_code >= 0 && cond_code <= AARCH64_NV); 12430 asm_fprintf (f, "%d", aarch64_nzcv_codes[cond_code]); 12431 } 12432 break; 12433 12434 case 'K': 12435 if (!REG_P (x) || !PR_REGNUM_P (REGNO (x))) 12436 { 12437 output_operand_lossage ("invalid operand for '%%%c'", code); 12438 return; 12439 } 12440 asm_fprintf (f, "pn%d", REGNO (x) - P0_REGNUM); 12441 break; 12442 12443 case 'y': 12444 case 'z': 12445 { 12446 machine_mode mode = GET_MODE (x); 12447 12448 if (!MEM_P (x) 12449 || (code == 'y' 12450 && maybe_ne (GET_MODE_SIZE (mode), 8) 12451 && maybe_ne (GET_MODE_SIZE (mode), 16) 12452 && maybe_ne (GET_MODE_SIZE (mode), 32))) 12453 { 12454 output_operand_lossage ("invalid operand for '%%%c'", code); 12455 return; 12456 } 12457 12458 if (!aarch64_print_address_internal (f, mode, XEXP (x, 0), 12459 code == 'y' 12460 ? ADDR_QUERY_LDP_STP_N 12461 : ADDR_QUERY_LDP_STP)) 12462 output_operand_lossage ("invalid operand prefix '%%%c'", code); 12463 } 12464 break; 12465 12466 default: 12467 output_operand_lossage ("invalid operand prefix '%%%c'", code); 12468 return; 12469 } 12470 } 12471 12472 /* Print address 'x' of a memory access with mode 'mode'. 12473 'op' is the context required by aarch64_classify_address. It can either be 12474 MEM for a normal memory access or PARALLEL for LDP/STP. */ 12475 static bool 12476 aarch64_print_address_internal (FILE *f, machine_mode mode, rtx x, 12477 aarch64_addr_query_type type) 12478 { 12479 struct aarch64_address_info addr; 12480 unsigned int size, vec_flags; 12481 12482 /* Check all addresses are Pmode - including ILP32. */ 12483 if (GET_MODE (x) != Pmode 12484 && (!CONST_INT_P (x) 12485 || trunc_int_for_mode (INTVAL (x), Pmode) != INTVAL (x))) 12486 { 12487 output_operand_lossage ("invalid address mode"); 12488 return false; 12489 } 12490 12491 const bool load_store_pair_p = (type == ADDR_QUERY_LDP_STP 12492 || type == ADDR_QUERY_LDP_STP_N); 12493 12494 if (aarch64_classify_address (&addr, x, mode, true, type)) 12495 switch (addr.type) 12496 { 12497 case ADDRESS_REG_IMM: 12498 if (known_eq (addr.const_offset, 0)) 12499 { 12500 asm_fprintf (f, "[%s]", reg_names[REGNO (addr.base)]); 12501 return true; 12502 } 12503 12504 vec_flags = aarch64_classify_vector_mode (mode); 12505 if ((vec_flags & VEC_ANY_SVE) && !load_store_pair_p) 12506 { 12507 HOST_WIDE_INT vnum 12508 = exact_div (addr.const_offset, 12509 aarch64_vl_bytes (mode, vec_flags)).to_constant (); 12510 asm_fprintf (f, "[%s, #%wd, mul vl]", 12511 reg_names[REGNO (addr.base)], vnum); 12512 return true; 12513 } 12514 12515 if (!CONST_INT_P (addr.offset)) 12516 return false; 12517 12518 asm_fprintf (f, "[%s, %wd]", reg_names[REGNO (addr.base)], 12519 INTVAL (addr.offset)); 12520 return true; 12521 12522 case ADDRESS_REG_REG: 12523 if (addr.shift == 0) 12524 asm_fprintf (f, "[%s, %s]", reg_names [REGNO (addr.base)], 12525 reg_names [REGNO (addr.offset)]); 12526 else 12527 asm_fprintf (f, "[%s, %s, lsl %u]", reg_names [REGNO (addr.base)], 12528 reg_names [REGNO (addr.offset)], addr.shift); 12529 return true; 12530 12531 case ADDRESS_REG_UXTW: 12532 if (addr.shift == 0) 12533 asm_fprintf (f, "[%s, w%d, uxtw]", reg_names [REGNO (addr.base)], 12534 REGNO (addr.offset) - R0_REGNUM); 12535 else 12536 asm_fprintf (f, "[%s, w%d, uxtw %u]", reg_names [REGNO (addr.base)], 12537 REGNO (addr.offset) - R0_REGNUM, addr.shift); 12538 return true; 12539 12540 case ADDRESS_REG_SXTW: 12541 if (addr.shift == 0) 12542 asm_fprintf (f, "[%s, w%d, sxtw]", reg_names [REGNO (addr.base)], 12543 REGNO (addr.offset) - R0_REGNUM); 12544 else 12545 asm_fprintf (f, "[%s, w%d, sxtw %u]", reg_names [REGNO (addr.base)], 12546 REGNO (addr.offset) - R0_REGNUM, addr.shift); 12547 return true; 12548 12549 case ADDRESS_REG_WB: 12550 /* Writeback is only supported for fixed-width modes. */ 12551 size = GET_MODE_SIZE (mode).to_constant (); 12552 switch (GET_CODE (x)) 12553 { 12554 case PRE_INC: 12555 asm_fprintf (f, "[%s, %d]!", reg_names [REGNO (addr.base)], size); 12556 return true; 12557 case POST_INC: 12558 asm_fprintf (f, "[%s], %d", reg_names [REGNO (addr.base)], size); 12559 return true; 12560 case PRE_DEC: 12561 asm_fprintf (f, "[%s, -%d]!", reg_names [REGNO (addr.base)], size); 12562 return true; 12563 case POST_DEC: 12564 asm_fprintf (f, "[%s], -%d", reg_names [REGNO (addr.base)], size); 12565 return true; 12566 case PRE_MODIFY: 12567 asm_fprintf (f, "[%s, %wd]!", reg_names[REGNO (addr.base)], 12568 INTVAL (addr.offset)); 12569 return true; 12570 case POST_MODIFY: 12571 asm_fprintf (f, "[%s], %wd", reg_names[REGNO (addr.base)], 12572 INTVAL (addr.offset)); 12573 return true; 12574 default: 12575 break; 12576 } 12577 break; 12578 12579 case ADDRESS_LO_SUM: 12580 asm_fprintf (f, "[%s, #:lo12:", reg_names [REGNO (addr.base)]); 12581 output_addr_const (f, addr.offset); 12582 asm_fprintf (f, "]"); 12583 return true; 12584 12585 case ADDRESS_SYMBOLIC: 12586 output_addr_const (f, x); 12587 return true; 12588 } 12589 12590 return false; 12591 } 12592 12593 /* Print address 'x' of a memory access with mode 'mode'. */ 12594 static void 12595 aarch64_print_operand_address (FILE *f, machine_mode mode, rtx x) 12596 { 12597 if (!aarch64_print_address_internal (f, mode, x, ADDR_QUERY_ANY)) 12598 output_addr_const (f, x); 12599 } 12600 12601 /* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */ 12602 12603 static bool 12604 aarch64_output_addr_const_extra (FILE *file, rtx x) 12605 { 12606 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SALT_ADDR) 12607 { 12608 output_addr_const (file, XVECEXP (x, 0, 0)); 12609 return true; 12610 } 12611 return false; 12612 } 12613 12614 bool 12615 aarch64_label_mentioned_p (rtx x) 12616 { 12617 const char *fmt; 12618 int i; 12619 12620 if (LABEL_REF_P (x)) 12621 return true; 12622 12623 /* UNSPEC_TLS entries for a symbol include a LABEL_REF for the 12624 referencing instruction, but they are constant offsets, not 12625 symbols. */ 12626 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLS) 12627 return false; 12628 12629 fmt = GET_RTX_FORMAT (GET_CODE (x)); 12630 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) 12631 { 12632 if (fmt[i] == 'E') 12633 { 12634 int j; 12635 12636 for (j = XVECLEN (x, i) - 1; j >= 0; j--) 12637 if (aarch64_label_mentioned_p (XVECEXP (x, i, j))) 12638 return 1; 12639 } 12640 else if (fmt[i] == 'e' && aarch64_label_mentioned_p (XEXP (x, i))) 12641 return 1; 12642 } 12643 12644 return 0; 12645 } 12646 12647 /* Implement REGNO_REG_CLASS. */ 12648 12649 enum reg_class 12650 aarch64_regno_regclass (unsigned regno) 12651 { 12652 if (W8_W11_REGNUM_P (regno)) 12653 return W8_W11_REGS; 12654 12655 if (W12_W15_REGNUM_P (regno)) 12656 return W12_W15_REGS; 12657 12658 if (STUB_REGNUM_P (regno)) 12659 return STUB_REGS; 12660 12661 if (GP_REGNUM_P (regno)) 12662 return GENERAL_REGS; 12663 12664 if (regno == SP_REGNUM) 12665 return STACK_REG; 12666 12667 if (regno == FRAME_POINTER_REGNUM 12668 || regno == ARG_POINTER_REGNUM) 12669 return POINTER_REGS; 12670 12671 if (FP_REGNUM_P (regno)) 12672 return (FP_LO8_REGNUM_P (regno) ? FP_LO8_REGS 12673 : FP_LO_REGNUM_P (regno) ? FP_LO_REGS : FP_REGS); 12674 12675 if (PR_REGNUM_P (regno)) 12676 return PR_LO_REGNUM_P (regno) ? PR_LO_REGS : PR_HI_REGS; 12677 12678 if (regno == FFR_REGNUM || regno == FFRT_REGNUM) 12679 return FFR_REGS; 12680 12681 if (FAKE_REGNUM_P (regno)) 12682 return FAKE_REGS; 12683 12684 return NO_REGS; 12685 } 12686 12687 /* OFFSET is an address offset for mode MODE, which has SIZE bytes. 12688 If OFFSET is out of range, return an offset of an anchor point 12689 that is in range. Return 0 otherwise. */ 12690 12691 static HOST_WIDE_INT 12692 aarch64_anchor_offset (HOST_WIDE_INT offset, HOST_WIDE_INT size, 12693 machine_mode mode) 12694 { 12695 /* Does it look like we'll need a 16-byte load/store-pair operation? */ 12696 if (size > 16) 12697 return (offset + 0x400) & ~0x7f0; 12698 12699 /* For offsets that aren't a multiple of the access size, the limit is 12700 -256...255. */ 12701 if (offset & (size - 1)) 12702 { 12703 /* BLKmode typically uses LDP of X-registers. */ 12704 if (mode == BLKmode) 12705 return (offset + 512) & ~0x3ff; 12706 return (offset + 0x100) & ~0x1ff; 12707 } 12708 12709 /* Small negative offsets are supported. */ 12710 if (IN_RANGE (offset, -256, 0)) 12711 return 0; 12712 12713 if (mode == TImode || mode == TFmode || mode == TDmode) 12714 return (offset + 0x100) & ~0x1ff; 12715 12716 /* Use 12-bit offset by access size. */ 12717 return offset & (~0xfff * size); 12718 } 12719 12720 static rtx 12721 aarch64_legitimize_address (rtx x, rtx /* orig_x */, machine_mode mode) 12722 { 12723 /* Try to split X+CONST into Y=X+(CONST & ~mask), Y+(CONST&mask), 12724 where mask is selected by alignment and size of the offset. 12725 We try to pick as large a range for the offset as possible to 12726 maximize the chance of a CSE. However, for aligned addresses 12727 we limit the range to 4k so that structures with different sized 12728 elements are likely to use the same base. We need to be careful 12729 not to split a CONST for some forms of address expression, otherwise 12730 it will generate sub-optimal code. */ 12731 12732 /* First split X + CONST (base, offset) into (base + X) + offset. */ 12733 if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST) 12734 { 12735 poly_int64 offset; 12736 rtx base = strip_offset (XEXP (x, 1), &offset); 12737 12738 base = expand_binop (Pmode, add_optab, base, XEXP (x, 0), 12739 NULL_RTX, true, OPTAB_DIRECT); 12740 x = plus_constant (Pmode, base, offset); 12741 } 12742 12743 if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1))) 12744 { 12745 rtx base = XEXP (x, 0); 12746 rtx offset_rtx = XEXP (x, 1); 12747 HOST_WIDE_INT offset = INTVAL (offset_rtx); 12748 12749 if (GET_CODE (base) == PLUS) 12750 { 12751 rtx op0 = XEXP (base, 0); 12752 rtx op1 = XEXP (base, 1); 12753 12754 /* Force any scaling into a temp for CSE. */ 12755 op0 = force_reg (Pmode, op0); 12756 op1 = force_reg (Pmode, op1); 12757 12758 /* Let the pointer register be in op0. */ 12759 if (REG_POINTER (op1)) 12760 std::swap (op0, op1); 12761 12762 /* If the pointer is virtual or frame related, then we know that 12763 virtual register instantiation or register elimination is going 12764 to apply a second constant. We want the two constants folded 12765 together easily. Therefore, emit as (OP0 + CONST) + OP1. */ 12766 if (virt_or_elim_regno_p (REGNO (op0))) 12767 { 12768 base = expand_binop (Pmode, add_optab, op0, offset_rtx, 12769 NULL_RTX, true, OPTAB_DIRECT); 12770 return gen_rtx_PLUS (Pmode, base, op1); 12771 } 12772 12773 /* Otherwise, in order to encourage CSE (and thence loop strength 12774 reduce) scaled addresses, emit as (OP0 + OP1) + CONST. */ 12775 base = expand_binop (Pmode, add_optab, op0, op1, 12776 NULL_RTX, true, OPTAB_DIRECT); 12777 x = gen_rtx_PLUS (Pmode, base, offset_rtx); 12778 } 12779 12780 HOST_WIDE_INT size; 12781 if (GET_MODE_SIZE (mode).is_constant (&size)) 12782 { 12783 HOST_WIDE_INT base_offset = aarch64_anchor_offset (offset, size, 12784 mode); 12785 if (base_offset != 0) 12786 { 12787 base = plus_constant (Pmode, base, base_offset); 12788 base = force_operand (base, NULL_RTX); 12789 return plus_constant (Pmode, base, offset - base_offset); 12790 } 12791 } 12792 } 12793 12794 return x; 12795 } 12796 12797 static reg_class_t 12798 aarch64_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x, 12799 reg_class_t rclass, 12800 machine_mode mode, 12801 secondary_reload_info *sri) 12802 { 12803 /* Use aarch64_sve_reload_mem for SVE memory reloads that cannot use 12804 LDR and STR. See the comment at the head of aarch64-sve.md for 12805 more details about the big-endian handling. */ 12806 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 12807 if (reg_class_subset_p (rclass, FP_REGS) 12808 && !((REG_P (x) && HARD_REGISTER_P (x)) 12809 || aarch64_simd_valid_immediate (x, NULL)) 12810 && mode != VNx16QImode 12811 && (vec_flags & VEC_SVE_DATA) 12812 && ((vec_flags & VEC_PARTIAL) || BYTES_BIG_ENDIAN)) 12813 { 12814 sri->icode = CODE_FOR_aarch64_sve_reload_mem; 12815 return NO_REGS; 12816 } 12817 12818 /* If we have to disable direct literal pool loads and stores because the 12819 function is too big, then we need a scratch register. */ 12820 if (MEM_P (x) && SYMBOL_REF_P (x) && CONSTANT_POOL_ADDRESS_P (x) 12821 && (SCALAR_FLOAT_MODE_P (GET_MODE (x)) 12822 || targetm.vector_mode_supported_p (GET_MODE (x))) 12823 && !aarch64_pcrelative_literal_loads) 12824 { 12825 sri->icode = code_for_aarch64_reload_movcp (mode, DImode); 12826 return NO_REGS; 12827 } 12828 12829 /* Without the TARGET_SIMD or TARGET_SVE instructions we cannot move a 12830 Q register to a Q register directly. We need a scratch. */ 12831 if (REG_P (x) 12832 && (mode == TFmode 12833 || mode == TImode 12834 || mode == TDmode 12835 || (vec_flags == VEC_ADVSIMD && known_eq (GET_MODE_SIZE (mode), 16))) 12836 && mode == GET_MODE (x) 12837 && !TARGET_SIMD 12838 && FP_REGNUM_P (REGNO (x)) 12839 && reg_class_subset_p (rclass, FP_REGS)) 12840 { 12841 sri->icode = code_for_aarch64_reload_mov (mode); 12842 return NO_REGS; 12843 } 12844 12845 /* A TFmode, TImode or TDmode memory access should be handled via an FP_REGS 12846 because AArch64 has richer addressing modes for LDR/STR instructions 12847 than LDP/STP instructions. */ 12848 if (TARGET_FLOAT && rclass == GENERAL_REGS 12849 && known_eq (GET_MODE_SIZE (mode), 16) && MEM_P (x)) 12850 return FP_REGS; 12851 12852 if (rclass == FP_REGS 12853 && (mode == TImode || mode == TFmode || mode == TDmode) 12854 && CONSTANT_P(x)) 12855 return GENERAL_REGS; 12856 12857 return NO_REGS; 12858 } 12859 12860 /* Implement TARGET_SECONDARY_MEMORY_NEEDED. */ 12861 12862 static bool 12863 aarch64_secondary_memory_needed (machine_mode mode, reg_class_t class1, 12864 reg_class_t class2) 12865 { 12866 if (!TARGET_SIMD 12867 && reg_classes_intersect_p (class1, FP_REGS) 12868 && reg_classes_intersect_p (class2, FP_REGS)) 12869 { 12870 /* We can't do a 128-bit FPR-to-FPR move without TARGET_SIMD, 12871 so we can't easily split a move involving tuples of 128-bit 12872 vectors. Force the copy through memory instead. 12873 12874 (Tuples of 64-bit vectors are fine.) */ 12875 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 12876 if (vec_flags == (VEC_ADVSIMD | VEC_STRUCT)) 12877 return true; 12878 } 12879 return false; 12880 } 12881 12882 /* Implement TARGET_FRAME_POINTER_REQUIRED. */ 12883 12884 static bool 12885 aarch64_frame_pointer_required () 12886 { 12887 /* If the function needs to record the incoming value of PSTATE.SM, 12888 make sure that the slot is accessible from the frame pointer. */ 12889 return aarch64_need_old_pstate_sm (); 12890 } 12891 12892 static bool 12893 aarch64_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) 12894 { 12895 gcc_assert (from == ARG_POINTER_REGNUM || from == FRAME_POINTER_REGNUM); 12896 12897 /* If we need a frame pointer, ARG_POINTER_REGNUM and FRAME_POINTER_REGNUM 12898 can only eliminate to HARD_FRAME_POINTER_REGNUM. */ 12899 if (frame_pointer_needed) 12900 return to == HARD_FRAME_POINTER_REGNUM; 12901 return true; 12902 } 12903 12904 poly_int64 12905 aarch64_initial_elimination_offset (unsigned from, unsigned to) 12906 { 12907 aarch64_frame &frame = cfun->machine->frame; 12908 12909 if (to == HARD_FRAME_POINTER_REGNUM) 12910 { 12911 if (from == ARG_POINTER_REGNUM) 12912 return frame.bytes_above_hard_fp; 12913 12914 if (from == FRAME_POINTER_REGNUM) 12915 return frame.bytes_above_hard_fp - frame.bytes_above_locals; 12916 } 12917 12918 if (to == STACK_POINTER_REGNUM) 12919 { 12920 if (from == FRAME_POINTER_REGNUM) 12921 return frame.frame_size - frame.bytes_above_locals; 12922 } 12923 12924 return frame.frame_size; 12925 } 12926 12927 12928 /* Get return address without mangling. */ 12929 12930 rtx 12931 aarch64_return_addr_rtx (void) 12932 { 12933 rtx val = get_hard_reg_initial_val (Pmode, LR_REGNUM); 12934 /* Note: aarch64_return_address_signing_enabled only 12935 works after cfun->machine->frame.laid_out is set, 12936 so here we don't know if the return address will 12937 be signed or not. */ 12938 rtx lr = gen_rtx_REG (Pmode, LR_REGNUM); 12939 emit_move_insn (lr, val); 12940 emit_insn (GEN_FCN (CODE_FOR_xpaclri) ()); 12941 return lr; 12942 } 12943 12944 12945 /* Implement RETURN_ADDR_RTX. We do not support moving back to a 12946 previous frame. */ 12947 12948 rtx 12949 aarch64_return_addr (int count, rtx frame ATTRIBUTE_UNUSED) 12950 { 12951 if (count != 0) 12952 return const0_rtx; 12953 return aarch64_return_addr_rtx (); 12954 } 12955 12956 static void 12957 aarch64_asm_trampoline_template (FILE *f) 12958 { 12959 /* Even if the current function doesn't have branch protection, some 12960 later function might, so since this template is only generated once 12961 we have to add a BTI just in case. */ 12962 asm_fprintf (f, "\thint\t34 // bti c\n"); 12963 12964 if (TARGET_ILP32) 12965 { 12966 asm_fprintf (f, "\tldr\tw%d, .+20\n", IP1_REGNUM - R0_REGNUM); 12967 asm_fprintf (f, "\tldr\tw%d, .+20\n", STATIC_CHAIN_REGNUM - R0_REGNUM); 12968 } 12969 else 12970 { 12971 asm_fprintf (f, "\tldr\t%s, .+20\n", reg_names [IP1_REGNUM]); 12972 asm_fprintf (f, "\tldr\t%s, .+24\n", reg_names [STATIC_CHAIN_REGNUM]); 12973 } 12974 asm_fprintf (f, "\tbr\t%s\n", reg_names [IP1_REGNUM]); 12975 12976 /* We always emit a speculation barrier. 12977 This is because the same trampoline template is used for every nested 12978 function. Since nested functions are not particularly common or 12979 performant we don't worry too much about the extra instructions to copy 12980 around. 12981 This is not yet a problem, since we have not yet implemented function 12982 specific attributes to choose between hardening against straight line 12983 speculation or not, but such function specific attributes are likely to 12984 happen in the future. */ 12985 asm_fprintf (f, "\tdsb\tsy\n\tisb\n"); 12986 12987 assemble_aligned_integer (POINTER_BYTES, const0_rtx); 12988 assemble_aligned_integer (POINTER_BYTES, const0_rtx); 12989 } 12990 12991 static void 12992 aarch64_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) 12993 { 12994 rtx fnaddr, mem, a_tramp; 12995 const int tramp_code_sz = 24; 12996 12997 /* Don't need to copy the trailing D-words, we fill those in below. */ 12998 /* We create our own memory address in Pmode so that `emit_block_move` can 12999 use parts of the backend which expect Pmode addresses. */ 13000 rtx temp = convert_memory_address (Pmode, XEXP (m_tramp, 0)); 13001 emit_block_move (gen_rtx_MEM (BLKmode, temp), 13002 assemble_trampoline_template (), 13003 GEN_INT (tramp_code_sz), BLOCK_OP_NORMAL); 13004 mem = adjust_address (m_tramp, ptr_mode, tramp_code_sz); 13005 fnaddr = XEXP (DECL_RTL (fndecl), 0); 13006 if (GET_MODE (fnaddr) != ptr_mode) 13007 fnaddr = convert_memory_address (ptr_mode, fnaddr); 13008 emit_move_insn (mem, fnaddr); 13009 13010 mem = adjust_address (m_tramp, ptr_mode, tramp_code_sz + POINTER_BYTES); 13011 emit_move_insn (mem, chain_value); 13012 13013 /* XXX We should really define a "clear_cache" pattern and use 13014 gen_clear_cache(). */ 13015 a_tramp = XEXP (m_tramp, 0); 13016 maybe_emit_call_builtin___clear_cache (a_tramp, 13017 plus_constant (ptr_mode, 13018 a_tramp, 13019 TRAMPOLINE_SIZE)); 13020 } 13021 13022 static unsigned char 13023 aarch64_class_max_nregs (reg_class_t regclass, machine_mode mode) 13024 { 13025 /* ??? Logically we should only need to provide a value when 13026 HARD_REGNO_MODE_OK says that at least one register in REGCLASS 13027 can hold MODE, but at the moment we need to handle all modes. 13028 Just ignore any runtime parts for registers that can't store them. */ 13029 HOST_WIDE_INT lowest_size = constant_lower_bound (GET_MODE_SIZE (mode)); 13030 unsigned int nregs, vec_flags; 13031 switch (regclass) 13032 { 13033 case W8_W11_REGS: 13034 case W12_W15_REGS: 13035 case STUB_REGS: 13036 case TAILCALL_ADDR_REGS: 13037 case POINTER_REGS: 13038 case GENERAL_REGS: 13039 case ALL_REGS: 13040 case POINTER_AND_FP_REGS: 13041 case FP_REGS: 13042 case FP_LO_REGS: 13043 case FP_LO8_REGS: 13044 vec_flags = aarch64_classify_vector_mode (mode); 13045 if ((vec_flags & VEC_SVE_DATA) 13046 && constant_multiple_p (GET_MODE_SIZE (mode), 13047 aarch64_vl_bytes (mode, vec_flags), &nregs)) 13048 return nregs; 13049 if (vec_flags == (VEC_ADVSIMD | VEC_STRUCT | VEC_PARTIAL)) 13050 return GET_MODE_SIZE (mode).to_constant () / 8; 13051 return (vec_flags & VEC_ADVSIMD 13052 ? CEIL (lowest_size, UNITS_PER_VREG) 13053 : CEIL (lowest_size, UNITS_PER_WORD)); 13054 13055 case PR_REGS: 13056 case PR_LO_REGS: 13057 case PR_HI_REGS: 13058 return mode == VNx32BImode ? 2 : 1; 13059 13060 case STACK_REG: 13061 case FFR_REGS: 13062 case PR_AND_FFR_REGS: 13063 case FAKE_REGS: 13064 return 1; 13065 13066 case NO_REGS: 13067 return 0; 13068 13069 default: 13070 break; 13071 } 13072 gcc_unreachable (); 13073 } 13074 13075 static reg_class_t 13076 aarch64_preferred_reload_class (rtx x, reg_class_t regclass) 13077 { 13078 if (regclass == POINTER_REGS) 13079 return GENERAL_REGS; 13080 13081 if (regclass == STACK_REG) 13082 { 13083 if (REG_P(x) 13084 && reg_class_subset_p (REGNO_REG_CLASS (REGNO (x)), POINTER_REGS)) 13085 return regclass; 13086 13087 return NO_REGS; 13088 } 13089 13090 /* Register eliminiation can result in a request for 13091 SP+constant->FP_REGS. We cannot support such operations which 13092 use SP as source and an FP_REG as destination, so reject out 13093 right now. */ 13094 if (! reg_class_subset_p (regclass, GENERAL_REGS) && GET_CODE (x) == PLUS) 13095 { 13096 rtx lhs = XEXP (x, 0); 13097 13098 /* Look through a possible SUBREG introduced by ILP32. */ 13099 if (SUBREG_P (lhs)) 13100 lhs = SUBREG_REG (lhs); 13101 13102 gcc_assert (REG_P (lhs)); 13103 gcc_assert (reg_class_subset_p (REGNO_REG_CLASS (REGNO (lhs)), 13104 POINTER_REGS)); 13105 return NO_REGS; 13106 } 13107 13108 return regclass; 13109 } 13110 13111 void 13112 aarch64_asm_output_labelref (FILE* f, const char *name) 13113 { 13114 asm_fprintf (f, "%U%s", name); 13115 } 13116 13117 static void 13118 aarch64_elf_asm_constructor (rtx symbol, int priority) 13119 { 13120 if (priority == DEFAULT_INIT_PRIORITY) 13121 default_ctor_section_asm_out_constructor (symbol, priority); 13122 else 13123 { 13124 section *s; 13125 /* While priority is known to be in range [0, 65535], so 18 bytes 13126 would be enough, the compiler might not know that. To avoid 13127 -Wformat-truncation false positive, use a larger size. */ 13128 char buf[23]; 13129 snprintf (buf, sizeof (buf), ".init_array.%.5u", priority); 13130 s = get_section (buf, SECTION_WRITE | SECTION_NOTYPE, NULL); 13131 switch_to_section (s); 13132 assemble_align (POINTER_SIZE); 13133 assemble_aligned_integer (POINTER_BYTES, symbol); 13134 } 13135 } 13136 13137 static void 13138 aarch64_elf_asm_destructor (rtx symbol, int priority) 13139 { 13140 if (priority == DEFAULT_INIT_PRIORITY) 13141 default_dtor_section_asm_out_destructor (symbol, priority); 13142 else 13143 { 13144 section *s; 13145 /* While priority is known to be in range [0, 65535], so 18 bytes 13146 would be enough, the compiler might not know that. To avoid 13147 -Wformat-truncation false positive, use a larger size. */ 13148 char buf[23]; 13149 snprintf (buf, sizeof (buf), ".fini_array.%.5u", priority); 13150 s = get_section (buf, SECTION_WRITE | SECTION_NOTYPE, NULL); 13151 switch_to_section (s); 13152 assemble_align (POINTER_SIZE); 13153 assemble_aligned_integer (POINTER_BYTES, symbol); 13154 } 13155 } 13156 13157 const char* 13158 aarch64_output_casesi (rtx *operands) 13159 { 13160 char buf[100]; 13161 char label[100]; 13162 rtx diff_vec = PATTERN (NEXT_INSN (as_a <rtx_insn *> (operands[2]))); 13163 int index; 13164 static const char *const patterns[4][2] = 13165 { 13166 { 13167 "ldrb\t%w3, [%0,%w1,uxtw]", 13168 "add\t%3, %4, %w3, sxtb #2" 13169 }, 13170 { 13171 "ldrh\t%w3, [%0,%w1,uxtw #1]", 13172 "add\t%3, %4, %w3, sxth #2" 13173 }, 13174 { 13175 "ldr\t%w3, [%0,%w1,uxtw #2]", 13176 "add\t%3, %4, %w3, sxtw #2" 13177 }, 13178 /* We assume that DImode is only generated when not optimizing and 13179 that we don't really need 64-bit address offsets. That would 13180 imply an object file with 8GB of code in a single function! */ 13181 { 13182 "ldr\t%w3, [%0,%w1,uxtw #2]", 13183 "add\t%3, %4, %w3, sxtw #2" 13184 } 13185 }; 13186 13187 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC); 13188 13189 scalar_int_mode mode = as_a <scalar_int_mode> (GET_MODE (diff_vec)); 13190 index = exact_log2 (GET_MODE_SIZE (mode)); 13191 13192 gcc_assert (index >= 0 && index <= 3); 13193 13194 /* Need to implement table size reduction, by chaning the code below. */ 13195 output_asm_insn (patterns[index][0], operands); 13196 ASM_GENERATE_INTERNAL_LABEL (label, "Lrtx", CODE_LABEL_NUMBER (operands[2])); 13197 snprintf (buf, sizeof (buf), 13198 "adr\t%%4, %s", targetm.strip_name_encoding (label)); 13199 output_asm_insn (buf, operands); 13200 output_asm_insn (patterns[index][1], operands); 13201 output_asm_insn ("br\t%3", operands); 13202 output_asm_insn (aarch64_sls_barrier (aarch64_harden_sls_retbr_p ()), 13203 operands); 13204 assemble_label (asm_out_file, label); 13205 return ""; 13206 } 13207 13208 /* Return the asm string for an SME ZERO instruction whose 8-bit mask 13209 operand is MASK. */ 13210 const char * 13211 aarch64_output_sme_zero_za (rtx mask) 13212 { 13213 auto mask_val = UINTVAL (mask); 13214 if (mask_val == 0) 13215 return "zero\t{}"; 13216 13217 if (mask_val == 0xff) 13218 return "zero\t{ za }"; 13219 13220 static constexpr struct { unsigned char mask; char letter; } tiles[] = { 13221 { 0xff, 'b' }, 13222 { 0x55, 'h' }, 13223 { 0x11, 's' }, 13224 { 0x01, 'd' } 13225 }; 13226 /* The last entry in the list has the form "za7.d }", but that's the 13227 same length as "za7.d, ". */ 13228 static char buffer[sizeof("zero\t{ ") + sizeof ("za7.d, ") * 8 + 1]; 13229 for (auto &tile : tiles) 13230 { 13231 unsigned int tile_mask = tile.mask; 13232 unsigned int tile_index = 0; 13233 unsigned int i = snprintf (buffer, sizeof (buffer), "zero\t"); 13234 const char *prefix = "{ "; 13235 auto remaining_mask = mask_val; 13236 while (tile_mask < 0x100) 13237 { 13238 if ((remaining_mask & tile_mask) == tile_mask) 13239 { 13240 i += snprintf (buffer + i, sizeof (buffer) - i, "%sza%d.%c", 13241 prefix, tile_index, tile.letter); 13242 prefix = ", "; 13243 remaining_mask &= ~tile_mask; 13244 } 13245 tile_mask <<= 1; 13246 tile_index += 1; 13247 } 13248 if (remaining_mask == 0) 13249 { 13250 gcc_assert (i + 3 <= sizeof (buffer)); 13251 snprintf (buffer + i, sizeof (buffer) - i, " }"); 13252 return buffer; 13253 } 13254 } 13255 gcc_unreachable (); 13256 } 13257 13258 /* Return size in bits of an arithmetic operand which is shifted/scaled and 13259 masked such that it is suitable for a UXTB, UXTH, or UXTW extend 13260 operator. */ 13261 13262 int 13263 aarch64_uxt_size (int shift, HOST_WIDE_INT mask) 13264 { 13265 if (shift >= 0 && shift <= 4) 13266 { 13267 int size; 13268 for (size = 8; size <= 32; size *= 2) 13269 { 13270 HOST_WIDE_INT bits = ((HOST_WIDE_INT)1U << size) - 1; 13271 if (mask == bits << shift) 13272 return size; 13273 } 13274 } 13275 return 0; 13276 } 13277 13278 /* Constant pools are per function only when PC relative 13279 literal loads are true or we are in the large memory 13280 model. */ 13281 13282 static inline bool 13283 aarch64_can_use_per_function_literal_pools_p (void) 13284 { 13285 return (aarch64_pcrelative_literal_loads 13286 || aarch64_cmodel == AARCH64_CMODEL_LARGE); 13287 } 13288 13289 static bool 13290 aarch64_use_blocks_for_constant_p (machine_mode, const_rtx) 13291 { 13292 /* We can't use blocks for constants when we're using a per-function 13293 constant pool. */ 13294 return !aarch64_can_use_per_function_literal_pools_p (); 13295 } 13296 13297 /* Select appropriate section for constants depending 13298 on where we place literal pools. */ 13299 13300 static section * 13301 aarch64_select_rtx_section (machine_mode mode, 13302 rtx x, 13303 unsigned HOST_WIDE_INT align) 13304 { 13305 if (aarch64_can_use_per_function_literal_pools_p ()) 13306 return function_section (current_function_decl); 13307 13308 return default_elf_select_rtx_section (mode, x, align); 13309 } 13310 13311 /* Implement ASM_OUTPUT_POOL_EPILOGUE. */ 13312 void 13313 aarch64_asm_output_pool_epilogue (FILE *f, const char *, tree, 13314 HOST_WIDE_INT offset) 13315 { 13316 /* When using per-function literal pools, we must ensure that any code 13317 section is aligned to the minimal instruction length, lest we get 13318 errors from the assembler re "unaligned instructions". */ 13319 if ((offset & 3) && aarch64_can_use_per_function_literal_pools_p ()) 13320 ASM_OUTPUT_ALIGN (f, 2); 13321 } 13322 13323 /* Costs. */ 13324 13325 /* Helper function for rtx cost calculation. Strip a shift expression 13326 from X. Returns the inner operand if successful, or the original 13327 expression on failure. */ 13328 static rtx 13329 aarch64_strip_shift (rtx x) 13330 { 13331 rtx op = x; 13332 13333 /* We accept both ROTATERT and ROTATE: since the RHS must be a constant 13334 we can convert both to ROR during final output. */ 13335 if ((GET_CODE (op) == ASHIFT 13336 || GET_CODE (op) == ASHIFTRT 13337 || GET_CODE (op) == LSHIFTRT 13338 || GET_CODE (op) == ROTATERT 13339 || GET_CODE (op) == ROTATE) 13340 && CONST_INT_P (XEXP (op, 1))) 13341 return XEXP (op, 0); 13342 13343 if (GET_CODE (op) == MULT 13344 && CONST_INT_P (XEXP (op, 1)) 13345 && ((unsigned) exact_log2 (INTVAL (XEXP (op, 1)))) < 64) 13346 return XEXP (op, 0); 13347 13348 return x; 13349 } 13350 13351 /* Helper function for rtx cost calculation. Strip an extend 13352 expression from X. Returns the inner operand if successful, or the 13353 original expression on failure. We deal with a number of possible 13354 canonicalization variations here. If STRIP_SHIFT is true, then 13355 we can strip off a shift also. */ 13356 static rtx 13357 aarch64_strip_extend (rtx x, bool strip_shift) 13358 { 13359 scalar_int_mode mode; 13360 rtx op = x; 13361 13362 if (!is_a <scalar_int_mode> (GET_MODE (op), &mode)) 13363 return op; 13364 13365 if (GET_CODE (op) == AND 13366 && GET_CODE (XEXP (op, 0)) == MULT 13367 && CONST_INT_P (XEXP (XEXP (op, 0), 1)) 13368 && CONST_INT_P (XEXP (op, 1)) 13369 && aarch64_uxt_size (exact_log2 (INTVAL (XEXP (XEXP (op, 0), 1))), 13370 INTVAL (XEXP (op, 1))) != 0) 13371 return XEXP (XEXP (op, 0), 0); 13372 13373 /* Now handle extended register, as this may also have an optional 13374 left shift by 1..4. */ 13375 if (strip_shift 13376 && GET_CODE (op) == ASHIFT 13377 && CONST_INT_P (XEXP (op, 1)) 13378 && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) <= 4) 13379 op = XEXP (op, 0); 13380 13381 if (GET_CODE (op) == ZERO_EXTEND 13382 || GET_CODE (op) == SIGN_EXTEND) 13383 op = XEXP (op, 0); 13384 13385 if (op != x) 13386 return op; 13387 13388 return x; 13389 } 13390 13391 /* Helper function for rtx cost calculation. Strip extension as well as any 13392 inner VEC_SELECT high-half from X. Returns the inner vector operand if 13393 successful, or the original expression on failure. */ 13394 static rtx 13395 aarch64_strip_extend_vec_half (rtx x) 13396 { 13397 if (GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND) 13398 { 13399 x = XEXP (x, 0); 13400 if (GET_CODE (x) == VEC_SELECT 13401 && vec_series_highpart_p (GET_MODE (x), GET_MODE (XEXP (x, 0)), 13402 XEXP (x, 1))) 13403 x = XEXP (x, 0); 13404 } 13405 return x; 13406 } 13407 13408 /* Helper function for rtx cost calculation. Strip VEC_DUPLICATE as well as 13409 any subsequent extend and VEC_SELECT from X. Returns the inner scalar 13410 operand if successful, or the original expression on failure. */ 13411 static rtx 13412 aarch64_strip_duplicate_vec_elt (rtx x) 13413 { 13414 if (GET_CODE (x) == VEC_DUPLICATE 13415 && is_a<scalar_mode> (GET_MODE (XEXP (x, 0)))) 13416 { 13417 x = XEXP (x, 0); 13418 if (GET_CODE (x) == VEC_SELECT) 13419 x = XEXP (x, 0); 13420 else if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND) 13421 && GET_CODE (XEXP (x, 0)) == VEC_SELECT) 13422 x = XEXP (XEXP (x, 0), 0); 13423 } 13424 return x; 13425 } 13426 13427 /* Return true iff CODE is a shift supported in combination 13428 with arithmetic instructions. */ 13429 13430 static bool 13431 aarch64_shift_p (enum rtx_code code) 13432 { 13433 return code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT; 13434 } 13435 13436 13437 /* Return true iff X is a cheap shift without a sign extend. */ 13438 13439 static bool 13440 aarch64_cheap_mult_shift_p (rtx x) 13441 { 13442 rtx op0, op1; 13443 13444 op0 = XEXP (x, 0); 13445 op1 = XEXP (x, 1); 13446 13447 if (!(aarch64_tune_params.extra_tuning_flags 13448 & AARCH64_EXTRA_TUNE_CHEAP_SHIFT_EXTEND)) 13449 return false; 13450 13451 if (GET_CODE (op0) == SIGN_EXTEND) 13452 return false; 13453 13454 if (GET_CODE (x) == ASHIFT && CONST_INT_P (op1) 13455 && UINTVAL (op1) <= 4) 13456 return true; 13457 13458 if (GET_CODE (x) != MULT || !CONST_INT_P (op1)) 13459 return false; 13460 13461 HOST_WIDE_INT l2 = exact_log2 (INTVAL (op1)); 13462 13463 if (l2 > 0 && l2 <= 4) 13464 return true; 13465 13466 return false; 13467 } 13468 13469 /* Helper function for rtx cost calculation. Calculate the cost of 13470 a MULT or ASHIFT, which may be part of a compound PLUS/MINUS rtx. 13471 Return the calculated cost of the expression, recursing manually in to 13472 operands where needed. */ 13473 13474 static int 13475 aarch64_rtx_mult_cost (rtx x, enum rtx_code code, int outer, bool speed) 13476 { 13477 rtx op0, op1; 13478 const struct cpu_cost_table *extra_cost 13479 = aarch64_tune_params.insn_extra_cost; 13480 int cost = 0; 13481 bool compound_p = (outer == PLUS || outer == MINUS); 13482 machine_mode mode = GET_MODE (x); 13483 13484 gcc_checking_assert (code == MULT); 13485 13486 op0 = XEXP (x, 0); 13487 op1 = XEXP (x, 1); 13488 13489 if (VECTOR_MODE_P (mode)) 13490 { 13491 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 13492 if (TARGET_SIMD && (vec_flags & VEC_ADVSIMD)) 13493 { 13494 /* The select-operand-high-half versions of the instruction have the 13495 same cost as the three vector version - don't add the costs of the 13496 extension or selection into the costs of the multiply. */ 13497 op0 = aarch64_strip_extend_vec_half (op0); 13498 op1 = aarch64_strip_extend_vec_half (op1); 13499 /* The by-element versions of the instruction have the same costs as 13500 the normal 3-vector version. We make an assumption that the input 13501 to the VEC_DUPLICATE is already on the FP & SIMD side. This means 13502 costing of a MUL by element pre RA is a bit optimistic. */ 13503 op0 = aarch64_strip_duplicate_vec_elt (op0); 13504 op1 = aarch64_strip_duplicate_vec_elt (op1); 13505 } 13506 cost += rtx_cost (op0, mode, MULT, 0, speed); 13507 cost += rtx_cost (op1, mode, MULT, 1, speed); 13508 if (speed) 13509 { 13510 if (GET_CODE (x) == MULT) 13511 cost += extra_cost->vect.mult; 13512 /* This is to catch the SSRA costing currently flowing here. */ 13513 else 13514 cost += extra_cost->vect.alu; 13515 } 13516 return cost; 13517 } 13518 13519 /* Integer multiply/fma. */ 13520 if (GET_MODE_CLASS (mode) == MODE_INT) 13521 { 13522 /* The multiply will be canonicalized as a shift, cost it as such. */ 13523 if (aarch64_shift_p (GET_CODE (x)) 13524 || (CONST_INT_P (op1) 13525 && exact_log2 (INTVAL (op1)) > 0)) 13526 { 13527 bool is_extend = GET_CODE (op0) == ZERO_EXTEND 13528 || GET_CODE (op0) == SIGN_EXTEND; 13529 if (speed) 13530 { 13531 if (compound_p) 13532 { 13533 /* If the shift is considered cheap, 13534 then don't add any cost. */ 13535 if (aarch64_cheap_mult_shift_p (x)) 13536 ; 13537 else if (REG_P (op1)) 13538 /* ARITH + shift-by-register. */ 13539 cost += extra_cost->alu.arith_shift_reg; 13540 else if (is_extend) 13541 /* ARITH + extended register. We don't have a cost field 13542 for ARITH+EXTEND+SHIFT, so use extend_arith here. */ 13543 cost += extra_cost->alu.extend_arith; 13544 else 13545 /* ARITH + shift-by-immediate. */ 13546 cost += extra_cost->alu.arith_shift; 13547 } 13548 else 13549 /* LSL (immediate). */ 13550 cost += extra_cost->alu.shift; 13551 13552 } 13553 /* Strip extends as we will have costed them in the case above. */ 13554 if (is_extend) 13555 op0 = aarch64_strip_extend (op0, true); 13556 13557 cost += rtx_cost (op0, VOIDmode, code, 0, speed); 13558 13559 return cost; 13560 } 13561 13562 /* MNEG or [US]MNEGL. Extract the NEG operand and indicate that it's a 13563 compound and let the below cases handle it. After all, MNEG is a 13564 special-case alias of MSUB. */ 13565 if (GET_CODE (op0) == NEG) 13566 { 13567 op0 = XEXP (op0, 0); 13568 compound_p = true; 13569 } 13570 13571 /* Integer multiplies or FMAs have zero/sign extending variants. */ 13572 if ((GET_CODE (op0) == ZERO_EXTEND 13573 && GET_CODE (op1) == ZERO_EXTEND) 13574 || (GET_CODE (op0) == SIGN_EXTEND 13575 && GET_CODE (op1) == SIGN_EXTEND)) 13576 { 13577 cost += rtx_cost (XEXP (op0, 0), VOIDmode, MULT, 0, speed); 13578 cost += rtx_cost (XEXP (op1, 0), VOIDmode, MULT, 1, speed); 13579 13580 if (speed) 13581 { 13582 if (compound_p) 13583 /* SMADDL/UMADDL/UMSUBL/SMSUBL. */ 13584 cost += extra_cost->mult[0].extend_add; 13585 else 13586 /* MUL/SMULL/UMULL. */ 13587 cost += extra_cost->mult[0].extend; 13588 } 13589 13590 return cost; 13591 } 13592 13593 /* This is either an integer multiply or a MADD. In both cases 13594 we want to recurse and cost the operands. */ 13595 cost += rtx_cost (op0, mode, MULT, 0, speed); 13596 cost += rtx_cost (op1, mode, MULT, 1, speed); 13597 13598 if (speed) 13599 { 13600 if (compound_p) 13601 /* MADD/MSUB. */ 13602 cost += extra_cost->mult[mode == DImode].add; 13603 else 13604 /* MUL. */ 13605 cost += extra_cost->mult[mode == DImode].simple; 13606 } 13607 13608 return cost; 13609 } 13610 else 13611 { 13612 if (speed) 13613 { 13614 /* Floating-point FMA/FMUL can also support negations of the 13615 operands, unless the rounding mode is upward or downward in 13616 which case FNMUL is different than FMUL with operand negation. */ 13617 bool neg0 = GET_CODE (op0) == NEG; 13618 bool neg1 = GET_CODE (op1) == NEG; 13619 if (compound_p || !flag_rounding_math || (neg0 && neg1)) 13620 { 13621 if (neg0) 13622 op0 = XEXP (op0, 0); 13623 if (neg1) 13624 op1 = XEXP (op1, 0); 13625 } 13626 13627 if (compound_p) 13628 /* FMADD/FNMADD/FNMSUB/FMSUB. */ 13629 cost += extra_cost->fp[mode == DFmode].fma; 13630 else 13631 /* FMUL/FNMUL. */ 13632 cost += extra_cost->fp[mode == DFmode].mult; 13633 } 13634 13635 cost += rtx_cost (op0, mode, MULT, 0, speed); 13636 cost += rtx_cost (op1, mode, MULT, 1, speed); 13637 return cost; 13638 } 13639 } 13640 13641 static int 13642 aarch64_address_cost (rtx x, 13643 machine_mode mode, 13644 addr_space_t as ATTRIBUTE_UNUSED, 13645 bool speed) 13646 { 13647 enum rtx_code c = GET_CODE (x); 13648 const struct cpu_addrcost_table *addr_cost = aarch64_tune_params.addr_cost; 13649 struct aarch64_address_info info; 13650 int cost = 0; 13651 info.shift = 0; 13652 13653 if (!aarch64_classify_address (&info, x, mode, false)) 13654 { 13655 if (GET_CODE (x) == CONST || SYMBOL_REF_P (x)) 13656 { 13657 /* This is a CONST or SYMBOL ref which will be split 13658 in a different way depending on the code model in use. 13659 Cost it through the generic infrastructure. */ 13660 int cost_symbol_ref = rtx_cost (x, Pmode, MEM, 1, speed); 13661 /* Divide through by the cost of one instruction to 13662 bring it to the same units as the address costs. */ 13663 cost_symbol_ref /= COSTS_N_INSNS (1); 13664 /* The cost is then the cost of preparing the address, 13665 followed by an immediate (possibly 0) offset. */ 13666 return cost_symbol_ref + addr_cost->imm_offset; 13667 } 13668 else 13669 { 13670 /* This is most likely a jump table from a case 13671 statement. */ 13672 return addr_cost->register_offset; 13673 } 13674 } 13675 13676 switch (info.type) 13677 { 13678 case ADDRESS_LO_SUM: 13679 case ADDRESS_SYMBOLIC: 13680 case ADDRESS_REG_IMM: 13681 cost += addr_cost->imm_offset; 13682 break; 13683 13684 case ADDRESS_REG_WB: 13685 if (c == PRE_INC || c == PRE_DEC || c == PRE_MODIFY) 13686 cost += addr_cost->pre_modify; 13687 else if (c == POST_INC || c == POST_DEC || c == POST_MODIFY) 13688 { 13689 unsigned int nvectors = aarch64_ldn_stn_vectors (mode); 13690 if (nvectors == 3) 13691 cost += addr_cost->post_modify_ld3_st3; 13692 else if (nvectors == 4) 13693 cost += addr_cost->post_modify_ld4_st4; 13694 else 13695 cost += addr_cost->post_modify; 13696 } 13697 else 13698 gcc_unreachable (); 13699 13700 break; 13701 13702 case ADDRESS_REG_REG: 13703 cost += addr_cost->register_offset; 13704 break; 13705 13706 case ADDRESS_REG_SXTW: 13707 cost += addr_cost->register_sextend; 13708 break; 13709 13710 case ADDRESS_REG_UXTW: 13711 cost += addr_cost->register_zextend; 13712 break; 13713 13714 default: 13715 gcc_unreachable (); 13716 } 13717 13718 13719 if (info.shift > 0) 13720 { 13721 /* For the sake of calculating the cost of the shifted register 13722 component, we can treat same sized modes in the same way. */ 13723 if (known_eq (GET_MODE_BITSIZE (mode), 16)) 13724 cost += addr_cost->addr_scale_costs.hi; 13725 else if (known_eq (GET_MODE_BITSIZE (mode), 32)) 13726 cost += addr_cost->addr_scale_costs.si; 13727 else if (known_eq (GET_MODE_BITSIZE (mode), 64)) 13728 cost += addr_cost->addr_scale_costs.di; 13729 else 13730 /* We can't tell, or this is a 128-bit vector. */ 13731 cost += addr_cost->addr_scale_costs.ti; 13732 } 13733 13734 return cost; 13735 } 13736 13737 /* Return the cost of a branch. If SPEED_P is true then the compiler is 13738 optimizing for speed. If PREDICTABLE_P is true then the branch is predicted 13739 to be taken. */ 13740 13741 int 13742 aarch64_branch_cost (bool speed_p, bool predictable_p) 13743 { 13744 /* When optimizing for speed, use the cost of unpredictable branches. */ 13745 const struct cpu_branch_cost *branch_costs = 13746 aarch64_tune_params.branch_costs; 13747 13748 if (!speed_p || predictable_p) 13749 return branch_costs->predictable; 13750 else 13751 return branch_costs->unpredictable; 13752 } 13753 13754 /* Return true if X is a zero or sign extract 13755 usable in an ADD or SUB (extended register) instruction. */ 13756 static bool 13757 aarch64_rtx_arith_op_extract_p (rtx x) 13758 { 13759 /* The simple case <ARITH>, XD, XN, XM, [us]xt. 13760 No shift. */ 13761 if (GET_CODE (x) == SIGN_EXTEND 13762 || GET_CODE (x) == ZERO_EXTEND) 13763 return REG_P (XEXP (x, 0)); 13764 13765 return false; 13766 } 13767 13768 static bool 13769 aarch64_frint_unspec_p (unsigned int u) 13770 { 13771 switch (u) 13772 { 13773 case UNSPEC_FRINTZ: 13774 case UNSPEC_FRINTP: 13775 case UNSPEC_FRINTM: 13776 case UNSPEC_FRINTA: 13777 case UNSPEC_FRINTN: 13778 case UNSPEC_FRINTX: 13779 case UNSPEC_FRINTI: 13780 return true; 13781 13782 default: 13783 return false; 13784 } 13785 } 13786 13787 /* Return true iff X is an rtx that will match an extr instruction 13788 i.e. as described in the *extr<mode>5_insn family of patterns. 13789 OP0 and OP1 will be set to the operands of the shifts involved 13790 on success and will be NULL_RTX otherwise. */ 13791 13792 static bool 13793 aarch64_extr_rtx_p (rtx x, rtx *res_op0, rtx *res_op1) 13794 { 13795 rtx op0, op1; 13796 scalar_int_mode mode; 13797 if (!is_a <scalar_int_mode> (GET_MODE (x), &mode)) 13798 return false; 13799 13800 *res_op0 = NULL_RTX; 13801 *res_op1 = NULL_RTX; 13802 13803 if (GET_CODE (x) != IOR) 13804 return false; 13805 13806 op0 = XEXP (x, 0); 13807 op1 = XEXP (x, 1); 13808 13809 if ((GET_CODE (op0) == ASHIFT && GET_CODE (op1) == LSHIFTRT) 13810 || (GET_CODE (op1) == ASHIFT && GET_CODE (op0) == LSHIFTRT)) 13811 { 13812 /* Canonicalise locally to ashift in op0, lshiftrt in op1. */ 13813 if (GET_CODE (op1) == ASHIFT) 13814 std::swap (op0, op1); 13815 13816 if (!CONST_INT_P (XEXP (op0, 1)) || !CONST_INT_P (XEXP (op1, 1))) 13817 return false; 13818 13819 unsigned HOST_WIDE_INT shft_amnt_0 = UINTVAL (XEXP (op0, 1)); 13820 unsigned HOST_WIDE_INT shft_amnt_1 = UINTVAL (XEXP (op1, 1)); 13821 13822 if (shft_amnt_0 < GET_MODE_BITSIZE (mode) 13823 && shft_amnt_0 + shft_amnt_1 == GET_MODE_BITSIZE (mode)) 13824 { 13825 *res_op0 = XEXP (op0, 0); 13826 *res_op1 = XEXP (op1, 0); 13827 return true; 13828 } 13829 } 13830 13831 return false; 13832 } 13833 13834 /* Calculate the cost of calculating (if_then_else (OP0) (OP1) (OP2)), 13835 storing it in *COST. Result is true if the total cost of the operation 13836 has now been calculated. */ 13837 static bool 13838 aarch64_if_then_else_costs (rtx op0, rtx op1, rtx op2, int *cost, bool speed) 13839 { 13840 rtx inner; 13841 rtx comparator; 13842 enum rtx_code cmpcode; 13843 const struct cpu_cost_table *extra_cost 13844 = aarch64_tune_params.insn_extra_cost; 13845 13846 if (COMPARISON_P (op0)) 13847 { 13848 inner = XEXP (op0, 0); 13849 comparator = XEXP (op0, 1); 13850 cmpcode = GET_CODE (op0); 13851 } 13852 else 13853 { 13854 inner = op0; 13855 comparator = const0_rtx; 13856 cmpcode = NE; 13857 } 13858 13859 if (GET_CODE (op1) == PC || GET_CODE (op2) == PC) 13860 { 13861 /* Conditional branch. */ 13862 if (GET_MODE_CLASS (GET_MODE (inner)) == MODE_CC) 13863 return true; 13864 else 13865 { 13866 if (cmpcode == NE || cmpcode == EQ) 13867 { 13868 if (comparator == const0_rtx) 13869 { 13870 /* TBZ/TBNZ/CBZ/CBNZ. */ 13871 if (GET_CODE (inner) == ZERO_EXTRACT) 13872 /* TBZ/TBNZ. */ 13873 *cost += rtx_cost (XEXP (inner, 0), VOIDmode, 13874 ZERO_EXTRACT, 0, speed); 13875 else 13876 /* CBZ/CBNZ. */ 13877 *cost += rtx_cost (inner, VOIDmode, cmpcode, 0, speed); 13878 13879 return true; 13880 } 13881 if (register_operand (inner, VOIDmode) 13882 && aarch64_imm24 (comparator, VOIDmode)) 13883 { 13884 /* SUB and SUBS. */ 13885 *cost += COSTS_N_INSNS (2); 13886 if (speed) 13887 *cost += extra_cost->alu.arith * 2; 13888 return true; 13889 } 13890 } 13891 else if (cmpcode == LT || cmpcode == GE) 13892 { 13893 /* TBZ/TBNZ. */ 13894 if (comparator == const0_rtx) 13895 return true; 13896 } 13897 } 13898 } 13899 else if (GET_MODE_CLASS (GET_MODE (inner)) == MODE_CC) 13900 { 13901 /* CCMP. */ 13902 if (GET_CODE (op1) == COMPARE) 13903 { 13904 /* Increase cost of CCMP reg, 0, imm, CC to prefer CMP reg, 0. */ 13905 if (XEXP (op1, 1) == const0_rtx) 13906 *cost += 1; 13907 if (speed) 13908 { 13909 machine_mode mode = GET_MODE (XEXP (op1, 0)); 13910 13911 if (GET_MODE_CLASS (mode) == MODE_INT) 13912 *cost += extra_cost->alu.arith; 13913 else 13914 *cost += extra_cost->fp[mode == DFmode].compare; 13915 } 13916 return true; 13917 } 13918 13919 /* It's a conditional operation based on the status flags, 13920 so it must be some flavor of CSEL. */ 13921 13922 /* CSNEG, CSINV, and CSINC are handled for free as part of CSEL. */ 13923 if (GET_CODE (op1) == NEG 13924 || GET_CODE (op1) == NOT 13925 || (GET_CODE (op1) == PLUS && XEXP (op1, 1) == const1_rtx)) 13926 op1 = XEXP (op1, 0); 13927 else if (GET_CODE (op1) == ZERO_EXTEND && GET_CODE (op2) == ZERO_EXTEND) 13928 { 13929 /* CSEL with zero-extension (*cmovdi_insn_uxtw). */ 13930 op1 = XEXP (op1, 0); 13931 op2 = XEXP (op2, 0); 13932 } 13933 else if (GET_CODE (op1) == ZERO_EXTEND && op2 == const0_rtx) 13934 { 13935 inner = XEXP (op1, 0); 13936 if (GET_CODE (inner) == NEG || GET_CODE (inner) == NOT) 13937 /* CSINV/NEG with zero extend + const 0 (*csinv3_uxtw_insn3). */ 13938 op1 = XEXP (inner, 0); 13939 } 13940 else if (op1 == constm1_rtx || op1 == const1_rtx) 13941 { 13942 /* Use CSINV or CSINC. */ 13943 *cost += rtx_cost (op2, VOIDmode, IF_THEN_ELSE, 2, speed); 13944 return true; 13945 } 13946 else if (op2 == constm1_rtx || op2 == const1_rtx) 13947 { 13948 /* Use CSINV or CSINC. */ 13949 *cost += rtx_cost (op1, VOIDmode, IF_THEN_ELSE, 1, speed); 13950 return true; 13951 } 13952 13953 *cost += rtx_cost (op1, VOIDmode, IF_THEN_ELSE, 1, speed); 13954 *cost += rtx_cost (op2, VOIDmode, IF_THEN_ELSE, 2, speed); 13955 return true; 13956 } 13957 13958 /* We don't know what this is, cost all operands. */ 13959 return false; 13960 } 13961 13962 /* Check whether X is a bitfield operation of the form shift + extend that 13963 maps down to a UBFIZ/SBFIZ/UBFX/SBFX instruction. If so, return the 13964 operand to which the bitfield operation is applied. Otherwise return 13965 NULL_RTX. */ 13966 13967 static rtx 13968 aarch64_extend_bitfield_pattern_p (rtx x) 13969 { 13970 rtx_code outer_code = GET_CODE (x); 13971 machine_mode outer_mode = GET_MODE (x); 13972 13973 if (outer_code != ZERO_EXTEND && outer_code != SIGN_EXTEND 13974 && outer_mode != SImode && outer_mode != DImode) 13975 return NULL_RTX; 13976 13977 rtx inner = XEXP (x, 0); 13978 rtx_code inner_code = GET_CODE (inner); 13979 machine_mode inner_mode = GET_MODE (inner); 13980 rtx op = NULL_RTX; 13981 13982 switch (inner_code) 13983 { 13984 case ASHIFT: 13985 if (CONST_INT_P (XEXP (inner, 1)) 13986 && (inner_mode == QImode || inner_mode == HImode)) 13987 op = XEXP (inner, 0); 13988 break; 13989 case LSHIFTRT: 13990 if (outer_code == ZERO_EXTEND && CONST_INT_P (XEXP (inner, 1)) 13991 && (inner_mode == QImode || inner_mode == HImode)) 13992 op = XEXP (inner, 0); 13993 break; 13994 case ASHIFTRT: 13995 if (outer_code == SIGN_EXTEND && CONST_INT_P (XEXP (inner, 1)) 13996 && (inner_mode == QImode || inner_mode == HImode)) 13997 op = XEXP (inner, 0); 13998 break; 13999 default: 14000 break; 14001 } 14002 14003 return op; 14004 } 14005 14006 /* Return true if the mask and a shift amount from an RTX of the form 14007 (x << SHFT_AMNT) & MASK are valid to combine into a UBFIZ instruction of 14008 mode MODE. See the *andim_ashift<mode>_bfiz pattern. */ 14009 14010 bool 14011 aarch64_mask_and_shift_for_ubfiz_p (scalar_int_mode mode, rtx mask, 14012 rtx shft_amnt) 14013 { 14014 return CONST_INT_P (mask) && CONST_INT_P (shft_amnt) 14015 && INTVAL (mask) > 0 14016 && UINTVAL (shft_amnt) < GET_MODE_BITSIZE (mode) 14017 && exact_log2 ((UINTVAL (mask) >> UINTVAL (shft_amnt)) + 1) >= 0 14018 && (UINTVAL (mask) 14019 & ((HOST_WIDE_INT_1U << UINTVAL (shft_amnt)) - 1)) == 0; 14020 } 14021 14022 /* Return true if the masks and a shift amount from an RTX of the form 14023 ((x & MASK1) | ((y << SHIFT_AMNT) & MASK2)) are valid to combine into 14024 a BFI instruction of mode MODE. See *arch64_bfi patterns. */ 14025 14026 bool 14027 aarch64_masks_and_shift_for_bfi_p (scalar_int_mode mode, 14028 unsigned HOST_WIDE_INT mask1, 14029 unsigned HOST_WIDE_INT shft_amnt, 14030 unsigned HOST_WIDE_INT mask2) 14031 { 14032 unsigned HOST_WIDE_INT t; 14033 14034 /* Verify that there is no overlap in what bits are set in the two masks. */ 14035 if (mask1 != ~mask2) 14036 return false; 14037 14038 /* Verify that mask2 is not all zeros or ones. */ 14039 if (mask2 == 0 || mask2 == HOST_WIDE_INT_M1U) 14040 return false; 14041 14042 /* The shift amount should always be less than the mode size. */ 14043 gcc_assert (shft_amnt < GET_MODE_BITSIZE (mode)); 14044 14045 /* Verify that the mask being shifted is contiguous and would be in the 14046 least significant bits after shifting by shft_amnt. */ 14047 t = mask2 + (HOST_WIDE_INT_1U << shft_amnt); 14048 return (t == (t & -t)); 14049 } 14050 14051 /* Return true if X is an RTX representing an operation in the ABD family 14052 of instructions. */ 14053 14054 static bool 14055 aarch64_abd_rtx_p (rtx x) 14056 { 14057 if (GET_CODE (x) != MINUS) 14058 return false; 14059 rtx max_arm = XEXP (x, 0); 14060 rtx min_arm = XEXP (x, 1); 14061 if (GET_CODE (max_arm) != SMAX && GET_CODE (max_arm) != UMAX) 14062 return false; 14063 bool signed_p = GET_CODE (max_arm) == SMAX; 14064 if (signed_p && GET_CODE (min_arm) != SMIN) 14065 return false; 14066 else if (!signed_p && GET_CODE (min_arm) != UMIN) 14067 return false; 14068 14069 rtx maxop0 = XEXP (max_arm, 0); 14070 rtx maxop1 = XEXP (max_arm, 1); 14071 rtx minop0 = XEXP (min_arm, 0); 14072 rtx minop1 = XEXP (min_arm, 1); 14073 return rtx_equal_p (maxop0, minop0) && rtx_equal_p (maxop1, minop1); 14074 } 14075 14076 /* Calculate the cost of calculating X, storing it in *COST. Result 14077 is true if the total cost of the operation has now been calculated. */ 14078 static bool 14079 aarch64_rtx_costs (rtx x, machine_mode mode, int outer ATTRIBUTE_UNUSED, 14080 int param ATTRIBUTE_UNUSED, int *cost, bool speed) 14081 { 14082 rtx op0, op1, op2; 14083 const struct cpu_cost_table *extra_cost 14084 = aarch64_tune_params.insn_extra_cost; 14085 rtx_code code = GET_CODE (x); 14086 scalar_int_mode int_mode; 14087 14088 /* By default, assume that everything has equivalent cost to the 14089 cheapest instruction. Any additional costs are applied as a delta 14090 above this default. */ 14091 *cost = COSTS_N_INSNS (1); 14092 14093 switch (code) 14094 { 14095 case SET: 14096 /* The cost depends entirely on the operands to SET. */ 14097 *cost = 0; 14098 op0 = SET_DEST (x); 14099 op1 = SET_SRC (x); 14100 14101 switch (GET_CODE (op0)) 14102 { 14103 case MEM: 14104 if (speed) 14105 { 14106 rtx address = XEXP (op0, 0); 14107 if (VECTOR_MODE_P (mode)) 14108 *cost += extra_cost->ldst.storev; 14109 else if (GET_MODE_CLASS (mode) == MODE_INT) 14110 *cost += extra_cost->ldst.store; 14111 else if (mode == SFmode || mode == SDmode) 14112 *cost += extra_cost->ldst.storef; 14113 else if (mode == DFmode || mode == DDmode) 14114 *cost += extra_cost->ldst.stored; 14115 14116 *cost += 14117 COSTS_N_INSNS (aarch64_address_cost (address, mode, 14118 0, speed)); 14119 } 14120 14121 *cost += rtx_cost (op1, mode, SET, 1, speed); 14122 return true; 14123 14124 case SUBREG: 14125 if (! REG_P (SUBREG_REG (op0))) 14126 *cost += rtx_cost (SUBREG_REG (op0), VOIDmode, SET, 0, speed); 14127 14128 /* Fall through. */ 14129 case REG: 14130 /* The cost is one per vector-register copied. */ 14131 if (VECTOR_MODE_P (GET_MODE (op0)) && REG_P (op1)) 14132 { 14133 int nregs = aarch64_hard_regno_nregs (V0_REGNUM, GET_MODE (op0)); 14134 *cost = COSTS_N_INSNS (nregs); 14135 } 14136 /* const0_rtx is in general free, but we will use an 14137 instruction to set a register to 0. */ 14138 else if (REG_P (op1) || op1 == const0_rtx) 14139 { 14140 /* The cost is 1 per register copied. */ 14141 int nregs = aarch64_hard_regno_nregs (R0_REGNUM, GET_MODE (op0)); 14142 *cost = COSTS_N_INSNS (nregs); 14143 } 14144 else 14145 /* Cost is just the cost of the RHS of the set. */ 14146 *cost += rtx_cost (op1, mode, SET, 1, speed); 14147 return true; 14148 14149 case ZERO_EXTRACT: 14150 case SIGN_EXTRACT: 14151 /* Bit-field insertion. Strip any redundant widening of 14152 the RHS to meet the width of the target. */ 14153 if (SUBREG_P (op1)) 14154 op1 = SUBREG_REG (op1); 14155 if ((GET_CODE (op1) == ZERO_EXTEND 14156 || GET_CODE (op1) == SIGN_EXTEND) 14157 && CONST_INT_P (XEXP (op0, 1)) 14158 && is_a <scalar_int_mode> (GET_MODE (XEXP (op1, 0)), &int_mode) 14159 && GET_MODE_BITSIZE (int_mode) >= INTVAL (XEXP (op0, 1))) 14160 op1 = XEXP (op1, 0); 14161 14162 if (CONST_INT_P (op1)) 14163 { 14164 /* MOV immediate is assumed to always be cheap. */ 14165 *cost = COSTS_N_INSNS (1); 14166 } 14167 else 14168 { 14169 /* BFM. */ 14170 if (speed) 14171 *cost += extra_cost->alu.bfi; 14172 *cost += rtx_cost (op1, VOIDmode, (enum rtx_code) code, 1, speed); 14173 } 14174 14175 return true; 14176 14177 default: 14178 /* We can't make sense of this, assume default cost. */ 14179 *cost = COSTS_N_INSNS (1); 14180 return false; 14181 } 14182 return false; 14183 14184 case CONST_INT: 14185 /* If an instruction can incorporate a constant within the 14186 instruction, the instruction's expression avoids calling 14187 rtx_cost() on the constant. If rtx_cost() is called on a 14188 constant, then it is usually because the constant must be 14189 moved into a register by one or more instructions. 14190 14191 The exception is constant 0, which can be expressed 14192 as XZR/WZR and is therefore free. The exception to this is 14193 if we have (set (reg) (const0_rtx)) in which case we must cost 14194 the move. However, we can catch that when we cost the SET, so 14195 we don't need to consider that here. */ 14196 if (x == const0_rtx) 14197 *cost = 0; 14198 else 14199 { 14200 /* To an approximation, building any other constant is 14201 proportionally expensive to the number of instructions 14202 required to build that constant. This is true whether we 14203 are compiling for SPEED or otherwise. */ 14204 machine_mode imode = known_le (GET_MODE_SIZE (mode), 4) 14205 ? SImode : DImode; 14206 *cost = COSTS_N_INSNS (aarch64_internal_mov_immediate 14207 (NULL_RTX, x, false, imode)); 14208 } 14209 return true; 14210 14211 case CONST_DOUBLE: 14212 14213 /* First determine number of instructions to do the move 14214 as an integer constant. */ 14215 if (!aarch64_float_const_representable_p (x) 14216 && !aarch64_can_const_movi_rtx_p (x, mode) 14217 && aarch64_float_const_rtx_p (x)) 14218 { 14219 unsigned HOST_WIDE_INT ival; 14220 bool succeed = aarch64_reinterpret_float_as_int (x, &ival); 14221 gcc_assert (succeed); 14222 14223 machine_mode imode = known_eq (GET_MODE_SIZE (mode), 8) 14224 ? DImode : SImode; 14225 int ncost = aarch64_internal_mov_immediate 14226 (NULL_RTX, gen_int_mode (ival, imode), false, imode); 14227 *cost += COSTS_N_INSNS (ncost); 14228 return true; 14229 } 14230 14231 if (speed) 14232 { 14233 /* mov[df,sf]_aarch64. */ 14234 if (aarch64_float_const_representable_p (x)) 14235 /* FMOV (scalar immediate). */ 14236 *cost += extra_cost->fp[mode == DFmode || mode == DDmode].fpconst; 14237 else if (!aarch64_float_const_zero_rtx_p (x)) 14238 { 14239 /* This will be a load from memory. */ 14240 if (mode == DFmode || mode == DDmode) 14241 *cost += extra_cost->ldst.loadd; 14242 else 14243 *cost += extra_cost->ldst.loadf; 14244 } 14245 else 14246 /* Otherwise this is +0.0. We get this using MOVI d0, #0 14247 or MOV v0.s[0], wzr - neither of which are modeled by the 14248 cost tables. Just use the default cost. */ 14249 { 14250 } 14251 } 14252 14253 return true; 14254 14255 case MEM: 14256 if (speed) 14257 { 14258 /* For loads we want the base cost of a load, plus an 14259 approximation for the additional cost of the addressing 14260 mode. */ 14261 rtx address = XEXP (x, 0); 14262 if (VECTOR_MODE_P (mode)) 14263 *cost += extra_cost->ldst.loadv; 14264 else if (GET_MODE_CLASS (mode) == MODE_INT) 14265 *cost += extra_cost->ldst.load; 14266 else if (mode == SFmode || mode == SDmode) 14267 *cost += extra_cost->ldst.loadf; 14268 else if (mode == DFmode || mode == DDmode) 14269 *cost += extra_cost->ldst.loadd; 14270 14271 *cost += 14272 COSTS_N_INSNS (aarch64_address_cost (address, mode, 14273 0, speed)); 14274 } 14275 14276 return true; 14277 14278 case NEG: 14279 op0 = XEXP (x, 0); 14280 14281 if (VECTOR_MODE_P (mode)) 14282 { 14283 /* Many vector comparison operations are represented as NEG 14284 of a comparison. */ 14285 if (COMPARISON_P (op0)) 14286 { 14287 rtx op00 = XEXP (op0, 0); 14288 rtx op01 = XEXP (op0, 1); 14289 machine_mode inner_mode = GET_MODE (op00); 14290 /* FACGE/FACGT. */ 14291 if (GET_MODE_CLASS (inner_mode) == MODE_VECTOR_FLOAT 14292 && GET_CODE (op00) == ABS 14293 && GET_CODE (op01) == ABS) 14294 { 14295 op00 = XEXP (op00, 0); 14296 op01 = XEXP (op01, 0); 14297 } 14298 *cost += rtx_cost (op00, inner_mode, GET_CODE (op0), 0, speed); 14299 *cost += rtx_cost (op01, inner_mode, GET_CODE (op0), 1, speed); 14300 if (speed) 14301 *cost += extra_cost->vect.alu; 14302 return true; 14303 } 14304 if (speed) 14305 { 14306 /* FNEG. */ 14307 *cost += extra_cost->vect.alu; 14308 } 14309 return false; 14310 } 14311 14312 if (GET_MODE_CLASS (mode) == MODE_INT) 14313 { 14314 if (GET_RTX_CLASS (GET_CODE (op0)) == RTX_COMPARE 14315 || GET_RTX_CLASS (GET_CODE (op0)) == RTX_COMM_COMPARE) 14316 { 14317 /* CSETM. */ 14318 *cost += rtx_cost (XEXP (op0, 0), VOIDmode, NEG, 0, speed); 14319 return true; 14320 } 14321 14322 /* Cost this as SUB wzr, X. */ 14323 op0 = CONST0_RTX (mode); 14324 op1 = XEXP (x, 0); 14325 goto cost_minus; 14326 } 14327 14328 if (GET_MODE_CLASS (mode) == MODE_FLOAT) 14329 { 14330 /* Support (neg(fma...)) as a single instruction only if 14331 sign of zeros is unimportant. This matches the decision 14332 making in aarch64.md. */ 14333 if (GET_CODE (op0) == FMA && !HONOR_SIGNED_ZEROS (GET_MODE (op0))) 14334 { 14335 /* FNMADD. */ 14336 *cost = rtx_cost (op0, mode, NEG, 0, speed); 14337 return true; 14338 } 14339 if (GET_CODE (op0) == MULT) 14340 { 14341 /* FNMUL. */ 14342 *cost = rtx_cost (op0, mode, NEG, 0, speed); 14343 return true; 14344 } 14345 if (speed) 14346 /* FNEG. */ 14347 *cost += extra_cost->fp[mode == DFmode].neg; 14348 return false; 14349 } 14350 14351 return false; 14352 14353 case CLRSB: 14354 case CLZ: 14355 if (speed) 14356 { 14357 if (VECTOR_MODE_P (mode)) 14358 *cost += extra_cost->vect.alu; 14359 else 14360 *cost += extra_cost->alu.clz; 14361 } 14362 14363 return false; 14364 14365 case CTZ: 14366 *cost = COSTS_N_INSNS (2); 14367 14368 if (speed) 14369 *cost += extra_cost->alu.clz + extra_cost->alu.rev; 14370 return false; 14371 14372 case COMPARE: 14373 op0 = XEXP (x, 0); 14374 op1 = XEXP (x, 1); 14375 14376 if (op1 == const0_rtx 14377 && GET_CODE (op0) == AND) 14378 { 14379 x = op0; 14380 mode = GET_MODE (op0); 14381 goto cost_logic; 14382 } 14383 14384 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT) 14385 { 14386 /* TODO: A write to the CC flags possibly costs extra, this 14387 needs encoding in the cost tables. */ 14388 14389 mode = GET_MODE (op0); 14390 /* ANDS. */ 14391 if (GET_CODE (op0) == AND) 14392 { 14393 x = op0; 14394 goto cost_logic; 14395 } 14396 14397 if (GET_CODE (op0) == PLUS) 14398 { 14399 /* ADDS (and CMN alias). */ 14400 x = op0; 14401 goto cost_plus; 14402 } 14403 14404 if (GET_CODE (op0) == MINUS) 14405 { 14406 /* SUBS. */ 14407 x = op0; 14408 goto cost_minus; 14409 } 14410 14411 if (GET_CODE (op0) == ZERO_EXTRACT && op1 == const0_rtx 14412 && GET_MODE (x) == CC_NZmode && CONST_INT_P (XEXP (op0, 1)) 14413 && CONST_INT_P (XEXP (op0, 2))) 14414 { 14415 /* COMPARE of ZERO_EXTRACT form of TST-immediate. 14416 Handle it here directly rather than going to cost_logic 14417 since we know the immediate generated for the TST is valid 14418 so we can avoid creating an intermediate rtx for it only 14419 for costing purposes. */ 14420 if (speed) 14421 *cost += extra_cost->alu.logical; 14422 14423 *cost += rtx_cost (XEXP (op0, 0), GET_MODE (op0), 14424 ZERO_EXTRACT, 0, speed); 14425 return true; 14426 } 14427 14428 if (GET_CODE (op1) == NEG) 14429 { 14430 /* CMN. */ 14431 if (speed) 14432 *cost += extra_cost->alu.arith; 14433 14434 *cost += rtx_cost (op0, mode, COMPARE, 0, speed); 14435 *cost += rtx_cost (XEXP (op1, 0), mode, NEG, 1, speed); 14436 return true; 14437 } 14438 14439 /* CMP. 14440 14441 Compare can freely swap the order of operands, and 14442 canonicalization puts the more complex operation first. 14443 But the integer MINUS logic expects the shift/extend 14444 operation in op1. */ 14445 if (! (REG_P (op0) 14446 || (SUBREG_P (op0) && REG_P (SUBREG_REG (op0))))) 14447 { 14448 op0 = XEXP (x, 1); 14449 op1 = XEXP (x, 0); 14450 } 14451 goto cost_minus; 14452 } 14453 14454 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT) 14455 { 14456 /* FCMP. */ 14457 if (speed) 14458 *cost += extra_cost->fp[mode == DFmode].compare; 14459 14460 if (CONST_DOUBLE_P (op1) && aarch64_float_const_zero_rtx_p (op1)) 14461 { 14462 *cost += rtx_cost (op0, VOIDmode, COMPARE, 0, speed); 14463 /* FCMP supports constant 0.0 for no extra cost. */ 14464 return true; 14465 } 14466 return false; 14467 } 14468 14469 if (VECTOR_MODE_P (mode)) 14470 { 14471 /* Vector compare. */ 14472 if (speed) 14473 *cost += extra_cost->vect.alu; 14474 14475 if (aarch64_float_const_zero_rtx_p (op1)) 14476 { 14477 /* Vector cm (eq|ge|gt|lt|le) supports constant 0.0 for no extra 14478 cost. */ 14479 return true; 14480 } 14481 return false; 14482 } 14483 return false; 14484 14485 case MINUS: 14486 { 14487 op0 = XEXP (x, 0); 14488 op1 = XEXP (x, 1); 14489 14490 cost_minus: 14491 if (VECTOR_MODE_P (mode)) 14492 { 14493 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 14494 if (TARGET_SIMD && (vec_flags & VEC_ADVSIMD)) 14495 { 14496 /* Recognise the SABD and UABD operation here. 14497 Recursion from the PLUS case will catch the accumulating 14498 forms. */ 14499 if (aarch64_abd_rtx_p (x)) 14500 { 14501 if (speed) 14502 *cost += extra_cost->vect.alu; 14503 return true; 14504 } 14505 /* SUBL2 and SUBW2. 14506 The select-operand-high-half versions of the sub instruction 14507 have the same cost as the regular three vector version - 14508 don't add the costs of the select into the costs of the sub. 14509 */ 14510 op0 = aarch64_strip_extend_vec_half (op0); 14511 op1 = aarch64_strip_extend_vec_half (op1); 14512 } 14513 } 14514 14515 *cost += rtx_cost (op0, mode, MINUS, 0, speed); 14516 14517 /* Detect valid immediates. */ 14518 if ((GET_MODE_CLASS (mode) == MODE_INT 14519 || (GET_MODE_CLASS (mode) == MODE_CC 14520 && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)) 14521 && CONST_INT_P (op1) 14522 && aarch64_uimm12_shift (INTVAL (op1))) 14523 { 14524 if (speed) 14525 /* SUB(S) (immediate). */ 14526 *cost += extra_cost->alu.arith; 14527 return true; 14528 } 14529 14530 /* Look for SUB (extended register). */ 14531 if (is_a <scalar_int_mode> (mode) 14532 && aarch64_rtx_arith_op_extract_p (op1)) 14533 { 14534 if (speed) 14535 *cost += extra_cost->alu.extend_arith; 14536 14537 op1 = aarch64_strip_extend (op1, true); 14538 *cost += rtx_cost (op1, VOIDmode, 14539 (enum rtx_code) GET_CODE (op1), 0, speed); 14540 return true; 14541 } 14542 14543 rtx new_op1 = aarch64_strip_extend (op1, false); 14544 14545 /* Cost this as an FMA-alike operation. */ 14546 if ((GET_CODE (new_op1) == MULT 14547 || aarch64_shift_p (GET_CODE (new_op1))) 14548 && code != COMPARE) 14549 { 14550 *cost += aarch64_rtx_mult_cost (new_op1, MULT, 14551 (enum rtx_code) code, 14552 speed); 14553 return true; 14554 } 14555 14556 *cost += rtx_cost (new_op1, VOIDmode, MINUS, 1, speed); 14557 14558 if (speed) 14559 { 14560 if (VECTOR_MODE_P (mode)) 14561 { 14562 /* Vector SUB. */ 14563 *cost += extra_cost->vect.alu; 14564 } 14565 else if (GET_MODE_CLASS (mode) == MODE_INT) 14566 { 14567 /* SUB(S). */ 14568 *cost += extra_cost->alu.arith; 14569 } 14570 else if (GET_MODE_CLASS (mode) == MODE_FLOAT) 14571 { 14572 /* FSUB. */ 14573 *cost += extra_cost->fp[mode == DFmode].addsub; 14574 } 14575 } 14576 return true; 14577 } 14578 14579 case PLUS: 14580 { 14581 rtx new_op0; 14582 14583 op0 = XEXP (x, 0); 14584 op1 = XEXP (x, 1); 14585 14586 cost_plus: 14587 if (VECTOR_MODE_P (mode)) 14588 { 14589 /* ADDL2 and ADDW2. */ 14590 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 14591 if (TARGET_SIMD && (vec_flags & VEC_ADVSIMD)) 14592 { 14593 /* The select-operand-high-half versions of the add instruction 14594 have the same cost as the regular three vector version - 14595 don't add the costs of the select into the costs of the add. 14596 */ 14597 op0 = aarch64_strip_extend_vec_half (op0); 14598 op1 = aarch64_strip_extend_vec_half (op1); 14599 } 14600 } 14601 14602 if (GET_RTX_CLASS (GET_CODE (op0)) == RTX_COMPARE 14603 || GET_RTX_CLASS (GET_CODE (op0)) == RTX_COMM_COMPARE) 14604 { 14605 /* CSINC. */ 14606 *cost += rtx_cost (XEXP (op0, 0), mode, PLUS, 0, speed); 14607 *cost += rtx_cost (op1, mode, PLUS, 1, speed); 14608 return true; 14609 } 14610 14611 if (GET_MODE_CLASS (mode) == MODE_INT 14612 && (aarch64_plus_immediate (op1, mode) 14613 || aarch64_sve_addvl_addpl_immediate (op1, mode))) 14614 { 14615 *cost += rtx_cost (op0, mode, PLUS, 0, speed); 14616 14617 if (speed) 14618 { 14619 /* ADD (immediate). */ 14620 *cost += extra_cost->alu.arith; 14621 14622 /* Some tunings prefer to not use the VL-based scalar ops. 14623 Increase the cost of the poly immediate to prevent their 14624 formation. */ 14625 if (GET_CODE (op1) == CONST_POLY_INT 14626 && (aarch64_tune_params.extra_tuning_flags 14627 & AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS)) 14628 *cost += COSTS_N_INSNS (1); 14629 } 14630 return true; 14631 } 14632 14633 if (aarch64_pluslong_immediate (op1, mode)) 14634 { 14635 /* 24-bit add in 2 instructions or 12-bit shifted add. */ 14636 if ((INTVAL (op1) & 0xfff) != 0) 14637 *cost += COSTS_N_INSNS (1); 14638 14639 *cost += rtx_cost (op0, mode, PLUS, 0, speed); 14640 return true; 14641 } 14642 14643 *cost += rtx_cost (op1, mode, PLUS, 1, speed); 14644 14645 /* Look for ADD (extended register). */ 14646 if (is_a <scalar_int_mode> (mode) 14647 && aarch64_rtx_arith_op_extract_p (op0)) 14648 { 14649 if (speed) 14650 *cost += extra_cost->alu.extend_arith; 14651 14652 op0 = aarch64_strip_extend (op0, true); 14653 *cost += rtx_cost (op0, VOIDmode, 14654 (enum rtx_code) GET_CODE (op0), 0, speed); 14655 return true; 14656 } 14657 14658 /* Strip any extend, leave shifts behind as we will 14659 cost them through mult_cost. */ 14660 new_op0 = aarch64_strip_extend (op0, false); 14661 14662 if (GET_CODE (new_op0) == MULT 14663 || aarch64_shift_p (GET_CODE (new_op0))) 14664 { 14665 *cost += aarch64_rtx_mult_cost (new_op0, MULT, PLUS, 14666 speed); 14667 return true; 14668 } 14669 14670 *cost += rtx_cost (new_op0, VOIDmode, PLUS, 0, speed); 14671 14672 if (speed) 14673 { 14674 if (VECTOR_MODE_P (mode)) 14675 { 14676 /* Vector ADD. */ 14677 *cost += extra_cost->vect.alu; 14678 } 14679 else if (GET_MODE_CLASS (mode) == MODE_INT) 14680 { 14681 /* ADD. */ 14682 *cost += extra_cost->alu.arith; 14683 } 14684 else if (GET_MODE_CLASS (mode) == MODE_FLOAT) 14685 { 14686 /* FADD. */ 14687 *cost += extra_cost->fp[mode == DFmode].addsub; 14688 } 14689 } 14690 return true; 14691 } 14692 14693 case BSWAP: 14694 *cost = COSTS_N_INSNS (1); 14695 14696 if (speed) 14697 { 14698 if (VECTOR_MODE_P (mode)) 14699 *cost += extra_cost->vect.alu; 14700 else 14701 *cost += extra_cost->alu.rev; 14702 } 14703 return false; 14704 14705 case IOR: 14706 if (aarch_rev16_p (x)) 14707 { 14708 *cost = COSTS_N_INSNS (1); 14709 14710 if (speed) 14711 { 14712 if (VECTOR_MODE_P (mode)) 14713 *cost += extra_cost->vect.alu; 14714 else 14715 *cost += extra_cost->alu.rev; 14716 } 14717 return true; 14718 } 14719 14720 if (aarch64_extr_rtx_p (x, &op0, &op1)) 14721 { 14722 *cost += rtx_cost (op0, mode, IOR, 0, speed); 14723 *cost += rtx_cost (op1, mode, IOR, 1, speed); 14724 if (speed) 14725 *cost += extra_cost->alu.shift; 14726 14727 return true; 14728 } 14729 /* Fall through. */ 14730 case XOR: 14731 case AND: 14732 cost_logic: 14733 op0 = XEXP (x, 0); 14734 op1 = XEXP (x, 1); 14735 14736 if (VECTOR_MODE_P (mode)) 14737 { 14738 if (speed) 14739 *cost += extra_cost->vect.alu; 14740 return true; 14741 } 14742 14743 if (code == AND 14744 && GET_CODE (op0) == MULT 14745 && CONST_INT_P (XEXP (op0, 1)) 14746 && CONST_INT_P (op1) 14747 && aarch64_uxt_size (exact_log2 (INTVAL (XEXP (op0, 1))), 14748 INTVAL (op1)) != 0) 14749 { 14750 /* This is a UBFM/SBFM. */ 14751 *cost += rtx_cost (XEXP (op0, 0), mode, ZERO_EXTRACT, 0, speed); 14752 if (speed) 14753 *cost += extra_cost->alu.bfx; 14754 return true; 14755 } 14756 14757 if (is_int_mode (mode, &int_mode)) 14758 { 14759 if (CONST_INT_P (op1)) 14760 { 14761 /* We have a mask + shift version of a UBFIZ 14762 i.e. the *andim_ashift<mode>_bfiz pattern. */ 14763 if (GET_CODE (op0) == ASHIFT 14764 && aarch64_mask_and_shift_for_ubfiz_p (int_mode, op1, 14765 XEXP (op0, 1))) 14766 { 14767 *cost += rtx_cost (XEXP (op0, 0), int_mode, 14768 (enum rtx_code) code, 0, speed); 14769 if (speed) 14770 *cost += extra_cost->alu.bfx; 14771 14772 return true; 14773 } 14774 else if (aarch64_bitmask_imm (INTVAL (op1), int_mode)) 14775 { 14776 /* We possibly get the immediate for free, this is not 14777 modelled. */ 14778 *cost += rtx_cost (op0, int_mode, 14779 (enum rtx_code) code, 0, speed); 14780 if (speed) 14781 *cost += extra_cost->alu.logical; 14782 14783 return true; 14784 } 14785 } 14786 else 14787 { 14788 rtx new_op0 = op0; 14789 14790 /* Handle ORN, EON, or BIC. */ 14791 if (GET_CODE (op0) == NOT) 14792 op0 = XEXP (op0, 0); 14793 14794 new_op0 = aarch64_strip_shift (op0); 14795 14796 /* If we had a shift on op0 then this is a logical-shift- 14797 by-register/immediate operation. Otherwise, this is just 14798 a logical operation. */ 14799 if (speed) 14800 { 14801 if (new_op0 != op0) 14802 { 14803 /* Shift by immediate. */ 14804 if (CONST_INT_P (XEXP (op0, 1))) 14805 *cost += extra_cost->alu.log_shift; 14806 else 14807 *cost += extra_cost->alu.log_shift_reg; 14808 } 14809 else 14810 *cost += extra_cost->alu.logical; 14811 } 14812 14813 /* In both cases we want to cost both operands. */ 14814 *cost += rtx_cost (new_op0, int_mode, (enum rtx_code) code, 14815 0, speed); 14816 *cost += rtx_cost (op1, int_mode, (enum rtx_code) code, 14817 1, speed); 14818 14819 return true; 14820 } 14821 } 14822 return false; 14823 14824 case NOT: 14825 x = XEXP (x, 0); 14826 op0 = aarch64_strip_shift (x); 14827 14828 if (VECTOR_MODE_P (mode)) 14829 { 14830 /* Vector NOT. */ 14831 *cost += extra_cost->vect.alu; 14832 return false; 14833 } 14834 14835 /* MVN-shifted-reg. */ 14836 if (op0 != x) 14837 { 14838 *cost += rtx_cost (op0, mode, (enum rtx_code) code, 0, speed); 14839 14840 if (speed) 14841 *cost += extra_cost->alu.log_shift; 14842 14843 return true; 14844 } 14845 /* EON can have two forms: (xor (not a) b) but also (not (xor a b)). 14846 Handle the second form here taking care that 'a' in the above can 14847 be a shift. */ 14848 else if (GET_CODE (op0) == XOR) 14849 { 14850 rtx newop0 = XEXP (op0, 0); 14851 rtx newop1 = XEXP (op0, 1); 14852 rtx op0_stripped = aarch64_strip_shift (newop0); 14853 14854 *cost += rtx_cost (newop1, mode, (enum rtx_code) code, 1, speed); 14855 *cost += rtx_cost (op0_stripped, mode, XOR, 0, speed); 14856 14857 if (speed) 14858 { 14859 if (op0_stripped != newop0) 14860 *cost += extra_cost->alu.log_shift; 14861 else 14862 *cost += extra_cost->alu.logical; 14863 } 14864 14865 return true; 14866 } 14867 /* MVN. */ 14868 if (speed) 14869 *cost += extra_cost->alu.logical; 14870 14871 return false; 14872 14873 case ZERO_EXTEND: 14874 14875 op0 = XEXP (x, 0); 14876 /* If a value is written in SI mode, then zero extended to DI 14877 mode, the operation will in general be free as a write to 14878 a 'w' register implicitly zeroes the upper bits of an 'x' 14879 register. However, if this is 14880 14881 (set (reg) (zero_extend (reg))) 14882 14883 we must cost the explicit register move. */ 14884 if (mode == DImode 14885 && GET_MODE (op0) == SImode) 14886 { 14887 int op_cost = rtx_cost (op0, VOIDmode, ZERO_EXTEND, 0, speed); 14888 14889 /* If OP_COST is non-zero, then the cost of the zero extend 14890 is effectively the cost of the inner operation. Otherwise 14891 we have a MOV instruction and we take the cost from the MOV 14892 itself. This is true independently of whether we are 14893 optimizing for space or time. */ 14894 if (op_cost) 14895 *cost = op_cost; 14896 14897 return true; 14898 } 14899 else if (MEM_P (op0)) 14900 { 14901 /* All loads can zero extend to any size for free. */ 14902 *cost = rtx_cost (op0, VOIDmode, ZERO_EXTEND, param, speed); 14903 return true; 14904 } 14905 14906 op0 = aarch64_extend_bitfield_pattern_p (x); 14907 if (op0) 14908 { 14909 *cost += rtx_cost (op0, mode, ZERO_EXTEND, 0, speed); 14910 if (speed) 14911 *cost += extra_cost->alu.bfx; 14912 return true; 14913 } 14914 14915 if (speed) 14916 { 14917 if (VECTOR_MODE_P (mode)) 14918 { 14919 /* UMOV. */ 14920 *cost += extra_cost->vect.alu; 14921 } 14922 else 14923 { 14924 /* We generate an AND instead of UXTB/UXTH. */ 14925 *cost += extra_cost->alu.logical; 14926 } 14927 } 14928 return false; 14929 14930 case SIGN_EXTEND: 14931 if (MEM_P (XEXP (x, 0))) 14932 { 14933 /* LDRSH. */ 14934 if (speed) 14935 { 14936 rtx address = XEXP (XEXP (x, 0), 0); 14937 *cost += extra_cost->ldst.load_sign_extend; 14938 14939 *cost += 14940 COSTS_N_INSNS (aarch64_address_cost (address, mode, 14941 0, speed)); 14942 } 14943 return true; 14944 } 14945 14946 op0 = aarch64_extend_bitfield_pattern_p (x); 14947 if (op0) 14948 { 14949 *cost += rtx_cost (op0, mode, SIGN_EXTEND, 0, speed); 14950 if (speed) 14951 *cost += extra_cost->alu.bfx; 14952 return true; 14953 } 14954 14955 if (speed) 14956 { 14957 if (VECTOR_MODE_P (mode)) 14958 *cost += extra_cost->vect.alu; 14959 else 14960 *cost += extra_cost->alu.extend; 14961 } 14962 return false; 14963 14964 case ROTATE: 14965 case ROTATERT: 14966 case LSHIFTRT: 14967 case ASHIFTRT: 14968 case ASHIFT: 14969 op0 = XEXP (x, 0); 14970 op1 = XEXP (x, 1); 14971 14972 if (CONST_INT_P (op1)) 14973 { 14974 if (speed) 14975 { 14976 if (VECTOR_MODE_P (mode)) 14977 { 14978 /* Vector shift (immediate). */ 14979 *cost += extra_cost->vect.alu; 14980 } 14981 else 14982 { 14983 /* LSL (immediate), ASR (immediate), UBMF, UBFIZ and friends. 14984 These are all aliases. */ 14985 *cost += extra_cost->alu.shift; 14986 } 14987 } 14988 14989 /* We can incorporate zero/sign extend for free. */ 14990 if (GET_CODE (op0) == ZERO_EXTEND 14991 || GET_CODE (op0) == SIGN_EXTEND) 14992 op0 = XEXP (op0, 0); 14993 14994 *cost += rtx_cost (op0, VOIDmode, ASHIFT, 0, speed); 14995 return true; 14996 } 14997 else 14998 { 14999 if (VECTOR_MODE_P (mode)) 15000 { 15001 if (speed) 15002 /* Vector shift (register). */ 15003 *cost += extra_cost->vect.alu; 15004 } 15005 else 15006 { 15007 if (speed) 15008 /* LSLV, ASRV. */ 15009 *cost += extra_cost->alu.shift_reg; 15010 15011 /* The register shift amount may be in a shorter mode expressed 15012 as a lowpart SUBREG. For costing purposes just look inside. */ 15013 if (SUBREG_P (op1) && subreg_lowpart_p (op1)) 15014 op1 = SUBREG_REG (op1); 15015 if (GET_CODE (op1) == AND && REG_P (XEXP (op1, 0)) 15016 && CONST_INT_P (XEXP (op1, 1)) 15017 && known_eq (INTVAL (XEXP (op1, 1)), 15018 GET_MODE_BITSIZE (mode) - 1)) 15019 { 15020 *cost += rtx_cost (op0, mode, (rtx_code) code, 0, speed); 15021 /* We already demanded XEXP (op1, 0) to be REG_P, so 15022 don't recurse into it. */ 15023 return true; 15024 } 15025 } 15026 return false; /* All arguments need to be in registers. */ 15027 } 15028 15029 case SYMBOL_REF: 15030 15031 if (aarch64_cmodel == AARCH64_CMODEL_LARGE 15032 || aarch64_cmodel == AARCH64_CMODEL_SMALL_SPIC) 15033 { 15034 /* LDR. */ 15035 if (speed) 15036 *cost += extra_cost->ldst.load; 15037 } 15038 else if (aarch64_cmodel == AARCH64_CMODEL_SMALL 15039 || aarch64_cmodel == AARCH64_CMODEL_SMALL_PIC) 15040 { 15041 /* ADRP, followed by ADD. */ 15042 *cost += COSTS_N_INSNS (1); 15043 if (speed) 15044 *cost += 2 * extra_cost->alu.arith; 15045 } 15046 else if (aarch64_cmodel == AARCH64_CMODEL_TINY 15047 || aarch64_cmodel == AARCH64_CMODEL_TINY_PIC) 15048 { 15049 /* ADR. */ 15050 if (speed) 15051 *cost += extra_cost->alu.arith; 15052 } 15053 15054 if (flag_pic) 15055 { 15056 /* One extra load instruction, after accessing the GOT. */ 15057 *cost += COSTS_N_INSNS (1); 15058 if (speed) 15059 *cost += extra_cost->ldst.load; 15060 } 15061 return true; 15062 15063 case HIGH: 15064 case LO_SUM: 15065 /* ADRP/ADD (immediate). */ 15066 if (speed) 15067 *cost += extra_cost->alu.arith; 15068 return true; 15069 15070 case ZERO_EXTRACT: 15071 case SIGN_EXTRACT: 15072 /* UBFX/SBFX. */ 15073 if (speed) 15074 { 15075 if (VECTOR_MODE_P (mode)) 15076 *cost += extra_cost->vect.alu; 15077 else 15078 *cost += extra_cost->alu.bfx; 15079 } 15080 15081 /* We can trust that the immediates used will be correct (there 15082 are no by-register forms), so we need only cost op0. */ 15083 *cost += rtx_cost (XEXP (x, 0), VOIDmode, (enum rtx_code) code, 0, speed); 15084 return true; 15085 15086 case MULT: 15087 *cost += aarch64_rtx_mult_cost (x, MULT, 0, speed); 15088 /* aarch64_rtx_mult_cost always handles recursion to its 15089 operands. */ 15090 return true; 15091 15092 case MOD: 15093 /* We can expand signed mod by power of 2 using a NEGS, two parallel 15094 ANDs and a CSNEG. Assume here that CSNEG is the same as the cost of 15095 an unconditional negate. This case should only ever be reached through 15096 the set_smod_pow2_cheap check in expmed.cc. */ 15097 if (CONST_INT_P (XEXP (x, 1)) 15098 && exact_log2 (INTVAL (XEXP (x, 1))) > 0 15099 && (mode == SImode || mode == DImode)) 15100 { 15101 /* We expand to 4 instructions. Reset the baseline. */ 15102 *cost = COSTS_N_INSNS (4); 15103 15104 if (speed) 15105 *cost += 2 * extra_cost->alu.logical 15106 + 2 * extra_cost->alu.arith; 15107 15108 return true; 15109 } 15110 15111 /* Fall-through. */ 15112 case UMOD: 15113 if (speed) 15114 { 15115 /* Slighly prefer UMOD over SMOD. */ 15116 if (VECTOR_MODE_P (mode)) 15117 *cost += extra_cost->vect.alu; 15118 else if (GET_MODE_CLASS (mode) == MODE_INT) 15119 *cost += (extra_cost->mult[mode == DImode].add 15120 + extra_cost->mult[mode == DImode].idiv 15121 + (code == MOD ? 1 : 0)); 15122 } 15123 return false; /* All arguments need to be in registers. */ 15124 15125 case DIV: 15126 case UDIV: 15127 case SQRT: 15128 if (speed) 15129 { 15130 if (VECTOR_MODE_P (mode)) 15131 *cost += extra_cost->vect.alu; 15132 else if (GET_MODE_CLASS (mode) == MODE_INT) 15133 /* There is no integer SQRT, so only DIV and UDIV can get 15134 here. */ 15135 *cost += (extra_cost->mult[mode == DImode].idiv 15136 /* Slighly prefer UDIV over SDIV. */ 15137 + (code == DIV ? 1 : 0)); 15138 else 15139 *cost += extra_cost->fp[mode == DFmode].div; 15140 } 15141 return false; /* All arguments need to be in registers. */ 15142 15143 case IF_THEN_ELSE: 15144 return aarch64_if_then_else_costs (XEXP (x, 0), XEXP (x, 1), 15145 XEXP (x, 2), cost, speed); 15146 15147 case EQ: 15148 case NE: 15149 case GT: 15150 case GTU: 15151 case LT: 15152 case LTU: 15153 case GE: 15154 case GEU: 15155 case LE: 15156 case LEU: 15157 15158 return false; /* All arguments must be in registers. */ 15159 15160 case FMA: 15161 op0 = XEXP (x, 0); 15162 op1 = XEXP (x, 1); 15163 op2 = XEXP (x, 2); 15164 15165 if (speed) 15166 { 15167 if (VECTOR_MODE_P (mode)) 15168 *cost += extra_cost->vect.alu; 15169 else 15170 *cost += extra_cost->fp[mode == DFmode].fma; 15171 } 15172 15173 /* FMSUB, FNMADD, and FNMSUB are free. */ 15174 if (GET_CODE (op0) == NEG) 15175 op0 = XEXP (op0, 0); 15176 15177 if (GET_CODE (op2) == NEG) 15178 op2 = XEXP (op2, 0); 15179 15180 /* aarch64_fnma4_elt_to_64v2df has the NEG as operand 1, 15181 and the by-element operand as operand 0. */ 15182 if (GET_CODE (op1) == NEG) 15183 op1 = XEXP (op1, 0); 15184 15185 /* Catch vector-by-element operations. The by-element operand can 15186 either be (vec_duplicate (vec_select (x))) or just 15187 (vec_select (x)), depending on whether we are multiplying by 15188 a vector or a scalar. 15189 15190 Canonicalization is not very good in these cases, FMA4 will put the 15191 by-element operand as operand 0, FNMA4 will have it as operand 1. */ 15192 if (GET_CODE (op0) == VEC_DUPLICATE) 15193 op0 = XEXP (op0, 0); 15194 else if (GET_CODE (op1) == VEC_DUPLICATE) 15195 op1 = XEXP (op1, 0); 15196 15197 if (GET_CODE (op0) == VEC_SELECT) 15198 op0 = XEXP (op0, 0); 15199 else if (GET_CODE (op1) == VEC_SELECT) 15200 op1 = XEXP (op1, 0); 15201 15202 /* If the remaining parameters are not registers, 15203 get the cost to put them into registers. */ 15204 *cost += rtx_cost (op0, mode, FMA, 0, speed); 15205 *cost += rtx_cost (op1, mode, FMA, 1, speed); 15206 *cost += rtx_cost (op2, mode, FMA, 2, speed); 15207 return true; 15208 15209 case FLOAT: 15210 case UNSIGNED_FLOAT: 15211 if (speed) 15212 *cost += extra_cost->fp[mode == DFmode].fromint; 15213 return false; 15214 15215 case FLOAT_EXTEND: 15216 if (speed) 15217 { 15218 if (VECTOR_MODE_P (mode)) 15219 { 15220 /*Vector truncate. */ 15221 *cost += extra_cost->vect.alu; 15222 } 15223 else 15224 *cost += extra_cost->fp[mode == DFmode].widen; 15225 } 15226 return false; 15227 15228 case FLOAT_TRUNCATE: 15229 if (speed) 15230 { 15231 if (VECTOR_MODE_P (mode)) 15232 { 15233 /*Vector conversion. */ 15234 *cost += extra_cost->vect.alu; 15235 } 15236 else 15237 *cost += extra_cost->fp[mode == DFmode].narrow; 15238 } 15239 return false; 15240 15241 case FIX: 15242 case UNSIGNED_FIX: 15243 x = XEXP (x, 0); 15244 /* Strip the rounding part. They will all be implemented 15245 by the fcvt* family of instructions anyway. */ 15246 if (GET_CODE (x) == UNSPEC) 15247 { 15248 unsigned int uns_code = XINT (x, 1); 15249 15250 if (uns_code == UNSPEC_FRINTA 15251 || uns_code == UNSPEC_FRINTM 15252 || uns_code == UNSPEC_FRINTN 15253 || uns_code == UNSPEC_FRINTP 15254 || uns_code == UNSPEC_FRINTZ) 15255 x = XVECEXP (x, 0, 0); 15256 } 15257 15258 if (speed) 15259 { 15260 if (VECTOR_MODE_P (mode)) 15261 *cost += extra_cost->vect.alu; 15262 else 15263 *cost += extra_cost->fp[GET_MODE (x) == DFmode].toint; 15264 } 15265 15266 /* We can combine fmul by a power of 2 followed by a fcvt into a single 15267 fixed-point fcvt. */ 15268 if (GET_CODE (x) == MULT 15269 && ((VECTOR_MODE_P (mode) 15270 && aarch64_vec_fpconst_pow_of_2 (XEXP (x, 1)) > 0) 15271 || aarch64_fpconst_pow_of_2 (XEXP (x, 1)) > 0)) 15272 { 15273 *cost += rtx_cost (XEXP (x, 0), VOIDmode, (rtx_code) code, 15274 0, speed); 15275 return true; 15276 } 15277 15278 *cost += rtx_cost (x, VOIDmode, (enum rtx_code) code, 0, speed); 15279 return true; 15280 15281 case ABS: 15282 if (VECTOR_MODE_P (mode)) 15283 { 15284 /* ABS (vector). */ 15285 if (speed) 15286 *cost += extra_cost->vect.alu; 15287 } 15288 else if (GET_MODE_CLASS (mode) == MODE_FLOAT) 15289 { 15290 op0 = XEXP (x, 0); 15291 15292 /* FABD, which is analogous to FADD. */ 15293 if (GET_CODE (op0) == MINUS) 15294 { 15295 *cost += rtx_cost (XEXP (op0, 0), mode, MINUS, 0, speed); 15296 *cost += rtx_cost (XEXP (op0, 1), mode, MINUS, 1, speed); 15297 if (speed) 15298 *cost += extra_cost->fp[mode == DFmode].addsub; 15299 15300 return true; 15301 } 15302 /* Simple FABS is analogous to FNEG. */ 15303 if (speed) 15304 *cost += extra_cost->fp[mode == DFmode].neg; 15305 } 15306 else 15307 { 15308 /* Integer ABS will either be split to 15309 two arithmetic instructions, or will be an ABS 15310 (scalar), which we don't model. */ 15311 *cost = COSTS_N_INSNS (2); 15312 if (speed) 15313 *cost += 2 * extra_cost->alu.arith; 15314 } 15315 return false; 15316 15317 case SMAX: 15318 case SMIN: 15319 if (speed) 15320 { 15321 if (VECTOR_MODE_P (mode)) 15322 *cost += extra_cost->vect.alu; 15323 else 15324 { 15325 /* FMAXNM/FMINNM/FMAX/FMIN. 15326 TODO: This may not be accurate for all implementations, but 15327 we do not model this in the cost tables. */ 15328 *cost += extra_cost->fp[mode == DFmode].addsub; 15329 } 15330 } 15331 return false; 15332 15333 case UNSPEC: 15334 /* The floating point round to integer frint* instructions. */ 15335 if (aarch64_frint_unspec_p (XINT (x, 1))) 15336 { 15337 if (speed) 15338 *cost += extra_cost->fp[mode == DFmode].roundint; 15339 15340 return false; 15341 } 15342 15343 if (XINT (x, 1) == UNSPEC_RBIT) 15344 { 15345 if (speed) 15346 *cost += extra_cost->alu.rev; 15347 15348 return false; 15349 } 15350 break; 15351 15352 case TRUNCATE: 15353 15354 /* Decompose <su>muldi3_highpart. */ 15355 if (/* (truncate:DI */ 15356 mode == DImode 15357 /* (lshiftrt:TI */ 15358 && GET_MODE (XEXP (x, 0)) == TImode 15359 && GET_CODE (XEXP (x, 0)) == LSHIFTRT 15360 /* (mult:TI */ 15361 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT 15362 /* (ANY_EXTEND:TI (reg:DI)) 15363 (ANY_EXTEND:TI (reg:DI))) */ 15364 && ((GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ZERO_EXTEND 15365 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == ZERO_EXTEND) 15366 || (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SIGN_EXTEND 15367 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == SIGN_EXTEND)) 15368 && GET_MODE (XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 0)) == DImode 15369 && GET_MODE (XEXP (XEXP (XEXP (XEXP (x, 0), 0), 1), 0)) == DImode 15370 /* (const_int 64) */ 15371 && CONST_INT_P (XEXP (XEXP (x, 0), 1)) 15372 && UINTVAL (XEXP (XEXP (x, 0), 1)) == 64) 15373 { 15374 /* UMULH/SMULH. */ 15375 if (speed) 15376 *cost += extra_cost->mult[mode == DImode].extend; 15377 *cost += rtx_cost (XEXP (XEXP (XEXP (XEXP (x, 0), 0), 0), 0), 15378 mode, MULT, 0, speed); 15379 *cost += rtx_cost (XEXP (XEXP (XEXP (XEXP (x, 0), 0), 1), 0), 15380 mode, MULT, 1, speed); 15381 return true; 15382 } 15383 break; 15384 case CONST_VECTOR: 15385 { 15386 /* Load using MOVI/MVNI. */ 15387 if (aarch64_simd_valid_immediate (x, NULL)) 15388 *cost = extra_cost->vect.movi; 15389 else /* Load using constant pool. */ 15390 *cost = extra_cost->ldst.load; 15391 break; 15392 } 15393 case VEC_CONCAT: 15394 /* depending on the operation, either DUP or INS. 15395 For now, keep default costing. */ 15396 break; 15397 case VEC_DUPLICATE: 15398 /* Load using a DUP. */ 15399 *cost = extra_cost->vect.dup; 15400 return false; 15401 case VEC_SELECT: 15402 { 15403 rtx op0 = XEXP (x, 0); 15404 *cost = rtx_cost (op0, GET_MODE (op0), VEC_SELECT, 0, speed); 15405 15406 /* cost subreg of 0 as free, otherwise as DUP */ 15407 rtx op1 = XEXP (x, 1); 15408 if (vec_series_lowpart_p (mode, GET_MODE (op1), op1)) 15409 ; 15410 else if (vec_series_highpart_p (mode, GET_MODE (op1), op1)) 15411 *cost = extra_cost->vect.dup; 15412 else 15413 *cost = extra_cost->vect.extract; 15414 return true; 15415 } 15416 default: 15417 break; 15418 } 15419 15420 if (dump_file 15421 && flag_aarch64_verbose_cost) 15422 fprintf (dump_file, 15423 "\nFailed to cost RTX. Assuming default cost.\n"); 15424 15425 return true; 15426 } 15427 15428 /* Wrapper around aarch64_rtx_costs, dumps the partial, or total cost 15429 calculated for X. This cost is stored in *COST. Returns true 15430 if the total cost of X was calculated. */ 15431 static bool 15432 aarch64_rtx_costs_wrapper (rtx x, machine_mode mode, int outer, 15433 int param, int *cost, bool speed) 15434 { 15435 bool result = aarch64_rtx_costs (x, mode, outer, param, cost, speed); 15436 15437 if (dump_file 15438 && flag_aarch64_verbose_cost) 15439 { 15440 print_rtl_single (dump_file, x); 15441 fprintf (dump_file, "\n%s cost: %d (%s)\n", 15442 speed ? "Hot" : "Cold", 15443 *cost, result ? "final" : "partial"); 15444 } 15445 15446 return result; 15447 } 15448 15449 static int 15450 aarch64_register_move_cost (machine_mode mode, 15451 reg_class_t from_i, reg_class_t to_i) 15452 { 15453 enum reg_class from = (enum reg_class) from_i; 15454 enum reg_class to = (enum reg_class) to_i; 15455 const struct cpu_regmove_cost *regmove_cost 15456 = aarch64_tune_params.regmove_cost; 15457 15458 /* Trest any subset of POINTER_REGS as though it were GENERAL_REGS. */ 15459 if (reg_class_subset_p (to, POINTER_REGS)) 15460 to = GENERAL_REGS; 15461 15462 if (reg_class_subset_p (from, POINTER_REGS)) 15463 from = GENERAL_REGS; 15464 15465 /* Make RDFFR very expensive. In particular, if we know that the FFR 15466 contains a PTRUE (e.g. after a SETFFR), we must never use RDFFR 15467 as a way of obtaining a PTRUE. */ 15468 if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL 15469 && hard_reg_set_subset_p (reg_class_contents[from_i], 15470 reg_class_contents[FFR_REGS])) 15471 return 80; 15472 15473 /* Moving between GPR and stack cost is the same as GP2GP. */ 15474 if ((from == GENERAL_REGS && to == STACK_REG) 15475 || (to == GENERAL_REGS && from == STACK_REG)) 15476 return regmove_cost->GP2GP; 15477 15478 /* To/From the stack register, we move via the gprs. */ 15479 if (to == STACK_REG || from == STACK_REG) 15480 return aarch64_register_move_cost (mode, from, GENERAL_REGS) 15481 + aarch64_register_move_cost (mode, GENERAL_REGS, to); 15482 15483 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 15484 if (vec_flags != (VEC_ADVSIMD | VEC_STRUCT | VEC_PARTIAL) 15485 && known_eq (GET_MODE_SIZE (mode), 16)) 15486 { 15487 /* 128-bit operations on general registers require 2 instructions. */ 15488 if (from == GENERAL_REGS && to == GENERAL_REGS) 15489 return regmove_cost->GP2GP * 2; 15490 else if (from == GENERAL_REGS) 15491 return regmove_cost->GP2FP * 2; 15492 else if (to == GENERAL_REGS) 15493 return regmove_cost->FP2GP * 2; 15494 15495 /* When AdvSIMD instructions are disabled it is not possible to move 15496 a 128-bit value directly between Q registers. This is handled in 15497 secondary reload. A general register is used as a scratch to move 15498 the upper DI value and the lower DI value is moved directly, 15499 hence the cost is the sum of three moves. */ 15500 if (!TARGET_SIMD && !TARGET_SVE) 15501 return regmove_cost->GP2FP + regmove_cost->FP2GP + regmove_cost->FP2FP; 15502 15503 return regmove_cost->FP2FP; 15504 } 15505 15506 if (from == GENERAL_REGS && to == GENERAL_REGS) 15507 return regmove_cost->GP2GP; 15508 else if (from == GENERAL_REGS) 15509 return regmove_cost->GP2FP; 15510 else if (to == GENERAL_REGS) 15511 return regmove_cost->FP2GP; 15512 15513 if (!TARGET_SIMD && vec_flags == (VEC_ADVSIMD | VEC_STRUCT)) 15514 { 15515 /* Needs a round-trip through memory, which can use LDP/STP for pairs. 15516 The cost must be greater than 2 units to indicate that direct 15517 moves aren't possible. */ 15518 auto per_vector = (aarch64_tune_params.memmov_cost.load_fp 15519 + aarch64_tune_params.memmov_cost.store_fp); 15520 return MIN (CEIL (per_vector, 2), 4); 15521 } 15522 15523 return regmove_cost->FP2FP; 15524 } 15525 15526 /* Implements TARGET_MEMORY_MOVE_COST. */ 15527 static int 15528 aarch64_memory_move_cost (machine_mode mode, reg_class_t rclass_i, bool in) 15529 { 15530 enum reg_class rclass = (enum reg_class) rclass_i; 15531 if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL 15532 ? reg_classes_intersect_p (rclass, PR_REGS) 15533 : reg_class_subset_p (rclass, PR_REGS)) 15534 return (in 15535 ? aarch64_tune_params.memmov_cost.load_pred 15536 : aarch64_tune_params.memmov_cost.store_pred); 15537 15538 if (VECTOR_MODE_P (mode) || FLOAT_MODE_P (mode) 15539 ? reg_classes_intersect_p (rclass, FP_REGS) 15540 : reg_class_subset_p (rclass, FP_REGS)) 15541 return (in 15542 ? aarch64_tune_params.memmov_cost.load_fp 15543 : aarch64_tune_params.memmov_cost.store_fp); 15544 15545 return (in 15546 ? aarch64_tune_params.memmov_cost.load_int 15547 : aarch64_tune_params.memmov_cost.store_int); 15548 } 15549 15550 /* Implement TARGET_INSN_COST. We have the opportunity to do something 15551 much more productive here, such as using insn attributes to cost things. 15552 But we don't, not yet. 15553 15554 The main point of this current definition is to make calling insn_cost 15555 on one instruction equivalent to calling seq_cost on a sequence that 15556 contains only that instruction. The default definition would instead 15557 only look at SET_SRCs, ignoring SET_DESTs. 15558 15559 This ensures that, for example, storing a 128-bit zero vector is more 15560 expensive than storing a 128-bit vector register. A move of zero 15561 into a 128-bit vector register followed by multiple stores of that 15562 register is then cheaper than multiple stores of zero (which would 15563 use STP of XZR). This in turn allows STP Qs to be formed. */ 15564 static int 15565 aarch64_insn_cost (rtx_insn *insn, bool speed) 15566 { 15567 if (rtx set = single_set (insn)) 15568 return set_rtx_cost (set, speed); 15569 return pattern_cost (PATTERN (insn), speed); 15570 } 15571 15572 /* Implement TARGET_INIT_BUILTINS. */ 15573 static void 15574 aarch64_init_builtins () 15575 { 15576 aarch64_general_init_builtins (); 15577 aarch64_sve::init_builtins (); 15578 #ifdef SUBTARGET_INIT_BUILTINS 15579 SUBTARGET_INIT_BUILTINS; 15580 #endif 15581 } 15582 15583 /* Implement TARGET_FOLD_BUILTIN. */ 15584 static tree 15585 aarch64_fold_builtin (tree fndecl, int nargs, tree *args, bool) 15586 { 15587 unsigned int code = DECL_MD_FUNCTION_CODE (fndecl); 15588 unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT; 15589 tree type = TREE_TYPE (TREE_TYPE (fndecl)); 15590 switch (code & AARCH64_BUILTIN_CLASS) 15591 { 15592 case AARCH64_BUILTIN_GENERAL: 15593 return aarch64_general_fold_builtin (subcode, type, nargs, args); 15594 15595 case AARCH64_BUILTIN_SVE: 15596 return NULL_TREE; 15597 } 15598 gcc_unreachable (); 15599 } 15600 15601 /* Implement TARGET_GIMPLE_FOLD_BUILTIN. */ 15602 static bool 15603 aarch64_gimple_fold_builtin (gimple_stmt_iterator *gsi) 15604 { 15605 gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi)); 15606 tree fndecl = gimple_call_fndecl (stmt); 15607 unsigned int code = DECL_MD_FUNCTION_CODE (fndecl); 15608 unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT; 15609 gimple *new_stmt = NULL; 15610 switch (code & AARCH64_BUILTIN_CLASS) 15611 { 15612 case AARCH64_BUILTIN_GENERAL: 15613 new_stmt = aarch64_general_gimple_fold_builtin (subcode, stmt, gsi); 15614 break; 15615 15616 case AARCH64_BUILTIN_SVE: 15617 new_stmt = aarch64_sve::gimple_fold_builtin (subcode, gsi, stmt); 15618 break; 15619 } 15620 15621 if (!new_stmt) 15622 return false; 15623 15624 gsi_replace (gsi, new_stmt, false); 15625 return true; 15626 } 15627 15628 /* Implement TARGET_EXPAND_BUILTIN. */ 15629 static rtx 15630 aarch64_expand_builtin (tree exp, rtx target, rtx, machine_mode, int ignore) 15631 { 15632 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 15633 unsigned int code = DECL_MD_FUNCTION_CODE (fndecl); 15634 unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT; 15635 switch (code & AARCH64_BUILTIN_CLASS) 15636 { 15637 case AARCH64_BUILTIN_GENERAL: 15638 return aarch64_general_expand_builtin (subcode, exp, target, ignore); 15639 15640 case AARCH64_BUILTIN_SVE: 15641 return aarch64_sve::expand_builtin (subcode, exp, target); 15642 } 15643 gcc_unreachable (); 15644 } 15645 15646 /* Implement TARGET_BUILTIN_DECL. */ 15647 static tree 15648 aarch64_builtin_decl (unsigned int code, bool initialize_p) 15649 { 15650 unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT; 15651 switch (code & AARCH64_BUILTIN_CLASS) 15652 { 15653 case AARCH64_BUILTIN_GENERAL: 15654 return aarch64_general_builtin_decl (subcode, initialize_p); 15655 15656 case AARCH64_BUILTIN_SVE: 15657 return aarch64_sve::builtin_decl (subcode, initialize_p); 15658 } 15659 gcc_unreachable (); 15660 } 15661 15662 /* Return true if it is safe and beneficial to use the approximate rsqrt optabs 15663 to optimize 1.0/sqrt. */ 15664 15665 static bool 15666 use_rsqrt_p (machine_mode mode) 15667 { 15668 return (!flag_trapping_math 15669 && flag_unsafe_math_optimizations 15670 && ((aarch64_tune_params.approx_modes->recip_sqrt 15671 & AARCH64_APPROX_MODE (mode)) 15672 || flag_mrecip_low_precision_sqrt)); 15673 } 15674 15675 /* Function to decide when to use the approximate reciprocal square root 15676 builtin. */ 15677 15678 static tree 15679 aarch64_builtin_reciprocal (tree fndecl) 15680 { 15681 machine_mode mode = TYPE_MODE (TREE_TYPE (fndecl)); 15682 15683 if (!use_rsqrt_p (mode)) 15684 return NULL_TREE; 15685 unsigned int code = DECL_MD_FUNCTION_CODE (fndecl); 15686 unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT; 15687 switch (code & AARCH64_BUILTIN_CLASS) 15688 { 15689 case AARCH64_BUILTIN_GENERAL: 15690 return aarch64_general_builtin_rsqrt (subcode); 15691 15692 case AARCH64_BUILTIN_SVE: 15693 return NULL_TREE; 15694 } 15695 gcc_unreachable (); 15696 } 15697 15698 /* Emit code to perform the floating-point operation: 15699 15700 DST = SRC1 * SRC2 15701 15702 where all three operands are already known to be registers. 15703 If the operation is an SVE one, PTRUE is a suitable all-true 15704 predicate. */ 15705 15706 static void 15707 aarch64_emit_mult (rtx dst, rtx ptrue, rtx src1, rtx src2) 15708 { 15709 if (ptrue) 15710 emit_insn (gen_aarch64_pred (UNSPEC_COND_FMUL, GET_MODE (dst), 15711 dst, ptrue, src1, src2, 15712 gen_int_mode (SVE_RELAXED_GP, SImode))); 15713 else 15714 emit_set_insn (dst, gen_rtx_MULT (GET_MODE (dst), src1, src2)); 15715 } 15716 15717 /* Emit instruction sequence to compute either the approximate square root 15718 or its approximate reciprocal, depending on the flag RECP, and return 15719 whether the sequence was emitted or not. */ 15720 15721 bool 15722 aarch64_emit_approx_sqrt (rtx dst, rtx src, bool recp) 15723 { 15724 machine_mode mode = GET_MODE (dst); 15725 15726 if (GET_MODE_INNER (mode) == HFmode) 15727 { 15728 gcc_assert (!recp); 15729 return false; 15730 } 15731 15732 if (!recp) 15733 { 15734 if (!(flag_mlow_precision_sqrt 15735 || (aarch64_tune_params.approx_modes->sqrt 15736 & AARCH64_APPROX_MODE (mode)))) 15737 return false; 15738 15739 if (!flag_finite_math_only 15740 || flag_trapping_math 15741 || !flag_unsafe_math_optimizations 15742 || optimize_function_for_size_p (cfun)) 15743 return false; 15744 } 15745 else 15746 /* Caller assumes we cannot fail. */ 15747 gcc_assert (use_rsqrt_p (mode)); 15748 15749 rtx pg = NULL_RTX; 15750 if (aarch64_sve_mode_p (mode)) 15751 pg = aarch64_ptrue_reg (aarch64_sve_pred_mode (mode)); 15752 machine_mode mmsk = (VECTOR_MODE_P (mode) 15753 ? related_int_vector_mode (mode).require () 15754 : int_mode_for_mode (mode).require ()); 15755 rtx xmsk = NULL_RTX; 15756 if (!recp) 15757 { 15758 /* When calculating the approximate square root, compare the 15759 argument with 0.0 and create a mask. */ 15760 rtx zero = CONST0_RTX (mode); 15761 if (pg) 15762 { 15763 xmsk = gen_reg_rtx (GET_MODE (pg)); 15764 rtx hint = gen_int_mode (SVE_KNOWN_PTRUE, SImode); 15765 emit_insn (gen_aarch64_pred_fcm (UNSPEC_COND_FCMNE, mode, 15766 xmsk, pg, hint, src, zero)); 15767 } 15768 else 15769 { 15770 xmsk = gen_reg_rtx (mmsk); 15771 emit_insn (gen_rtx_SET (xmsk, 15772 gen_rtx_NEG (mmsk, 15773 gen_rtx_EQ (mmsk, src, zero)))); 15774 } 15775 } 15776 15777 /* Estimate the approximate reciprocal square root. */ 15778 rtx xdst = gen_reg_rtx (mode); 15779 emit_insn (gen_aarch64_rsqrte (mode, xdst, src)); 15780 15781 /* Iterate over the series twice for SF and thrice for DF. */ 15782 int iterations = (GET_MODE_INNER (mode) == DFmode) ? 3 : 2; 15783 15784 /* Optionally iterate over the series once less for faster performance 15785 while sacrificing the accuracy. */ 15786 if ((recp && flag_mrecip_low_precision_sqrt) 15787 || (!recp && flag_mlow_precision_sqrt)) 15788 iterations--; 15789 15790 /* Iterate over the series to calculate the approximate reciprocal square 15791 root. */ 15792 rtx x1 = gen_reg_rtx (mode); 15793 while (iterations--) 15794 { 15795 rtx x2 = gen_reg_rtx (mode); 15796 aarch64_emit_mult (x2, pg, xdst, xdst); 15797 15798 emit_insn (gen_aarch64_rsqrts (mode, x1, src, x2)); 15799 15800 if (iterations > 0) 15801 aarch64_emit_mult (xdst, pg, xdst, x1); 15802 } 15803 15804 if (!recp) 15805 { 15806 if (pg) 15807 /* Multiply nonzero source values by the corresponding intermediate 15808 result elements, so that the final calculation is the approximate 15809 square root rather than its reciprocal. Select a zero result for 15810 zero source values, to avoid the Inf * 0 -> NaN that we'd get 15811 otherwise. */ 15812 emit_insn (gen_cond (UNSPEC_COND_FMUL, mode, 15813 xdst, xmsk, xdst, src, CONST0_RTX (mode))); 15814 else 15815 { 15816 /* Qualify the approximate reciprocal square root when the 15817 argument is 0.0 by squashing the intermediary result to 0.0. */ 15818 rtx xtmp = gen_reg_rtx (mmsk); 15819 emit_set_insn (xtmp, gen_rtx_AND (mmsk, gen_rtx_NOT (mmsk, xmsk), 15820 gen_rtx_SUBREG (mmsk, xdst, 0))); 15821 emit_move_insn (xdst, gen_rtx_SUBREG (mode, xtmp, 0)); 15822 15823 /* Calculate the approximate square root. */ 15824 aarch64_emit_mult (xdst, pg, xdst, src); 15825 } 15826 } 15827 15828 /* Finalize the approximation. */ 15829 aarch64_emit_mult (dst, pg, xdst, x1); 15830 15831 return true; 15832 } 15833 15834 /* Emit the instruction sequence to compute the approximation for the division 15835 of NUM by DEN in QUO and return whether the sequence was emitted or not. */ 15836 15837 bool 15838 aarch64_emit_approx_div (rtx quo, rtx num, rtx den) 15839 { 15840 machine_mode mode = GET_MODE (quo); 15841 15842 if (GET_MODE_INNER (mode) == HFmode) 15843 return false; 15844 15845 bool use_approx_division_p = (flag_mlow_precision_div 15846 || (aarch64_tune_params.approx_modes->division 15847 & AARCH64_APPROX_MODE (mode))); 15848 15849 if (!flag_finite_math_only 15850 || flag_trapping_math 15851 || !flag_unsafe_math_optimizations 15852 || optimize_function_for_size_p (cfun) 15853 || !use_approx_division_p) 15854 return false; 15855 15856 if (!TARGET_SIMD && VECTOR_MODE_P (mode)) 15857 return false; 15858 15859 rtx pg = NULL_RTX; 15860 if (aarch64_sve_mode_p (mode)) 15861 pg = aarch64_ptrue_reg (aarch64_sve_pred_mode (mode)); 15862 15863 /* Estimate the approximate reciprocal. */ 15864 rtx xrcp = gen_reg_rtx (mode); 15865 emit_insn (gen_aarch64_frecpe (mode, xrcp, den)); 15866 15867 /* Iterate over the series twice for SF and thrice for DF. */ 15868 int iterations = (GET_MODE_INNER (mode) == DFmode) ? 3 : 2; 15869 15870 /* Optionally iterate over the series less for faster performance, 15871 while sacrificing the accuracy. The default is 2 for DF and 1 for SF. */ 15872 if (flag_mlow_precision_div) 15873 iterations = (GET_MODE_INNER (mode) == DFmode 15874 ? aarch64_double_recp_precision 15875 : aarch64_float_recp_precision); 15876 15877 /* Iterate over the series to calculate the approximate reciprocal. */ 15878 rtx xtmp = gen_reg_rtx (mode); 15879 while (iterations--) 15880 { 15881 emit_insn (gen_aarch64_frecps (mode, xtmp, xrcp, den)); 15882 15883 if (iterations > 0) 15884 aarch64_emit_mult (xrcp, pg, xrcp, xtmp); 15885 } 15886 15887 if (num != CONST1_RTX (mode)) 15888 { 15889 /* As the approximate reciprocal of DEN is already calculated, only 15890 calculate the approximate division when NUM is not 1.0. */ 15891 rtx xnum = force_reg (mode, num); 15892 aarch64_emit_mult (xrcp, pg, xrcp, xnum); 15893 } 15894 15895 /* Finalize the approximation. */ 15896 aarch64_emit_mult (quo, pg, xrcp, xtmp); 15897 return true; 15898 } 15899 15900 /* Return the number of instructions that can be issued per cycle. */ 15901 static int 15902 aarch64_sched_issue_rate (void) 15903 { 15904 return aarch64_tune_params.issue_rate; 15905 } 15906 15907 /* Implement TARGET_SCHED_VARIABLE_ISSUE. */ 15908 static int 15909 aarch64_sched_variable_issue (FILE *, int, rtx_insn *insn, int more) 15910 { 15911 if (DEBUG_INSN_P (insn)) 15912 return more; 15913 15914 rtx_code code = GET_CODE (PATTERN (insn)); 15915 if (code == USE || code == CLOBBER) 15916 return more; 15917 15918 if (get_attr_type (insn) == TYPE_NO_INSN) 15919 return more; 15920 15921 return more - 1; 15922 } 15923 15924 static int 15925 aarch64_sched_first_cycle_multipass_dfa_lookahead (void) 15926 { 15927 int issue_rate = aarch64_sched_issue_rate (); 15928 15929 return issue_rate > 1 && !sched_fusion ? issue_rate : 0; 15930 } 15931 15932 15933 /* Implement TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD as 15934 autopref_multipass_dfa_lookahead_guard from haifa-sched.cc. It only 15935 has an effect if PARAM_SCHED_AUTOPREF_QUEUE_DEPTH > 0. */ 15936 15937 static int 15938 aarch64_first_cycle_multipass_dfa_lookahead_guard (rtx_insn *insn, 15939 int ready_index) 15940 { 15941 return autopref_multipass_dfa_lookahead_guard (insn, ready_index); 15942 } 15943 15944 15945 /* Vectorizer cost model target hooks. */ 15946 15947 /* If a vld1 from address ADDR should be recorded in vector_load_decls, 15948 return the decl that should be recorded. Return null otherwise. */ 15949 tree 15950 aarch64_vector_load_decl (tree addr) 15951 { 15952 if (TREE_CODE (addr) != ADDR_EXPR) 15953 return NULL_TREE; 15954 tree base = get_base_address (TREE_OPERAND (addr, 0)); 15955 if (TREE_CODE (base) != VAR_DECL) 15956 return NULL_TREE; 15957 return base; 15958 } 15959 15960 /* Return true if STMT_INFO accesses a decl that is known to be the 15961 argument to a vld1 in the same function. */ 15962 static bool 15963 aarch64_accesses_vector_load_decl_p (stmt_vec_info stmt_info) 15964 { 15965 if (!cfun->machine->vector_load_decls) 15966 return false; 15967 auto dr = STMT_VINFO_DATA_REF (stmt_info); 15968 if (!dr) 15969 return false; 15970 tree decl = aarch64_vector_load_decl (DR_BASE_ADDRESS (dr)); 15971 return decl && cfun->machine->vector_load_decls->contains (decl); 15972 } 15973 15974 /* Information about how the CPU would issue the scalar, Advanced SIMD 15975 or SVE version of a vector loop, using the scheme defined by the 15976 aarch64_base_vec_issue_info hierarchy of structures. */ 15977 class aarch64_vec_op_count 15978 { 15979 public: 15980 aarch64_vec_op_count () = default; 15981 aarch64_vec_op_count (const aarch64_vec_issue_info *, unsigned int, 15982 unsigned int = 1); 15983 15984 unsigned int vec_flags () const { return m_vec_flags; } 15985 unsigned int vf_factor () const { return m_vf_factor; } 15986 15987 const aarch64_base_vec_issue_info *base_issue_info () const; 15988 const aarch64_simd_vec_issue_info *simd_issue_info () const; 15989 const aarch64_sve_vec_issue_info *sve_issue_info () const; 15990 15991 fractional_cost rename_cycles_per_iter () const; 15992 fractional_cost min_nonpred_cycles_per_iter () const; 15993 fractional_cost min_pred_cycles_per_iter () const; 15994 fractional_cost min_cycles_per_iter () const; 15995 15996 void dump () const; 15997 15998 /* The number of individual "general" operations. See the comments 15999 in aarch64_base_vec_issue_info for details. */ 16000 unsigned int general_ops = 0; 16001 16002 /* The number of load and store operations, under the same scheme 16003 as above. */ 16004 unsigned int loads = 0; 16005 unsigned int stores = 0; 16006 16007 /* The minimum number of cycles needed to execute all loop-carried 16008 operations, which in the vector code become associated with 16009 reductions. */ 16010 unsigned int reduction_latency = 0; 16011 16012 /* The number of individual predicate operations. See the comments 16013 in aarch64_sve_vec_issue_info for details. */ 16014 unsigned int pred_ops = 0; 16015 16016 private: 16017 /* The issue information for the core. */ 16018 const aarch64_vec_issue_info *m_issue_info = nullptr; 16019 16020 /* - If M_VEC_FLAGS is zero then this structure describes scalar code 16021 - If M_VEC_FLAGS & VEC_ADVSIMD is nonzero then this structure describes 16022 Advanced SIMD code. 16023 - If M_VEC_FLAGS & VEC_ANY_SVE is nonzero then this structure describes 16024 SVE code. */ 16025 unsigned int m_vec_flags = 0; 16026 16027 /* Assume that, when the code is executing on the core described 16028 by M_ISSUE_INFO, one iteration of the loop will handle M_VF_FACTOR 16029 times more data than the vectorizer anticipates. 16030 16031 This is only ever different from 1 for SVE. It allows us to consider 16032 what would happen on a 256-bit SVE target even when the -mtune 16033 parameters say that the likely SVE length is 128 bits. */ 16034 unsigned int m_vf_factor = 1; 16035 }; 16036 16037 aarch64_vec_op_count:: 16038 aarch64_vec_op_count (const aarch64_vec_issue_info *issue_info, 16039 unsigned int vec_flags, unsigned int vf_factor) 16040 : m_issue_info (issue_info), 16041 m_vec_flags (vec_flags), 16042 m_vf_factor (vf_factor) 16043 { 16044 } 16045 16046 /* Return the base issue information (i.e. the parts that make sense 16047 for both scalar and vector code). Return null if we have no issue 16048 information. */ 16049 const aarch64_base_vec_issue_info * 16050 aarch64_vec_op_count::base_issue_info () const 16051 { 16052 if (auto *ret = simd_issue_info ()) 16053 return ret; 16054 return m_issue_info->scalar; 16055 } 16056 16057 /* If the structure describes vector code and we have associated issue 16058 information, return that issue information, otherwise return null. */ 16059 const aarch64_simd_vec_issue_info * 16060 aarch64_vec_op_count::simd_issue_info () const 16061 { 16062 if (auto *ret = sve_issue_info ()) 16063 return ret; 16064 if (m_vec_flags) 16065 return m_issue_info->advsimd; 16066 return nullptr; 16067 } 16068 16069 /* If the structure describes SVE code and we have associated issue 16070 information, return that issue information, otherwise return null. */ 16071 const aarch64_sve_vec_issue_info * 16072 aarch64_vec_op_count::sve_issue_info () const 16073 { 16074 if (m_vec_flags & VEC_ANY_SVE) 16075 return m_issue_info->sve; 16076 return nullptr; 16077 } 16078 16079 /* Estimate the minimum number of cycles per iteration needed to rename 16080 the instructions. 16081 16082 ??? For now this is done inline rather than via cost tables, since it 16083 isn't clear how it should be parameterized for the general case. */ 16084 fractional_cost 16085 aarch64_vec_op_count::rename_cycles_per_iter () const 16086 { 16087 if (sve_issue_info () == &neoverse512tvb_sve_issue_info 16088 || sve_issue_info () == &neoversen2_sve_issue_info 16089 || sve_issue_info () == &neoversev2_sve_issue_info) 16090 /* + 1 for an addition. We've already counted a general op for each 16091 store, so we don't need to account for stores separately. The branch 16092 reads no registers and so does not need to be counted either. 16093 16094 ??? This value is very much on the pessimistic side, but seems to work 16095 pretty well in practice. */ 16096 return { general_ops + loads + pred_ops + 1, 5 }; 16097 16098 return 0; 16099 } 16100 16101 /* Like min_cycles_per_iter, but excluding predicate operations. */ 16102 fractional_cost 16103 aarch64_vec_op_count::min_nonpred_cycles_per_iter () const 16104 { 16105 auto *issue_info = base_issue_info (); 16106 16107 fractional_cost cycles = MAX (reduction_latency, 1); 16108 cycles = std::max (cycles, { stores, issue_info->stores_per_cycle }); 16109 cycles = std::max (cycles, { loads + stores, 16110 issue_info->loads_stores_per_cycle }); 16111 cycles = std::max (cycles, { general_ops, 16112 issue_info->general_ops_per_cycle }); 16113 cycles = std::max (cycles, rename_cycles_per_iter ()); 16114 return cycles; 16115 } 16116 16117 /* Like min_cycles_per_iter, but including only the predicate operations. */ 16118 fractional_cost 16119 aarch64_vec_op_count::min_pred_cycles_per_iter () const 16120 { 16121 if (auto *issue_info = sve_issue_info ()) 16122 return { pred_ops, issue_info->pred_ops_per_cycle }; 16123 return 0; 16124 } 16125 16126 /* Estimate the minimum number of cycles needed to issue the operations. 16127 This is a very simplistic model! */ 16128 fractional_cost 16129 aarch64_vec_op_count::min_cycles_per_iter () const 16130 { 16131 return std::max (min_nonpred_cycles_per_iter (), 16132 min_pred_cycles_per_iter ()); 16133 } 16134 16135 /* Dump information about the structure. */ 16136 void 16137 aarch64_vec_op_count::dump () const 16138 { 16139 dump_printf_loc (MSG_NOTE, vect_location, 16140 " load operations = %d\n", loads); 16141 dump_printf_loc (MSG_NOTE, vect_location, 16142 " store operations = %d\n", stores); 16143 dump_printf_loc (MSG_NOTE, vect_location, 16144 " general operations = %d\n", general_ops); 16145 if (sve_issue_info ()) 16146 dump_printf_loc (MSG_NOTE, vect_location, 16147 " predicate operations = %d\n", pred_ops); 16148 dump_printf_loc (MSG_NOTE, vect_location, 16149 " reduction latency = %d\n", reduction_latency); 16150 if (auto rcpi = rename_cycles_per_iter ()) 16151 dump_printf_loc (MSG_NOTE, vect_location, 16152 " estimated cycles per iteration to rename = %f\n", 16153 rcpi.as_double ()); 16154 if (auto pred_cpi = min_pred_cycles_per_iter ()) 16155 { 16156 dump_printf_loc (MSG_NOTE, vect_location, 16157 " estimated min cycles per iteration" 16158 " without predication = %f\n", 16159 min_nonpred_cycles_per_iter ().as_double ()); 16160 dump_printf_loc (MSG_NOTE, vect_location, 16161 " estimated min cycles per iteration" 16162 " for predication = %f\n", pred_cpi.as_double ()); 16163 } 16164 if (auto cpi = min_cycles_per_iter ()) 16165 dump_printf_loc (MSG_NOTE, vect_location, 16166 " estimated min cycles per iteration = %f\n", 16167 cpi.as_double ()); 16168 } 16169 16170 /* Information about vector code that we're in the process of costing. */ 16171 class aarch64_vector_costs : public vector_costs 16172 { 16173 public: 16174 aarch64_vector_costs (vec_info *, bool); 16175 16176 unsigned int add_stmt_cost (int count, vect_cost_for_stmt kind, 16177 stmt_vec_info stmt_info, slp_tree, tree vectype, 16178 int misalign, 16179 vect_cost_model_location where) override; 16180 void finish_cost (const vector_costs *) override; 16181 bool better_main_loop_than_p (const vector_costs *other) const override; 16182 16183 private: 16184 void record_potential_advsimd_unrolling (loop_vec_info); 16185 void analyze_loop_vinfo (loop_vec_info); 16186 void count_ops (unsigned int, vect_cost_for_stmt, stmt_vec_info, 16187 aarch64_vec_op_count *); 16188 fractional_cost adjust_body_cost_sve (const aarch64_vec_op_count *, 16189 fractional_cost, unsigned int, 16190 unsigned int *, bool *); 16191 unsigned int adjust_body_cost (loop_vec_info, const aarch64_vector_costs *, 16192 unsigned int); 16193 bool prefer_unrolled_loop () const; 16194 unsigned int determine_suggested_unroll_factor (); 16195 16196 /* True if we have performed one-time initialization based on the 16197 vec_info. */ 16198 bool m_analyzed_vinfo = false; 16199 16200 /* This loop uses an average operation that is not supported by SVE, but is 16201 supported by Advanced SIMD and SVE2. */ 16202 bool m_has_avg = false; 16203 16204 /* True if the vector body contains a store to a decl and if the 16205 function is known to have a vld1 from the same decl. 16206 16207 In the Advanced SIMD ACLE, the recommended endian-agnostic way of 16208 initializing a vector is: 16209 16210 float f[4] = { elts }; 16211 float32x4_t x = vld1q_f32(f); 16212 16213 We should strongly prefer vectorization of the initialization of f, 16214 so that the store to f and the load back can be optimized away, 16215 leaving a vectorization of { elts }. */ 16216 bool m_stores_to_vector_load_decl = false; 16217 16218 /* Non-zero if the last operation we costed is a vector promotion or demotion. 16219 In this case the value is the number of insns in the last operation. 16220 16221 On AArch64 vector promotion and demotions require us to first widen or 16222 narrow the input and only after that emit conversion instructions. For 16223 costing this means we need to emit the cost of the final conversions as 16224 well. */ 16225 unsigned int m_num_last_promote_demote = 0; 16226 16227 /* - If M_VEC_FLAGS is zero then we're costing the original scalar code. 16228 - If M_VEC_FLAGS & VEC_ADVSIMD is nonzero then we're costing Advanced 16229 SIMD code. 16230 - If M_VEC_FLAGS & VEC_ANY_SVE is nonzero then we're costing SVE code. */ 16231 unsigned int m_vec_flags = 0; 16232 16233 /* At the moment, we do not model LDP and STP in the vector and scalar costs. 16234 This means that code such as: 16235 16236 a[0] = x; 16237 a[1] = x; 16238 16239 will be costed as two scalar instructions and two vector instructions 16240 (a scalar_to_vec and an unaligned_store). For SLP, the vector form 16241 wins if the costs are equal, because of the fact that the vector costs 16242 include constant initializations whereas the scalar costs don't. 16243 We would therefore tend to vectorize the code above, even though 16244 the scalar version can use a single STP. 16245 16246 We should eventually fix this and model LDP and STP in the main costs; 16247 see the comment in aarch64_sve_adjust_stmt_cost for some of the problems. 16248 Until then, we look specifically for code that does nothing more than 16249 STP-like operations. We cost them on that basis in addition to the 16250 normal latency-based costs. 16251 16252 If the scalar or vector code could be a sequence of STPs + 16253 initialization, this variable counts the cost of the sequence, 16254 with 2 units per instruction. The variable is ~0U for other 16255 kinds of code. */ 16256 unsigned int m_stp_sequence_cost = 0; 16257 16258 /* On some CPUs, SVE and Advanced SIMD provide the same theoretical vector 16259 throughput, such as 4x128 Advanced SIMD vs. 2x256 SVE. In those 16260 situations, we try to predict whether an Advanced SIMD implementation 16261 of the loop could be completely unrolled and become straight-line code. 16262 If so, it is generally better to use the Advanced SIMD version rather 16263 than length-agnostic SVE, since the SVE loop would execute an unknown 16264 number of times and so could not be completely unrolled in the same way. 16265 16266 If we're applying this heuristic, M_UNROLLED_ADVSIMD_NITERS is the 16267 number of Advanced SIMD loop iterations that would be unrolled and 16268 M_UNROLLED_ADVSIMD_STMTS estimates the total number of statements 16269 in the unrolled loop. Both values are zero if we're not applying 16270 the heuristic. */ 16271 unsigned HOST_WIDE_INT m_unrolled_advsimd_niters = 0; 16272 unsigned HOST_WIDE_INT m_unrolled_advsimd_stmts = 0; 16273 16274 /* If we're vectorizing a loop that executes a constant number of times, 16275 this variable gives the number of times that the vector loop would 16276 iterate, otherwise it is zero. */ 16277 uint64_t m_num_vector_iterations = 0; 16278 16279 /* Used only when vectorizing loops. Estimates the number and kind of 16280 operations that would be needed by one iteration of the scalar 16281 or vector loop. There is one entry for each tuning option of 16282 interest. */ 16283 auto_vec<aarch64_vec_op_count, 2> m_ops; 16284 }; 16285 16286 aarch64_vector_costs::aarch64_vector_costs (vec_info *vinfo, 16287 bool costing_for_scalar) 16288 : vector_costs (vinfo, costing_for_scalar), 16289 m_vec_flags (costing_for_scalar ? 0 16290 : aarch64_classify_vector_mode (vinfo->vector_mode)) 16291 { 16292 if (auto *issue_info = aarch64_tune_params.vec_costs->issue_info) 16293 { 16294 m_ops.quick_push ({ issue_info, m_vec_flags }); 16295 if (aarch64_tune_params.vec_costs == &neoverse512tvb_vector_cost) 16296 { 16297 unsigned int vf_factor = (m_vec_flags & VEC_ANY_SVE) ? 2 : 1; 16298 m_ops.quick_push ({ &neoversev1_vec_issue_info, m_vec_flags, 16299 vf_factor }); 16300 } 16301 } 16302 } 16303 16304 /* Implement TARGET_VECTORIZE_CREATE_COSTS. */ 16305 vector_costs * 16306 aarch64_vectorize_create_costs (vec_info *vinfo, bool costing_for_scalar) 16307 { 16308 return new aarch64_vector_costs (vinfo, costing_for_scalar); 16309 } 16310 16311 /* Return true if the current CPU should use the new costs defined 16312 in GCC 11. This should be removed for GCC 12 and above, with the 16313 costs applying to all CPUs instead. */ 16314 static bool 16315 aarch64_use_new_vector_costs_p () 16316 { 16317 return (aarch64_tune_params.extra_tuning_flags 16318 & AARCH64_EXTRA_TUNE_USE_NEW_VECTOR_COSTS); 16319 } 16320 16321 /* Return the appropriate SIMD costs for vectors of type VECTYPE. */ 16322 static const simd_vec_cost * 16323 aarch64_simd_vec_costs (tree vectype) 16324 { 16325 const cpu_vector_cost *costs = aarch64_tune_params.vec_costs; 16326 if (vectype != NULL 16327 && aarch64_sve_mode_p (TYPE_MODE (vectype)) 16328 && costs->sve != NULL) 16329 return costs->sve; 16330 return costs->advsimd; 16331 } 16332 16333 /* Return the appropriate SIMD costs for vectors with VEC_* flags FLAGS. */ 16334 static const simd_vec_cost * 16335 aarch64_simd_vec_costs_for_flags (unsigned int flags) 16336 { 16337 const cpu_vector_cost *costs = aarch64_tune_params.vec_costs; 16338 if ((flags & VEC_ANY_SVE) && costs->sve) 16339 return costs->sve; 16340 return costs->advsimd; 16341 } 16342 16343 /* If STMT_INFO is a memory reference, return the scalar memory type, 16344 otherwise return null. */ 16345 static tree 16346 aarch64_dr_type (stmt_vec_info stmt_info) 16347 { 16348 if (auto dr = STMT_VINFO_DATA_REF (stmt_info)) 16349 return TREE_TYPE (DR_REF (dr)); 16350 return NULL_TREE; 16351 } 16352 16353 /* Decide whether to use the unrolling heuristic described above 16354 m_unrolled_advsimd_niters, updating that field if so. LOOP_VINFO 16355 describes the loop that we're vectorizing. */ 16356 void 16357 aarch64_vector_costs:: 16358 record_potential_advsimd_unrolling (loop_vec_info loop_vinfo) 16359 { 16360 /* The heuristic only makes sense on targets that have the same 16361 vector throughput for SVE and Advanced SIMD. */ 16362 if (!(aarch64_tune_params.extra_tuning_flags 16363 & AARCH64_EXTRA_TUNE_MATCHED_VECTOR_THROUGHPUT)) 16364 return; 16365 16366 /* We only want to apply the heuristic if LOOP_VINFO is being 16367 vectorized for SVE. */ 16368 if (!(m_vec_flags & VEC_ANY_SVE)) 16369 return; 16370 16371 /* Check whether it is possible in principle to use Advanced SIMD 16372 instead. */ 16373 if (aarch64_autovec_preference == 2) 16374 return; 16375 16376 /* We don't want to apply the heuristic to outer loops, since it's 16377 harder to track two levels of unrolling. */ 16378 if (LOOP_VINFO_LOOP (loop_vinfo)->inner) 16379 return; 16380 16381 /* Only handle cases in which the number of Advanced SIMD iterations 16382 would be known at compile time but the number of SVE iterations 16383 would not. */ 16384 if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) 16385 || aarch64_sve_vg.is_constant ()) 16386 return; 16387 16388 /* Guess how many times the Advanced SIMD loop would iterate and make 16389 sure that it is within the complete unrolling limit. Even if the 16390 number of iterations is small enough, the number of statements might 16391 not be, which is why we need to estimate the number of statements too. */ 16392 unsigned int estimated_vq = aarch64_estimated_sve_vq (); 16393 unsigned int advsimd_vf = CEIL (vect_vf_for_cost (loop_vinfo), estimated_vq); 16394 unsigned HOST_WIDE_INT unrolled_advsimd_niters 16395 = LOOP_VINFO_INT_NITERS (loop_vinfo) / advsimd_vf; 16396 if (unrolled_advsimd_niters > (unsigned int) param_max_completely_peel_times) 16397 return; 16398 16399 /* Record that we're applying the heuristic and should try to estimate 16400 the number of statements in the Advanced SIMD loop. */ 16401 m_unrolled_advsimd_niters = unrolled_advsimd_niters; 16402 } 16403 16404 /* Do one-time initialization of the aarch64_vector_costs given that we're 16405 costing the loop vectorization described by LOOP_VINFO. */ 16406 void 16407 aarch64_vector_costs::analyze_loop_vinfo (loop_vec_info loop_vinfo) 16408 { 16409 /* Record the number of times that the vector loop would execute, 16410 if known. */ 16411 class loop *loop = LOOP_VINFO_LOOP (loop_vinfo); 16412 auto scalar_niters = max_stmt_executions_int (loop); 16413 if (scalar_niters >= 0) 16414 { 16415 unsigned int vf = vect_vf_for_cost (loop_vinfo); 16416 if (LOOP_VINFO_MASKS (loop_vinfo).is_empty ()) 16417 m_num_vector_iterations = scalar_niters / vf; 16418 else 16419 m_num_vector_iterations = CEIL (scalar_niters, vf); 16420 } 16421 16422 /* Detect whether we're vectorizing for SVE and should apply the unrolling 16423 heuristic described above m_unrolled_advsimd_niters. */ 16424 record_potential_advsimd_unrolling (loop_vinfo); 16425 } 16426 16427 /* Implement targetm.vectorize.builtin_vectorization_cost. */ 16428 static int 16429 aarch64_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost, 16430 tree vectype, 16431 int misalign ATTRIBUTE_UNUSED) 16432 { 16433 unsigned elements; 16434 const cpu_vector_cost *costs = aarch64_tune_params.vec_costs; 16435 bool fp = false; 16436 16437 if (vectype != NULL) 16438 fp = FLOAT_TYPE_P (vectype); 16439 16440 const simd_vec_cost *simd_costs = aarch64_simd_vec_costs (vectype); 16441 16442 switch (type_of_cost) 16443 { 16444 case scalar_stmt: 16445 return fp ? costs->scalar_fp_stmt_cost : costs->scalar_int_stmt_cost; 16446 16447 case scalar_load: 16448 return costs->scalar_load_cost; 16449 16450 case scalar_store: 16451 return costs->scalar_store_cost; 16452 16453 case vector_stmt: 16454 return fp ? simd_costs->fp_stmt_cost 16455 : simd_costs->int_stmt_cost; 16456 16457 case vector_load: 16458 return simd_costs->align_load_cost; 16459 16460 case vector_store: 16461 return simd_costs->store_cost; 16462 16463 case vec_to_scalar: 16464 return simd_costs->vec_to_scalar_cost; 16465 16466 case scalar_to_vec: 16467 return simd_costs->scalar_to_vec_cost; 16468 16469 case unaligned_load: 16470 case vector_gather_load: 16471 return simd_costs->unalign_load_cost; 16472 16473 case unaligned_store: 16474 case vector_scatter_store: 16475 return simd_costs->unalign_store_cost; 16476 16477 case cond_branch_taken: 16478 return costs->cond_taken_branch_cost; 16479 16480 case cond_branch_not_taken: 16481 return costs->cond_not_taken_branch_cost; 16482 16483 case vec_perm: 16484 return simd_costs->permute_cost; 16485 16486 case vec_promote_demote: 16487 return fp ? simd_costs->fp_stmt_cost 16488 : simd_costs->int_stmt_cost; 16489 16490 case vec_construct: 16491 elements = estimated_poly_value (TYPE_VECTOR_SUBPARTS (vectype)); 16492 return elements / 2 + 1; 16493 16494 default: 16495 gcc_unreachable (); 16496 } 16497 } 16498 16499 /* Return true if an access of kind KIND for STMT_INFO represents one 16500 vector of an LD[234] or ST[234] operation. Return the total number of 16501 vectors (2, 3 or 4) if so, otherwise return a value outside that range. */ 16502 static int 16503 aarch64_ld234_st234_vectors (vect_cost_for_stmt kind, stmt_vec_info stmt_info) 16504 { 16505 if ((kind == vector_load 16506 || kind == unaligned_load 16507 || kind == vector_store 16508 || kind == unaligned_store) 16509 && STMT_VINFO_DATA_REF (stmt_info)) 16510 { 16511 stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info); 16512 if (stmt_info 16513 && STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) == VMAT_LOAD_STORE_LANES) 16514 return DR_GROUP_SIZE (stmt_info); 16515 } 16516 return 0; 16517 } 16518 16519 /* Return true if creating multiple copies of STMT_INFO for Advanced SIMD 16520 vectors would produce a series of LDP or STP operations. KIND is the 16521 kind of statement that STMT_INFO represents. */ 16522 static bool 16523 aarch64_advsimd_ldp_stp_p (enum vect_cost_for_stmt kind, 16524 stmt_vec_info stmt_info) 16525 { 16526 switch (kind) 16527 { 16528 case vector_load: 16529 case vector_store: 16530 case unaligned_load: 16531 case unaligned_store: 16532 break; 16533 16534 default: 16535 return false; 16536 } 16537 16538 if (aarch64_tune_params.extra_tuning_flags 16539 & AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS) 16540 return false; 16541 16542 return is_gimple_assign (stmt_info->stmt); 16543 } 16544 16545 /* Return true if STMT_INFO is the second part of a two-statement multiply-add 16546 or multiply-subtract sequence that might be suitable for fusing into a 16547 single instruction. If VEC_FLAGS is zero, analyze the operation as 16548 a scalar one, otherwise analyze it as an operation on vectors with those 16549 VEC_* flags. */ 16550 static bool 16551 aarch64_multiply_add_p (vec_info *vinfo, stmt_vec_info stmt_info, 16552 unsigned int vec_flags) 16553 { 16554 gassign *assign = dyn_cast<gassign *> (stmt_info->stmt); 16555 if (!assign) 16556 return false; 16557 tree_code code = gimple_assign_rhs_code (assign); 16558 if (code != PLUS_EXPR && code != MINUS_EXPR) 16559 return false; 16560 16561 auto is_mul_result = [&](int i) 16562 { 16563 tree rhs = gimple_op (assign, i); 16564 /* ??? Should we try to check for a single use as well? */ 16565 if (TREE_CODE (rhs) != SSA_NAME) 16566 return false; 16567 16568 stmt_vec_info def_stmt_info = vinfo->lookup_def (rhs); 16569 if (!def_stmt_info 16570 || STMT_VINFO_DEF_TYPE (def_stmt_info) != vect_internal_def) 16571 return false; 16572 gassign *rhs_assign = dyn_cast<gassign *> (def_stmt_info->stmt); 16573 if (!rhs_assign || gimple_assign_rhs_code (rhs_assign) != MULT_EXPR) 16574 return false; 16575 16576 if (vec_flags & VEC_ADVSIMD) 16577 { 16578 /* Scalar and SVE code can tie the result to any FMLA input (or none, 16579 although that requires a MOVPRFX for SVE). However, Advanced SIMD 16580 only supports MLA forms, so will require a move if the result 16581 cannot be tied to the accumulator. The most important case in 16582 which this is true is when the accumulator input is invariant. */ 16583 rhs = gimple_op (assign, 3 - i); 16584 if (TREE_CODE (rhs) != SSA_NAME) 16585 return false; 16586 def_stmt_info = vinfo->lookup_def (rhs); 16587 if (!def_stmt_info 16588 || STMT_VINFO_DEF_TYPE (def_stmt_info) == vect_external_def 16589 || STMT_VINFO_DEF_TYPE (def_stmt_info) == vect_constant_def) 16590 return false; 16591 } 16592 16593 return true; 16594 }; 16595 16596 if (code == MINUS_EXPR && (vec_flags & VEC_ADVSIMD)) 16597 /* Advanced SIMD doesn't have FNMADD/FNMSUB/FNMLA/FNMLS, so the 16598 multiplication must be on the second operand (to form an FMLS). 16599 But if both operands are multiplications and the second operand 16600 is used more than once, we'll instead negate the second operand 16601 and use it as an accumulator for the first operand. */ 16602 return (is_mul_result (2) 16603 && (has_single_use (gimple_assign_rhs2 (assign)) 16604 || !is_mul_result (1))); 16605 16606 return is_mul_result (1) || is_mul_result (2); 16607 } 16608 16609 /* Return true if STMT_INFO is the second part of a two-statement boolean AND 16610 expression sequence that might be suitable for fusing into a 16611 single instruction. If VEC_FLAGS is zero, analyze the operation as 16612 a scalar one, otherwise analyze it as an operation on vectors with those 16613 VEC_* flags. */ 16614 16615 static bool 16616 aarch64_bool_compound_p (vec_info *vinfo, stmt_vec_info stmt_info, 16617 unsigned int vec_flags) 16618 { 16619 gassign *assign = dyn_cast<gassign *> (stmt_info->stmt); 16620 if (!assign 16621 || gimple_assign_rhs_code (assign) != BIT_AND_EXPR 16622 || !STMT_VINFO_VECTYPE (stmt_info) 16623 || !VECTOR_BOOLEAN_TYPE_P (STMT_VINFO_VECTYPE (stmt_info))) 16624 return false; 16625 16626 for (int i = 1; i < 3; ++i) 16627 { 16628 tree rhs = gimple_op (assign, i); 16629 16630 if (TREE_CODE (rhs) != SSA_NAME) 16631 continue; 16632 16633 stmt_vec_info def_stmt_info = vinfo->lookup_def (rhs); 16634 if (!def_stmt_info 16635 || STMT_VINFO_DEF_TYPE (def_stmt_info) != vect_internal_def) 16636 continue; 16637 16638 gassign *rhs_assign = dyn_cast<gassign *> (def_stmt_info->stmt); 16639 if (!rhs_assign 16640 || TREE_CODE_CLASS (gimple_assign_rhs_code (rhs_assign)) 16641 != tcc_comparison) 16642 continue; 16643 16644 if (vec_flags & VEC_ADVSIMD) 16645 return false; 16646 16647 return true; 16648 } 16649 return false; 16650 } 16651 16652 /* We are considering implementing STMT_INFO using SVE. If STMT_INFO is an 16653 in-loop reduction that SVE supports directly, return its latency in cycles, 16654 otherwise return zero. SVE_COSTS specifies the latencies of the relevant 16655 instructions. */ 16656 static unsigned int 16657 aarch64_sve_in_loop_reduction_latency (vec_info *vinfo, 16658 stmt_vec_info stmt_info, 16659 const sve_vec_cost *sve_costs) 16660 { 16661 switch (vect_reduc_type (vinfo, stmt_info)) 16662 { 16663 case EXTRACT_LAST_REDUCTION: 16664 return sve_costs->clast_cost; 16665 16666 case FOLD_LEFT_REDUCTION: 16667 switch (TYPE_MODE (TREE_TYPE (gimple_get_lhs (stmt_info->stmt)))) 16668 { 16669 case E_HFmode: 16670 case E_BFmode: 16671 return sve_costs->fadda_f16_cost; 16672 16673 case E_SFmode: 16674 return sve_costs->fadda_f32_cost; 16675 16676 case E_DFmode: 16677 return sve_costs->fadda_f64_cost; 16678 16679 default: 16680 break; 16681 } 16682 break; 16683 } 16684 16685 return 0; 16686 } 16687 16688 /* STMT_INFO describes a loop-carried operation in the original scalar code 16689 that we are considering implementing as a reduction. Return one of the 16690 following values, depending on VEC_FLAGS: 16691 16692 - If VEC_FLAGS is zero, return the loop carry latency of the original 16693 scalar operation. 16694 16695 - If VEC_FLAGS & VEC_ADVSIMD, return the loop carry latency of the 16696 Advanced SIMD implementation. 16697 16698 - If VEC_FLAGS & VEC_ANY_SVE, return the loop carry latency of the 16699 SVE implementation. */ 16700 static unsigned int 16701 aarch64_in_loop_reduction_latency (vec_info *vinfo, stmt_vec_info stmt_info, 16702 unsigned int vec_flags) 16703 { 16704 const cpu_vector_cost *vec_costs = aarch64_tune_params.vec_costs; 16705 const sve_vec_cost *sve_costs = nullptr; 16706 if (vec_flags & VEC_ANY_SVE) 16707 sve_costs = aarch64_tune_params.vec_costs->sve; 16708 16709 /* If the caller is asking for the SVE latency, check for forms of reduction 16710 that only SVE can handle directly. */ 16711 if (sve_costs) 16712 { 16713 unsigned int latency 16714 = aarch64_sve_in_loop_reduction_latency (vinfo, stmt_info, sve_costs); 16715 if (latency) 16716 return latency; 16717 } 16718 16719 /* Handle scalar costs. */ 16720 bool is_float = FLOAT_TYPE_P (TREE_TYPE (gimple_get_lhs (stmt_info->stmt))); 16721 if (vec_flags == 0) 16722 { 16723 if (is_float) 16724 return vec_costs->scalar_fp_stmt_cost; 16725 return vec_costs->scalar_int_stmt_cost; 16726 } 16727 16728 /* Otherwise, the loop body just contains normal integer or FP operations, 16729 with a vector reduction outside the loop. */ 16730 const simd_vec_cost *simd_costs 16731 = aarch64_simd_vec_costs_for_flags (vec_flags); 16732 if (is_float) 16733 return simd_costs->fp_stmt_cost; 16734 return simd_costs->int_stmt_cost; 16735 } 16736 16737 /* STMT_COST is the cost calculated by aarch64_builtin_vectorization_cost 16738 for STMT_INFO, which has cost kind KIND. If this is a scalar operation, 16739 try to subdivide the target-independent categorization provided by KIND 16740 to get a more accurate cost. */ 16741 static fractional_cost 16742 aarch64_detect_scalar_stmt_subtype (vec_info *vinfo, vect_cost_for_stmt kind, 16743 stmt_vec_info stmt_info, 16744 fractional_cost stmt_cost) 16745 { 16746 /* Detect an extension of a loaded value. In general, we'll be able to fuse 16747 the extension with the load. */ 16748 if (kind == scalar_stmt && vect_is_extending_load (vinfo, stmt_info)) 16749 return 0; 16750 16751 return stmt_cost; 16752 } 16753 16754 /* STMT_COST is the cost calculated by aarch64_builtin_vectorization_cost 16755 for the vectorized form of STMT_INFO, which has cost kind KIND and which 16756 when vectorized would operate on vector type VECTYPE. Try to subdivide 16757 the target-independent categorization provided by KIND to get a more 16758 accurate cost. WHERE specifies where the cost associated with KIND 16759 occurs. */ 16760 static fractional_cost 16761 aarch64_detect_vector_stmt_subtype (vec_info *vinfo, vect_cost_for_stmt kind, 16762 stmt_vec_info stmt_info, tree vectype, 16763 enum vect_cost_model_location where, 16764 fractional_cost stmt_cost) 16765 { 16766 const simd_vec_cost *simd_costs = aarch64_simd_vec_costs (vectype); 16767 const sve_vec_cost *sve_costs = nullptr; 16768 if (aarch64_sve_mode_p (TYPE_MODE (vectype))) 16769 sve_costs = aarch64_tune_params.vec_costs->sve; 16770 16771 /* It's generally better to avoid costing inductions, since the induction 16772 will usually be hidden by other operations. This is particularly true 16773 for things like COND_REDUCTIONS. */ 16774 if (is_a<gphi *> (stmt_info->stmt)) 16775 return 0; 16776 16777 /* Detect cases in which vec_to_scalar is describing the extraction of a 16778 vector element in preparation for a scalar store. The store itself is 16779 costed separately. */ 16780 if (vect_is_store_elt_extraction (kind, stmt_info)) 16781 return simd_costs->store_elt_extra_cost; 16782 16783 /* Detect SVE gather loads, which are costed as a single scalar_load 16784 for each element. We therefore need to divide the full-instruction 16785 cost by the number of elements in the vector. */ 16786 if (kind == scalar_load 16787 && sve_costs 16788 && STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) == VMAT_GATHER_SCATTER) 16789 { 16790 unsigned int nunits = vect_nunits_for_cost (vectype); 16791 if (GET_MODE_UNIT_BITSIZE (TYPE_MODE (vectype)) == 64) 16792 return { sve_costs->gather_load_x64_cost, nunits }; 16793 return { sve_costs->gather_load_x32_cost, nunits }; 16794 } 16795 16796 /* Detect cases in which a scalar_store is really storing one element 16797 in a scatter operation. */ 16798 if (kind == scalar_store 16799 && sve_costs 16800 && STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) == VMAT_GATHER_SCATTER) 16801 return sve_costs->scatter_store_elt_cost; 16802 16803 /* Detect cases in which vec_to_scalar represents an in-loop reduction. */ 16804 if (kind == vec_to_scalar 16805 && where == vect_body 16806 && sve_costs) 16807 { 16808 unsigned int latency 16809 = aarch64_sve_in_loop_reduction_latency (vinfo, stmt_info, sve_costs); 16810 if (latency) 16811 return latency; 16812 } 16813 16814 /* Detect cases in which vec_to_scalar represents a single reduction 16815 instruction like FADDP or MAXV. */ 16816 if (kind == vec_to_scalar 16817 && where == vect_epilogue 16818 && vect_is_reduction (stmt_info)) 16819 switch (GET_MODE_INNER (TYPE_MODE (vectype))) 16820 { 16821 case E_QImode: 16822 return simd_costs->reduc_i8_cost; 16823 16824 case E_HImode: 16825 return simd_costs->reduc_i16_cost; 16826 16827 case E_SImode: 16828 return simd_costs->reduc_i32_cost; 16829 16830 case E_DImode: 16831 return simd_costs->reduc_i64_cost; 16832 16833 case E_HFmode: 16834 case E_BFmode: 16835 return simd_costs->reduc_f16_cost; 16836 16837 case E_SFmode: 16838 return simd_costs->reduc_f32_cost; 16839 16840 case E_DFmode: 16841 return simd_costs->reduc_f64_cost; 16842 16843 default: 16844 break; 16845 } 16846 16847 /* Otherwise stick with the original categorization. */ 16848 return stmt_cost; 16849 } 16850 16851 /* STMT_COST is the cost calculated by aarch64_builtin_vectorization_cost 16852 for STMT_INFO, which has cost kind KIND and which when vectorized would 16853 operate on vector type VECTYPE. Adjust the cost as necessary for SVE 16854 targets. */ 16855 static fractional_cost 16856 aarch64_sve_adjust_stmt_cost (class vec_info *vinfo, vect_cost_for_stmt kind, 16857 stmt_vec_info stmt_info, tree vectype, 16858 fractional_cost stmt_cost) 16859 { 16860 /* Unlike vec_promote_demote, vector_stmt conversions do not change the 16861 vector register size or number of units. Integer promotions of this 16862 type therefore map to SXT[BHW] or UXT[BHW]. 16863 16864 Most loads have extending forms that can do the sign or zero extension 16865 on the fly. Optimistically assume that a load followed by an extension 16866 will fold to this form during combine, and that the extension therefore 16867 comes for free. */ 16868 if (kind == vector_stmt && vect_is_extending_load (vinfo, stmt_info)) 16869 stmt_cost = 0; 16870 16871 /* For similar reasons, vector_stmt integer truncations are a no-op, 16872 because we can just ignore the unused upper bits of the source. */ 16873 if (kind == vector_stmt && vect_is_integer_truncation (stmt_info)) 16874 stmt_cost = 0; 16875 16876 /* Advanced SIMD can load and store pairs of registers using LDP and STP, 16877 but there are no equivalent instructions for SVE. This means that 16878 (all other things being equal) 128-bit SVE needs twice as many load 16879 and store instructions as Advanced SIMD in order to process vector pairs. 16880 16881 Also, scalar code can often use LDP and STP to access pairs of values, 16882 so it is too simplistic to say that one SVE load or store replaces 16883 VF scalar loads and stores. 16884 16885 Ideally we would account for this in the scalar and Advanced SIMD 16886 costs by making suitable load/store pairs as cheap as a single 16887 load/store. However, that would be a very invasive change and in 16888 practice it tends to stress other parts of the cost model too much. 16889 E.g. stores of scalar constants currently count just a store, 16890 whereas stores of vector constants count a store and a vec_init. 16891 This is an artificial distinction for AArch64, where stores of 16892 nonzero scalar constants need the same kind of register invariant 16893 as vector stores. 16894 16895 An alternative would be to double the cost of any SVE loads and stores 16896 that could be paired in Advanced SIMD (and possibly also paired in 16897 scalar code). But this tends to stress other parts of the cost model 16898 in the same way. It also means that we can fall back to Advanced SIMD 16899 even if full-loop predication would have been useful. 16900 16901 Here we go for a more conservative version: double the costs of SVE 16902 loads and stores if one iteration of the scalar loop processes enough 16903 elements for it to use a whole number of Advanced SIMD LDP or STP 16904 instructions. This makes it very likely that the VF would be 1 for 16905 Advanced SIMD, and so no epilogue should be needed. */ 16906 if (STMT_VINFO_GROUPED_ACCESS (stmt_info)) 16907 { 16908 stmt_vec_info first = DR_GROUP_FIRST_ELEMENT (stmt_info); 16909 unsigned int count = DR_GROUP_SIZE (first) - DR_GROUP_GAP (first); 16910 unsigned int elt_bits = GET_MODE_UNIT_BITSIZE (TYPE_MODE (vectype)); 16911 if (multiple_p (count * elt_bits, 256) 16912 && aarch64_advsimd_ldp_stp_p (kind, stmt_info)) 16913 stmt_cost *= 2; 16914 } 16915 16916 return stmt_cost; 16917 } 16918 16919 /* STMT_COST is the cost calculated for STMT_INFO, which has cost kind KIND 16920 and which when vectorized would operate on vector type VECTYPE. Add the 16921 cost of any embedded operations. */ 16922 static fractional_cost 16923 aarch64_adjust_stmt_cost (vec_info *vinfo, vect_cost_for_stmt kind, 16924 stmt_vec_info stmt_info, tree vectype, 16925 unsigned vec_flags, fractional_cost stmt_cost) 16926 { 16927 if (vectype) 16928 { 16929 const simd_vec_cost *simd_costs = aarch64_simd_vec_costs (vectype); 16930 16931 /* Detect cases in which a vector load or store represents an 16932 LD[234] or ST[234] instruction. */ 16933 switch (aarch64_ld234_st234_vectors (kind, stmt_info)) 16934 { 16935 case 2: 16936 stmt_cost += simd_costs->ld2_st2_permute_cost; 16937 break; 16938 16939 case 3: 16940 stmt_cost += simd_costs->ld3_st3_permute_cost; 16941 break; 16942 16943 case 4: 16944 stmt_cost += simd_costs->ld4_st4_permute_cost; 16945 break; 16946 } 16947 16948 gassign *assign = dyn_cast<gassign *> (STMT_VINFO_STMT (stmt_info)); 16949 if ((kind == scalar_stmt || kind == vector_stmt) && assign) 16950 { 16951 /* For MLA we need to reduce the cost since MLA is 1 instruction. */ 16952 if (!vect_is_reduction (stmt_info) 16953 && aarch64_multiply_add_p (vinfo, stmt_info, vec_flags)) 16954 return 0; 16955 16956 /* For vector boolean ANDs with a compare operand we just need 16957 one insn. */ 16958 if (aarch64_bool_compound_p (vinfo, stmt_info, vec_flags)) 16959 return 0; 16960 } 16961 16962 if (kind == vector_stmt || kind == vec_to_scalar) 16963 if (tree cmp_type = vect_embedded_comparison_type (stmt_info)) 16964 { 16965 if (FLOAT_TYPE_P (cmp_type)) 16966 stmt_cost += simd_costs->fp_stmt_cost; 16967 else 16968 stmt_cost += simd_costs->int_stmt_cost; 16969 } 16970 } 16971 16972 if (kind == scalar_stmt) 16973 if (tree cmp_type = vect_embedded_comparison_type (stmt_info)) 16974 { 16975 if (FLOAT_TYPE_P (cmp_type)) 16976 stmt_cost += aarch64_tune_params.vec_costs->scalar_fp_stmt_cost; 16977 else 16978 stmt_cost += aarch64_tune_params.vec_costs->scalar_int_stmt_cost; 16979 } 16980 16981 return stmt_cost; 16982 } 16983 16984 /* Return true if STMT_INFO is part of a reduction that has the form: 16985 16986 r = r op ...; 16987 r = r op ...; 16988 16989 with the single accumulator being read and written multiple times. */ 16990 static bool 16991 aarch64_force_single_cycle (vec_info *vinfo, stmt_vec_info stmt_info) 16992 { 16993 if (!STMT_VINFO_REDUC_DEF (stmt_info)) 16994 return false; 16995 16996 auto reduc_info = info_for_reduction (vinfo, stmt_info); 16997 return STMT_VINFO_FORCE_SINGLE_CYCLE (reduc_info); 16998 } 16999 17000 /* COUNT, KIND and STMT_INFO are the same as for vector_costs::add_stmt_cost 17001 and they describe an operation in the body of a vector loop. Record issue 17002 information relating to the vector operation in OPS. */ 17003 void 17004 aarch64_vector_costs::count_ops (unsigned int count, vect_cost_for_stmt kind, 17005 stmt_vec_info stmt_info, 17006 aarch64_vec_op_count *ops) 17007 { 17008 const aarch64_base_vec_issue_info *base_issue = ops->base_issue_info (); 17009 if (!base_issue) 17010 return; 17011 const aarch64_simd_vec_issue_info *simd_issue = ops->simd_issue_info (); 17012 const aarch64_sve_vec_issue_info *sve_issue = ops->sve_issue_info (); 17013 17014 /* Calculate the minimum cycles per iteration imposed by a reduction 17015 operation. */ 17016 if ((kind == scalar_stmt || kind == vector_stmt || kind == vec_to_scalar) 17017 && vect_is_reduction (stmt_info)) 17018 { 17019 unsigned int base 17020 = aarch64_in_loop_reduction_latency (m_vinfo, stmt_info, m_vec_flags); 17021 if (aarch64_force_single_cycle (m_vinfo, stmt_info)) 17022 /* ??? Ideally we'd use a tree to reduce the copies down to 1 vector, 17023 and then accumulate that, but at the moment the loop-carried 17024 dependency includes all copies. */ 17025 ops->reduction_latency = MAX (ops->reduction_latency, base * count); 17026 else 17027 ops->reduction_latency = MAX (ops->reduction_latency, base); 17028 } 17029 17030 if (stmt_info && (kind == scalar_stmt || kind == vector_stmt)) 17031 { 17032 /* Assume that multiply-adds will become a single operation. */ 17033 if (aarch64_multiply_add_p (m_vinfo, stmt_info, m_vec_flags)) 17034 return; 17035 17036 /* Assume that bool AND with compare operands will become a single 17037 operation. */ 17038 if (aarch64_bool_compound_p (m_vinfo, stmt_info, m_vec_flags)) 17039 return; 17040 } 17041 17042 17043 /* Count the basic operation cost associated with KIND. */ 17044 switch (kind) 17045 { 17046 case cond_branch_taken: 17047 case cond_branch_not_taken: 17048 case vector_gather_load: 17049 case vector_scatter_store: 17050 /* We currently don't expect these to be used in a loop body. */ 17051 break; 17052 17053 case vec_perm: 17054 case vec_promote_demote: 17055 case vec_construct: 17056 case vec_to_scalar: 17057 case scalar_to_vec: 17058 case vector_stmt: 17059 case scalar_stmt: 17060 ops->general_ops += count; 17061 break; 17062 17063 case scalar_load: 17064 case vector_load: 17065 case unaligned_load: 17066 ops->loads += count; 17067 if (m_vec_flags || FLOAT_TYPE_P (aarch64_dr_type (stmt_info))) 17068 ops->general_ops += base_issue->fp_simd_load_general_ops * count; 17069 break; 17070 17071 case vector_store: 17072 case unaligned_store: 17073 case scalar_store: 17074 ops->stores += count; 17075 if (m_vec_flags || FLOAT_TYPE_P (aarch64_dr_type (stmt_info))) 17076 ops->general_ops += base_issue->fp_simd_store_general_ops * count; 17077 break; 17078 } 17079 17080 /* Add any embedded comparison operations. */ 17081 if ((kind == scalar_stmt || kind == vector_stmt || kind == vec_to_scalar) 17082 && vect_embedded_comparison_type (stmt_info)) 17083 ops->general_ops += count; 17084 17085 /* COND_REDUCTIONS need two sets of VEC_COND_EXPRs, whereas so far we 17086 have only accounted for one. */ 17087 if ((kind == vector_stmt || kind == vec_to_scalar) 17088 && vect_reduc_type (m_vinfo, stmt_info) == COND_REDUCTION) 17089 ops->general_ops += count; 17090 17091 /* Count the predicate operations needed by an SVE comparison. */ 17092 if (sve_issue && (kind == vector_stmt || kind == vec_to_scalar)) 17093 if (tree type = vect_comparison_type (stmt_info)) 17094 { 17095 unsigned int base = (FLOAT_TYPE_P (type) 17096 ? sve_issue->fp_cmp_pred_ops 17097 : sve_issue->int_cmp_pred_ops); 17098 ops->pred_ops += base * count; 17099 } 17100 17101 /* Add any extra overhead associated with LD[234] and ST[234] operations. */ 17102 if (simd_issue) 17103 switch (aarch64_ld234_st234_vectors (kind, stmt_info)) 17104 { 17105 case 2: 17106 ops->general_ops += simd_issue->ld2_st2_general_ops * count; 17107 break; 17108 17109 case 3: 17110 ops->general_ops += simd_issue->ld3_st3_general_ops * count; 17111 break; 17112 17113 case 4: 17114 ops->general_ops += simd_issue->ld4_st4_general_ops * count; 17115 break; 17116 } 17117 17118 /* Add any overhead associated with gather loads and scatter stores. */ 17119 if (sve_issue 17120 && (kind == scalar_load || kind == scalar_store) 17121 && STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) == VMAT_GATHER_SCATTER) 17122 { 17123 unsigned int pairs = CEIL (count, 2); 17124 ops->pred_ops += sve_issue->gather_scatter_pair_pred_ops * pairs; 17125 ops->general_ops += sve_issue->gather_scatter_pair_general_ops * pairs; 17126 } 17127 } 17128 17129 /* Return true if STMT_INFO contains a memory access and if the constant 17130 component of the memory address is aligned to SIZE bytes. */ 17131 static bool 17132 aarch64_aligned_constant_offset_p (stmt_vec_info stmt_info, 17133 poly_uint64 size) 17134 { 17135 if (!STMT_VINFO_DATA_REF (stmt_info)) 17136 return false; 17137 17138 if (auto first_stmt = DR_GROUP_FIRST_ELEMENT (stmt_info)) 17139 stmt_info = first_stmt; 17140 tree constant_offset = DR_INIT (STMT_VINFO_DATA_REF (stmt_info)); 17141 /* Needed for gathers & scatters, for example. */ 17142 if (!constant_offset) 17143 return false; 17144 17145 return multiple_p (wi::to_poly_offset (constant_offset), size); 17146 } 17147 17148 /* Check if a scalar or vector stmt could be part of a region of code 17149 that does nothing more than store values to memory, in the scalar 17150 case using STP. Return the cost of the stmt if so, counting 2 for 17151 one instruction. Return ~0U otherwise. 17152 17153 The arguments are a subset of those passed to add_stmt_cost. */ 17154 unsigned int 17155 aarch64_stp_sequence_cost (unsigned int count, vect_cost_for_stmt kind, 17156 stmt_vec_info stmt_info, tree vectype) 17157 { 17158 /* Code that stores vector constants uses a vector_load to create 17159 the constant. We don't apply the heuristic to that case for two 17160 main reasons: 17161 17162 - At the moment, STPs are only formed via peephole2, and the 17163 constant scalar moves would often come between STRs and so 17164 prevent STP formation. 17165 17166 - The scalar code also has to load the constant somehow, and that 17167 isn't costed. */ 17168 switch (kind) 17169 { 17170 case scalar_to_vec: 17171 /* Count 2 insns for a GPR->SIMD dup and 1 insn for a FPR->SIMD dup. */ 17172 return (FLOAT_TYPE_P (vectype) ? 2 : 4) * count; 17173 17174 case vec_construct: 17175 if (FLOAT_TYPE_P (vectype)) 17176 /* Count 1 insn for the maximum number of FP->SIMD INS 17177 instructions. */ 17178 return (vect_nunits_for_cost (vectype) - 1) * 2 * count; 17179 17180 /* Count 2 insns for a GPR->SIMD move and 2 insns for the 17181 maximum number of GPR->SIMD INS instructions. */ 17182 return vect_nunits_for_cost (vectype) * 4 * count; 17183 17184 case vector_store: 17185 case unaligned_store: 17186 /* Count 1 insn per vector if we can't form STP Q pairs. */ 17187 if (aarch64_sve_mode_p (TYPE_MODE (vectype))) 17188 return count * 2; 17189 if (aarch64_tune_params.extra_tuning_flags 17190 & AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS) 17191 return count * 2; 17192 17193 if (stmt_info) 17194 { 17195 /* Assume we won't be able to use STP if the constant offset 17196 component of the address is misaligned. ??? This could be 17197 removed if we formed STP pairs earlier, rather than relying 17198 on peephole2. */ 17199 auto size = GET_MODE_SIZE (TYPE_MODE (vectype)); 17200 if (!aarch64_aligned_constant_offset_p (stmt_info, size)) 17201 return count * 2; 17202 } 17203 return CEIL (count, 2) * 2; 17204 17205 case scalar_store: 17206 if (stmt_info && STMT_VINFO_DATA_REF (stmt_info)) 17207 { 17208 /* Check for a mode in which STP pairs can be formed. */ 17209 auto size = GET_MODE_SIZE (TYPE_MODE (aarch64_dr_type (stmt_info))); 17210 if (maybe_ne (size, 4) && maybe_ne (size, 8)) 17211 return ~0U; 17212 17213 /* Assume we won't be able to use STP if the constant offset 17214 component of the address is misaligned. ??? This could be 17215 removed if we formed STP pairs earlier, rather than relying 17216 on peephole2. */ 17217 if (!aarch64_aligned_constant_offset_p (stmt_info, size)) 17218 return ~0U; 17219 } 17220 return count; 17221 17222 default: 17223 return ~0U; 17224 } 17225 } 17226 17227 unsigned 17228 aarch64_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind, 17229 stmt_vec_info stmt_info, slp_tree, 17230 tree vectype, int misalign, 17231 vect_cost_model_location where) 17232 { 17233 fractional_cost stmt_cost 17234 = aarch64_builtin_vectorization_cost (kind, vectype, misalign); 17235 17236 bool in_inner_loop_p = (where == vect_body 17237 && stmt_info 17238 && stmt_in_inner_loop_p (m_vinfo, stmt_info)); 17239 17240 /* Do one-time initialization based on the vinfo. */ 17241 loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo); 17242 if (!m_analyzed_vinfo && aarch64_use_new_vector_costs_p ()) 17243 { 17244 if (loop_vinfo) 17245 analyze_loop_vinfo (loop_vinfo); 17246 17247 m_analyzed_vinfo = true; 17248 } 17249 17250 /* Apply the heuristic described above m_stp_sequence_cost. */ 17251 if (m_stp_sequence_cost != ~0U) 17252 { 17253 uint64_t cost = aarch64_stp_sequence_cost (count, kind, 17254 stmt_info, vectype); 17255 m_stp_sequence_cost = MIN (m_stp_sequence_cost + cost, ~0U); 17256 } 17257 17258 /* Try to get a more accurate cost by looking at STMT_INFO instead 17259 of just looking at KIND. */ 17260 if (stmt_info && aarch64_use_new_vector_costs_p ()) 17261 { 17262 /* If we scalarize a strided store, the vectorizer costs one 17263 vec_to_scalar for each element. However, we can store the first 17264 element using an FP store without a separate extract step. */ 17265 if (vect_is_store_elt_extraction (kind, stmt_info)) 17266 count -= 1; 17267 17268 stmt_cost = aarch64_detect_scalar_stmt_subtype (m_vinfo, kind, 17269 stmt_info, stmt_cost); 17270 17271 if (vectype && m_vec_flags) 17272 stmt_cost = aarch64_detect_vector_stmt_subtype (m_vinfo, kind, 17273 stmt_info, vectype, 17274 where, stmt_cost); 17275 } 17276 17277 /* Do any SVE-specific adjustments to the cost. */ 17278 if (stmt_info && vectype && aarch64_sve_mode_p (TYPE_MODE (vectype))) 17279 stmt_cost = aarch64_sve_adjust_stmt_cost (m_vinfo, kind, stmt_info, 17280 vectype, stmt_cost); 17281 17282 /* Vector promotion and demotion requires us to widen the operation first 17283 and only after that perform the conversion. Unfortunately the mid-end 17284 expects this to be doable as a single operation and doesn't pass on 17285 enough context here for us to tell which operation is happening. To 17286 account for this we count every promote-demote operation twice and if 17287 the previously costed operation was also a promote-demote we reduce 17288 the cost of the currently being costed operation to simulate the final 17289 conversion cost. Note that for SVE we can do better here if the converted 17290 value comes from a load since the widening load would consume the widening 17291 operations. However since we're in stage 3 we can't change the helper 17292 vect_is_extending_load and duplicating the code seems not useful. */ 17293 gassign *assign = NULL; 17294 if (kind == vec_promote_demote 17295 && (assign = dyn_cast <gassign *> (STMT_VINFO_STMT (stmt_info))) 17296 && gimple_assign_rhs_code (assign) == FLOAT_EXPR) 17297 { 17298 auto new_count = count * 2 - m_num_last_promote_demote; 17299 m_num_last_promote_demote = count; 17300 count = new_count; 17301 } 17302 else 17303 m_num_last_promote_demote = 0; 17304 17305 if (stmt_info && aarch64_use_new_vector_costs_p ()) 17306 { 17307 /* Account for any extra "embedded" costs that apply additively 17308 to the base cost calculated above. */ 17309 stmt_cost = aarch64_adjust_stmt_cost (m_vinfo, kind, stmt_info, 17310 vectype, m_vec_flags, stmt_cost); 17311 17312 /* If we're recording a nonzero vector loop body cost for the 17313 innermost loop, also estimate the operations that would need 17314 to be issued by all relevant implementations of the loop. */ 17315 if (loop_vinfo 17316 && (m_costing_for_scalar || where == vect_body) 17317 && (!LOOP_VINFO_LOOP (loop_vinfo)->inner || in_inner_loop_p) 17318 && stmt_cost != 0) 17319 for (auto &ops : m_ops) 17320 count_ops (count, kind, stmt_info, &ops); 17321 17322 /* If we're applying the SVE vs. Advanced SIMD unrolling heuristic, 17323 estimate the number of statements in the unrolled Advanced SIMD 17324 loop. For simplicitly, we assume that one iteration of the 17325 Advanced SIMD loop would need the same number of statements 17326 as one iteration of the SVE loop. */ 17327 if (where == vect_body && m_unrolled_advsimd_niters) 17328 m_unrolled_advsimd_stmts += count * m_unrolled_advsimd_niters; 17329 17330 /* Detect the use of an averaging operation. */ 17331 gimple *stmt = stmt_info->stmt; 17332 if (is_gimple_call (stmt) 17333 && gimple_call_internal_p (stmt)) 17334 { 17335 switch (gimple_call_internal_fn (stmt)) 17336 { 17337 case IFN_AVG_FLOOR: 17338 case IFN_AVG_CEIL: 17339 m_has_avg = true; 17340 default: 17341 break; 17342 } 17343 } 17344 } 17345 17346 /* If the statement stores to a decl that is known to be the argument 17347 to a vld1 in the same function, ignore the store for costing purposes. 17348 See the comment above m_stores_to_vector_load_decl for more details. */ 17349 if (stmt_info 17350 && (kind == vector_store || kind == unaligned_store) 17351 && aarch64_accesses_vector_load_decl_p (stmt_info)) 17352 { 17353 stmt_cost = 0; 17354 m_stores_to_vector_load_decl = true; 17355 } 17356 17357 return record_stmt_cost (stmt_info, where, (count * stmt_cost).ceil ()); 17358 } 17359 17360 /* Return true if (a) we're applying the Advanced SIMD vs. SVE unrolling 17361 heuristic described above m_unrolled_advsimd_niters and (b) the heuristic 17362 says that we should prefer the Advanced SIMD loop. */ 17363 bool 17364 aarch64_vector_costs::prefer_unrolled_loop () const 17365 { 17366 if (!m_unrolled_advsimd_stmts) 17367 return false; 17368 17369 if (dump_enabled_p ()) 17370 dump_printf_loc (MSG_NOTE, vect_location, "Number of insns in" 17371 " unrolled Advanced SIMD loop = " 17372 HOST_WIDE_INT_PRINT_UNSIGNED "\n", 17373 m_unrolled_advsimd_stmts); 17374 17375 /* The balance here is tricky. On the one hand, we can't be sure whether 17376 the code is vectorizable with Advanced SIMD or not. However, even if 17377 it isn't vectorizable with Advanced SIMD, there's a possibility that 17378 the scalar code could also be unrolled. Some of the code might then 17379 benefit from SLP, or from using LDP and STP. We therefore apply 17380 the heuristic regardless of can_use_advsimd_p. */ 17381 return (m_unrolled_advsimd_stmts 17382 && (m_unrolled_advsimd_stmts 17383 <= (unsigned int) param_max_completely_peeled_insns)); 17384 } 17385 17386 /* Subroutine of adjust_body_cost for handling SVE. Use ISSUE_INFO to work out 17387 how fast the SVE code can be issued and compare it to the equivalent value 17388 for scalar code (SCALAR_CYCLES_PER_ITER). If COULD_USE_ADVSIMD is true, 17389 also compare it to the issue rate of Advanced SIMD code 17390 (ADVSIMD_CYCLES_PER_ITER). 17391 17392 ORIG_BODY_COST is the cost originally passed to adjust_body_cost and 17393 *BODY_COST is the current value of the adjusted cost. *SHOULD_DISPARAGE 17394 is true if we think the loop body is too expensive. */ 17395 17396 fractional_cost 17397 aarch64_vector_costs:: 17398 adjust_body_cost_sve (const aarch64_vec_op_count *ops, 17399 fractional_cost scalar_cycles_per_iter, 17400 unsigned int orig_body_cost, unsigned int *body_cost, 17401 bool *should_disparage) 17402 { 17403 if (dump_enabled_p ()) 17404 ops->dump (); 17405 17406 fractional_cost sve_pred_cycles_per_iter = ops->min_pred_cycles_per_iter (); 17407 fractional_cost sve_cycles_per_iter = ops->min_cycles_per_iter (); 17408 17409 /* If the scalar version of the loop could issue at least as 17410 quickly as the predicate parts of the SVE loop, make the SVE loop 17411 prohibitively expensive. In this case vectorization is adding an 17412 overhead that the original scalar code didn't have. 17413 17414 This is mostly intended to detect cases in which WHILELOs dominate 17415 for very tight loops, which is something that normal latency-based 17416 costs would not model. Adding this kind of cliffedge would be 17417 too drastic for scalar_cycles_per_iter vs. sve_cycles_per_iter; 17418 code in the caller handles that case in a more conservative way. */ 17419 fractional_cost sve_estimate = sve_pred_cycles_per_iter + 1; 17420 if (scalar_cycles_per_iter < sve_estimate) 17421 { 17422 unsigned int min_cost 17423 = orig_body_cost * estimated_poly_value (BYTES_PER_SVE_VECTOR); 17424 if (*body_cost < min_cost) 17425 { 17426 if (dump_enabled_p ()) 17427 dump_printf_loc (MSG_NOTE, vect_location, 17428 "Increasing body cost to %d because the" 17429 " scalar code could issue within the limit" 17430 " imposed by predicate operations\n", 17431 min_cost); 17432 *body_cost = min_cost; 17433 *should_disparage = true; 17434 } 17435 } 17436 17437 return sve_cycles_per_iter; 17438 } 17439 17440 unsigned int 17441 aarch64_vector_costs::determine_suggested_unroll_factor () 17442 { 17443 bool sve = m_vec_flags & VEC_ANY_SVE; 17444 /* If we are trying to unroll an Advanced SIMD main loop that contains 17445 an averaging operation that we do not support with SVE and we might use a 17446 predicated epilogue, we need to be conservative and block unrolling as 17447 this might lead to a less optimal loop for the first and only epilogue 17448 using the original loop's vectorization factor. 17449 TODO: Remove this constraint when we add support for multiple epilogue 17450 vectorization. */ 17451 if (!sve && !TARGET_SVE2 && m_has_avg) 17452 return 1; 17453 17454 unsigned int max_unroll_factor = 1; 17455 for (auto vec_ops : m_ops) 17456 { 17457 aarch64_simd_vec_issue_info const *vec_issue 17458 = vec_ops.simd_issue_info (); 17459 if (!vec_issue) 17460 return 1; 17461 /* Limit unroll factor to a value adjustable by the user, the default 17462 value is 4. */ 17463 unsigned int unroll_factor = aarch64_vect_unroll_limit; 17464 unsigned int factor 17465 = vec_ops.reduction_latency > 1 ? vec_ops.reduction_latency : 1; 17466 unsigned int temp; 17467 17468 /* Sanity check, this should never happen. */ 17469 if ((vec_ops.stores + vec_ops.loads + vec_ops.general_ops) == 0) 17470 return 1; 17471 17472 /* Check stores. */ 17473 if (vec_ops.stores > 0) 17474 { 17475 temp = CEIL (factor * vec_issue->stores_per_cycle, 17476 vec_ops.stores); 17477 unroll_factor = MIN (unroll_factor, temp); 17478 } 17479 17480 /* Check loads + stores. */ 17481 if (vec_ops.loads > 0) 17482 { 17483 temp = CEIL (factor * vec_issue->loads_stores_per_cycle, 17484 vec_ops.loads + vec_ops.stores); 17485 unroll_factor = MIN (unroll_factor, temp); 17486 } 17487 17488 /* Check general ops. */ 17489 if (vec_ops.general_ops > 0) 17490 { 17491 temp = CEIL (factor * vec_issue->general_ops_per_cycle, 17492 vec_ops.general_ops); 17493 unroll_factor = MIN (unroll_factor, temp); 17494 } 17495 max_unroll_factor = MAX (max_unroll_factor, unroll_factor); 17496 } 17497 17498 /* Make sure unroll factor is power of 2. */ 17499 return 1 << ceil_log2 (max_unroll_factor); 17500 } 17501 17502 /* BODY_COST is the cost of a vector loop body. Adjust the cost as necessary 17503 and return the new cost. */ 17504 unsigned int 17505 aarch64_vector_costs:: 17506 adjust_body_cost (loop_vec_info loop_vinfo, 17507 const aarch64_vector_costs *scalar_costs, 17508 unsigned int body_cost) 17509 { 17510 if (scalar_costs->m_ops.is_empty () || m_ops.is_empty ()) 17511 return body_cost; 17512 17513 const auto &scalar_ops = scalar_costs->m_ops[0]; 17514 const auto &vector_ops = m_ops[0]; 17515 unsigned int estimated_vf = vect_vf_for_cost (loop_vinfo); 17516 unsigned int orig_body_cost = body_cost; 17517 bool should_disparage = false; 17518 17519 if (dump_enabled_p ()) 17520 dump_printf_loc (MSG_NOTE, vect_location, 17521 "Original vector body cost = %d\n", body_cost); 17522 17523 fractional_cost scalar_cycles_per_iter 17524 = scalar_ops.min_cycles_per_iter () * estimated_vf; 17525 17526 fractional_cost vector_cycles_per_iter = vector_ops.min_cycles_per_iter (); 17527 17528 if (dump_enabled_p ()) 17529 { 17530 if (IN_RANGE (m_num_vector_iterations, 0, 65536)) 17531 dump_printf_loc (MSG_NOTE, vect_location, 17532 "Vector loop iterates at most %wd times\n", 17533 m_num_vector_iterations); 17534 dump_printf_loc (MSG_NOTE, vect_location, "Scalar issue estimate:\n"); 17535 scalar_ops.dump (); 17536 dump_printf_loc (MSG_NOTE, vect_location, 17537 " estimated cycles per vector iteration" 17538 " (for VF %d) = %f\n", 17539 estimated_vf, scalar_cycles_per_iter.as_double ()); 17540 } 17541 17542 if (vector_ops.sve_issue_info ()) 17543 { 17544 if (dump_enabled_p ()) 17545 dump_printf_loc (MSG_NOTE, vect_location, "SVE issue estimate:\n"); 17546 vector_cycles_per_iter 17547 = adjust_body_cost_sve (&vector_ops, scalar_cycles_per_iter, 17548 orig_body_cost, &body_cost, &should_disparage); 17549 17550 if (aarch64_tune_params.vec_costs == &neoverse512tvb_vector_cost) 17551 { 17552 /* Also take Neoverse V1 tuning into account, doubling the 17553 scalar and Advanced SIMD estimates to account for the 17554 doubling in SVE vector length. */ 17555 if (dump_enabled_p ()) 17556 dump_printf_loc (MSG_NOTE, vect_location, 17557 "Neoverse V1 estimate:\n"); 17558 auto vf_factor = m_ops[1].vf_factor (); 17559 adjust_body_cost_sve (&m_ops[1], scalar_cycles_per_iter * vf_factor, 17560 orig_body_cost, &body_cost, &should_disparage); 17561 } 17562 } 17563 else 17564 { 17565 if (dump_enabled_p ()) 17566 { 17567 dump_printf_loc (MSG_NOTE, vect_location, 17568 "Vector issue estimate:\n"); 17569 vector_ops.dump (); 17570 } 17571 } 17572 17573 /* Decide whether to stick to latency-based costs or whether to try to 17574 take issue rates into account. */ 17575 unsigned int threshold = aarch64_loop_vect_issue_rate_niters; 17576 if (m_vec_flags & VEC_ANY_SVE) 17577 threshold = CEIL (threshold, aarch64_estimated_sve_vq ()); 17578 17579 if (m_num_vector_iterations >= 1 17580 && m_num_vector_iterations < threshold) 17581 { 17582 if (dump_enabled_p ()) 17583 dump_printf_loc (MSG_NOTE, vect_location, 17584 "Low iteration count, so using pure latency" 17585 " costs\n"); 17586 } 17587 /* Increase the cost of the vector code if it looks like the scalar code 17588 could issue more quickly. These values are only rough estimates, 17589 so minor differences should only result in minor changes. */ 17590 else if (scalar_cycles_per_iter < vector_cycles_per_iter) 17591 { 17592 body_cost = fractional_cost::scale (body_cost, vector_cycles_per_iter, 17593 scalar_cycles_per_iter); 17594 if (dump_enabled_p ()) 17595 dump_printf_loc (MSG_NOTE, vect_location, 17596 "Increasing body cost to %d because scalar code" 17597 " would issue more quickly\n", body_cost); 17598 } 17599 /* In general, it's expected that the proposed vector code would be able 17600 to issue more quickly than the original scalar code. This should 17601 already be reflected to some extent in the latency-based costs. 17602 17603 However, the latency-based costs effectively assume that the scalar 17604 code and the vector code execute serially, which tends to underplay 17605 one important case: if the real (non-serialized) execution time of 17606 a scalar iteration is dominated by loop-carried dependencies, 17607 and if the vector code is able to reduce both the length of 17608 the loop-carried dependencies *and* the number of cycles needed 17609 to issue the code in general, we can be more confident that the 17610 vector code is an improvement, even if adding the other (non-loop-carried) 17611 latencies tends to hide this saving. We therefore reduce the cost of the 17612 vector loop body in proportion to the saving. */ 17613 else if (scalar_ops.reduction_latency > vector_ops.reduction_latency 17614 && scalar_ops.reduction_latency == scalar_cycles_per_iter 17615 && scalar_cycles_per_iter > vector_cycles_per_iter 17616 && !should_disparage) 17617 { 17618 body_cost = fractional_cost::scale (body_cost, vector_cycles_per_iter, 17619 scalar_cycles_per_iter); 17620 if (dump_enabled_p ()) 17621 dump_printf_loc (MSG_NOTE, vect_location, 17622 "Decreasing body cost to %d account for smaller" 17623 " reduction latency\n", body_cost); 17624 } 17625 17626 return body_cost; 17627 } 17628 17629 void 17630 aarch64_vector_costs::finish_cost (const vector_costs *uncast_scalar_costs) 17631 { 17632 /* Record the issue information for any SVE WHILE instructions that the 17633 loop needs. */ 17634 loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo); 17635 if (!m_ops.is_empty () 17636 && loop_vinfo 17637 && LOOP_VINFO_FULLY_MASKED_P (loop_vinfo)) 17638 { 17639 unsigned int num_masks = 0; 17640 rgroup_controls *rgm; 17641 unsigned int num_vectors_m1; 17642 FOR_EACH_VEC_ELT (LOOP_VINFO_MASKS (loop_vinfo).rgc_vec, 17643 num_vectors_m1, rgm) 17644 if (rgm->type) 17645 num_masks += num_vectors_m1 + 1; 17646 for (auto &ops : m_ops) 17647 if (auto *issue = ops.sve_issue_info ()) 17648 ops.pred_ops += num_masks * issue->while_pred_ops; 17649 } 17650 17651 auto *scalar_costs 17652 = static_cast<const aarch64_vector_costs *> (uncast_scalar_costs); 17653 if (loop_vinfo 17654 && m_vec_flags 17655 && aarch64_use_new_vector_costs_p ()) 17656 { 17657 m_costs[vect_body] = adjust_body_cost (loop_vinfo, scalar_costs, 17658 m_costs[vect_body]); 17659 m_suggested_unroll_factor = determine_suggested_unroll_factor (); 17660 } 17661 17662 /* Apply the heuristic described above m_stp_sequence_cost. Prefer 17663 the scalar code in the event of a tie, since there is more chance 17664 of scalar code being optimized with surrounding operations. 17665 17666 In addition, if the vector body is a simple store to a decl that 17667 is elsewhere loaded using vld1, strongly prefer the vector form, 17668 to the extent of giving the prologue a zero cost. See the comment 17669 above m_stores_to_vector_load_decl for details. */ 17670 if (!loop_vinfo 17671 && scalar_costs 17672 && m_stp_sequence_cost != ~0U) 17673 { 17674 if (m_stores_to_vector_load_decl) 17675 m_costs[vect_prologue] = 0; 17676 else if (m_stp_sequence_cost >= scalar_costs->m_stp_sequence_cost) 17677 m_costs[vect_body] = 2 * scalar_costs->total_cost (); 17678 } 17679 17680 vector_costs::finish_cost (scalar_costs); 17681 } 17682 17683 bool 17684 aarch64_vector_costs:: 17685 better_main_loop_than_p (const vector_costs *uncast_other) const 17686 { 17687 auto other = static_cast<const aarch64_vector_costs *> (uncast_other); 17688 17689 auto this_loop_vinfo = as_a<loop_vec_info> (this->m_vinfo); 17690 auto other_loop_vinfo = as_a<loop_vec_info> (other->m_vinfo); 17691 17692 if (dump_enabled_p ()) 17693 dump_printf_loc (MSG_NOTE, vect_location, 17694 "Comparing two main loops (%s at VF %d vs %s at VF %d)\n", 17695 GET_MODE_NAME (this_loop_vinfo->vector_mode), 17696 vect_vf_for_cost (this_loop_vinfo), 17697 GET_MODE_NAME (other_loop_vinfo->vector_mode), 17698 vect_vf_for_cost (other_loop_vinfo)); 17699 17700 /* Apply the unrolling heuristic described above 17701 m_unrolled_advsimd_niters. */ 17702 if (bool (m_unrolled_advsimd_stmts) 17703 != bool (other->m_unrolled_advsimd_stmts)) 17704 { 17705 bool this_prefer_unrolled = this->prefer_unrolled_loop (); 17706 bool other_prefer_unrolled = other->prefer_unrolled_loop (); 17707 if (this_prefer_unrolled != other_prefer_unrolled) 17708 { 17709 if (dump_enabled_p ()) 17710 dump_printf_loc (MSG_NOTE, vect_location, 17711 "Preferring Advanced SIMD loop because" 17712 " it can be unrolled\n"); 17713 return other_prefer_unrolled; 17714 } 17715 } 17716 17717 for (unsigned int i = 0; i < m_ops.length (); ++i) 17718 { 17719 if (dump_enabled_p ()) 17720 { 17721 if (i) 17722 dump_printf_loc (MSG_NOTE, vect_location, 17723 "Reconsidering with subtuning %d\n", i); 17724 dump_printf_loc (MSG_NOTE, vect_location, 17725 "Issue info for %s loop:\n", 17726 GET_MODE_NAME (this_loop_vinfo->vector_mode)); 17727 this->m_ops[i].dump (); 17728 dump_printf_loc (MSG_NOTE, vect_location, 17729 "Issue info for %s loop:\n", 17730 GET_MODE_NAME (other_loop_vinfo->vector_mode)); 17731 other->m_ops[i].dump (); 17732 } 17733 17734 auto this_estimated_vf = (vect_vf_for_cost (this_loop_vinfo) 17735 * this->m_ops[i].vf_factor ()); 17736 auto other_estimated_vf = (vect_vf_for_cost (other_loop_vinfo) 17737 * other->m_ops[i].vf_factor ()); 17738 17739 /* If it appears that one loop could process the same amount of data 17740 in fewer cycles, prefer that loop over the other one. */ 17741 fractional_cost this_cost 17742 = this->m_ops[i].min_cycles_per_iter () * other_estimated_vf; 17743 fractional_cost other_cost 17744 = other->m_ops[i].min_cycles_per_iter () * this_estimated_vf; 17745 if (dump_enabled_p ()) 17746 { 17747 dump_printf_loc (MSG_NOTE, vect_location, 17748 "Weighted cycles per iteration of %s loop ~= %f\n", 17749 GET_MODE_NAME (this_loop_vinfo->vector_mode), 17750 this_cost.as_double ()); 17751 dump_printf_loc (MSG_NOTE, vect_location, 17752 "Weighted cycles per iteration of %s loop ~= %f\n", 17753 GET_MODE_NAME (other_loop_vinfo->vector_mode), 17754 other_cost.as_double ()); 17755 } 17756 if (this_cost != other_cost) 17757 { 17758 if (dump_enabled_p ()) 17759 dump_printf_loc (MSG_NOTE, vect_location, 17760 "Preferring loop with lower cycles" 17761 " per iteration\n"); 17762 return this_cost < other_cost; 17763 } 17764 17765 /* If the issue rate of SVE code is limited by predicate operations 17766 (i.e. if sve_pred_cycles_per_iter > sve_nonpred_cycles_per_iter), 17767 and if Advanced SIMD code could issue within the limit imposed 17768 by the predicate operations, the predicate operations are adding an 17769 overhead that the original code didn't have and so we should prefer 17770 the Advanced SIMD version. */ 17771 auto better_pred_limit_p = [](const aarch64_vec_op_count &a, 17772 const aarch64_vec_op_count &b) -> bool 17773 { 17774 if (a.pred_ops == 0 17775 && (b.min_pred_cycles_per_iter () 17776 > b.min_nonpred_cycles_per_iter ())) 17777 { 17778 if (dump_enabled_p ()) 17779 dump_printf_loc (MSG_NOTE, vect_location, 17780 "Preferring Advanced SIMD loop since" 17781 " SVE loop is predicate-limited\n"); 17782 return true; 17783 } 17784 return false; 17785 }; 17786 if (better_pred_limit_p (this->m_ops[i], other->m_ops[i])) 17787 return true; 17788 if (better_pred_limit_p (other->m_ops[i], this->m_ops[i])) 17789 return false; 17790 } 17791 17792 return vector_costs::better_main_loop_than_p (other); 17793 } 17794 17795 static void initialize_aarch64_code_model (struct gcc_options *); 17796 17797 /* Parse the TO_PARSE string and put the architecture struct that it 17798 selects into RES and the architectural features into ISA_FLAGS. 17799 Return an aarch_parse_opt_result describing the parse result. 17800 If there is an error parsing, RES and ISA_FLAGS are left unchanged. 17801 When the TO_PARSE string contains an invalid extension, 17802 a copy of the string is created and stored to INVALID_EXTENSION. */ 17803 17804 static enum aarch_parse_opt_result 17805 aarch64_parse_arch (const char *to_parse, const struct processor **res, 17806 aarch64_feature_flags *isa_flags, 17807 std::string *invalid_extension) 17808 { 17809 const char *ext; 17810 const struct processor *arch; 17811 size_t len; 17812 17813 ext = strchr (to_parse, '+'); 17814 17815 if (ext != NULL) 17816 len = ext - to_parse; 17817 else 17818 len = strlen (to_parse); 17819 17820 if (len == 0) 17821 return AARCH_PARSE_MISSING_ARG; 17822 17823 17824 /* Loop through the list of supported ARCHes to find a match. */ 17825 for (arch = all_architectures; arch->name != NULL; arch++) 17826 { 17827 if (strlen (arch->name) == len 17828 && strncmp (arch->name, to_parse, len) == 0) 17829 { 17830 auto isa_temp = arch->flags; 17831 17832 if (ext != NULL) 17833 { 17834 /* TO_PARSE string contains at least one extension. */ 17835 enum aarch_parse_opt_result ext_res 17836 = aarch64_parse_extension (ext, &isa_temp, invalid_extension); 17837 17838 if (ext_res != AARCH_PARSE_OK) 17839 return ext_res; 17840 } 17841 /* Extension parsing was successful. Confirm the result 17842 arch and ISA flags. */ 17843 *res = arch; 17844 *isa_flags = isa_temp; 17845 return AARCH_PARSE_OK; 17846 } 17847 } 17848 17849 /* ARCH name not found in list. */ 17850 return AARCH_PARSE_INVALID_ARG; 17851 } 17852 17853 /* Parse the TO_PARSE string and put the result tuning in RES and the 17854 architecture flags in ISA_FLAGS. Return an aarch_parse_opt_result 17855 describing the parse result. If there is an error parsing, RES and 17856 ISA_FLAGS are left unchanged. 17857 When the TO_PARSE string contains an invalid extension, 17858 a copy of the string is created and stored to INVALID_EXTENSION. */ 17859 17860 static enum aarch_parse_opt_result 17861 aarch64_parse_cpu (const char *to_parse, const struct processor **res, 17862 aarch64_feature_flags *isa_flags, 17863 std::string *invalid_extension) 17864 { 17865 const char *ext; 17866 const struct processor *cpu; 17867 size_t len; 17868 17869 ext = strchr (to_parse, '+'); 17870 17871 if (ext != NULL) 17872 len = ext - to_parse; 17873 else 17874 len = strlen (to_parse); 17875 17876 if (len == 0) 17877 return AARCH_PARSE_MISSING_ARG; 17878 17879 17880 /* Loop through the list of supported CPUs to find a match. */ 17881 for (cpu = all_cores; cpu->name != NULL; cpu++) 17882 { 17883 if (strlen (cpu->name) == len && strncmp (cpu->name, to_parse, len) == 0) 17884 { 17885 auto isa_temp = cpu->flags; 17886 17887 if (ext != NULL) 17888 { 17889 /* TO_PARSE string contains at least one extension. */ 17890 enum aarch_parse_opt_result ext_res 17891 = aarch64_parse_extension (ext, &isa_temp, invalid_extension); 17892 17893 if (ext_res != AARCH_PARSE_OK) 17894 return ext_res; 17895 } 17896 /* Extension parsing was successfull. Confirm the result 17897 cpu and ISA flags. */ 17898 *res = cpu; 17899 *isa_flags = isa_temp; 17900 return AARCH_PARSE_OK; 17901 } 17902 } 17903 17904 /* CPU name not found in list. */ 17905 return AARCH_PARSE_INVALID_ARG; 17906 } 17907 17908 /* Parse the TO_PARSE string and put the cpu it selects into RES. 17909 Return an aarch_parse_opt_result describing the parse result. 17910 If the parsing fails the RES does not change. */ 17911 17912 static enum aarch_parse_opt_result 17913 aarch64_parse_tune (const char *to_parse, const struct processor **res) 17914 { 17915 const struct processor *cpu; 17916 17917 /* Loop through the list of supported CPUs to find a match. */ 17918 for (cpu = all_cores; cpu->name != NULL; cpu++) 17919 { 17920 if (strcmp (cpu->name, to_parse) == 0) 17921 { 17922 *res = cpu; 17923 return AARCH_PARSE_OK; 17924 } 17925 } 17926 17927 /* CPU name not found in list. */ 17928 return AARCH_PARSE_INVALID_ARG; 17929 } 17930 17931 /* Parse TOKEN, which has length LENGTH to see if it is an option 17932 described in FLAG. If it is, return the index bit for that fusion type. 17933 If not, error (printing OPTION_NAME) and return zero. */ 17934 17935 static unsigned int 17936 aarch64_parse_one_option_token (const char *token, 17937 size_t length, 17938 const struct aarch64_flag_desc *flag, 17939 const char *option_name) 17940 { 17941 for (; flag->name != NULL; flag++) 17942 { 17943 if (length == strlen (flag->name) 17944 && !strncmp (flag->name, token, length)) 17945 return flag->flag; 17946 } 17947 17948 error ("unknown flag passed in %<-moverride=%s%> (%s)", option_name, token); 17949 return 0; 17950 } 17951 17952 /* Parse OPTION which is a comma-separated list of flags to enable. 17953 FLAGS gives the list of flags we understand, INITIAL_STATE gives any 17954 default state we inherit from the CPU tuning structures. OPTION_NAME 17955 gives the top-level option we are parsing in the -moverride string, 17956 for use in error messages. */ 17957 17958 static unsigned int 17959 aarch64_parse_boolean_options (const char *option, 17960 const struct aarch64_flag_desc *flags, 17961 unsigned int initial_state, 17962 const char *option_name) 17963 { 17964 const char separator = '.'; 17965 const char* specs = option; 17966 const char* ntoken = option; 17967 unsigned int found_flags = initial_state; 17968 17969 while ((ntoken = strchr (specs, separator))) 17970 { 17971 size_t token_length = ntoken - specs; 17972 unsigned token_ops = aarch64_parse_one_option_token (specs, 17973 token_length, 17974 flags, 17975 option_name); 17976 /* If we find "none" (or, for simplicity's sake, an error) anywhere 17977 in the token stream, reset the supported operations. So: 17978 17979 adrp+add.cmp+branch.none.adrp+add 17980 17981 would have the result of turning on only adrp+add fusion. */ 17982 if (!token_ops) 17983 found_flags = 0; 17984 17985 found_flags |= token_ops; 17986 specs = ++ntoken; 17987 } 17988 17989 /* We ended with a comma, print something. */ 17990 if (!(*specs)) 17991 { 17992 error ("%qs string ill-formed", option_name); 17993 return 0; 17994 } 17995 17996 /* We still have one more token to parse. */ 17997 size_t token_length = strlen (specs); 17998 unsigned token_ops = aarch64_parse_one_option_token (specs, 17999 token_length, 18000 flags, 18001 option_name); 18002 if (!token_ops) 18003 found_flags = 0; 18004 18005 found_flags |= token_ops; 18006 return found_flags; 18007 } 18008 18009 /* Support for overriding instruction fusion. */ 18010 18011 static void 18012 aarch64_parse_fuse_string (const char *fuse_string, 18013 struct tune_params *tune) 18014 { 18015 tune->fusible_ops = aarch64_parse_boolean_options (fuse_string, 18016 aarch64_fusible_pairs, 18017 tune->fusible_ops, 18018 "fuse="); 18019 } 18020 18021 /* Support for overriding other tuning flags. */ 18022 18023 static void 18024 aarch64_parse_tune_string (const char *tune_string, 18025 struct tune_params *tune) 18026 { 18027 tune->extra_tuning_flags 18028 = aarch64_parse_boolean_options (tune_string, 18029 aarch64_tuning_flags, 18030 tune->extra_tuning_flags, 18031 "tune="); 18032 } 18033 18034 /* Parse the sve_width tuning moverride string in TUNE_STRING. 18035 Accept the valid SVE vector widths allowed by 18036 aarch64_sve_vector_bits_enum and use it to override sve_width 18037 in TUNE. */ 18038 18039 static void 18040 aarch64_parse_sve_width_string (const char *tune_string, 18041 struct tune_params *tune) 18042 { 18043 int width = -1; 18044 18045 int n = sscanf (tune_string, "%d", &width); 18046 if (n == EOF) 18047 { 18048 error ("invalid format for %<sve_width%>"); 18049 return; 18050 } 18051 switch (width) 18052 { 18053 case SVE_128: 18054 case SVE_256: 18055 case SVE_512: 18056 case SVE_1024: 18057 case SVE_2048: 18058 break; 18059 default: 18060 error ("invalid %<sve_width%> value: %d", width); 18061 } 18062 tune->sve_width = (enum aarch64_sve_vector_bits_enum) width; 18063 } 18064 18065 /* Parse TOKEN, which has length LENGTH to see if it is a tuning option 18066 we understand. If it is, extract the option string and handoff to 18067 the appropriate function. */ 18068 18069 void 18070 aarch64_parse_one_override_token (const char* token, 18071 size_t length, 18072 struct tune_params *tune) 18073 { 18074 const struct aarch64_tuning_override_function *fn 18075 = aarch64_tuning_override_functions; 18076 18077 const char *option_part = strchr (token, '='); 18078 if (!option_part) 18079 { 18080 error ("tuning string missing in option (%s)", token); 18081 return; 18082 } 18083 18084 /* Get the length of the option name. */ 18085 length = option_part - token; 18086 /* Skip the '=' to get to the option string. */ 18087 option_part++; 18088 18089 for (; fn->name != NULL; fn++) 18090 { 18091 if (!strncmp (fn->name, token, length)) 18092 { 18093 fn->parse_override (option_part, tune); 18094 return; 18095 } 18096 } 18097 18098 error ("unknown tuning option (%s)",token); 18099 return; 18100 } 18101 18102 /* A checking mechanism for the implementation of the tls size. */ 18103 18104 static void 18105 initialize_aarch64_tls_size (struct gcc_options *opts) 18106 { 18107 if (aarch64_tls_size == 0) 18108 aarch64_tls_size = 24; 18109 18110 switch (opts->x_aarch64_cmodel_var) 18111 { 18112 case AARCH64_CMODEL_TINY: 18113 /* Both the default and maximum TLS size allowed under tiny is 1M which 18114 needs two instructions to address, so we clamp the size to 24. */ 18115 if (aarch64_tls_size > 24) 18116 aarch64_tls_size = 24; 18117 break; 18118 case AARCH64_CMODEL_SMALL: 18119 /* The maximum TLS size allowed under small is 4G. */ 18120 if (aarch64_tls_size > 32) 18121 aarch64_tls_size = 32; 18122 break; 18123 case AARCH64_CMODEL_LARGE: 18124 /* The maximum TLS size allowed under large is 16E. 18125 FIXME: 16E should be 64bit, we only support 48bit offset now. */ 18126 if (aarch64_tls_size > 48) 18127 aarch64_tls_size = 48; 18128 break; 18129 default: 18130 gcc_unreachable (); 18131 } 18132 18133 return; 18134 } 18135 18136 /* Return the CPU corresponding to the enum CPU. */ 18137 18138 static const struct processor * 18139 aarch64_get_tune_cpu (enum aarch64_processor cpu) 18140 { 18141 gcc_assert (cpu != aarch64_none); 18142 18143 return &all_cores[cpu]; 18144 } 18145 18146 /* Return the architecture corresponding to the enum ARCH. */ 18147 18148 static const struct processor * 18149 aarch64_get_arch (enum aarch64_arch arch) 18150 { 18151 gcc_assert (arch != aarch64_no_arch); 18152 18153 return &all_architectures[arch]; 18154 } 18155 18156 /* Parse STRING looking for options in the format: 18157 string :: option:string 18158 option :: name=substring 18159 name :: {a-z} 18160 substring :: defined by option. */ 18161 18162 static void 18163 aarch64_parse_override_string (const char* input_string, 18164 struct tune_params* tune) 18165 { 18166 const char separator = ':'; 18167 size_t string_length = strlen (input_string) + 1; 18168 char *string_root = (char *) xmalloc (sizeof (*string_root) * string_length); 18169 char *string = string_root; 18170 strncpy (string, input_string, string_length); 18171 string[string_length - 1] = '\0'; 18172 18173 char* ntoken = string; 18174 18175 while ((ntoken = strchr (string, separator))) 18176 { 18177 size_t token_length = ntoken - string; 18178 /* Make this substring look like a string. */ 18179 *ntoken = '\0'; 18180 aarch64_parse_one_override_token (string, token_length, tune); 18181 string = ++ntoken; 18182 } 18183 18184 /* One last option to parse. */ 18185 aarch64_parse_one_override_token (string, strlen (string), tune); 18186 free (string_root); 18187 } 18188 18189 /* Adjust CURRENT_TUNE (a generic tuning struct) with settings that 18190 are best for a generic target with the currently-enabled architecture 18191 extensions. */ 18192 static void 18193 aarch64_adjust_generic_arch_tuning (struct tune_params ¤t_tune) 18194 { 18195 /* Neoverse V1 is the only core that is known to benefit from 18196 AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS. There is therefore no 18197 point enabling it for SVE2 and above. */ 18198 if (TARGET_SVE2) 18199 current_tune.extra_tuning_flags 18200 &= ~AARCH64_EXTRA_TUNE_CSE_SVE_VL_CONSTANTS; 18201 } 18202 18203 static void 18204 aarch64_override_options_after_change_1 (struct gcc_options *opts) 18205 { 18206 /* PR 70044: We have to be careful about being called multiple times for the 18207 same function. This means all changes should be repeatable. */ 18208 18209 /* Set aarch64_use_frame_pointer based on -fno-omit-frame-pointer. 18210 Disable the frame pointer flag so the mid-end will not use a frame 18211 pointer in leaf functions in order to support -fomit-leaf-frame-pointer. 18212 Set x_flag_omit_frame_pointer to the special value 2 to differentiate 18213 between -fomit-frame-pointer (1) and -fno-omit-frame-pointer (2). */ 18214 aarch64_use_frame_pointer = opts->x_flag_omit_frame_pointer != 1; 18215 if (opts->x_flag_omit_frame_pointer == 0) 18216 opts->x_flag_omit_frame_pointer = 2; 18217 18218 /* If not optimizing for size, set the default 18219 alignment to what the target wants. */ 18220 if (!opts->x_optimize_size) 18221 { 18222 if (opts->x_flag_align_loops && !opts->x_str_align_loops) 18223 opts->x_str_align_loops = aarch64_tune_params.loop_align; 18224 if (opts->x_flag_align_jumps && !opts->x_str_align_jumps) 18225 opts->x_str_align_jumps = aarch64_tune_params.jump_align; 18226 if (opts->x_flag_align_functions && !opts->x_str_align_functions) 18227 opts->x_str_align_functions = aarch64_tune_params.function_align; 18228 } 18229 18230 /* We default to no pc-relative literal loads. */ 18231 18232 aarch64_pcrelative_literal_loads = false; 18233 18234 /* If -mpc-relative-literal-loads is set on the command line, this 18235 implies that the user asked for PC relative literal loads. */ 18236 if (opts->x_pcrelative_literal_loads == 1) 18237 aarch64_pcrelative_literal_loads = true; 18238 18239 /* In the tiny memory model it makes no sense to disallow PC relative 18240 literal pool loads. */ 18241 if (aarch64_cmodel == AARCH64_CMODEL_TINY 18242 || aarch64_cmodel == AARCH64_CMODEL_TINY_PIC) 18243 aarch64_pcrelative_literal_loads = true; 18244 18245 /* When enabling the lower precision Newton series for the square root, also 18246 enable it for the reciprocal square root, since the latter is an 18247 intermediary step for the former. */ 18248 if (flag_mlow_precision_sqrt) 18249 flag_mrecip_low_precision_sqrt = true; 18250 } 18251 18252 /* 'Unpack' up the internal tuning structs and update the options 18253 in OPTS. The caller must have set up selected_tune and selected_arch 18254 as all the other target-specific codegen decisions are 18255 derived from them. */ 18256 18257 void 18258 aarch64_override_options_internal (struct gcc_options *opts) 18259 { 18260 const struct processor *tune = aarch64_get_tune_cpu (opts->x_selected_tune); 18261 aarch64_tune_flags = tune->flags; 18262 aarch64_tune = tune->sched_core; 18263 /* Make a copy of the tuning parameters attached to the core, which 18264 we may later overwrite. */ 18265 aarch64_tune_params = *(tune->tune); 18266 if (tune->tune == &generic_tunings) 18267 aarch64_adjust_generic_arch_tuning (aarch64_tune_params); 18268 18269 if (opts->x_aarch64_override_tune_string) 18270 aarch64_parse_override_string (opts->x_aarch64_override_tune_string, 18271 &aarch64_tune_params); 18272 18273 if (opts->x_aarch64_ldp_policy_param) 18274 aarch64_tune_params.ldp_policy_model = opts->x_aarch64_ldp_policy_param; 18275 18276 if (opts->x_aarch64_stp_policy_param) 18277 aarch64_tune_params.stp_policy_model = opts->x_aarch64_stp_policy_param; 18278 18279 /* This target defaults to strict volatile bitfields. */ 18280 if (opts->x_flag_strict_volatile_bitfields < 0 && abi_version_at_least (2)) 18281 opts->x_flag_strict_volatile_bitfields = 1; 18282 18283 if (aarch64_stack_protector_guard == SSP_GLOBAL 18284 && opts->x_aarch64_stack_protector_guard_offset_str) 18285 { 18286 error ("incompatible options %<-mstack-protector-guard=global%> and " 18287 "%<-mstack-protector-guard-offset=%s%>", 18288 aarch64_stack_protector_guard_offset_str); 18289 } 18290 18291 if (aarch64_stack_protector_guard == SSP_SYSREG 18292 && !(opts->x_aarch64_stack_protector_guard_offset_str 18293 && opts->x_aarch64_stack_protector_guard_reg_str)) 18294 { 18295 error ("both %<-mstack-protector-guard-offset%> and " 18296 "%<-mstack-protector-guard-reg%> must be used " 18297 "with %<-mstack-protector-guard=sysreg%>"); 18298 } 18299 18300 if (opts->x_aarch64_stack_protector_guard_reg_str) 18301 { 18302 if (strlen (opts->x_aarch64_stack_protector_guard_reg_str) > 100) 18303 error ("specify a system register with a small string length"); 18304 } 18305 18306 if (opts->x_aarch64_stack_protector_guard_offset_str) 18307 { 18308 char *end; 18309 const char *str = aarch64_stack_protector_guard_offset_str; 18310 errno = 0; 18311 long offs = strtol (aarch64_stack_protector_guard_offset_str, &end, 0); 18312 if (!*str || *end || errno) 18313 error ("%qs is not a valid offset in %qs", str, 18314 "-mstack-protector-guard-offset="); 18315 aarch64_stack_protector_guard_offset = offs; 18316 } 18317 18318 if ((flag_sanitize & SANITIZE_SHADOW_CALL_STACK) 18319 && !fixed_regs[R18_REGNUM]) 18320 error ("%<-fsanitize=shadow-call-stack%> requires %<-ffixed-x18%>"); 18321 18322 if ((opts->x_aarch64_isa_flags & (AARCH64_FL_SM_ON | AARCH64_FL_ZA_ON)) 18323 && !(opts->x_aarch64_isa_flags & AARCH64_FL_SME)) 18324 { 18325 if (opts->x_aarch64_isa_flags & AARCH64_FL_SM_ON) 18326 error ("streaming functions require the ISA extension %qs", "sme"); 18327 else 18328 error ("functions with SME state require the ISA extension %qs", 18329 "sme"); 18330 inform (input_location, "you can enable %qs using the command-line" 18331 " option %<-march%>, or by using the %<target%>" 18332 " attribute or pragma", "sme"); 18333 opts->x_target_flags &= ~MASK_GENERAL_REGS_ONLY; 18334 auto new_flags = (opts->x_aarch64_asm_isa_flags 18335 | feature_deps::SME ().enable); 18336 aarch64_set_asm_isa_flags (opts, new_flags); 18337 } 18338 18339 initialize_aarch64_code_model (opts); 18340 initialize_aarch64_tls_size (opts); 18341 aarch64_tpidr_register = opts->x_aarch64_tpidr_reg; 18342 18343 int queue_depth = 0; 18344 switch (aarch64_tune_params.autoprefetcher_model) 18345 { 18346 case tune_params::AUTOPREFETCHER_OFF: 18347 queue_depth = -1; 18348 break; 18349 case tune_params::AUTOPREFETCHER_WEAK: 18350 queue_depth = 0; 18351 break; 18352 case tune_params::AUTOPREFETCHER_STRONG: 18353 queue_depth = max_insn_queue_index + 1; 18354 break; 18355 default: 18356 gcc_unreachable (); 18357 } 18358 18359 /* We don't mind passing in global_options_set here as we don't use 18360 the *options_set structs anyway. */ 18361 SET_OPTION_IF_UNSET (opts, &global_options_set, 18362 param_sched_autopref_queue_depth, queue_depth); 18363 18364 /* Set up parameters to be used in prefetching algorithm. Do not 18365 override the defaults unless we are tuning for a core we have 18366 researched values for. */ 18367 if (aarch64_tune_params.prefetch->num_slots > 0) 18368 SET_OPTION_IF_UNSET (opts, &global_options_set, 18369 param_simultaneous_prefetches, 18370 aarch64_tune_params.prefetch->num_slots); 18371 if (aarch64_tune_params.prefetch->l1_cache_size >= 0) 18372 SET_OPTION_IF_UNSET (opts, &global_options_set, 18373 param_l1_cache_size, 18374 aarch64_tune_params.prefetch->l1_cache_size); 18375 if (aarch64_tune_params.prefetch->l1_cache_line_size >= 0) 18376 SET_OPTION_IF_UNSET (opts, &global_options_set, 18377 param_l1_cache_line_size, 18378 aarch64_tune_params.prefetch->l1_cache_line_size); 18379 18380 if (aarch64_tune_params.prefetch->l1_cache_line_size >= 0) 18381 { 18382 SET_OPTION_IF_UNSET (opts, &global_options_set, 18383 param_destruct_interfere_size, 18384 aarch64_tune_params.prefetch->l1_cache_line_size); 18385 SET_OPTION_IF_UNSET (opts, &global_options_set, 18386 param_construct_interfere_size, 18387 aarch64_tune_params.prefetch->l1_cache_line_size); 18388 } 18389 else 18390 { 18391 /* For a generic AArch64 target, cover the current range of cache line 18392 sizes. */ 18393 SET_OPTION_IF_UNSET (opts, &global_options_set, 18394 param_destruct_interfere_size, 18395 256); 18396 SET_OPTION_IF_UNSET (opts, &global_options_set, 18397 param_construct_interfere_size, 18398 64); 18399 } 18400 18401 if (aarch64_tune_params.prefetch->l2_cache_size >= 0) 18402 SET_OPTION_IF_UNSET (opts, &global_options_set, 18403 param_l2_cache_size, 18404 aarch64_tune_params.prefetch->l2_cache_size); 18405 if (!aarch64_tune_params.prefetch->prefetch_dynamic_strides) 18406 SET_OPTION_IF_UNSET (opts, &global_options_set, 18407 param_prefetch_dynamic_strides, 0); 18408 if (aarch64_tune_params.prefetch->minimum_stride >= 0) 18409 SET_OPTION_IF_UNSET (opts, &global_options_set, 18410 param_prefetch_minimum_stride, 18411 aarch64_tune_params.prefetch->minimum_stride); 18412 18413 /* Use the alternative scheduling-pressure algorithm by default. */ 18414 SET_OPTION_IF_UNSET (opts, &global_options_set, 18415 param_sched_pressure_algorithm, 18416 SCHED_PRESSURE_MODEL); 18417 18418 /* Validate the guard size. */ 18419 int guard_size = param_stack_clash_protection_guard_size; 18420 18421 if (guard_size != 12 && guard_size != 16) 18422 error ("only values 12 (4 KB) and 16 (64 KB) are supported for guard " 18423 "size. Given value %d (%llu KB) is out of range", 18424 guard_size, (1ULL << guard_size) / 1024ULL); 18425 18426 /* Enforce that interval is the same size as size so the mid-end does the 18427 right thing. */ 18428 SET_OPTION_IF_UNSET (opts, &global_options_set, 18429 param_stack_clash_protection_probe_interval, 18430 guard_size); 18431 18432 /* The maybe_set calls won't update the value if the user has explicitly set 18433 one. Which means we need to validate that probing interval and guard size 18434 are equal. */ 18435 int probe_interval 18436 = param_stack_clash_protection_probe_interval; 18437 if (guard_size != probe_interval) 18438 error ("stack clash guard size %<%d%> must be equal to probing interval " 18439 "%<%d%>", guard_size, probe_interval); 18440 18441 /* Enable sw prefetching at specified optimization level for 18442 CPUS that have prefetch. Lower optimization level threshold by 1 18443 when profiling is enabled. */ 18444 if (opts->x_flag_prefetch_loop_arrays < 0 18445 && !opts->x_optimize_size 18446 && aarch64_tune_params.prefetch->default_opt_level >= 0 18447 && opts->x_optimize >= aarch64_tune_params.prefetch->default_opt_level) 18448 opts->x_flag_prefetch_loop_arrays = 1; 18449 18450 /* Avoid loop-dependant FMA chains. */ 18451 if (aarch64_tune_params.extra_tuning_flags 18452 & AARCH64_EXTRA_TUNE_AVOID_CROSS_LOOP_FMA) 18453 SET_OPTION_IF_UNSET (opts, &global_options_set, param_avoid_fma_max_bits, 18454 512); 18455 18456 /* Consider fully pipelined FMA in reassociation. */ 18457 if (aarch64_tune_params.extra_tuning_flags 18458 & AARCH64_EXTRA_TUNE_FULLY_PIPELINED_FMA) 18459 SET_OPTION_IF_UNSET (opts, &global_options_set, param_fully_pipelined_fma, 18460 1); 18461 18462 aarch64_override_options_after_change_1 (opts); 18463 } 18464 18465 /* Print a hint with a suggestion for a core or architecture name that 18466 most closely resembles what the user passed in STR. ARCH is true if 18467 the user is asking for an architecture name. ARCH is false if the user 18468 is asking for a core name. */ 18469 18470 static void 18471 aarch64_print_hint_for_core_or_arch (const char *str, bool arch) 18472 { 18473 auto_vec<const char *> candidates; 18474 const struct processor *entry = arch ? all_architectures : all_cores; 18475 for (; entry->name != NULL; entry++) 18476 candidates.safe_push (entry->name); 18477 18478 #ifdef HAVE_LOCAL_CPU_DETECT 18479 /* Add also "native" as possible value. */ 18480 if (arch) 18481 candidates.safe_push ("native"); 18482 #endif 18483 18484 char *s; 18485 const char *hint = candidates_list_and_hint (str, s, candidates); 18486 if (hint) 18487 inform (input_location, "valid arguments are: %s;" 18488 " did you mean %qs?", s, hint); 18489 else 18490 inform (input_location, "valid arguments are: %s", s); 18491 18492 XDELETEVEC (s); 18493 } 18494 18495 /* Print a hint with a suggestion for a core name that most closely resembles 18496 what the user passed in STR. */ 18497 18498 inline static void 18499 aarch64_print_hint_for_core (const char *str) 18500 { 18501 aarch64_print_hint_for_core_or_arch (str, false); 18502 } 18503 18504 /* Print a hint with a suggestion for an architecture name that most closely 18505 resembles what the user passed in STR. */ 18506 18507 inline static void 18508 aarch64_print_hint_for_arch (const char *str) 18509 { 18510 aarch64_print_hint_for_core_or_arch (str, true); 18511 } 18512 18513 18514 /* Print a hint with a suggestion for an extension name 18515 that most closely resembles what the user passed in STR. */ 18516 18517 void 18518 aarch64_print_hint_for_extensions (const std::string &str) 18519 { 18520 auto_vec<const char *> candidates; 18521 aarch64_get_all_extension_candidates (&candidates); 18522 char *s; 18523 const char *hint = candidates_list_and_hint (str.c_str (), s, candidates); 18524 if (hint) 18525 inform (input_location, "valid arguments are: %s;" 18526 " did you mean %qs?", s, hint); 18527 else 18528 inform (input_location, "valid arguments are: %s", s); 18529 18530 XDELETEVEC (s); 18531 } 18532 18533 /* Validate a command-line -mcpu option. Parse the cpu and extensions (if any) 18534 specified in STR and throw errors if appropriate. Put the results if 18535 they are valid in RES and ISA_FLAGS. Return whether the option is 18536 valid. */ 18537 18538 static bool 18539 aarch64_validate_mcpu (const char *str, const struct processor **res, 18540 aarch64_feature_flags *isa_flags) 18541 { 18542 std::string invalid_extension; 18543 enum aarch_parse_opt_result parse_res 18544 = aarch64_parse_cpu (str, res, isa_flags, &invalid_extension); 18545 18546 if (parse_res == AARCH_PARSE_OK) 18547 return true; 18548 18549 switch (parse_res) 18550 { 18551 case AARCH_PARSE_MISSING_ARG: 18552 error ("missing cpu name in %<-mcpu=%s%>", str); 18553 break; 18554 case AARCH_PARSE_INVALID_ARG: 18555 error ("unknown value %qs for %<-mcpu%>", str); 18556 aarch64_print_hint_for_core (str); 18557 /* A common user error is confusing -march and -mcpu. 18558 If the -mcpu string matches a known architecture then suggest 18559 -march=. */ 18560 parse_res = aarch64_parse_arch (str, res, isa_flags, &invalid_extension); 18561 if (parse_res == AARCH_PARSE_OK) 18562 inform (input_location, "did you mean %<-march=%s%>?", str); 18563 break; 18564 case AARCH_PARSE_INVALID_FEATURE: 18565 error ("invalid feature modifier %qs in %<-mcpu=%s%>", 18566 invalid_extension.c_str (), str); 18567 aarch64_print_hint_for_extensions (invalid_extension); 18568 break; 18569 default: 18570 gcc_unreachable (); 18571 } 18572 18573 return false; 18574 } 18575 18576 /* Straight line speculation indicators. */ 18577 enum aarch64_sls_hardening_type 18578 { 18579 SLS_NONE = 0, 18580 SLS_RETBR = 1, 18581 SLS_BLR = 2, 18582 SLS_ALL = 3, 18583 }; 18584 static enum aarch64_sls_hardening_type aarch64_sls_hardening; 18585 18586 /* Return whether we should mitigatate Straight Line Speculation for the RET 18587 and BR instructions. */ 18588 bool 18589 aarch64_harden_sls_retbr_p (void) 18590 { 18591 return aarch64_sls_hardening & SLS_RETBR; 18592 } 18593 18594 /* Return whether we should mitigatate Straight Line Speculation for the BLR 18595 instruction. */ 18596 bool 18597 aarch64_harden_sls_blr_p (void) 18598 { 18599 return aarch64_sls_hardening & SLS_BLR; 18600 } 18601 18602 /* As of yet we only allow setting these options globally, in the future we may 18603 allow setting them per function. */ 18604 static void 18605 aarch64_validate_sls_mitigation (const char *const_str) 18606 { 18607 char *token_save = NULL; 18608 char *str = NULL; 18609 18610 if (strcmp (const_str, "none") == 0) 18611 { 18612 aarch64_sls_hardening = SLS_NONE; 18613 return; 18614 } 18615 if (strcmp (const_str, "all") == 0) 18616 { 18617 aarch64_sls_hardening = SLS_ALL; 18618 return; 18619 } 18620 18621 char *str_root = xstrdup (const_str); 18622 str = strtok_r (str_root, ",", &token_save); 18623 if (!str) 18624 error ("invalid argument given to %<-mharden-sls=%>"); 18625 18626 int temp = SLS_NONE; 18627 while (str) 18628 { 18629 if (strcmp (str, "blr") == 0) 18630 temp |= SLS_BLR; 18631 else if (strcmp (str, "retbr") == 0) 18632 temp |= SLS_RETBR; 18633 else if (strcmp (str, "none") == 0 || strcmp (str, "all") == 0) 18634 { 18635 error ("%qs must be by itself for %<-mharden-sls=%>", str); 18636 break; 18637 } 18638 else 18639 { 18640 error ("invalid argument %<%s%> for %<-mharden-sls=%>", str); 18641 break; 18642 } 18643 str = strtok_r (NULL, ",", &token_save); 18644 } 18645 aarch64_sls_hardening = (aarch64_sls_hardening_type) temp; 18646 free (str_root); 18647 } 18648 18649 /* Validate a command-line -march option. Parse the arch and extensions 18650 (if any) specified in STR and throw errors if appropriate. Put the 18651 results, if they are valid, in RES and ISA_FLAGS. Return whether the 18652 option is valid. */ 18653 18654 static bool 18655 aarch64_validate_march (const char *str, const struct processor **res, 18656 aarch64_feature_flags *isa_flags) 18657 { 18658 std::string invalid_extension; 18659 enum aarch_parse_opt_result parse_res 18660 = aarch64_parse_arch (str, res, isa_flags, &invalid_extension); 18661 18662 if (parse_res == AARCH_PARSE_OK) 18663 return true; 18664 18665 switch (parse_res) 18666 { 18667 case AARCH_PARSE_MISSING_ARG: 18668 error ("missing arch name in %<-march=%s%>", str); 18669 break; 18670 case AARCH_PARSE_INVALID_ARG: 18671 error ("unknown value %qs for %<-march%>", str); 18672 aarch64_print_hint_for_arch (str); 18673 /* A common user error is confusing -march and -mcpu. 18674 If the -march string matches a known CPU suggest -mcpu. */ 18675 parse_res = aarch64_parse_cpu (str, res, isa_flags, &invalid_extension); 18676 if (parse_res == AARCH_PARSE_OK) 18677 inform (input_location, "did you mean %<-mcpu=%s%>?", str); 18678 break; 18679 case AARCH_PARSE_INVALID_FEATURE: 18680 error ("invalid feature modifier %qs in %<-march=%s%>", 18681 invalid_extension.c_str (), str); 18682 aarch64_print_hint_for_extensions (invalid_extension); 18683 break; 18684 default: 18685 gcc_unreachable (); 18686 } 18687 18688 return false; 18689 } 18690 18691 /* Validate a command-line -mtune option. Parse the cpu 18692 specified in STR and throw errors if appropriate. Put the 18693 result, if it is valid, in RES. Return whether the option is 18694 valid. */ 18695 18696 static bool 18697 aarch64_validate_mtune (const char *str, const struct processor **res) 18698 { 18699 enum aarch_parse_opt_result parse_res 18700 = aarch64_parse_tune (str, res); 18701 18702 if (parse_res == AARCH_PARSE_OK) 18703 return true; 18704 18705 switch (parse_res) 18706 { 18707 case AARCH_PARSE_MISSING_ARG: 18708 error ("missing cpu name in %<-mtune=%s%>", str); 18709 break; 18710 case AARCH_PARSE_INVALID_ARG: 18711 error ("unknown value %qs for %<-mtune%>", str); 18712 aarch64_print_hint_for_core (str); 18713 break; 18714 default: 18715 gcc_unreachable (); 18716 } 18717 return false; 18718 } 18719 18720 /* Return the VG value associated with -msve-vector-bits= value VALUE. */ 18721 18722 static poly_uint16 18723 aarch64_convert_sve_vector_bits (aarch64_sve_vector_bits_enum value) 18724 { 18725 /* 128-bit SVE and Advanced SIMD modes use different register layouts 18726 on big-endian targets, so we would need to forbid subregs that convert 18727 from one to the other. By default a reinterpret sequence would then 18728 involve a store to memory in one mode and a load back in the other. 18729 Even if we optimize that sequence using reverse instructions, 18730 it would still be a significant potential overhead. 18731 18732 For now, it seems better to generate length-agnostic code for that 18733 case instead. */ 18734 if (value == SVE_SCALABLE 18735 || (value == SVE_128 && BYTES_BIG_ENDIAN)) 18736 return poly_uint16 (2, 2); 18737 else 18738 return (int) value / 64; 18739 } 18740 18741 /* Set the global aarch64_asm_isa_flags to FLAGS and update 18742 aarch64_isa_flags accordingly. */ 18743 18744 void 18745 aarch64_set_asm_isa_flags (aarch64_feature_flags flags) 18746 { 18747 aarch64_set_asm_isa_flags (&global_options, flags); 18748 } 18749 18750 static void 18751 aarch64_handle_no_branch_protection (void) 18752 { 18753 aarch_ra_sign_scope = AARCH_FUNCTION_NONE; 18754 aarch_enable_bti = 0; 18755 } 18756 18757 static void 18758 aarch64_handle_standard_branch_protection (void) 18759 { 18760 aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF; 18761 aarch64_ra_sign_key = AARCH64_KEY_A; 18762 aarch_enable_bti = 1; 18763 } 18764 18765 static void 18766 aarch64_handle_pac_ret_protection (void) 18767 { 18768 aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF; 18769 aarch64_ra_sign_key = AARCH64_KEY_A; 18770 } 18771 18772 static void 18773 aarch64_handle_pac_ret_leaf (void) 18774 { 18775 aarch_ra_sign_scope = AARCH_FUNCTION_ALL; 18776 } 18777 18778 static void 18779 aarch64_handle_pac_ret_b_key (void) 18780 { 18781 aarch64_ra_sign_key = AARCH64_KEY_B; 18782 } 18783 18784 static void 18785 aarch64_handle_bti_protection (void) 18786 { 18787 aarch_enable_bti = 1; 18788 } 18789 18790 static const struct aarch_branch_protect_type aarch64_pac_ret_subtypes[] = { 18791 { "leaf", false, aarch64_handle_pac_ret_leaf, NULL, 0 }, 18792 { "b-key", false, aarch64_handle_pac_ret_b_key, NULL, 0 }, 18793 { NULL, false, NULL, NULL, 0 } 18794 }; 18795 18796 static const struct aarch_branch_protect_type aarch64_branch_protect_types[] = 18797 { 18798 { "none", true, aarch64_handle_no_branch_protection, NULL, 0 }, 18799 { "standard", true, aarch64_handle_standard_branch_protection, NULL, 0 }, 18800 { "pac-ret", false, aarch64_handle_pac_ret_protection, 18801 aarch64_pac_ret_subtypes, ARRAY_SIZE (aarch64_pac_ret_subtypes) }, 18802 { "bti", false, aarch64_handle_bti_protection, NULL, 0 }, 18803 { NULL, false, NULL, NULL, 0 } 18804 }; 18805 18806 /* Implement TARGET_OPTION_OVERRIDE. This is called once in the beginning 18807 and is used to parse the -m{cpu,tune,arch} strings and setup the initial 18808 tuning structs. In particular it must set selected_tune and 18809 aarch64_asm_isa_flags that define the available ISA features and tuning 18810 decisions. It must also set selected_arch as this will be used to 18811 output the .arch asm tags for each function. */ 18812 18813 static void 18814 aarch64_override_options (void) 18815 { 18816 aarch64_feature_flags cpu_isa = 0; 18817 aarch64_feature_flags arch_isa = 0; 18818 aarch64_set_asm_isa_flags (0); 18819 18820 const struct processor *cpu = NULL; 18821 const struct processor *arch = NULL; 18822 const struct processor *tune = NULL; 18823 18824 if (aarch64_harden_sls_string) 18825 aarch64_validate_sls_mitigation (aarch64_harden_sls_string); 18826 18827 if (aarch64_branch_protection_string) 18828 aarch_validate_mbranch_protection (aarch64_branch_protect_types, 18829 aarch64_branch_protection_string, 18830 "-mbranch-protection="); 18831 18832 /* -mcpu=CPU is shorthand for -march=ARCH_FOR_CPU, -mtune=CPU. 18833 If either of -march or -mtune is given, they override their 18834 respective component of -mcpu. */ 18835 if (aarch64_cpu_string) 18836 aarch64_validate_mcpu (aarch64_cpu_string, &cpu, &cpu_isa); 18837 18838 if (aarch64_arch_string) 18839 aarch64_validate_march (aarch64_arch_string, &arch, &arch_isa); 18840 18841 if (aarch64_tune_string) 18842 aarch64_validate_mtune (aarch64_tune_string, &tune); 18843 18844 #ifdef SUBTARGET_OVERRIDE_OPTIONS 18845 SUBTARGET_OVERRIDE_OPTIONS; 18846 #endif 18847 18848 auto isa_mode = AARCH64_FL_DEFAULT_ISA_MODE; 18849 if (cpu && arch) 18850 { 18851 /* If both -mcpu and -march are specified, warn if they are not 18852 feature compatible. feature compatible means that the inclusion of the 18853 cpu features would end up disabling an achitecture feature. In 18854 otherwords the cpu features need to be a strict superset of the arch 18855 features and if so prefer the -march ISA flags. */ 18856 auto full_arch_flags = arch->flags | arch_isa; 18857 auto full_cpu_flags = cpu->flags | cpu_isa; 18858 if (~full_cpu_flags & full_arch_flags) 18859 { 18860 std::string ext_diff 18861 = aarch64_get_extension_string_for_isa_flags (full_arch_flags, 18862 full_cpu_flags); 18863 warning (0, "switch %<-mcpu=%s%> conflicts with %<-march=%s%> switch " 18864 "and resulted in options %<%s%> being added", 18865 aarch64_cpu_string, 18866 aarch64_arch_string, 18867 ext_diff.c_str ()); 18868 } 18869 18870 selected_arch = arch->arch; 18871 aarch64_set_asm_isa_flags (arch_isa | isa_mode); 18872 } 18873 else if (cpu) 18874 { 18875 selected_arch = cpu->arch; 18876 aarch64_set_asm_isa_flags (cpu_isa | isa_mode); 18877 } 18878 else if (arch) 18879 { 18880 cpu = &all_cores[arch->ident]; 18881 selected_arch = arch->arch; 18882 aarch64_set_asm_isa_flags (arch_isa | isa_mode); 18883 } 18884 else 18885 { 18886 /* No -mcpu or -march specified, so use the default CPU. */ 18887 cpu = &all_cores[TARGET_CPU_DEFAULT]; 18888 selected_arch = cpu->arch; 18889 aarch64_set_asm_isa_flags (cpu->flags | isa_mode); 18890 } 18891 18892 selected_tune = tune ? tune->ident : cpu->ident; 18893 18894 if (aarch_enable_bti == 2) 18895 { 18896 #ifdef TARGET_ENABLE_BTI 18897 aarch_enable_bti = 1; 18898 #else 18899 aarch_enable_bti = 0; 18900 #endif 18901 } 18902 18903 /* Return address signing is currently not supported for ILP32 targets. For 18904 LP64 targets use the configured option in the absence of a command-line 18905 option for -mbranch-protection. */ 18906 if (!TARGET_ILP32 && aarch64_branch_protection_string == NULL) 18907 { 18908 #ifdef TARGET_ENABLE_PAC_RET 18909 aarch_ra_sign_scope = AARCH_FUNCTION_NON_LEAF; 18910 #else 18911 aarch_ra_sign_scope = AARCH_FUNCTION_NONE; 18912 #endif 18913 } 18914 18915 #ifndef HAVE_AS_MABI_OPTION 18916 /* The compiler may have been configured with 2.23.* binutils, which does 18917 not have support for ILP32. */ 18918 if (TARGET_ILP32) 18919 error ("assembler does not support %<-mabi=ilp32%>"); 18920 #endif 18921 18922 /* Convert -msve-vector-bits to a VG count. */ 18923 aarch64_sve_vg = aarch64_convert_sve_vector_bits (aarch64_sve_vector_bits); 18924 18925 if (aarch_ra_sign_scope != AARCH_FUNCTION_NONE && TARGET_ILP32) 18926 sorry ("return address signing is only supported for %<-mabi=lp64%>"); 18927 18928 /* The pass to insert speculation tracking runs before 18929 shrink-wrapping and the latter does not know how to update the 18930 tracking status. So disable it in this case. */ 18931 if (aarch64_track_speculation) 18932 flag_shrink_wrap = 0; 18933 18934 aarch64_override_options_internal (&global_options); 18935 18936 /* Save these options as the default ones in case we push and pop them later 18937 while processing functions with potential target attributes. */ 18938 target_option_default_node = target_option_current_node 18939 = build_target_option_node (&global_options, &global_options_set); 18940 } 18941 18942 /* Implement targetm.override_options_after_change. */ 18943 18944 static void 18945 aarch64_override_options_after_change (void) 18946 { 18947 aarch64_override_options_after_change_1 (&global_options); 18948 } 18949 18950 /* Implement the TARGET_OFFLOAD_OPTIONS hook. */ 18951 static char * 18952 aarch64_offload_options (void) 18953 { 18954 if (TARGET_ILP32) 18955 return xstrdup ("-foffload-abi=ilp32"); 18956 else 18957 return xstrdup ("-foffload-abi=lp64"); 18958 } 18959 18960 static struct machine_function * 18961 aarch64_init_machine_status (void) 18962 { 18963 struct machine_function *machine; 18964 machine = ggc_cleared_alloc<machine_function> (); 18965 return machine; 18966 } 18967 18968 void 18969 aarch64_init_expanders (void) 18970 { 18971 init_machine_status = aarch64_init_machine_status; 18972 } 18973 18974 /* A checking mechanism for the implementation of the various code models. */ 18975 static void 18976 initialize_aarch64_code_model (struct gcc_options *opts) 18977 { 18978 aarch64_cmodel = opts->x_aarch64_cmodel_var; 18979 switch (opts->x_aarch64_cmodel_var) 18980 { 18981 case AARCH64_CMODEL_TINY: 18982 if (opts->x_flag_pic) 18983 aarch64_cmodel = AARCH64_CMODEL_TINY_PIC; 18984 break; 18985 case AARCH64_CMODEL_SMALL: 18986 if (opts->x_flag_pic) 18987 { 18988 #ifdef HAVE_AS_SMALL_PIC_RELOCS 18989 aarch64_cmodel = (flag_pic == 2 18990 ? AARCH64_CMODEL_SMALL_PIC 18991 : AARCH64_CMODEL_SMALL_SPIC); 18992 #else 18993 aarch64_cmodel = AARCH64_CMODEL_SMALL_PIC; 18994 #endif 18995 } 18996 break; 18997 case AARCH64_CMODEL_LARGE: 18998 if (opts->x_flag_pic) 18999 sorry ("code model %qs with %<-f%s%>", "large", 19000 opts->x_flag_pic > 1 ? "PIC" : "pic"); 19001 if (opts->x_aarch64_abi == AARCH64_ABI_ILP32) 19002 sorry ("code model %qs not supported in ilp32 mode", "large"); 19003 break; 19004 case AARCH64_CMODEL_TINY_PIC: 19005 case AARCH64_CMODEL_SMALL_PIC: 19006 case AARCH64_CMODEL_SMALL_SPIC: 19007 gcc_unreachable (); 19008 } 19009 } 19010 19011 /* Implements TARGET_OPTION_RESTORE. Restore the backend codegen decisions 19012 using the information saved in PTR. */ 19013 19014 static void 19015 aarch64_option_restore (struct gcc_options *opts, 19016 struct gcc_options * /* opts_set */, 19017 struct cl_target_option * /* ptr */) 19018 { 19019 aarch64_override_options_internal (opts); 19020 } 19021 19022 /* Implement TARGET_OPTION_PRINT. */ 19023 19024 static void 19025 aarch64_option_print (FILE *file, int indent, struct cl_target_option *ptr) 19026 { 19027 const struct processor *cpu 19028 = aarch64_get_tune_cpu (ptr->x_selected_tune); 19029 const struct processor *arch = aarch64_get_arch (ptr->x_selected_arch); 19030 std::string extension 19031 = aarch64_get_extension_string_for_isa_flags (ptr->x_aarch64_asm_isa_flags, 19032 arch->flags); 19033 19034 fprintf (file, "%*sselected tune = %s\n", indent, "", cpu->name); 19035 fprintf (file, "%*sselected arch = %s%s\n", indent, "", 19036 arch->name, extension.c_str ()); 19037 } 19038 19039 static GTY(()) tree aarch64_previous_fndecl; 19040 19041 void 19042 aarch64_reset_previous_fndecl (void) 19043 { 19044 aarch64_previous_fndecl = NULL; 19045 } 19046 19047 /* Restore or save the TREE_TARGET_GLOBALS from or to NEW_TREE. 19048 Used by aarch64_set_current_function and aarch64_pragma_target_parse to 19049 make sure optab availability predicates are recomputed when necessary. */ 19050 19051 void 19052 aarch64_save_restore_target_globals (tree new_tree) 19053 { 19054 if (TREE_TARGET_GLOBALS (new_tree)) 19055 restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); 19056 else if (new_tree == target_option_default_node) 19057 restore_target_globals (&default_target_globals); 19058 else 19059 TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts (); 19060 } 19061 19062 /* Return the target_option_node for FNDECL, or the current options 19063 if FNDECL is null. */ 19064 19065 static tree 19066 aarch64_fndecl_options (tree fndecl) 19067 { 19068 if (!fndecl) 19069 return target_option_current_node; 19070 19071 if (tree options = DECL_FUNCTION_SPECIFIC_TARGET (fndecl)) 19072 return options; 19073 19074 return target_option_default_node; 19075 } 19076 19077 /* Implement TARGET_SET_CURRENT_FUNCTION. Unpack the codegen decisions 19078 like tuning and ISA features from the DECL_FUNCTION_SPECIFIC_TARGET 19079 of the function, if such exists. This function may be called multiple 19080 times on a single function so use aarch64_previous_fndecl to avoid 19081 setting up identical state. */ 19082 19083 static void 19084 aarch64_set_current_function (tree fndecl) 19085 { 19086 tree old_tree = aarch64_fndecl_options (aarch64_previous_fndecl); 19087 tree new_tree = aarch64_fndecl_options (fndecl); 19088 19089 auto new_isa_mode = (fndecl 19090 ? aarch64_fndecl_isa_mode (fndecl) 19091 : AARCH64_FL_DEFAULT_ISA_MODE); 19092 auto isa_flags = TREE_TARGET_OPTION (new_tree)->x_aarch64_isa_flags; 19093 19094 static bool reported_zt0_p; 19095 if (!reported_zt0_p 19096 && !(isa_flags & AARCH64_FL_SME2) 19097 && fndecl 19098 && aarch64_fndecl_has_state (fndecl, "zt0")) 19099 { 19100 error ("functions with %qs state require the ISA extension %qs", 19101 "zt0", "sme2"); 19102 inform (input_location, "you can enable %qs using the command-line" 19103 " option %<-march%>, or by using the %<target%>" 19104 " attribute or pragma", "sme2"); 19105 reported_zt0_p = true; 19106 } 19107 19108 /* If nothing to do, return. #pragma GCC reset or #pragma GCC pop to 19109 the default have been handled by aarch64_save_restore_target_globals from 19110 aarch64_pragma_target_parse. */ 19111 if (old_tree == new_tree 19112 && (!fndecl || aarch64_previous_fndecl) 19113 && (isa_flags & AARCH64_FL_ISA_MODES) == new_isa_mode) 19114 { 19115 gcc_assert (AARCH64_ISA_MODE == new_isa_mode); 19116 return; 19117 } 19118 19119 aarch64_previous_fndecl = fndecl; 19120 19121 /* First set the target options. */ 19122 cl_target_option_restore (&global_options, &global_options_set, 19123 TREE_TARGET_OPTION (new_tree)); 19124 19125 /* The ISA mode can vary based on function type attributes and 19126 function declaration attributes. Make sure that the target 19127 options correctly reflect these attributes. */ 19128 if ((isa_flags & AARCH64_FL_ISA_MODES) != new_isa_mode) 19129 { 19130 auto base_flags = (aarch64_asm_isa_flags & ~AARCH64_FL_ISA_MODES); 19131 aarch64_set_asm_isa_flags (base_flags | new_isa_mode); 19132 19133 aarch64_override_options_internal (&global_options); 19134 new_tree = build_target_option_node (&global_options, 19135 &global_options_set); 19136 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_tree; 19137 19138 tree new_optimize = build_optimization_node (&global_options, 19139 &global_options_set); 19140 if (new_optimize != optimization_default_node) 19141 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize; 19142 } 19143 19144 aarch64_save_restore_target_globals (new_tree); 19145 19146 gcc_assert (AARCH64_ISA_MODE == new_isa_mode); 19147 } 19148 19149 /* Enum describing the various ways we can handle attributes. 19150 In many cases we can reuse the generic option handling machinery. */ 19151 19152 enum aarch64_attr_opt_type 19153 { 19154 aarch64_attr_mask, /* Attribute should set a bit in target_flags. */ 19155 aarch64_attr_bool, /* Attribute sets or unsets a boolean variable. */ 19156 aarch64_attr_enum, /* Attribute sets an enum variable. */ 19157 aarch64_attr_custom /* Attribute requires a custom handling function. */ 19158 }; 19159 19160 /* All the information needed to handle a target attribute. 19161 NAME is the name of the attribute. 19162 ATTR_TYPE specifies the type of behavior of the attribute as described 19163 in the definition of enum aarch64_attr_opt_type. 19164 ALLOW_NEG is true if the attribute supports a "no-" form. 19165 HANDLER is the function that takes the attribute string as an argument 19166 It is needed only when the ATTR_TYPE is aarch64_attr_custom. 19167 OPT_NUM is the enum specifying the option that the attribute modifies. 19168 This is needed for attributes that mirror the behavior of a command-line 19169 option, that is it has ATTR_TYPE aarch64_attr_mask, aarch64_attr_bool or 19170 aarch64_attr_enum. */ 19171 19172 struct aarch64_attribute_info 19173 { 19174 const char *name; 19175 enum aarch64_attr_opt_type attr_type; 19176 bool allow_neg; 19177 bool (*handler) (const char *); 19178 enum opt_code opt_num; 19179 }; 19180 19181 /* Handle the ARCH_STR argument to the arch= target attribute. */ 19182 19183 static bool 19184 aarch64_handle_attr_arch (const char *str) 19185 { 19186 const struct processor *tmp_arch = NULL; 19187 std::string invalid_extension; 19188 aarch64_feature_flags tmp_flags; 19189 enum aarch_parse_opt_result parse_res 19190 = aarch64_parse_arch (str, &tmp_arch, &tmp_flags, &invalid_extension); 19191 19192 if (parse_res == AARCH_PARSE_OK) 19193 { 19194 gcc_assert (tmp_arch); 19195 selected_arch = tmp_arch->arch; 19196 aarch64_set_asm_isa_flags (tmp_flags | AARCH64_ISA_MODE); 19197 return true; 19198 } 19199 19200 switch (parse_res) 19201 { 19202 case AARCH_PARSE_MISSING_ARG: 19203 error ("missing name in %<target(\"arch=\")%> pragma or attribute"); 19204 break; 19205 case AARCH_PARSE_INVALID_ARG: 19206 error ("invalid name %qs in %<target(\"arch=\")%> pragma or attribute", str); 19207 aarch64_print_hint_for_arch (str); 19208 break; 19209 case AARCH_PARSE_INVALID_FEATURE: 19210 error ("invalid feature modifier %s of value %qs in " 19211 "%<target()%> pragma or attribute", invalid_extension.c_str (), str); 19212 aarch64_print_hint_for_extensions (invalid_extension); 19213 break; 19214 default: 19215 gcc_unreachable (); 19216 } 19217 19218 return false; 19219 } 19220 19221 /* Handle the argument CPU_STR to the cpu= target attribute. */ 19222 19223 static bool 19224 aarch64_handle_attr_cpu (const char *str) 19225 { 19226 const struct processor *tmp_cpu = NULL; 19227 std::string invalid_extension; 19228 aarch64_feature_flags tmp_flags; 19229 enum aarch_parse_opt_result parse_res 19230 = aarch64_parse_cpu (str, &tmp_cpu, &tmp_flags, &invalid_extension); 19231 19232 if (parse_res == AARCH_PARSE_OK) 19233 { 19234 gcc_assert (tmp_cpu); 19235 selected_tune = tmp_cpu->ident; 19236 selected_arch = tmp_cpu->arch; 19237 aarch64_set_asm_isa_flags (tmp_flags | AARCH64_ISA_MODE); 19238 return true; 19239 } 19240 19241 switch (parse_res) 19242 { 19243 case AARCH_PARSE_MISSING_ARG: 19244 error ("missing name in %<target(\"cpu=\")%> pragma or attribute"); 19245 break; 19246 case AARCH_PARSE_INVALID_ARG: 19247 error ("invalid name %qs in %<target(\"cpu=\")%> pragma or attribute", str); 19248 aarch64_print_hint_for_core (str); 19249 break; 19250 case AARCH_PARSE_INVALID_FEATURE: 19251 error ("invalid feature modifier %qs of value %qs in " 19252 "%<target()%> pragma or attribute", invalid_extension.c_str (), str); 19253 aarch64_print_hint_for_extensions (invalid_extension); 19254 break; 19255 default: 19256 gcc_unreachable (); 19257 } 19258 19259 return false; 19260 } 19261 19262 /* Handle the argument STR to the branch-protection= attribute. */ 19263 19264 static bool 19265 aarch64_handle_attr_branch_protection (const char* str) 19266 { 19267 return aarch_validate_mbranch_protection (aarch64_branch_protect_types, str, 19268 "target(\"branch-protection=\")"); 19269 } 19270 19271 /* Handle the argument STR to the tune= target attribute. */ 19272 19273 static bool 19274 aarch64_handle_attr_tune (const char *str) 19275 { 19276 const struct processor *tmp_tune = NULL; 19277 enum aarch_parse_opt_result parse_res 19278 = aarch64_parse_tune (str, &tmp_tune); 19279 19280 if (parse_res == AARCH_PARSE_OK) 19281 { 19282 gcc_assert (tmp_tune); 19283 selected_tune = tmp_tune->ident; 19284 return true; 19285 } 19286 19287 switch (parse_res) 19288 { 19289 case AARCH_PARSE_INVALID_ARG: 19290 error ("invalid name %qs in %<target(\"tune=\")%> pragma or attribute", str); 19291 aarch64_print_hint_for_core (str); 19292 break; 19293 default: 19294 gcc_unreachable (); 19295 } 19296 19297 return false; 19298 } 19299 19300 /* Parse an architecture extensions target attribute string specified in STR. 19301 For example "+fp+nosimd". Show any errors if needed. Return TRUE 19302 if successful. Update aarch64_isa_flags to reflect the ISA features 19303 modified. */ 19304 19305 static bool 19306 aarch64_handle_attr_isa_flags (char *str) 19307 { 19308 enum aarch_parse_opt_result parse_res; 19309 auto isa_flags = aarch64_asm_isa_flags; 19310 19311 /* We allow "+nothing" in the beginning to clear out all architectural 19312 features if the user wants to handpick specific features. */ 19313 if (strncmp ("+nothing", str, 8) == 0) 19314 { 19315 isa_flags = AARCH64_ISA_MODE; 19316 str += 8; 19317 } 19318 19319 std::string invalid_extension; 19320 parse_res = aarch64_parse_extension (str, &isa_flags, &invalid_extension); 19321 19322 if (parse_res == AARCH_PARSE_OK) 19323 { 19324 aarch64_set_asm_isa_flags (isa_flags); 19325 return true; 19326 } 19327 19328 switch (parse_res) 19329 { 19330 case AARCH_PARSE_MISSING_ARG: 19331 error ("missing value in %<target()%> pragma or attribute"); 19332 break; 19333 19334 case AARCH_PARSE_INVALID_FEATURE: 19335 error ("invalid feature modifier %qs of value %qs in " 19336 "%<target()%> pragma or attribute", invalid_extension.c_str (), str); 19337 break; 19338 19339 default: 19340 gcc_unreachable (); 19341 } 19342 19343 return false; 19344 } 19345 19346 /* The target attributes that we support. On top of these we also support just 19347 ISA extensions, like __attribute__ ((target ("+crc"))), but that case is 19348 handled explicitly in aarch64_process_one_target_attr. */ 19349 19350 static const struct aarch64_attribute_info aarch64_attributes[] = 19351 { 19352 { "general-regs-only", aarch64_attr_mask, false, NULL, 19353 OPT_mgeneral_regs_only }, 19354 { "fix-cortex-a53-835769", aarch64_attr_bool, true, NULL, 19355 OPT_mfix_cortex_a53_835769 }, 19356 { "fix-cortex-a53-843419", aarch64_attr_bool, true, NULL, 19357 OPT_mfix_cortex_a53_843419 }, 19358 { "cmodel", aarch64_attr_enum, false, NULL, OPT_mcmodel_ }, 19359 { "strict-align", aarch64_attr_mask, true, NULL, OPT_mstrict_align }, 19360 { "omit-leaf-frame-pointer", aarch64_attr_bool, true, NULL, 19361 OPT_momit_leaf_frame_pointer }, 19362 { "tls-dialect", aarch64_attr_enum, false, NULL, OPT_mtls_dialect_ }, 19363 { "arch", aarch64_attr_custom, false, aarch64_handle_attr_arch, 19364 OPT_march_ }, 19365 { "cpu", aarch64_attr_custom, false, aarch64_handle_attr_cpu, OPT_mcpu_ }, 19366 { "tune", aarch64_attr_custom, false, aarch64_handle_attr_tune, 19367 OPT_mtune_ }, 19368 { "branch-protection", aarch64_attr_custom, false, 19369 aarch64_handle_attr_branch_protection, OPT_mbranch_protection_ }, 19370 { "sign-return-address", aarch64_attr_enum, false, NULL, 19371 OPT_msign_return_address_ }, 19372 { "outline-atomics", aarch64_attr_bool, true, NULL, 19373 OPT_moutline_atomics}, 19374 { NULL, aarch64_attr_custom, false, NULL, OPT____ } 19375 }; 19376 19377 /* Parse ARG_STR which contains the definition of one target attribute. 19378 Show appropriate errors if any or return true if the attribute is valid. */ 19379 19380 static bool 19381 aarch64_process_one_target_attr (char *arg_str) 19382 { 19383 bool invert = false; 19384 19385 size_t len = strlen (arg_str); 19386 19387 if (len == 0) 19388 { 19389 error ("malformed %<target()%> pragma or attribute"); 19390 return false; 19391 } 19392 19393 char *str_to_check = (char *) alloca (len + 1); 19394 strcpy (str_to_check, arg_str); 19395 19396 /* We have something like __attribute__ ((target ("+fp+nosimd"))). 19397 It is easier to detect and handle it explicitly here rather than going 19398 through the machinery for the rest of the target attributes in this 19399 function. */ 19400 if (*str_to_check == '+') 19401 return aarch64_handle_attr_isa_flags (str_to_check); 19402 19403 if (len > 3 && startswith (str_to_check, "no-")) 19404 { 19405 invert = true; 19406 str_to_check += 3; 19407 } 19408 char *arg = strchr (str_to_check, '='); 19409 19410 /* If we found opt=foo then terminate STR_TO_CHECK at the '=' 19411 and point ARG to "foo". */ 19412 if (arg) 19413 { 19414 *arg = '\0'; 19415 arg++; 19416 } 19417 const struct aarch64_attribute_info *p_attr; 19418 bool found = false; 19419 for (p_attr = aarch64_attributes; p_attr->name; p_attr++) 19420 { 19421 /* If the names don't match up, or the user has given an argument 19422 to an attribute that doesn't accept one, or didn't give an argument 19423 to an attribute that expects one, fail to match. */ 19424 if (strcmp (str_to_check, p_attr->name) != 0) 19425 continue; 19426 19427 found = true; 19428 bool attr_need_arg_p = p_attr->attr_type == aarch64_attr_custom 19429 || p_attr->attr_type == aarch64_attr_enum; 19430 19431 if (attr_need_arg_p ^ (arg != NULL)) 19432 { 19433 error ("pragma or attribute %<target(\"%s\")%> does not accept an argument", str_to_check); 19434 return false; 19435 } 19436 19437 /* If the name matches but the attribute does not allow "no-" versions 19438 then we can't match. */ 19439 if (invert && !p_attr->allow_neg) 19440 { 19441 error ("pragma or attribute %<target(\"%s\")%> does not allow a negated form", str_to_check); 19442 return false; 19443 } 19444 19445 switch (p_attr->attr_type) 19446 { 19447 /* Has a custom handler registered. 19448 For example, cpu=, arch=, tune=. */ 19449 case aarch64_attr_custom: 19450 gcc_assert (p_attr->handler); 19451 if (!p_attr->handler (arg)) 19452 return false; 19453 break; 19454 19455 /* Either set or unset a boolean option. */ 19456 case aarch64_attr_bool: 19457 { 19458 struct cl_decoded_option decoded; 19459 19460 generate_option (p_attr->opt_num, NULL, !invert, 19461 CL_TARGET, &decoded); 19462 aarch64_handle_option (&global_options, &global_options_set, 19463 &decoded, input_location); 19464 break; 19465 } 19466 /* Set or unset a bit in the target_flags. aarch64_handle_option 19467 should know what mask to apply given the option number. */ 19468 case aarch64_attr_mask: 19469 { 19470 struct cl_decoded_option decoded; 19471 /* We only need to specify the option number. 19472 aarch64_handle_option will know which mask to apply. */ 19473 decoded.opt_index = p_attr->opt_num; 19474 decoded.value = !invert; 19475 aarch64_handle_option (&global_options, &global_options_set, 19476 &decoded, input_location); 19477 break; 19478 } 19479 /* Use the option setting machinery to set an option to an enum. */ 19480 case aarch64_attr_enum: 19481 { 19482 gcc_assert (arg); 19483 bool valid; 19484 int value; 19485 valid = opt_enum_arg_to_value (p_attr->opt_num, arg, 19486 &value, CL_TARGET); 19487 if (valid) 19488 { 19489 set_option (&global_options, NULL, p_attr->opt_num, value, 19490 NULL, DK_UNSPECIFIED, input_location, 19491 global_dc); 19492 } 19493 else 19494 { 19495 error ("pragma or attribute %<target(\"%s=%s\")%> is not valid", str_to_check, arg); 19496 } 19497 break; 19498 } 19499 default: 19500 gcc_unreachable (); 19501 } 19502 } 19503 19504 /* If we reached here we either have found an attribute and validated 19505 it or didn't match any. If we matched an attribute but its arguments 19506 were malformed we will have returned false already. */ 19507 return found; 19508 } 19509 19510 /* Count how many times the character C appears in 19511 NULL-terminated string STR. */ 19512 19513 static unsigned int 19514 num_occurences_in_str (char c, char *str) 19515 { 19516 unsigned int res = 0; 19517 while (*str != '\0') 19518 { 19519 if (*str == c) 19520 res++; 19521 19522 str++; 19523 } 19524 19525 return res; 19526 } 19527 19528 /* Parse the tree in ARGS that contains the target attribute information 19529 and update the global target options space. */ 19530 19531 bool 19532 aarch64_process_target_attr (tree args) 19533 { 19534 if (TREE_CODE (args) == TREE_LIST) 19535 { 19536 do 19537 { 19538 tree head = TREE_VALUE (args); 19539 if (head) 19540 { 19541 if (!aarch64_process_target_attr (head)) 19542 return false; 19543 } 19544 args = TREE_CHAIN (args); 19545 } while (args); 19546 19547 return true; 19548 } 19549 19550 if (TREE_CODE (args) != STRING_CST) 19551 { 19552 error ("attribute %<target%> argument not a string"); 19553 return false; 19554 } 19555 19556 size_t len = strlen (TREE_STRING_POINTER (args)); 19557 char *str_to_check = (char *) alloca (len + 1); 19558 strcpy (str_to_check, TREE_STRING_POINTER (args)); 19559 19560 if (len == 0) 19561 { 19562 error ("malformed %<target()%> pragma or attribute"); 19563 return false; 19564 } 19565 19566 /* Used to catch empty spaces between commas i.e. 19567 attribute ((target ("attr1,,attr2"))). */ 19568 unsigned int num_commas = num_occurences_in_str (',', str_to_check); 19569 19570 /* Handle multiple target attributes separated by ','. */ 19571 char *token = strtok_r (str_to_check, ",", &str_to_check); 19572 19573 unsigned int num_attrs = 0; 19574 while (token) 19575 { 19576 num_attrs++; 19577 if (!aarch64_process_one_target_attr (token)) 19578 { 19579 /* Check if token is possibly an arch extension without 19580 leading '+'. */ 19581 aarch64_feature_flags isa_temp = 0; 19582 auto with_plus = std::string ("+") + token; 19583 enum aarch_parse_opt_result ext_res 19584 = aarch64_parse_extension (with_plus.c_str (), &isa_temp, nullptr); 19585 19586 if (ext_res == AARCH_PARSE_OK) 19587 error ("arch extension %<%s%> should be prefixed by %<+%>", 19588 token); 19589 else 19590 error ("pragma or attribute %<target(\"%s\")%> is not valid", token); 19591 return false; 19592 } 19593 19594 token = strtok_r (NULL, ",", &str_to_check); 19595 } 19596 19597 if (num_attrs != num_commas + 1) 19598 { 19599 error ("malformed %<target(\"%s\")%> pragma or attribute", TREE_STRING_POINTER (args)); 19600 return false; 19601 } 19602 19603 return true; 19604 } 19605 19606 static bool aarch64_process_target_version_attr (tree args); 19607 19608 /* Implement TARGET_OPTION_VALID_ATTRIBUTE_P. This is used to 19609 process attribute ((target ("..."))). */ 19610 19611 static bool 19612 aarch64_option_valid_attribute_p (tree fndecl, tree, tree args, int) 19613 { 19614 struct cl_target_option cur_target; 19615 bool ret; 19616 tree old_optimize; 19617 tree new_target, new_optimize; 19618 tree existing_target = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); 19619 19620 /* If what we're processing is the current pragma string then the 19621 target option node is already stored in target_option_current_node 19622 by aarch64_pragma_target_parse in aarch64-c.cc. Use that to avoid 19623 having to re-parse the string. This is especially useful to keep 19624 arm_neon.h compile times down since that header contains a lot 19625 of intrinsics enclosed in pragmas. */ 19626 if (!existing_target && args == current_target_pragma) 19627 { 19628 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = target_option_current_node; 19629 return true; 19630 } 19631 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); 19632 19633 old_optimize 19634 = build_optimization_node (&global_options, &global_options_set); 19635 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); 19636 19637 /* If the function changed the optimization levels as well as setting 19638 target options, start with the optimizations specified. */ 19639 if (func_optimize && func_optimize != old_optimize) 19640 cl_optimization_restore (&global_options, &global_options_set, 19641 TREE_OPTIMIZATION (func_optimize)); 19642 19643 /* Save the current target options to restore at the end. */ 19644 cl_target_option_save (&cur_target, &global_options, &global_options_set); 19645 19646 /* If fndecl already has some target attributes applied to it, unpack 19647 them so that we add this attribute on top of them, rather than 19648 overwriting them. */ 19649 if (existing_target) 19650 { 19651 struct cl_target_option *existing_options 19652 = TREE_TARGET_OPTION (existing_target); 19653 19654 if (existing_options) 19655 cl_target_option_restore (&global_options, &global_options_set, 19656 existing_options); 19657 } 19658 else 19659 cl_target_option_restore (&global_options, &global_options_set, 19660 TREE_TARGET_OPTION (target_option_current_node)); 19661 19662 ret = aarch64_process_target_attr (args); 19663 if (ret) 19664 { 19665 tree version_attr = lookup_attribute ("target_version", 19666 DECL_ATTRIBUTES (fndecl)); 19667 if (version_attr != NULL_TREE) 19668 { 19669 /* Reapply any target_version attribute after target attribute. 19670 This should be equivalent to applying the target_version once 19671 after processing all target attributes. */ 19672 tree version_args = TREE_VALUE (version_attr); 19673 ret = aarch64_process_target_version_attr (version_args); 19674 } 19675 } 19676 19677 /* Set up any additional state. */ 19678 if (ret) 19679 { 19680 aarch64_override_options_internal (&global_options); 19681 new_target = build_target_option_node (&global_options, 19682 &global_options_set); 19683 } 19684 else 19685 new_target = NULL; 19686 19687 new_optimize = build_optimization_node (&global_options, 19688 &global_options_set); 19689 19690 if (fndecl && ret) 19691 { 19692 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target; 19693 19694 if (old_optimize != new_optimize) 19695 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize; 19696 } 19697 19698 cl_target_option_restore (&global_options, &global_options_set, &cur_target); 19699 19700 if (old_optimize != new_optimize) 19701 cl_optimization_restore (&global_options, &global_options_set, 19702 TREE_OPTIMIZATION (old_optimize)); 19703 return ret; 19704 } 19705 19706 typedef unsigned long long aarch64_fmv_feature_mask; 19707 19708 typedef struct 19709 { 19710 const char *name; 19711 aarch64_fmv_feature_mask feature_mask; 19712 aarch64_feature_flags opt_flags; 19713 } aarch64_fmv_feature_datum; 19714 19715 #define AARCH64_FMV_FEATURE(NAME, FEAT_NAME, C) \ 19716 {NAME, 1ULL << FEAT_##FEAT_NAME, ::feature_deps::fmv_deps_##FEAT_NAME}, 19717 19718 /* The "rdma" alias uses a different FEAT_NAME to avoid a duplicate 19719 feature_deps name. */ 19720 #define FEAT_RDMA FEAT_RDM 19721 19722 /* FMV features are listed in priority order, to make it easier to sort target 19723 strings. */ 19724 static aarch64_fmv_feature_datum aarch64_fmv_feature_data[] = { 19725 #include "config/aarch64/aarch64-option-extensions.def" 19726 }; 19727 19728 /* Parse a function multiversioning feature string STR, as found in a 19729 target_version or target_clones attribute. 19730 19731 If ISA_FLAGS is nonnull, then update it with the specified architecture 19732 features turned on. If FEATURE_MASK is nonnull, then assign to it a bitmask 19733 representing the set of features explicitly specified in the feature string. 19734 Return an aarch_parse_opt_result describing the result. 19735 19736 When the STR string contains an invalid or duplicate extension, a copy of 19737 the extension string is created and stored to INVALID_EXTENSION. */ 19738 19739 static enum aarch_parse_opt_result 19740 aarch64_parse_fmv_features (const char *str, aarch64_feature_flags *isa_flags, 19741 aarch64_fmv_feature_mask *feature_mask, 19742 std::string *invalid_extension) 19743 { 19744 if (feature_mask) 19745 *feature_mask = 0ULL; 19746 19747 if (strcmp (str, "default") == 0) 19748 return AARCH_PARSE_OK; 19749 19750 while (str != NULL && *str != 0) 19751 { 19752 const char *ext; 19753 size_t len; 19754 19755 ext = strchr (str, '+'); 19756 19757 if (ext != NULL) 19758 len = ext - str; 19759 else 19760 len = strlen (str); 19761 19762 if (len == 0) 19763 return AARCH_PARSE_MISSING_ARG; 19764 19765 int num_features = ARRAY_SIZE (aarch64_fmv_feature_data); 19766 int i; 19767 for (i = 0; i < num_features; i++) 19768 { 19769 if (strlen (aarch64_fmv_feature_data[i].name) == len 19770 && strncmp (aarch64_fmv_feature_data[i].name, str, len) == 0) 19771 { 19772 if (isa_flags) 19773 *isa_flags |= aarch64_fmv_feature_data[i].opt_flags; 19774 if (feature_mask) 19775 { 19776 auto old_feature_mask = *feature_mask; 19777 *feature_mask |= aarch64_fmv_feature_data[i].feature_mask; 19778 if (*feature_mask == old_feature_mask) 19779 { 19780 /* Duplicate feature. */ 19781 if (invalid_extension) 19782 *invalid_extension = std::string (str, len); 19783 return AARCH_PARSE_DUPLICATE_FEATURE; 19784 } 19785 } 19786 break; 19787 } 19788 } 19789 19790 if (i == num_features) 19791 { 19792 /* Feature not found in list. */ 19793 if (invalid_extension) 19794 *invalid_extension = std::string (str, len); 19795 return AARCH_PARSE_INVALID_FEATURE; 19796 } 19797 19798 str = ext; 19799 if (str) 19800 /* Skip over the next '+'. */ 19801 str++; 19802 } 19803 19804 return AARCH_PARSE_OK; 19805 } 19806 19807 /* Parse the tree in ARGS that contains the target_version attribute 19808 information and update the global target options space. */ 19809 19810 static bool 19811 aarch64_process_target_version_attr (tree args) 19812 { 19813 if (TREE_CODE (args) == TREE_LIST) 19814 { 19815 if (TREE_CHAIN (args)) 19816 { 19817 error ("attribute %<target_version%> has multiple values"); 19818 return false; 19819 } 19820 args = TREE_VALUE (args); 19821 } 19822 19823 if (!args || TREE_CODE (args) != STRING_CST) 19824 { 19825 error ("attribute %<target_version%> argument not a string"); 19826 return false; 19827 } 19828 19829 const char *str = TREE_STRING_POINTER (args); 19830 19831 enum aarch_parse_opt_result parse_res; 19832 auto isa_flags = aarch64_asm_isa_flags; 19833 19834 std::string invalid_extension; 19835 parse_res = aarch64_parse_fmv_features (str, &isa_flags, NULL, 19836 &invalid_extension); 19837 19838 if (parse_res == AARCH_PARSE_OK) 19839 { 19840 aarch64_set_asm_isa_flags (isa_flags); 19841 return true; 19842 } 19843 19844 switch (parse_res) 19845 { 19846 case AARCH_PARSE_MISSING_ARG: 19847 error ("missing value in %<target_version%> attribute"); 19848 break; 19849 19850 case AARCH_PARSE_INVALID_FEATURE: 19851 error ("invalid feature modifier %qs of value %qs in " 19852 "%<target_version%> attribute", invalid_extension.c_str (), 19853 str); 19854 break; 19855 19856 case AARCH_PARSE_DUPLICATE_FEATURE: 19857 error ("duplicate feature modifier %qs of value %qs in " 19858 "%<target_version%> attribute", invalid_extension.c_str (), 19859 str); 19860 break; 19861 19862 default: 19863 gcc_unreachable (); 19864 } 19865 19866 return false; 19867 } 19868 19869 /* Implement TARGET_OPTION_VALID_VERSION_ATTRIBUTE_P. This is used to 19870 process attribute ((target_version ("..."))). */ 19871 19872 static bool 19873 aarch64_option_valid_version_attribute_p (tree fndecl, tree, tree args, int) 19874 { 19875 struct cl_target_option cur_target; 19876 bool ret; 19877 tree new_target; 19878 tree existing_target = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); 19879 19880 /* Save the current target options to restore at the end. */ 19881 cl_target_option_save (&cur_target, &global_options, &global_options_set); 19882 19883 /* If fndecl already has some target attributes applied to it, unpack 19884 them so that we add this attribute on top of them, rather than 19885 overwriting them. */ 19886 if (existing_target) 19887 { 19888 struct cl_target_option *existing_options 19889 = TREE_TARGET_OPTION (existing_target); 19890 19891 if (existing_options) 19892 cl_target_option_restore (&global_options, &global_options_set, 19893 existing_options); 19894 } 19895 else 19896 cl_target_option_restore (&global_options, &global_options_set, 19897 TREE_TARGET_OPTION (target_option_current_node)); 19898 19899 ret = aarch64_process_target_version_attr (args); 19900 19901 /* Set up any additional state. */ 19902 if (ret) 19903 { 19904 aarch64_override_options_internal (&global_options); 19905 new_target = build_target_option_node (&global_options, 19906 &global_options_set); 19907 } 19908 else 19909 new_target = NULL; 19910 19911 if (fndecl && ret) 19912 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target; 19913 19914 cl_target_option_restore (&global_options, &global_options_set, &cur_target); 19915 19916 return ret; 19917 } 19918 19919 /* This parses the attribute arguments to target_version in DECL and the 19920 feature mask required to select those targets. No adjustments are made to 19921 add or remove redundant feature requirements. */ 19922 19923 static aarch64_fmv_feature_mask 19924 get_feature_mask_for_version (tree decl) 19925 { 19926 tree version_attr = lookup_attribute ("target_version", 19927 DECL_ATTRIBUTES (decl)); 19928 if (version_attr == NULL) 19929 return 0; 19930 19931 const char *version_string = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE 19932 (version_attr))); 19933 enum aarch_parse_opt_result parse_res; 19934 aarch64_fmv_feature_mask feature_mask; 19935 19936 parse_res = aarch64_parse_fmv_features (version_string, NULL, &feature_mask, 19937 NULL); 19938 19939 /* We should have detected any errors before getting here. */ 19940 gcc_assert (parse_res == AARCH_PARSE_OK); 19941 19942 return feature_mask; 19943 } 19944 19945 /* Compare priorities of two feature masks. Return: 19946 1: mask1 is higher priority 19947 -1: mask2 is higher priority 19948 0: masks are equal. */ 19949 19950 static int 19951 compare_feature_masks (aarch64_fmv_feature_mask mask1, 19952 aarch64_fmv_feature_mask mask2) 19953 { 19954 int pop1 = popcount_hwi (mask1); 19955 int pop2 = popcount_hwi (mask2); 19956 if (pop1 > pop2) 19957 return 1; 19958 if (pop2 > pop1) 19959 return -1; 19960 19961 auto diff_mask = mask1 ^ mask2; 19962 if (diff_mask == 0ULL) 19963 return 0; 19964 int num_features = ARRAY_SIZE (aarch64_fmv_feature_data); 19965 for (int i = num_features - 1; i >= 0; i--) 19966 { 19967 auto bit_mask = aarch64_fmv_feature_data[i].feature_mask; 19968 if (diff_mask & bit_mask) 19969 return (mask1 & bit_mask) ? 1 : -1; 19970 } 19971 gcc_unreachable(); 19972 } 19973 19974 /* Compare priorities of two version decls. */ 19975 19976 int 19977 aarch64_compare_version_priority (tree decl1, tree decl2) 19978 { 19979 auto mask1 = get_feature_mask_for_version (decl1); 19980 auto mask2 = get_feature_mask_for_version (decl2); 19981 19982 return compare_feature_masks (mask1, mask2); 19983 } 19984 19985 /* Build the struct __ifunc_arg_t type: 19986 19987 struct __ifunc_arg_t 19988 { 19989 unsigned long _size; // Size of the struct, so it can grow. 19990 unsigned long _hwcap; 19991 unsigned long _hwcap2; 19992 } 19993 */ 19994 19995 static tree 19996 build_ifunc_arg_type () 19997 { 19998 tree ifunc_arg_type = lang_hooks.types.make_type (RECORD_TYPE); 19999 tree field1 = build_decl (UNKNOWN_LOCATION, FIELD_DECL, 20000 get_identifier ("_size"), 20001 long_unsigned_type_node); 20002 tree field2 = build_decl (UNKNOWN_LOCATION, FIELD_DECL, 20003 get_identifier ("_hwcap"), 20004 long_unsigned_type_node); 20005 tree field3 = build_decl (UNKNOWN_LOCATION, FIELD_DECL, 20006 get_identifier ("_hwcap2"), 20007 long_unsigned_type_node); 20008 20009 DECL_FIELD_CONTEXT (field1) = ifunc_arg_type; 20010 DECL_FIELD_CONTEXT (field2) = ifunc_arg_type; 20011 DECL_FIELD_CONTEXT (field3) = ifunc_arg_type; 20012 20013 TYPE_FIELDS (ifunc_arg_type) = field1; 20014 DECL_CHAIN (field1) = field2; 20015 DECL_CHAIN (field2) = field3; 20016 20017 layout_type (ifunc_arg_type); 20018 20019 tree const_type = build_qualified_type (ifunc_arg_type, TYPE_QUAL_CONST); 20020 tree pointer_type = build_pointer_type (const_type); 20021 20022 return pointer_type; 20023 } 20024 20025 /* Implement TARGET_MANGLE_DECL_ASSEMBLER_NAME, to add function multiversioning 20026 suffixes. */ 20027 20028 tree 20029 aarch64_mangle_decl_assembler_name (tree decl, tree id) 20030 { 20031 /* For function version, add the target suffix to the assembler name. */ 20032 if (TREE_CODE (decl) == FUNCTION_DECL 20033 && DECL_FUNCTION_VERSIONED (decl)) 20034 { 20035 aarch64_fmv_feature_mask feature_mask = get_feature_mask_for_version (decl); 20036 20037 std::string name = IDENTIFIER_POINTER (id); 20038 20039 /* For the default version, append ".default". */ 20040 if (feature_mask == 0ULL) 20041 { 20042 name += ".default"; 20043 return get_identifier (name.c_str()); 20044 } 20045 20046 name += "._"; 20047 20048 int num_features = ARRAY_SIZE (aarch64_fmv_feature_data); 20049 for (int i = 0; i < num_features; i++) 20050 { 20051 if (feature_mask & aarch64_fmv_feature_data[i].feature_mask) 20052 { 20053 name += "M"; 20054 name += aarch64_fmv_feature_data[i].name; 20055 } 20056 } 20057 20058 if (DECL_ASSEMBLER_NAME_SET_P (decl)) 20059 SET_DECL_RTL (decl, NULL); 20060 20061 id = get_identifier (name.c_str()); 20062 } 20063 return id; 20064 } 20065 20066 /* Return an identifier for the base assembler name of a versioned function. 20067 This is computed by taking the default version's assembler name, and 20068 stripping off the ".default" suffix if it's already been appended. */ 20069 20070 static tree 20071 get_suffixed_assembler_name (tree default_decl, const char *suffix) 20072 { 20073 std::string name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (default_decl)); 20074 20075 auto size = name.size (); 20076 if (size >= 8 && name.compare (size - 8, 8, ".default") == 0) 20077 name.resize (size - 8); 20078 name += suffix; 20079 return get_identifier (name.c_str()); 20080 } 20081 20082 /* Make the resolver function decl to dispatch the versions of 20083 a multi-versioned function, DEFAULT_DECL. IFUNC_ALIAS_DECL is 20084 ifunc alias that will point to the created resolver. Create an 20085 empty basic block in the resolver and store the pointer in 20086 EMPTY_BB. Return the decl of the resolver function. */ 20087 20088 static tree 20089 make_resolver_func (const tree default_decl, 20090 const tree ifunc_alias_decl, 20091 basic_block *empty_bb) 20092 { 20093 tree decl, type, t; 20094 20095 /* Create resolver function name based on default_decl. We need to remove an 20096 existing ".default" suffix if this has already been appended. */ 20097 tree decl_name = get_suffixed_assembler_name (default_decl, ".resolver"); 20098 const char *resolver_name = IDENTIFIER_POINTER (decl_name); 20099 20100 /* The resolver function should have signature 20101 (void *) resolver (uint64_t, const __ifunc_arg_t *) */ 20102 type = build_function_type_list (ptr_type_node, 20103 uint64_type_node, 20104 build_ifunc_arg_type (), 20105 NULL_TREE); 20106 20107 decl = build_fn_decl (resolver_name, type); 20108 SET_DECL_ASSEMBLER_NAME (decl, decl_name); 20109 20110 DECL_NAME (decl) = decl_name; 20111 TREE_USED (decl) = 1; 20112 DECL_ARTIFICIAL (decl) = 1; 20113 DECL_IGNORED_P (decl) = 1; 20114 TREE_PUBLIC (decl) = 0; 20115 DECL_UNINLINABLE (decl) = 1; 20116 20117 /* Resolver is not external, body is generated. */ 20118 DECL_EXTERNAL (decl) = 0; 20119 DECL_EXTERNAL (ifunc_alias_decl) = 0; 20120 20121 DECL_CONTEXT (decl) = NULL_TREE; 20122 DECL_INITIAL (decl) = make_node (BLOCK); 20123 DECL_STATIC_CONSTRUCTOR (decl) = 0; 20124 20125 if (DECL_COMDAT_GROUP (default_decl) 20126 || TREE_PUBLIC (default_decl)) 20127 { 20128 /* In this case, each translation unit with a call to this 20129 versioned function will put out a resolver. Ensure it 20130 is comdat to keep just one copy. */ 20131 DECL_COMDAT (decl) = 1; 20132 make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl)); 20133 } 20134 else 20135 TREE_PUBLIC (ifunc_alias_decl) = 0; 20136 20137 /* Build result decl and add to function_decl. */ 20138 t = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, ptr_type_node); 20139 DECL_CONTEXT (t) = decl; 20140 DECL_ARTIFICIAL (t) = 1; 20141 DECL_IGNORED_P (t) = 1; 20142 DECL_RESULT (decl) = t; 20143 20144 /* Build parameter decls and add to function_decl. */ 20145 tree arg1 = build_decl (UNKNOWN_LOCATION, PARM_DECL, 20146 get_identifier ("hwcap"), 20147 uint64_type_node); 20148 tree arg2 = build_decl (UNKNOWN_LOCATION, PARM_DECL, 20149 get_identifier ("arg"), 20150 build_ifunc_arg_type()); 20151 DECL_CONTEXT (arg1) = decl; 20152 DECL_CONTEXT (arg2) = decl; 20153 DECL_ARTIFICIAL (arg1) = 1; 20154 DECL_ARTIFICIAL (arg2) = 1; 20155 DECL_IGNORED_P (arg1) = 1; 20156 DECL_IGNORED_P (arg2) = 1; 20157 DECL_ARG_TYPE (arg1) = uint64_type_node; 20158 DECL_ARG_TYPE (arg2) = build_ifunc_arg_type (); 20159 DECL_ARGUMENTS (decl) = arg1; 20160 TREE_CHAIN (arg1) = arg2; 20161 20162 gimplify_function_tree (decl); 20163 push_cfun (DECL_STRUCT_FUNCTION (decl)); 20164 *empty_bb = init_lowered_empty_function (decl, false, 20165 profile_count::uninitialized ()); 20166 20167 cgraph_node::add_new_function (decl, true); 20168 symtab->call_cgraph_insertion_hooks (cgraph_node::get_create (decl)); 20169 20170 pop_cfun (); 20171 20172 gcc_assert (ifunc_alias_decl != NULL); 20173 /* Mark ifunc_alias_decl as "ifunc" with resolver as resolver_name. */ 20174 DECL_ATTRIBUTES (ifunc_alias_decl) 20175 = make_attribute ("ifunc", resolver_name, 20176 DECL_ATTRIBUTES (ifunc_alias_decl)); 20177 20178 /* Create the alias for dispatch to resolver here. */ 20179 cgraph_node::create_same_body_alias (ifunc_alias_decl, decl); 20180 return decl; 20181 } 20182 20183 /* This adds a condition to the basic_block NEW_BB in function FUNCTION_DECL 20184 to return a pointer to VERSION_DECL if all feature bits specified in 20185 FEATURE_MASK are not set in MASK_VAR. This function will be called during 20186 version dispatch to decide which function version to execute. It returns 20187 the basic block at the end, to which more conditions can be added. */ 20188 static basic_block 20189 add_condition_to_bb (tree function_decl, tree version_decl, 20190 aarch64_fmv_feature_mask feature_mask, 20191 tree mask_var, basic_block new_bb) 20192 { 20193 gimple *return_stmt; 20194 tree convert_expr, result_var; 20195 gimple *convert_stmt; 20196 gimple *if_else_stmt; 20197 20198 basic_block bb1, bb2, bb3; 20199 edge e12, e23; 20200 20201 gimple_seq gseq; 20202 20203 push_cfun (DECL_STRUCT_FUNCTION (function_decl)); 20204 20205 gcc_assert (new_bb != NULL); 20206 gseq = bb_seq (new_bb); 20207 20208 convert_expr = build1 (CONVERT_EXPR, ptr_type_node, 20209 build_fold_addr_expr (version_decl)); 20210 result_var = create_tmp_var (ptr_type_node); 20211 convert_stmt = gimple_build_assign (result_var, convert_expr); 20212 return_stmt = gimple_build_return (result_var); 20213 20214 if (feature_mask == 0ULL) 20215 { 20216 /* Default version. */ 20217 gimple_seq_add_stmt (&gseq, convert_stmt); 20218 gimple_seq_add_stmt (&gseq, return_stmt); 20219 set_bb_seq (new_bb, gseq); 20220 gimple_set_bb (convert_stmt, new_bb); 20221 gimple_set_bb (return_stmt, new_bb); 20222 pop_cfun (); 20223 return new_bb; 20224 } 20225 20226 tree and_expr_var = create_tmp_var (long_long_unsigned_type_node); 20227 tree and_expr = build2 (BIT_AND_EXPR, 20228 long_long_unsigned_type_node, 20229 mask_var, 20230 build_int_cst (long_long_unsigned_type_node, 20231 feature_mask)); 20232 gimple *and_stmt = gimple_build_assign (and_expr_var, and_expr); 20233 gimple_set_block (and_stmt, DECL_INITIAL (function_decl)); 20234 gimple_set_bb (and_stmt, new_bb); 20235 gimple_seq_add_stmt (&gseq, and_stmt); 20236 20237 tree zero_llu = build_int_cst (long_long_unsigned_type_node, 0); 20238 if_else_stmt = gimple_build_cond (EQ_EXPR, and_expr_var, zero_llu, 20239 NULL_TREE, NULL_TREE); 20240 gimple_set_block (if_else_stmt, DECL_INITIAL (function_decl)); 20241 gimple_set_bb (if_else_stmt, new_bb); 20242 gimple_seq_add_stmt (&gseq, if_else_stmt); 20243 20244 gimple_seq_add_stmt (&gseq, convert_stmt); 20245 gimple_seq_add_stmt (&gseq, return_stmt); 20246 set_bb_seq (new_bb, gseq); 20247 20248 bb1 = new_bb; 20249 e12 = split_block (bb1, if_else_stmt); 20250 bb2 = e12->dest; 20251 e12->flags &= ~EDGE_FALLTHRU; 20252 e12->flags |= EDGE_TRUE_VALUE; 20253 20254 e23 = split_block (bb2, return_stmt); 20255 20256 gimple_set_bb (convert_stmt, bb2); 20257 gimple_set_bb (return_stmt, bb2); 20258 20259 bb3 = e23->dest; 20260 make_edge (bb1, bb3, EDGE_FALSE_VALUE); 20261 20262 remove_edge (e23); 20263 make_edge (bb2, EXIT_BLOCK_PTR_FOR_FN (cfun), 0); 20264 20265 pop_cfun (); 20266 20267 return bb3; 20268 } 20269 20270 /* This function generates the dispatch function for 20271 multi-versioned functions. DISPATCH_DECL is the function which will 20272 contain the dispatch logic. FNDECLS are the function choices for 20273 dispatch, and is a tree chain. EMPTY_BB is the basic block pointer 20274 in DISPATCH_DECL in which the dispatch code is generated. */ 20275 20276 static int 20277 dispatch_function_versions (tree dispatch_decl, 20278 void *fndecls_p, 20279 basic_block *empty_bb) 20280 { 20281 gimple *ifunc_cpu_init_stmt; 20282 gimple_seq gseq; 20283 vec<tree> *fndecls; 20284 20285 gcc_assert (dispatch_decl != NULL 20286 && fndecls_p != NULL 20287 && empty_bb != NULL); 20288 20289 push_cfun (DECL_STRUCT_FUNCTION (dispatch_decl)); 20290 20291 gseq = bb_seq (*empty_bb); 20292 /* Function version dispatch is via IFUNC. IFUNC resolvers fire before 20293 constructors, so explicity call __init_cpu_features_resolver here. */ 20294 tree init_fn_type = build_function_type_list (void_type_node, 20295 long_unsigned_type_node, 20296 build_ifunc_arg_type(), 20297 NULL); 20298 tree init_fn_id = get_identifier ("__init_cpu_features_resolver"); 20299 tree init_fn_decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, 20300 init_fn_id, init_fn_type); 20301 DECL_EXTERNAL (init_fn_decl) = 1; 20302 TREE_PUBLIC (init_fn_decl) = 1; 20303 DECL_VISIBILITY (init_fn_decl) = VISIBILITY_HIDDEN; 20304 DECL_VISIBILITY_SPECIFIED (init_fn_decl) = 1; 20305 tree arg1 = DECL_ARGUMENTS (dispatch_decl); 20306 tree arg2 = TREE_CHAIN (arg1); 20307 ifunc_cpu_init_stmt = gimple_build_call (init_fn_decl, 2, arg1, arg2); 20308 gimple_seq_add_stmt (&gseq, ifunc_cpu_init_stmt); 20309 gimple_set_bb (ifunc_cpu_init_stmt, *empty_bb); 20310 20311 /* Build the struct type for __aarch64_cpu_features. */ 20312 tree global_type = lang_hooks.types.make_type (RECORD_TYPE); 20313 tree field1 = build_decl (UNKNOWN_LOCATION, FIELD_DECL, 20314 get_identifier ("features"), 20315 long_long_unsigned_type_node); 20316 DECL_FIELD_CONTEXT (field1) = global_type; 20317 TYPE_FIELDS (global_type) = field1; 20318 layout_type (global_type); 20319 20320 tree global_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, 20321 get_identifier ("__aarch64_cpu_features"), 20322 global_type); 20323 DECL_EXTERNAL (global_var) = 1; 20324 TREE_PUBLIC (global_var) = 1; 20325 DECL_VISIBILITY (global_var) = VISIBILITY_HIDDEN; 20326 DECL_VISIBILITY_SPECIFIED (global_var) = 1; 20327 tree mask_var = create_tmp_var (long_long_unsigned_type_node); 20328 20329 tree component_expr = build3 (COMPONENT_REF, long_long_unsigned_type_node, 20330 global_var, field1, NULL_TREE); 20331 gimple *component_stmt = gimple_build_assign (mask_var, component_expr); 20332 gimple_set_block (component_stmt, DECL_INITIAL (dispatch_decl)); 20333 gimple_set_bb (component_stmt, *empty_bb); 20334 gimple_seq_add_stmt (&gseq, component_stmt); 20335 20336 tree not_expr = build1 (BIT_NOT_EXPR, long_long_unsigned_type_node, mask_var); 20337 gimple *not_stmt = gimple_build_assign (mask_var, not_expr); 20338 gimple_set_block (not_stmt, DECL_INITIAL (dispatch_decl)); 20339 gimple_set_bb (not_stmt, *empty_bb); 20340 gimple_seq_add_stmt (&gseq, not_stmt); 20341 20342 set_bb_seq (*empty_bb, gseq); 20343 20344 pop_cfun (); 20345 20346 /* fndecls_p is actually a vector. */ 20347 fndecls = static_cast<vec<tree> *> (fndecls_p); 20348 20349 /* At least one more version other than the default. */ 20350 unsigned int num_versions = fndecls->length (); 20351 gcc_assert (num_versions >= 2); 20352 20353 struct function_version_info 20354 { 20355 tree version_decl; 20356 aarch64_fmv_feature_mask feature_mask; 20357 } *function_versions; 20358 20359 function_versions = (struct function_version_info *) 20360 XNEWVEC (struct function_version_info, (num_versions)); 20361 20362 unsigned int actual_versions = 0; 20363 20364 for (tree version_decl : *fndecls) 20365 { 20366 aarch64_fmv_feature_mask feature_mask; 20367 /* Get attribute string, parse it and find the right features. */ 20368 feature_mask = get_feature_mask_for_version (version_decl); 20369 function_versions [actual_versions].version_decl = version_decl; 20370 function_versions [actual_versions].feature_mask = feature_mask; 20371 actual_versions++; 20372 } 20373 20374 auto compare_feature_version_info = [](const void *p1, const void *p2) { 20375 const function_version_info v1 = *(const function_version_info *)p1; 20376 const function_version_info v2 = *(const function_version_info *)p2; 20377 return - compare_feature_masks (v1.feature_mask, v2.feature_mask); 20378 }; 20379 20380 /* Sort the versions according to descending order of dispatch priority. */ 20381 qsort (function_versions, actual_versions, 20382 sizeof (struct function_version_info), compare_feature_version_info); 20383 20384 for (unsigned int i = 0; i < actual_versions; ++i) 20385 *empty_bb = add_condition_to_bb (dispatch_decl, 20386 function_versions[i].version_decl, 20387 function_versions[i].feature_mask, 20388 mask_var, 20389 *empty_bb); 20390 20391 free (function_versions); 20392 return 0; 20393 } 20394 20395 /* Implement TARGET_GENERATE_VERSION_DISPATCHER_BODY. */ 20396 20397 tree 20398 aarch64_generate_version_dispatcher_body (void *node_p) 20399 { 20400 tree resolver_decl; 20401 basic_block empty_bb; 20402 tree default_ver_decl; 20403 struct cgraph_node *versn; 20404 struct cgraph_node *node; 20405 20406 struct cgraph_function_version_info *node_version_info = NULL; 20407 struct cgraph_function_version_info *versn_info = NULL; 20408 20409 node = (cgraph_node *)node_p; 20410 20411 node_version_info = node->function_version (); 20412 gcc_assert (node->dispatcher_function 20413 && node_version_info != NULL); 20414 20415 if (node_version_info->dispatcher_resolver) 20416 return node_version_info->dispatcher_resolver; 20417 20418 /* The first version in the chain corresponds to the default version. */ 20419 default_ver_decl = node_version_info->next->this_node->decl; 20420 20421 /* node is going to be an alias, so remove the finalized bit. */ 20422 node->definition = false; 20423 20424 resolver_decl = make_resolver_func (default_ver_decl, 20425 node->decl, &empty_bb); 20426 20427 node_version_info->dispatcher_resolver = resolver_decl; 20428 20429 push_cfun (DECL_STRUCT_FUNCTION (resolver_decl)); 20430 20431 auto_vec<tree, 2> fn_ver_vec; 20432 20433 for (versn_info = node_version_info->next; versn_info; 20434 versn_info = versn_info->next) 20435 { 20436 versn = versn_info->this_node; 20437 /* Check for virtual functions here again, as by this time it should 20438 have been determined if this function needs a vtable index or 20439 not. This happens for methods in derived classes that override 20440 virtual methods in base classes but are not explicitly marked as 20441 virtual. */ 20442 if (DECL_VINDEX (versn->decl)) 20443 sorry ("virtual function multiversioning not supported"); 20444 20445 fn_ver_vec.safe_push (versn->decl); 20446 } 20447 20448 dispatch_function_versions (resolver_decl, &fn_ver_vec, &empty_bb); 20449 cgraph_edge::rebuild_edges (); 20450 pop_cfun (); 20451 20452 /* Fix up symbol names. First we need to obtain the base name, which may 20453 have already been mangled. */ 20454 tree base_name = get_suffixed_assembler_name (default_ver_decl, ""); 20455 20456 /* We need to redo the version mangling on the non-default versions for the 20457 target_clones case. Redoing the mangling for the target_version case is 20458 redundant but does no harm. We need to skip the default version, because 20459 expand_clones will append ".default" later; fortunately that suffix is the 20460 one we want anyway. */ 20461 for (versn_info = node_version_info->next->next; versn_info; 20462 versn_info = versn_info->next) 20463 { 20464 tree version_decl = versn_info->this_node->decl; 20465 tree name = aarch64_mangle_decl_assembler_name (version_decl, 20466 base_name); 20467 symtab->change_decl_assembler_name (version_decl, name); 20468 } 20469 20470 /* We also need to use the base name for the ifunc declaration. */ 20471 symtab->change_decl_assembler_name (node->decl, base_name); 20472 20473 return resolver_decl; 20474 } 20475 20476 /* Make a dispatcher declaration for the multi-versioned function DECL. 20477 Calls to DECL function will be replaced with calls to the dispatcher 20478 by the front-end. Returns the decl of the dispatcher function. */ 20479 20480 tree 20481 aarch64_get_function_versions_dispatcher (void *decl) 20482 { 20483 tree fn = (tree) decl; 20484 struct cgraph_node *node = NULL; 20485 struct cgraph_node *default_node = NULL; 20486 struct cgraph_function_version_info *node_v = NULL; 20487 struct cgraph_function_version_info *first_v = NULL; 20488 20489 tree dispatch_decl = NULL; 20490 20491 struct cgraph_function_version_info *default_version_info = NULL; 20492 20493 gcc_assert (fn != NULL && DECL_FUNCTION_VERSIONED (fn)); 20494 20495 node = cgraph_node::get (fn); 20496 gcc_assert (node != NULL); 20497 20498 node_v = node->function_version (); 20499 gcc_assert (node_v != NULL); 20500 20501 if (node_v->dispatcher_resolver != NULL) 20502 return node_v->dispatcher_resolver; 20503 20504 /* Find the default version and make it the first node. */ 20505 first_v = node_v; 20506 /* Go to the beginning of the chain. */ 20507 while (first_v->prev != NULL) 20508 first_v = first_v->prev; 20509 default_version_info = first_v; 20510 while (default_version_info != NULL) 20511 { 20512 if (get_feature_mask_for_version 20513 (default_version_info->this_node->decl) == 0ULL) 20514 break; 20515 default_version_info = default_version_info->next; 20516 } 20517 20518 /* If there is no default node, just return NULL. */ 20519 if (default_version_info == NULL) 20520 return NULL; 20521 20522 /* Make default info the first node. */ 20523 if (first_v != default_version_info) 20524 { 20525 default_version_info->prev->next = default_version_info->next; 20526 if (default_version_info->next) 20527 default_version_info->next->prev = default_version_info->prev; 20528 first_v->prev = default_version_info; 20529 default_version_info->next = first_v; 20530 default_version_info->prev = NULL; 20531 } 20532 20533 default_node = default_version_info->this_node; 20534 20535 if (targetm.has_ifunc_p ()) 20536 { 20537 struct cgraph_function_version_info *it_v = NULL; 20538 struct cgraph_node *dispatcher_node = NULL; 20539 struct cgraph_function_version_info *dispatcher_version_info = NULL; 20540 20541 /* Right now, the dispatching is done via ifunc. */ 20542 dispatch_decl = make_dispatcher_decl (default_node->decl); 20543 TREE_NOTHROW (dispatch_decl) = TREE_NOTHROW (fn); 20544 20545 dispatcher_node = cgraph_node::get_create (dispatch_decl); 20546 gcc_assert (dispatcher_node != NULL); 20547 dispatcher_node->dispatcher_function = 1; 20548 dispatcher_version_info 20549 = dispatcher_node->insert_new_function_version (); 20550 dispatcher_version_info->next = default_version_info; 20551 dispatcher_node->definition = 1; 20552 20553 /* Set the dispatcher for all the versions. */ 20554 it_v = default_version_info; 20555 while (it_v != NULL) 20556 { 20557 it_v->dispatcher_resolver = dispatch_decl; 20558 it_v = it_v->next; 20559 } 20560 } 20561 else 20562 { 20563 error_at (DECL_SOURCE_LOCATION (default_node->decl), 20564 "multiversioning needs %<ifunc%> which is not supported " 20565 "on this target"); 20566 } 20567 20568 return dispatch_decl; 20569 } 20570 20571 /* This function returns true if FN1 and FN2 are versions of the same function, 20572 that is, the target_version attributes of the function decls are different. 20573 This assumes that FN1 and FN2 have the same signature. */ 20574 20575 bool 20576 aarch64_common_function_versions (tree fn1, tree fn2) 20577 { 20578 if (TREE_CODE (fn1) != FUNCTION_DECL 20579 || TREE_CODE (fn2) != FUNCTION_DECL) 20580 return false; 20581 20582 return (aarch64_compare_version_priority (fn1, fn2) != 0); 20583 } 20584 20585 /* Implement TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P. Use an opt-out 20586 rather than an opt-in list. */ 20587 20588 static bool 20589 aarch64_function_attribute_inlinable_p (const_tree fndecl) 20590 { 20591 /* A function that has local SME state cannot be inlined into its caller, 20592 since we only support managing PSTATE.ZA switches at function scope. */ 20593 return (!aarch64_fndecl_has_new_state (fndecl, "za") 20594 && !aarch64_fndecl_has_new_state (fndecl, "zt0")); 20595 } 20596 20597 /* Helper for aarch64_can_inline_p. In the case where CALLER and CALLEE are 20598 tri-bool options (yes, no, don't care) and the default value is 20599 DEF, determine whether to reject inlining. */ 20600 20601 static bool 20602 aarch64_tribools_ok_for_inlining_p (int caller, int callee, 20603 int dont_care, int def) 20604 { 20605 /* If the callee doesn't care, always allow inlining. */ 20606 if (callee == dont_care) 20607 return true; 20608 20609 /* If the caller doesn't care, always allow inlining. */ 20610 if (caller == dont_care) 20611 return true; 20612 20613 /* Otherwise, allow inlining if either the callee and caller values 20614 agree, or if the callee is using the default value. */ 20615 return (callee == caller || callee == def); 20616 } 20617 20618 /* Bit allocations for ipa_fn_summary::target_info. */ 20619 20620 /* Set if the function contains a stmt that relies on the function's 20621 choice of PSTATE.SM setting (0 for non-streaming, 1 for streaming). 20622 Not meaningful for streaming-compatible functions. */ 20623 constexpr auto AARCH64_IPA_SM_FIXED = 1U << 0; 20624 20625 /* Set if the function clobbers ZA and ZT0. Not meaningful for functions that 20626 have ZA state. */ 20627 constexpr auto AARCH64_IPA_CLOBBERS_ZA = 1U << 1; 20628 constexpr auto AARCH64_IPA_CLOBBERS_ZT0 = 1U << 2; 20629 20630 /* Implement TARGET_NEED_IPA_FN_TARGET_INFO. */ 20631 20632 static bool 20633 aarch64_need_ipa_fn_target_info (const_tree, unsigned int &) 20634 { 20635 /* We could in principle skip this for streaming-compatible functions 20636 that have ZA state, but that's a rare combination. */ 20637 return true; 20638 } 20639 20640 /* Implement TARGET_UPDATE_IPA_FN_TARGET_INFO. */ 20641 20642 static bool 20643 aarch64_update_ipa_fn_target_info (unsigned int &info, const gimple *stmt) 20644 { 20645 if (auto *ga = dyn_cast<const gasm *> (stmt)) 20646 { 20647 /* We don't know what the asm does, so conservatively assume that 20648 it requires the function's current SM mode. */ 20649 info |= AARCH64_IPA_SM_FIXED; 20650 for (unsigned int i = 0; i < gimple_asm_nclobbers (ga); ++i) 20651 { 20652 tree op = gimple_asm_clobber_op (ga, i); 20653 const char *clobber = TREE_STRING_POINTER (TREE_VALUE (op)); 20654 if (strcmp (clobber, "za") == 0) 20655 info |= AARCH64_IPA_CLOBBERS_ZA; 20656 if (strcmp (clobber, "zt0") == 0) 20657 info |= AARCH64_IPA_CLOBBERS_ZT0; 20658 } 20659 } 20660 if (auto *call = dyn_cast<const gcall *> (stmt)) 20661 { 20662 if (gimple_call_builtin_p (call, BUILT_IN_MD)) 20663 { 20664 /* The attributes on AArch64 builtins are supposed to be accurate. 20665 If the function isn't marked streaming-compatible then it 20666 needs whichever SM mode it selects. */ 20667 tree decl = gimple_call_fndecl (call); 20668 if (aarch64_fndecl_pstate_sm (decl) != 0) 20669 info |= AARCH64_IPA_SM_FIXED; 20670 } 20671 } 20672 return true; 20673 } 20674 20675 /* Implement TARGET_CAN_INLINE_P. Decide whether it is valid 20676 to inline CALLEE into CALLER based on target-specific info. 20677 Make sure that the caller and callee have compatible architectural 20678 features. Then go through the other possible target attributes 20679 and see if they can block inlining. Try not to reject always_inline 20680 callees unless they are incompatible architecturally. */ 20681 20682 static bool 20683 aarch64_can_inline_p (tree caller, tree callee) 20684 { 20685 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller); 20686 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee); 20687 20688 struct cl_target_option *caller_opts 20689 = TREE_TARGET_OPTION (caller_tree ? caller_tree 20690 : target_option_default_node); 20691 20692 struct cl_target_option *callee_opts 20693 = TREE_TARGET_OPTION (callee_tree ? callee_tree 20694 : target_option_default_node); 20695 20696 /* Callee's ISA flags should be a subset of the caller's. */ 20697 auto caller_asm_isa = (caller_opts->x_aarch64_asm_isa_flags 20698 & ~AARCH64_FL_ISA_MODES); 20699 auto callee_asm_isa = (callee_opts->x_aarch64_asm_isa_flags 20700 & ~AARCH64_FL_ISA_MODES); 20701 if (callee_asm_isa & ~caller_asm_isa) 20702 return false; 20703 20704 auto caller_isa = (caller_opts->x_aarch64_isa_flags 20705 & ~AARCH64_FL_ISA_MODES); 20706 auto callee_isa = (callee_opts->x_aarch64_isa_flags 20707 & ~AARCH64_FL_ISA_MODES); 20708 if (callee_isa & ~caller_isa) 20709 return false; 20710 20711 /* Return true if the callee might have target_info property PROPERTY. 20712 The answer must be true unless we have positive proof to the contrary. */ 20713 auto callee_has_property = [&](unsigned int property) 20714 { 20715 if (ipa_fn_summaries) 20716 if (auto *summary = ipa_fn_summaries->get (cgraph_node::get (callee))) 20717 if (!(summary->target_info & property)) 20718 return false; 20719 return true; 20720 }; 20721 20722 /* Streaming-compatible code can be inlined into functions with any 20723 PSTATE.SM mode. Otherwise the caller and callee must agree on 20724 PSTATE.SM mode, unless we can prove that the callee is naturally 20725 streaming-compatible. */ 20726 auto caller_sm = (caller_opts->x_aarch64_isa_flags & AARCH64_FL_SM_STATE); 20727 auto callee_sm = (callee_opts->x_aarch64_isa_flags & AARCH64_FL_SM_STATE); 20728 if (callee_sm 20729 && caller_sm != callee_sm 20730 && callee_has_property (AARCH64_IPA_SM_FIXED)) 20731 return false; 20732 20733 /* aarch64_function_attribute_inlinable_p prevents new-ZA and new-ZT0 20734 functions from being inlined into others. We also need to prevent 20735 inlining of shared-ZA functions into functions without ZA state, 20736 since this is an error condition. 20737 20738 The only other problematic case for ZA is inlining a function that 20739 directly clobbers ZA or ZT0 into a function that has ZA or ZT0 state. */ 20740 auto caller_za = (caller_opts->x_aarch64_isa_flags & AARCH64_FL_ZA_ON); 20741 auto callee_za = (callee_opts->x_aarch64_isa_flags & AARCH64_FL_ZA_ON); 20742 if (!caller_za && callee_za) 20743 return false; 20744 if (!callee_za 20745 && aarch64_fndecl_has_state (caller, "za") 20746 && callee_has_property (AARCH64_IPA_CLOBBERS_ZA)) 20747 return false; 20748 if (!callee_za 20749 && aarch64_fndecl_has_state (caller, "zt0") 20750 && callee_has_property (AARCH64_IPA_CLOBBERS_ZT0)) 20751 return false; 20752 20753 /* Allow non-strict aligned functions inlining into strict 20754 aligned ones. */ 20755 if ((TARGET_STRICT_ALIGN_P (caller_opts->x_target_flags) 20756 != TARGET_STRICT_ALIGN_P (callee_opts->x_target_flags)) 20757 && !(!TARGET_STRICT_ALIGN_P (callee_opts->x_target_flags) 20758 && TARGET_STRICT_ALIGN_P (caller_opts->x_target_flags))) 20759 return false; 20760 20761 bool always_inline = lookup_attribute ("always_inline", 20762 DECL_ATTRIBUTES (callee)); 20763 20764 /* If the architectural features match up and the callee is always_inline 20765 then the other attributes don't matter. */ 20766 if (always_inline) 20767 return true; 20768 20769 if (caller_opts->x_aarch64_cmodel_var 20770 != callee_opts->x_aarch64_cmodel_var) 20771 return false; 20772 20773 if (caller_opts->x_aarch64_tls_dialect 20774 != callee_opts->x_aarch64_tls_dialect) 20775 return false; 20776 20777 /* Honour explicit requests to workaround errata. */ 20778 if (!aarch64_tribools_ok_for_inlining_p ( 20779 caller_opts->x_aarch64_fix_a53_err835769, 20780 callee_opts->x_aarch64_fix_a53_err835769, 20781 2, TARGET_FIX_ERR_A53_835769_DEFAULT)) 20782 return false; 20783 20784 if (!aarch64_tribools_ok_for_inlining_p ( 20785 caller_opts->x_aarch64_fix_a53_err843419, 20786 callee_opts->x_aarch64_fix_a53_err843419, 20787 2, TARGET_FIX_ERR_A53_843419)) 20788 return false; 20789 20790 /* If the user explicitly specified -momit-leaf-frame-pointer for the 20791 caller and calle and they don't match up, reject inlining. */ 20792 if (!aarch64_tribools_ok_for_inlining_p ( 20793 caller_opts->x_flag_omit_leaf_frame_pointer, 20794 callee_opts->x_flag_omit_leaf_frame_pointer, 20795 2, 1)) 20796 return false; 20797 20798 /* If the callee has specific tuning overrides, respect them. */ 20799 if (callee_opts->x_aarch64_override_tune_string != NULL 20800 && caller_opts->x_aarch64_override_tune_string == NULL) 20801 return false; 20802 20803 /* If the user specified tuning override strings for the 20804 caller and callee and they don't match up, reject inlining. 20805 We just do a string compare here, we don't analyze the meaning 20806 of the string, as it would be too costly for little gain. */ 20807 if (callee_opts->x_aarch64_override_tune_string 20808 && caller_opts->x_aarch64_override_tune_string 20809 && (strcmp (callee_opts->x_aarch64_override_tune_string, 20810 caller_opts->x_aarch64_override_tune_string) != 0)) 20811 return false; 20812 20813 return true; 20814 } 20815 20816 /* Return the ID of the TLDESC ABI, initializing the descriptor if hasn't 20817 been already. */ 20818 20819 arm_pcs 20820 aarch64_tlsdesc_abi_id () 20821 { 20822 predefined_function_abi &tlsdesc_abi = function_abis[ARM_PCS_TLSDESC]; 20823 if (!tlsdesc_abi.initialized_p ()) 20824 { 20825 HARD_REG_SET full_reg_clobbers; 20826 CLEAR_HARD_REG_SET (full_reg_clobbers); 20827 SET_HARD_REG_BIT (full_reg_clobbers, R0_REGNUM); 20828 SET_HARD_REG_BIT (full_reg_clobbers, CC_REGNUM); 20829 for (int regno = P0_REGNUM; regno <= P15_REGNUM; ++regno) 20830 SET_HARD_REG_BIT (full_reg_clobbers, regno); 20831 tlsdesc_abi.initialize (ARM_PCS_TLSDESC, full_reg_clobbers); 20832 } 20833 return ARM_PCS_TLSDESC; 20834 } 20835 20836 /* Return true if SYMBOL_REF X binds locally. */ 20837 20838 static bool 20839 aarch64_symbol_binds_local_p (const_rtx x) 20840 { 20841 return (SYMBOL_REF_DECL (x) 20842 ? targetm.binds_local_p (SYMBOL_REF_DECL (x)) 20843 : SYMBOL_REF_LOCAL_P (x)); 20844 } 20845 20846 /* Return true if SYMBOL_REF X is thread local */ 20847 static bool 20848 aarch64_tls_symbol_p (rtx x) 20849 { 20850 if (! TARGET_HAVE_TLS) 20851 return false; 20852 20853 x = strip_salt (x); 20854 if (!SYMBOL_REF_P (x)) 20855 return false; 20856 20857 return SYMBOL_REF_TLS_MODEL (x) != 0; 20858 } 20859 20860 /* Classify a TLS symbol into one of the TLS kinds. */ 20861 enum aarch64_symbol_type 20862 aarch64_classify_tls_symbol (rtx x) 20863 { 20864 enum tls_model tls_kind = tls_symbolic_operand_type (x); 20865 20866 switch (tls_kind) 20867 { 20868 case TLS_MODEL_GLOBAL_DYNAMIC: 20869 case TLS_MODEL_LOCAL_DYNAMIC: 20870 return TARGET_TLS_DESC ? SYMBOL_SMALL_TLSDESC : SYMBOL_SMALL_TLSGD; 20871 20872 case TLS_MODEL_INITIAL_EXEC: 20873 switch (aarch64_cmodel) 20874 { 20875 case AARCH64_CMODEL_TINY: 20876 case AARCH64_CMODEL_TINY_PIC: 20877 return SYMBOL_TINY_TLSIE; 20878 default: 20879 return SYMBOL_SMALL_TLSIE; 20880 } 20881 20882 case TLS_MODEL_LOCAL_EXEC: 20883 if (aarch64_tls_size == 12) 20884 return SYMBOL_TLSLE12; 20885 else if (aarch64_tls_size == 24) 20886 return SYMBOL_TLSLE24; 20887 else if (aarch64_tls_size == 32) 20888 return SYMBOL_TLSLE32; 20889 else if (aarch64_tls_size == 48) 20890 return SYMBOL_TLSLE48; 20891 else 20892 gcc_unreachable (); 20893 20894 case TLS_MODEL_EMULATED: 20895 case TLS_MODEL_NONE: 20896 return SYMBOL_FORCE_TO_MEM; 20897 20898 default: 20899 gcc_unreachable (); 20900 } 20901 } 20902 20903 /* Return the correct method for accessing X + OFFSET, where X is either 20904 a SYMBOL_REF or LABEL_REF. */ 20905 20906 enum aarch64_symbol_type 20907 aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset) 20908 { 20909 x = strip_salt (x); 20910 20911 if (LABEL_REF_P (x)) 20912 { 20913 switch (aarch64_cmodel) 20914 { 20915 case AARCH64_CMODEL_LARGE: 20916 return SYMBOL_FORCE_TO_MEM; 20917 20918 case AARCH64_CMODEL_TINY_PIC: 20919 case AARCH64_CMODEL_TINY: 20920 return SYMBOL_TINY_ABSOLUTE; 20921 20922 case AARCH64_CMODEL_SMALL_SPIC: 20923 case AARCH64_CMODEL_SMALL_PIC: 20924 case AARCH64_CMODEL_SMALL: 20925 return SYMBOL_SMALL_ABSOLUTE; 20926 20927 default: 20928 gcc_unreachable (); 20929 } 20930 } 20931 20932 if (SYMBOL_REF_P (x)) 20933 { 20934 if (aarch64_tls_symbol_p (x)) 20935 return aarch64_classify_tls_symbol (x); 20936 20937 switch (aarch64_cmodel) 20938 { 20939 case AARCH64_CMODEL_TINY_PIC: 20940 case AARCH64_CMODEL_TINY: 20941 /* With -fPIC non-local symbols use the GOT. For orthogonality 20942 always use the GOT for extern weak symbols. */ 20943 if ((flag_pic || SYMBOL_REF_WEAK (x)) 20944 && !aarch64_symbol_binds_local_p (x)) 20945 return SYMBOL_TINY_GOT; 20946 20947 /* When we retrieve symbol + offset address, we have to make sure 20948 the offset does not cause overflow of the final address. But 20949 we have no way of knowing the address of symbol at compile time 20950 so we can't accurately say if the distance between the PC and 20951 symbol + offset is outside the addressible range of +/-1MB in the 20952 TINY code model. So we limit the maximum offset to +/-64KB and 20953 assume the offset to the symbol is not larger than +/-(1MB - 64KB). 20954 If offset_within_block_p is true we allow larger offsets. */ 20955 if (!(IN_RANGE (offset, -0x10000, 0x10000) 20956 || offset_within_block_p (x, offset))) 20957 return SYMBOL_FORCE_TO_MEM; 20958 20959 return SYMBOL_TINY_ABSOLUTE; 20960 20961 20962 case AARCH64_CMODEL_SMALL_SPIC: 20963 case AARCH64_CMODEL_SMALL_PIC: 20964 case AARCH64_CMODEL_SMALL: 20965 if ((flag_pic || SYMBOL_REF_WEAK (x)) 20966 && !aarch64_symbol_binds_local_p (x)) 20967 return aarch64_cmodel == AARCH64_CMODEL_SMALL_SPIC 20968 ? SYMBOL_SMALL_GOT_28K : SYMBOL_SMALL_GOT_4G; 20969 20970 /* Same reasoning as the tiny code model, but the offset cap here is 20971 1MB, allowing +/-3.9GB for the offset to the symbol. */ 20972 if (!(IN_RANGE (offset, -0x100000, 0x100000) 20973 || offset_within_block_p (x, offset))) 20974 return SYMBOL_FORCE_TO_MEM; 20975 20976 return SYMBOL_SMALL_ABSOLUTE; 20977 20978 case AARCH64_CMODEL_LARGE: 20979 /* This is alright even in PIC code as the constant 20980 pool reference is always PC relative and within 20981 the same translation unit. */ 20982 if (!aarch64_pcrelative_literal_loads && CONSTANT_POOL_ADDRESS_P (x)) 20983 return SYMBOL_SMALL_ABSOLUTE; 20984 else 20985 return SYMBOL_FORCE_TO_MEM; 20986 20987 default: 20988 gcc_unreachable (); 20989 } 20990 } 20991 20992 /* By default push everything into the constant pool. */ 20993 return SYMBOL_FORCE_TO_MEM; 20994 } 20995 20996 bool 20997 aarch64_constant_address_p (rtx x) 20998 { 20999 return (CONSTANT_P (x) && memory_address_p (DImode, x)); 21000 } 21001 21002 bool 21003 aarch64_legitimate_pic_operand_p (rtx x) 21004 { 21005 poly_int64 offset; 21006 x = strip_offset_and_salt (x, &offset); 21007 if (SYMBOL_REF_P (x)) 21008 return false; 21009 21010 return true; 21011 } 21012 21013 /* Implement TARGET_LEGITIMATE_CONSTANT_P hook. Return true for constants 21014 that should be rematerialized rather than spilled. */ 21015 21016 static bool 21017 aarch64_legitimate_constant_p (machine_mode mode, rtx x) 21018 { 21019 /* Support CSE and rematerialization of common constants. */ 21020 if (CONST_INT_P (x) 21021 || CONST_DOUBLE_P (x)) 21022 return true; 21023 21024 /* Only accept variable-length vector constants if they can be 21025 handled directly. 21026 21027 ??? It would be possible (but complex) to handle rematerialization 21028 of other constants via secondary reloads. */ 21029 if (!GET_MODE_SIZE (mode).is_constant ()) 21030 return aarch64_simd_valid_immediate (x, NULL); 21031 21032 /* Otherwise, accept any CONST_VECTOR that, if all else fails, can at 21033 least be forced to memory and loaded from there. */ 21034 if (CONST_VECTOR_P (x)) 21035 return !targetm.cannot_force_const_mem (mode, x); 21036 21037 /* Do not allow vector struct mode constants for Advanced SIMD. 21038 We could support 0 and -1 easily, but they need support in 21039 aarch64-simd.md. */ 21040 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 21041 if (vec_flags == (VEC_ADVSIMD | VEC_STRUCT)) 21042 return false; 21043 21044 if (GET_CODE (x) == HIGH) 21045 x = XEXP (x, 0); 21046 21047 /* Accept polynomial constants that can be calculated by using the 21048 destination of a move as the sole temporary. Constants that 21049 require a second temporary cannot be rematerialized (they can't be 21050 forced to memory and also aren't legitimate constants). */ 21051 poly_int64 offset; 21052 if (poly_int_rtx_p (x, &offset)) 21053 return aarch64_offset_temporaries (false, offset) <= 1; 21054 21055 /* If an offset is being added to something else, we need to allow the 21056 base to be moved into the destination register, meaning that there 21057 are no free temporaries for the offset. */ 21058 x = strip_offset_and_salt (x, &offset); 21059 if (!offset.is_constant () && aarch64_offset_temporaries (true, offset) > 0) 21060 return false; 21061 21062 /* Do not allow const (plus (anchor_symbol, const_int)). */ 21063 if (maybe_ne (offset, 0) && SYMBOL_REF_P (x) && SYMBOL_REF_ANCHOR_P (x)) 21064 return false; 21065 21066 /* Treat symbols as constants. Avoid TLS symbols as they are complex, 21067 so spilling them is better than rematerialization. */ 21068 if (SYMBOL_REF_P (x) && !SYMBOL_REF_TLS_MODEL (x)) 21069 return true; 21070 21071 /* Label references are always constant. */ 21072 if (LABEL_REF_P (x)) 21073 return true; 21074 21075 return false; 21076 } 21077 21078 rtx 21079 aarch64_load_tp (rtx target) 21080 { 21081 if (!target 21082 || GET_MODE (target) != Pmode 21083 || !register_operand (target, Pmode)) 21084 target = gen_reg_rtx (Pmode); 21085 21086 /* Can return in any reg. */ 21087 emit_insn (gen_aarch64_load_tp_hard (target)); 21088 return target; 21089 } 21090 21091 /* On AAPCS systems, this is the "struct __va_list". */ 21092 static GTY(()) tree va_list_type; 21093 21094 /* Implement TARGET_BUILD_BUILTIN_VA_LIST. 21095 Return the type to use as __builtin_va_list. 21096 21097 AAPCS64 \S 7.1.4 requires that va_list be a typedef for a type defined as: 21098 21099 struct __va_list 21100 { 21101 void *__stack; 21102 void *__gr_top; 21103 void *__vr_top; 21104 int __gr_offs; 21105 int __vr_offs; 21106 }; */ 21107 21108 static tree 21109 aarch64_build_builtin_va_list (void) 21110 { 21111 tree va_list_name; 21112 tree f_stack, f_grtop, f_vrtop, f_groff, f_vroff; 21113 21114 /* Create the type. */ 21115 va_list_type = lang_hooks.types.make_type (RECORD_TYPE); 21116 /* Give it the required name. */ 21117 va_list_name = build_decl (BUILTINS_LOCATION, 21118 TYPE_DECL, 21119 get_identifier ("__va_list"), 21120 va_list_type); 21121 DECL_ARTIFICIAL (va_list_name) = 1; 21122 TYPE_NAME (va_list_type) = va_list_name; 21123 TYPE_STUB_DECL (va_list_type) = va_list_name; 21124 21125 /* Create the fields. */ 21126 f_stack = build_decl (BUILTINS_LOCATION, 21127 FIELD_DECL, get_identifier ("__stack"), 21128 ptr_type_node); 21129 f_grtop = build_decl (BUILTINS_LOCATION, 21130 FIELD_DECL, get_identifier ("__gr_top"), 21131 ptr_type_node); 21132 f_vrtop = build_decl (BUILTINS_LOCATION, 21133 FIELD_DECL, get_identifier ("__vr_top"), 21134 ptr_type_node); 21135 f_groff = build_decl (BUILTINS_LOCATION, 21136 FIELD_DECL, get_identifier ("__gr_offs"), 21137 integer_type_node); 21138 f_vroff = build_decl (BUILTINS_LOCATION, 21139 FIELD_DECL, get_identifier ("__vr_offs"), 21140 integer_type_node); 21141 21142 /* Tell tree-stdarg pass about our internal offset fields. 21143 NOTE: va_list_gpr/fpr_counter_field are only used for tree comparision 21144 purpose to identify whether the code is updating va_list internal 21145 offset fields through irregular way. */ 21146 va_list_gpr_counter_field = f_groff; 21147 va_list_fpr_counter_field = f_vroff; 21148 21149 DECL_ARTIFICIAL (f_stack) = 1; 21150 DECL_ARTIFICIAL (f_grtop) = 1; 21151 DECL_ARTIFICIAL (f_vrtop) = 1; 21152 DECL_ARTIFICIAL (f_groff) = 1; 21153 DECL_ARTIFICIAL (f_vroff) = 1; 21154 21155 DECL_FIELD_CONTEXT (f_stack) = va_list_type; 21156 DECL_FIELD_CONTEXT (f_grtop) = va_list_type; 21157 DECL_FIELD_CONTEXT (f_vrtop) = va_list_type; 21158 DECL_FIELD_CONTEXT (f_groff) = va_list_type; 21159 DECL_FIELD_CONTEXT (f_vroff) = va_list_type; 21160 21161 TYPE_FIELDS (va_list_type) = f_stack; 21162 DECL_CHAIN (f_stack) = f_grtop; 21163 DECL_CHAIN (f_grtop) = f_vrtop; 21164 DECL_CHAIN (f_vrtop) = f_groff; 21165 DECL_CHAIN (f_groff) = f_vroff; 21166 21167 /* Compute its layout. */ 21168 layout_type (va_list_type); 21169 21170 return va_list_type; 21171 } 21172 21173 /* Implement TARGET_EXPAND_BUILTIN_VA_START. */ 21174 static void 21175 aarch64_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED) 21176 { 21177 const CUMULATIVE_ARGS *cum; 21178 tree f_stack, f_grtop, f_vrtop, f_groff, f_vroff; 21179 tree stack, grtop, vrtop, groff, vroff; 21180 tree t; 21181 int gr_save_area_size = cfun->va_list_gpr_size; 21182 int vr_save_area_size = cfun->va_list_fpr_size; 21183 int vr_offset; 21184 21185 cum = &crtl->args.info; 21186 if (cfun->va_list_gpr_size) 21187 gr_save_area_size = MIN ((NUM_ARG_REGS - cum->aapcs_ncrn) * UNITS_PER_WORD, 21188 cfun->va_list_gpr_size); 21189 if (cfun->va_list_fpr_size) 21190 vr_save_area_size = MIN ((NUM_FP_ARG_REGS - cum->aapcs_nvrn) 21191 * UNITS_PER_VREG, cfun->va_list_fpr_size); 21192 21193 if (!TARGET_FLOAT) 21194 { 21195 gcc_assert (cum->aapcs_nvrn == 0); 21196 vr_save_area_size = 0; 21197 } 21198 21199 f_stack = TYPE_FIELDS (va_list_type_node); 21200 f_grtop = DECL_CHAIN (f_stack); 21201 f_vrtop = DECL_CHAIN (f_grtop); 21202 f_groff = DECL_CHAIN (f_vrtop); 21203 f_vroff = DECL_CHAIN (f_groff); 21204 21205 stack = build3 (COMPONENT_REF, TREE_TYPE (f_stack), valist, f_stack, 21206 NULL_TREE); 21207 grtop = build3 (COMPONENT_REF, TREE_TYPE (f_grtop), valist, f_grtop, 21208 NULL_TREE); 21209 vrtop = build3 (COMPONENT_REF, TREE_TYPE (f_vrtop), valist, f_vrtop, 21210 NULL_TREE); 21211 groff = build3 (COMPONENT_REF, TREE_TYPE (f_groff), valist, f_groff, 21212 NULL_TREE); 21213 vroff = build3 (COMPONENT_REF, TREE_TYPE (f_vroff), valist, f_vroff, 21214 NULL_TREE); 21215 21216 /* Emit code to initialize STACK, which points to the next varargs stack 21217 argument. CUM->AAPCS_STACK_SIZE gives the number of stack words used 21218 by named arguments. STACK is 8-byte aligned. */ 21219 t = make_tree (TREE_TYPE (stack), virtual_incoming_args_rtx); 21220 if (cum->aapcs_stack_size > 0) 21221 t = fold_build_pointer_plus_hwi (t, cum->aapcs_stack_size * UNITS_PER_WORD); 21222 t = build2 (MODIFY_EXPR, TREE_TYPE (stack), stack, t); 21223 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 21224 21225 /* Emit code to initialize GRTOP, the top of the GR save area. 21226 virtual_incoming_args_rtx should have been 16 byte aligned. */ 21227 t = make_tree (TREE_TYPE (grtop), virtual_incoming_args_rtx); 21228 t = build2 (MODIFY_EXPR, TREE_TYPE (grtop), grtop, t); 21229 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 21230 21231 /* Emit code to initialize VRTOP, the top of the VR save area. 21232 This address is gr_save_area_bytes below GRTOP, rounded 21233 down to the next 16-byte boundary. */ 21234 t = make_tree (TREE_TYPE (vrtop), virtual_incoming_args_rtx); 21235 vr_offset = ROUND_UP (gr_save_area_size, 21236 STACK_BOUNDARY / BITS_PER_UNIT); 21237 21238 if (vr_offset) 21239 t = fold_build_pointer_plus_hwi (t, -vr_offset); 21240 t = build2 (MODIFY_EXPR, TREE_TYPE (vrtop), vrtop, t); 21241 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 21242 21243 /* Emit code to initialize GROFF, the offset from GRTOP of the 21244 next GPR argument. */ 21245 t = build2 (MODIFY_EXPR, TREE_TYPE (groff), groff, 21246 build_int_cst (TREE_TYPE (groff), -gr_save_area_size)); 21247 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 21248 21249 /* Likewise emit code to initialize VROFF, the offset from FTOP 21250 of the next VR argument. */ 21251 t = build2 (MODIFY_EXPR, TREE_TYPE (vroff), vroff, 21252 build_int_cst (TREE_TYPE (vroff), -vr_save_area_size)); 21253 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); 21254 } 21255 21256 /* Implement TARGET_GIMPLIFY_VA_ARG_EXPR. */ 21257 21258 static tree 21259 aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, 21260 gimple_seq *post_p ATTRIBUTE_UNUSED) 21261 { 21262 tree addr; 21263 bool indirect_p; 21264 bool is_ha; /* is HFA or HVA. */ 21265 bool dw_align; /* double-word align. */ 21266 machine_mode ag_mode = VOIDmode; 21267 int nregs; 21268 machine_mode mode; 21269 21270 tree f_stack, f_grtop, f_vrtop, f_groff, f_vroff; 21271 tree stack, f_top, f_off, off, arg, roundup, on_stack; 21272 HOST_WIDE_INT size, rsize, adjust, align; 21273 tree t, u, cond1, cond2; 21274 21275 indirect_p = pass_va_arg_by_reference (type); 21276 if (indirect_p) 21277 type = build_pointer_type (type); 21278 21279 mode = TYPE_MODE (type); 21280 21281 f_stack = TYPE_FIELDS (va_list_type_node); 21282 f_grtop = DECL_CHAIN (f_stack); 21283 f_vrtop = DECL_CHAIN (f_grtop); 21284 f_groff = DECL_CHAIN (f_vrtop); 21285 f_vroff = DECL_CHAIN (f_groff); 21286 21287 stack = build3 (COMPONENT_REF, TREE_TYPE (f_stack), unshare_expr (valist), 21288 f_stack, NULL_TREE); 21289 size = int_size_in_bytes (type); 21290 21291 unsigned int abi_break_gcc_9; 21292 unsigned int abi_break_gcc_13; 21293 unsigned int abi_break_gcc_14; 21294 align 21295 = aarch64_function_arg_alignment (mode, type, &abi_break_gcc_9, 21296 &abi_break_gcc_13, &abi_break_gcc_14) 21297 / BITS_PER_UNIT; 21298 21299 dw_align = false; 21300 adjust = 0; 21301 if (aarch64_vfp_is_call_or_return_candidate (mode, type, &ag_mode, &nregs, 21302 &is_ha, false)) 21303 { 21304 /* No frontends can create types with variable-sized modes, so we 21305 shouldn't be asked to pass or return them. */ 21306 unsigned int ag_size = GET_MODE_SIZE (ag_mode).to_constant (); 21307 21308 /* TYPE passed in fp/simd registers. */ 21309 if (!TARGET_FLOAT) 21310 aarch64_err_no_fpadvsimd (mode); 21311 21312 f_top = build3 (COMPONENT_REF, TREE_TYPE (f_vrtop), 21313 unshare_expr (valist), f_vrtop, NULL_TREE); 21314 f_off = build3 (COMPONENT_REF, TREE_TYPE (f_vroff), 21315 unshare_expr (valist), f_vroff, NULL_TREE); 21316 21317 rsize = nregs * UNITS_PER_VREG; 21318 21319 if (is_ha) 21320 { 21321 if (BYTES_BIG_ENDIAN && ag_size < UNITS_PER_VREG) 21322 adjust = UNITS_PER_VREG - ag_size; 21323 } 21324 else if (BLOCK_REG_PADDING (mode, type, 1) == PAD_DOWNWARD 21325 && size < UNITS_PER_VREG) 21326 { 21327 adjust = UNITS_PER_VREG - size; 21328 } 21329 } 21330 else 21331 { 21332 /* TYPE passed in general registers. */ 21333 f_top = build3 (COMPONENT_REF, TREE_TYPE (f_grtop), 21334 unshare_expr (valist), f_grtop, NULL_TREE); 21335 f_off = build3 (COMPONENT_REF, TREE_TYPE (f_groff), 21336 unshare_expr (valist), f_groff, NULL_TREE); 21337 rsize = ROUND_UP (size, UNITS_PER_WORD); 21338 nregs = rsize / UNITS_PER_WORD; 21339 21340 if (align <= 8 21341 && abi_break_gcc_13 21342 && warn_psabi 21343 && !bitint_or_aggr_of_bitint_p (type)) 21344 inform (input_location, "parameter passing for argument of type " 21345 "%qT changed in GCC 13.1", type); 21346 21347 if (warn_psabi 21348 && abi_break_gcc_14 21349 && (abi_break_gcc_14 > 8 * BITS_PER_UNIT) != (align > 8) 21350 && !bitint_or_aggr_of_bitint_p (type)) 21351 inform (input_location, "parameter passing for argument of type " 21352 "%qT changed in GCC 14.1", type); 21353 21354 if (align > 8) 21355 { 21356 if (abi_break_gcc_9 21357 && warn_psabi 21358 && !bitint_or_aggr_of_bitint_p (type)) 21359 inform (input_location, "parameter passing for argument of type " 21360 "%qT changed in GCC 9.1", type); 21361 dw_align = true; 21362 } 21363 21364 if (BLOCK_REG_PADDING (mode, type, 1) == PAD_DOWNWARD 21365 && size < UNITS_PER_WORD) 21366 { 21367 adjust = UNITS_PER_WORD - size; 21368 } 21369 } 21370 21371 /* Get a local temporary for the field value. */ 21372 off = get_initialized_tmp_var (f_off, pre_p, NULL); 21373 21374 /* Emit code to branch if off >= 0. */ 21375 t = build2 (GE_EXPR, boolean_type_node, off, 21376 build_int_cst (TREE_TYPE (off), 0)); 21377 cond1 = build3 (COND_EXPR, ptr_type_node, t, NULL_TREE, NULL_TREE); 21378 21379 if (dw_align) 21380 { 21381 /* Emit: offs = (offs + 15) & -16. */ 21382 t = build2 (PLUS_EXPR, TREE_TYPE (off), off, 21383 build_int_cst (TREE_TYPE (off), 15)); 21384 t = build2 (BIT_AND_EXPR, TREE_TYPE (off), t, 21385 build_int_cst (TREE_TYPE (off), -16)); 21386 roundup = build2 (MODIFY_EXPR, TREE_TYPE (off), off, t); 21387 } 21388 else 21389 roundup = NULL; 21390 21391 /* Update ap.__[g|v]r_offs */ 21392 t = build2 (PLUS_EXPR, TREE_TYPE (off), off, 21393 build_int_cst (TREE_TYPE (off), rsize)); 21394 t = build2 (MODIFY_EXPR, TREE_TYPE (f_off), unshare_expr (f_off), t); 21395 21396 /* String up. */ 21397 if (roundup) 21398 t = build2 (COMPOUND_EXPR, TREE_TYPE (t), roundup, t); 21399 21400 /* [cond2] if (ap.__[g|v]r_offs > 0) */ 21401 u = build2 (GT_EXPR, boolean_type_node, unshare_expr (f_off), 21402 build_int_cst (TREE_TYPE (f_off), 0)); 21403 cond2 = build3 (COND_EXPR, ptr_type_node, u, NULL_TREE, NULL_TREE); 21404 21405 /* String up: make sure the assignment happens before the use. */ 21406 t = build2 (COMPOUND_EXPR, TREE_TYPE (cond2), t, cond2); 21407 COND_EXPR_ELSE (cond1) = t; 21408 21409 /* Prepare the trees handling the argument that is passed on the stack; 21410 the top level node will store in ON_STACK. */ 21411 arg = get_initialized_tmp_var (stack, pre_p, NULL); 21412 if (align > 8) 21413 { 21414 /* if (alignof(type) > 8) (arg = arg + 15) & -16; */ 21415 t = fold_build_pointer_plus_hwi (arg, 15); 21416 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t, 21417 build_int_cst (TREE_TYPE (t), -16)); 21418 roundup = build2 (MODIFY_EXPR, TREE_TYPE (arg), arg, t); 21419 } 21420 else 21421 roundup = NULL; 21422 /* Advance ap.__stack */ 21423 t = fold_build_pointer_plus_hwi (arg, size + 7); 21424 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t, 21425 build_int_cst (TREE_TYPE (t), -8)); 21426 t = build2 (MODIFY_EXPR, TREE_TYPE (stack), unshare_expr (stack), t); 21427 /* String up roundup and advance. */ 21428 if (roundup) 21429 t = build2 (COMPOUND_EXPR, TREE_TYPE (t), roundup, t); 21430 /* String up with arg */ 21431 on_stack = build2 (COMPOUND_EXPR, TREE_TYPE (arg), t, arg); 21432 /* Big-endianness related address adjustment. */ 21433 if (BLOCK_REG_PADDING (mode, type, 1) == PAD_DOWNWARD 21434 && size < UNITS_PER_WORD) 21435 { 21436 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (arg), arg, 21437 size_int (UNITS_PER_WORD - size)); 21438 on_stack = build2 (COMPOUND_EXPR, TREE_TYPE (arg), on_stack, t); 21439 } 21440 21441 COND_EXPR_THEN (cond1) = unshare_expr (on_stack); 21442 COND_EXPR_THEN (cond2) = unshare_expr (on_stack); 21443 21444 /* Adjustment to OFFSET in the case of BIG_ENDIAN. */ 21445 t = off; 21446 if (adjust) 21447 t = build2 (PREINCREMENT_EXPR, TREE_TYPE (off), off, 21448 build_int_cst (TREE_TYPE (off), adjust)); 21449 21450 t = fold_convert (sizetype, t); 21451 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (f_top), f_top, t); 21452 21453 if (is_ha) 21454 { 21455 /* type ha; // treat as "struct {ftype field[n];}" 21456 ... [computing offs] 21457 for (i = 0; i <nregs; ++i, offs += 16) 21458 ha.field[i] = *((ftype *)(ap.__vr_top + offs)); 21459 return ha; */ 21460 int i; 21461 tree tmp_ha, field_t, field_ptr_t; 21462 21463 /* Declare a local variable. */ 21464 tmp_ha = create_tmp_var_raw (type, "ha"); 21465 gimple_add_tmp_var (tmp_ha); 21466 21467 /* Establish the base type. */ 21468 switch (ag_mode) 21469 { 21470 case E_SFmode: 21471 field_t = float_type_node; 21472 field_ptr_t = float_ptr_type_node; 21473 break; 21474 case E_DFmode: 21475 field_t = double_type_node; 21476 field_ptr_t = double_ptr_type_node; 21477 break; 21478 case E_TFmode: 21479 field_t = long_double_type_node; 21480 field_ptr_t = long_double_ptr_type_node; 21481 break; 21482 case E_SDmode: 21483 field_t = dfloat32_type_node; 21484 field_ptr_t = build_pointer_type (dfloat32_type_node); 21485 break; 21486 case E_DDmode: 21487 field_t = dfloat64_type_node; 21488 field_ptr_t = build_pointer_type (dfloat64_type_node); 21489 break; 21490 case E_TDmode: 21491 field_t = dfloat128_type_node; 21492 field_ptr_t = build_pointer_type (dfloat128_type_node); 21493 break; 21494 case E_HFmode: 21495 field_t = aarch64_fp16_type_node; 21496 field_ptr_t = aarch64_fp16_ptr_type_node; 21497 break; 21498 case E_BFmode: 21499 field_t = bfloat16_type_node; 21500 field_ptr_t = aarch64_bf16_ptr_type_node; 21501 break; 21502 case E_V2SImode: 21503 case E_V4SImode: 21504 { 21505 tree innertype = make_signed_type (GET_MODE_PRECISION (SImode)); 21506 field_t = build_vector_type_for_mode (innertype, ag_mode); 21507 field_ptr_t = build_pointer_type (field_t); 21508 } 21509 break; 21510 default: 21511 gcc_assert (0); 21512 } 21513 21514 /* *(field_ptr_t)&ha = *((field_ptr_t)vr_saved_area */ 21515 TREE_ADDRESSABLE (tmp_ha) = 1; 21516 tmp_ha = build1 (ADDR_EXPR, field_ptr_t, tmp_ha); 21517 addr = t; 21518 t = fold_convert (field_ptr_t, addr); 21519 t = build2 (MODIFY_EXPR, field_t, 21520 build1 (INDIRECT_REF, field_t, tmp_ha), 21521 build1 (INDIRECT_REF, field_t, t)); 21522 21523 /* ha.field[i] = *((field_ptr_t)vr_saved_area + i) */ 21524 for (i = 1; i < nregs; ++i) 21525 { 21526 addr = fold_build_pointer_plus_hwi (addr, UNITS_PER_VREG); 21527 u = fold_convert (field_ptr_t, addr); 21528 u = build2 (MODIFY_EXPR, field_t, 21529 build2 (MEM_REF, field_t, tmp_ha, 21530 build_int_cst (field_ptr_t, 21531 (i * 21532 int_size_in_bytes (field_t)))), 21533 build1 (INDIRECT_REF, field_t, u)); 21534 t = build2 (COMPOUND_EXPR, TREE_TYPE (t), t, u); 21535 } 21536 21537 u = fold_convert (TREE_TYPE (f_top), tmp_ha); 21538 t = build2 (COMPOUND_EXPR, TREE_TYPE (f_top), t, u); 21539 } 21540 21541 COND_EXPR_ELSE (cond2) = t; 21542 addr = fold_convert (build_pointer_type (type), cond1); 21543 addr = build_va_arg_indirect_ref (addr); 21544 21545 if (indirect_p) 21546 addr = build_va_arg_indirect_ref (addr); 21547 21548 return addr; 21549 } 21550 21551 /* Implement TARGET_SETUP_INCOMING_VARARGS. */ 21552 21553 static void 21554 aarch64_setup_incoming_varargs (cumulative_args_t cum_v, 21555 const function_arg_info &arg, 21556 int *pretend_size ATTRIBUTE_UNUSED, int no_rtl) 21557 { 21558 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 21559 CUMULATIVE_ARGS local_cum; 21560 int gr_saved = cfun->va_list_gpr_size; 21561 int vr_saved = cfun->va_list_fpr_size; 21562 21563 /* The caller has advanced CUM up to, but not beyond, the last named 21564 argument. Advance a local copy of CUM past the last "real" named 21565 argument, to find out how many registers are left over. */ 21566 local_cum = *cum; 21567 if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))) 21568 aarch64_function_arg_advance (pack_cumulative_args(&local_cum), arg); 21569 21570 /* Found out how many registers we need to save. 21571 Honor tree-stdvar analysis results. */ 21572 if (cfun->va_list_gpr_size) 21573 gr_saved = MIN (NUM_ARG_REGS - local_cum.aapcs_ncrn, 21574 cfun->va_list_gpr_size / UNITS_PER_WORD); 21575 if (cfun->va_list_fpr_size) 21576 vr_saved = MIN (NUM_FP_ARG_REGS - local_cum.aapcs_nvrn, 21577 cfun->va_list_fpr_size / UNITS_PER_VREG); 21578 21579 if (!TARGET_FLOAT) 21580 { 21581 gcc_assert (local_cum.aapcs_nvrn == 0); 21582 vr_saved = 0; 21583 } 21584 21585 if (!no_rtl) 21586 { 21587 if (gr_saved > 0) 21588 { 21589 rtx ptr, mem; 21590 21591 /* virtual_incoming_args_rtx should have been 16-byte aligned. */ 21592 ptr = plus_constant (Pmode, virtual_incoming_args_rtx, 21593 - gr_saved * UNITS_PER_WORD); 21594 mem = gen_frame_mem (BLKmode, ptr); 21595 set_mem_alias_set (mem, get_varargs_alias_set ()); 21596 21597 move_block_from_reg (local_cum.aapcs_ncrn + R0_REGNUM, 21598 mem, gr_saved); 21599 } 21600 if (vr_saved > 0) 21601 { 21602 /* We can't use move_block_from_reg, because it will use 21603 the wrong mode, storing D regs only. */ 21604 machine_mode mode = TImode; 21605 int off, i, vr_start; 21606 21607 /* Set OFF to the offset from virtual_incoming_args_rtx of 21608 the first vector register. The VR save area lies below 21609 the GR one, and is aligned to 16 bytes. */ 21610 off = -ROUND_UP (gr_saved * UNITS_PER_WORD, 21611 STACK_BOUNDARY / BITS_PER_UNIT); 21612 off -= vr_saved * UNITS_PER_VREG; 21613 21614 vr_start = V0_REGNUM + local_cum.aapcs_nvrn; 21615 for (i = 0; i < vr_saved; ++i) 21616 { 21617 rtx ptr, mem; 21618 21619 ptr = plus_constant (Pmode, virtual_incoming_args_rtx, off); 21620 mem = gen_frame_mem (mode, ptr); 21621 set_mem_alias_set (mem, get_varargs_alias_set ()); 21622 aarch64_emit_move (mem, gen_rtx_REG (mode, vr_start + i)); 21623 off += UNITS_PER_VREG; 21624 } 21625 } 21626 } 21627 21628 /* We don't save the size into *PRETEND_SIZE because we want to avoid 21629 any complication of having crtl->args.pretend_args_size changed. */ 21630 cfun->machine->frame.saved_varargs_size 21631 = (ROUND_UP (gr_saved * UNITS_PER_WORD, 21632 STACK_BOUNDARY / BITS_PER_UNIT) 21633 + vr_saved * UNITS_PER_VREG); 21634 } 21635 21636 static void 21637 aarch64_conditional_register_usage (void) 21638 { 21639 int i; 21640 if (!TARGET_FLOAT) 21641 { 21642 for (i = V0_REGNUM; i <= V31_REGNUM; i++) 21643 { 21644 fixed_regs[i] = 1; 21645 call_used_regs[i] = 1; 21646 CLEAR_HARD_REG_BIT (operand_reg_set, i); 21647 } 21648 } 21649 if (!TARGET_SVE) 21650 for (i = P0_REGNUM; i <= P15_REGNUM; i++) 21651 { 21652 fixed_regs[i] = 1; 21653 call_used_regs[i] = 1; 21654 } 21655 21656 /* Only allow these registers to be accessed via special patterns. */ 21657 CLEAR_HARD_REG_BIT (operand_reg_set, VG_REGNUM); 21658 CLEAR_HARD_REG_BIT (operand_reg_set, FFR_REGNUM); 21659 CLEAR_HARD_REG_BIT (operand_reg_set, FFRT_REGNUM); 21660 for (int i = FIRST_FAKE_REGNUM; i <= LAST_FAKE_REGNUM; ++i) 21661 CLEAR_HARD_REG_BIT (operand_reg_set, i); 21662 21663 /* When tracking speculation, we need a couple of call-clobbered registers 21664 to track the speculation state. It would be nice to just use 21665 IP0 and IP1, but currently there are numerous places that just 21666 assume these registers are free for other uses (eg pointer 21667 authentication). */ 21668 if (aarch64_track_speculation) 21669 { 21670 fixed_regs[SPECULATION_TRACKER_REGNUM] = 1; 21671 call_used_regs[SPECULATION_TRACKER_REGNUM] = 1; 21672 fixed_regs[SPECULATION_SCRATCH_REGNUM] = 1; 21673 call_used_regs[SPECULATION_SCRATCH_REGNUM] = 1; 21674 } 21675 } 21676 21677 /* Implement TARGET_MEMBER_TYPE_FORCES_BLK. */ 21678 21679 bool 21680 aarch64_member_type_forces_blk (const_tree field_or_array, machine_mode mode) 21681 { 21682 /* For records we're passed a FIELD_DECL, for arrays we're passed 21683 an ARRAY_TYPE. In both cases we're interested in the TREE_TYPE. */ 21684 const_tree type = TREE_TYPE (field_or_array); 21685 21686 /* Assign BLKmode to anything that contains more than 2 SVE predicates. 21687 For structures, the "multiple" case is indicated by MODE being 21688 VOIDmode. */ 21689 unsigned int num_zr, num_pr; 21690 if (aarch64_sve::builtin_type_p (type, &num_zr, &num_pr) && num_pr > 2) 21691 { 21692 if (TREE_CODE (field_or_array) == ARRAY_TYPE) 21693 return !simple_cst_equal (TYPE_SIZE (field_or_array), 21694 TYPE_SIZE (type)); 21695 return mode == VOIDmode; 21696 } 21697 21698 return default_member_type_forces_blk (field_or_array, mode); 21699 } 21700 21701 /* Bitmasks that indicate whether earlier versions of GCC would have 21702 taken a different path through the ABI logic. This should result in 21703 a -Wpsabi warning if the earlier path led to a different ABI decision. 21704 21705 WARN_PSABI_EMPTY_CXX17_BASE 21706 Indicates that the type includes an artificial empty C++17 base field 21707 that, prior to GCC 10.1, would prevent the type from being treated as 21708 a HFA or HVA. See PR94383 for details. 21709 21710 WARN_PSABI_NO_UNIQUE_ADDRESS 21711 Indicates that the type includes an empty [[no_unique_address]] field 21712 that, prior to GCC 10.1, would prevent the type from being treated as 21713 a HFA or HVA. */ 21714 const unsigned int WARN_PSABI_EMPTY_CXX17_BASE = 1U << 0; 21715 const unsigned int WARN_PSABI_NO_UNIQUE_ADDRESS = 1U << 1; 21716 const unsigned int WARN_PSABI_ZERO_WIDTH_BITFIELD = 1U << 2; 21717 21718 /* Walk down the type tree of TYPE counting consecutive base elements. 21719 If *MODEP is VOIDmode, then set it to the first valid floating point 21720 type. If a non-floating point type is found, or if a floating point 21721 type that doesn't match a non-VOIDmode *MODEP is found, then return -1, 21722 otherwise return the count in the sub-tree. 21723 21724 The WARN_PSABI_FLAGS argument allows the caller to check whether this 21725 function has changed its behavior relative to earlier versions of GCC. 21726 Normally the argument should be nonnull and point to a zero-initialized 21727 variable. The function then records whether the ABI decision might 21728 be affected by a known fix to the ABI logic, setting the associated 21729 WARN_PSABI_* bits if so. 21730 21731 When the argument is instead a null pointer, the function tries to 21732 simulate the behavior of GCC before all such ABI fixes were made. 21733 This is useful to check whether the function returns something 21734 different after the ABI fixes. */ 21735 static int 21736 aapcs_vfp_sub_candidate (const_tree type, machine_mode *modep, 21737 unsigned int *warn_psabi_flags) 21738 { 21739 machine_mode mode; 21740 HOST_WIDE_INT size; 21741 21742 if (aarch64_sve::builtin_type_p (type)) 21743 return -1; 21744 21745 switch (TREE_CODE (type)) 21746 { 21747 case REAL_TYPE: 21748 mode = TYPE_MODE (type); 21749 if (mode != DFmode && mode != SFmode 21750 && mode != TFmode && mode != HFmode 21751 && mode != SDmode && mode != DDmode && mode != TDmode) 21752 return -1; 21753 21754 if (*modep == VOIDmode) 21755 *modep = mode; 21756 21757 if (*modep == mode) 21758 return 1; 21759 21760 break; 21761 21762 case COMPLEX_TYPE: 21763 mode = TYPE_MODE (TREE_TYPE (type)); 21764 if (mode != DFmode && mode != SFmode 21765 && mode != TFmode && mode != HFmode) 21766 return -1; 21767 21768 if (*modep == VOIDmode) 21769 *modep = mode; 21770 21771 if (*modep == mode) 21772 return 2; 21773 21774 break; 21775 21776 case VECTOR_TYPE: 21777 /* Use V2SImode and V4SImode as representatives of all 64-bit 21778 and 128-bit vector types. */ 21779 size = int_size_in_bytes (type); 21780 switch (size) 21781 { 21782 case 8: 21783 mode = V2SImode; 21784 break; 21785 case 16: 21786 mode = V4SImode; 21787 break; 21788 default: 21789 return -1; 21790 } 21791 21792 if (*modep == VOIDmode) 21793 *modep = mode; 21794 21795 /* Vector modes are considered to be opaque: two vectors are 21796 equivalent for the purposes of being homogeneous aggregates 21797 if they are the same size. */ 21798 if (*modep == mode) 21799 return 1; 21800 21801 break; 21802 21803 case ARRAY_TYPE: 21804 { 21805 int count; 21806 tree index = TYPE_DOMAIN (type); 21807 21808 /* Can't handle incomplete types nor sizes that are not 21809 fixed. */ 21810 if (!COMPLETE_TYPE_P (type) 21811 || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) 21812 return -1; 21813 21814 count = aapcs_vfp_sub_candidate (TREE_TYPE (type), modep, 21815 warn_psabi_flags); 21816 if (count == -1 21817 || !index 21818 || !TYPE_MAX_VALUE (index) 21819 || !tree_fits_uhwi_p (TYPE_MAX_VALUE (index)) 21820 || !TYPE_MIN_VALUE (index) 21821 || !tree_fits_uhwi_p (TYPE_MIN_VALUE (index)) 21822 || count < 0) 21823 return -1; 21824 21825 count *= (1 + tree_to_uhwi (TYPE_MAX_VALUE (index)) 21826 - tree_to_uhwi (TYPE_MIN_VALUE (index))); 21827 21828 /* There must be no padding. */ 21829 if (maybe_ne (wi::to_poly_wide (TYPE_SIZE (type)), 21830 count * GET_MODE_BITSIZE (*modep))) 21831 return -1; 21832 21833 return count; 21834 } 21835 21836 case RECORD_TYPE: 21837 { 21838 int count = 0; 21839 int sub_count; 21840 tree field; 21841 21842 /* Can't handle incomplete types nor sizes that are not 21843 fixed. */ 21844 if (!COMPLETE_TYPE_P (type) 21845 || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) 21846 return -1; 21847 21848 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) 21849 { 21850 if (TREE_CODE (field) != FIELD_DECL) 21851 continue; 21852 21853 if (DECL_FIELD_ABI_IGNORED (field)) 21854 { 21855 /* See whether this is something that earlier versions of 21856 GCC failed to ignore. */ 21857 unsigned int flag; 21858 if (lookup_attribute ("no_unique_address", 21859 DECL_ATTRIBUTES (field))) 21860 flag = WARN_PSABI_NO_UNIQUE_ADDRESS; 21861 else if (cxx17_empty_base_field_p (field)) 21862 flag = WARN_PSABI_EMPTY_CXX17_BASE; 21863 else 21864 /* No compatibility problem. */ 21865 continue; 21866 21867 /* Simulate the old behavior when WARN_PSABI_FLAGS is null. */ 21868 if (warn_psabi_flags) 21869 { 21870 *warn_psabi_flags |= flag; 21871 continue; 21872 } 21873 } 21874 /* A zero-width bitfield may affect layout in some 21875 circumstances, but adds no members. The determination 21876 of whether or not a type is an HFA is performed after 21877 layout is complete, so if the type still looks like an 21878 HFA afterwards, it is still classed as one. This is 21879 potentially an ABI break for the hard-float ABI. */ 21880 else if (DECL_BIT_FIELD (field) 21881 && integer_zerop (DECL_SIZE (field))) 21882 { 21883 /* Prior to GCC-12 these fields were striped early, 21884 hiding them from the back-end entirely and 21885 resulting in the correct behaviour for argument 21886 passing. Simulate that old behaviour without 21887 generating a warning. */ 21888 if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field)) 21889 continue; 21890 if (warn_psabi_flags) 21891 { 21892 *warn_psabi_flags |= WARN_PSABI_ZERO_WIDTH_BITFIELD; 21893 continue; 21894 } 21895 } 21896 21897 sub_count = aapcs_vfp_sub_candidate (TREE_TYPE (field), modep, 21898 warn_psabi_flags); 21899 if (sub_count < 0) 21900 return -1; 21901 count += sub_count; 21902 } 21903 21904 /* There must be no padding. */ 21905 if (maybe_ne (wi::to_poly_wide (TYPE_SIZE (type)), 21906 count * GET_MODE_BITSIZE (*modep))) 21907 return -1; 21908 21909 return count; 21910 } 21911 21912 case UNION_TYPE: 21913 case QUAL_UNION_TYPE: 21914 { 21915 /* These aren't very interesting except in a degenerate case. */ 21916 int count = 0; 21917 int sub_count; 21918 tree field; 21919 21920 /* Can't handle incomplete types nor sizes that are not 21921 fixed. */ 21922 if (!COMPLETE_TYPE_P (type) 21923 || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) 21924 return -1; 21925 21926 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) 21927 { 21928 if (TREE_CODE (field) != FIELD_DECL) 21929 continue; 21930 21931 sub_count = aapcs_vfp_sub_candidate (TREE_TYPE (field), modep, 21932 warn_psabi_flags); 21933 if (sub_count < 0) 21934 return -1; 21935 count = count > sub_count ? count : sub_count; 21936 } 21937 21938 /* There must be no padding. */ 21939 if (maybe_ne (wi::to_poly_wide (TYPE_SIZE (type)), 21940 count * GET_MODE_BITSIZE (*modep))) 21941 return -1; 21942 21943 return count; 21944 } 21945 21946 default: 21947 break; 21948 } 21949 21950 return -1; 21951 } 21952 21953 /* Return TRUE if the type, as described by TYPE and MODE, is a short vector 21954 type as described in AAPCS64 \S 4.1.2. 21955 21956 See the comment above aarch64_composite_type_p for the notes on MODE. */ 21957 21958 static bool 21959 aarch64_short_vector_p (const_tree type, 21960 machine_mode mode) 21961 { 21962 poly_int64 size = -1; 21963 21964 if (type && VECTOR_TYPE_P (type)) 21965 { 21966 if (aarch64_sve::builtin_type_p (type)) 21967 return false; 21968 size = int_size_in_bytes (type); 21969 } 21970 else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT 21971 || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT) 21972 { 21973 /* The containing "else if" is too loose: it means that we look at TYPE 21974 if the type is a vector type (good), but that we otherwise ignore TYPE 21975 and look only at the mode. This is wrong because the type describes 21976 the language-level information whereas the mode is purely an internal 21977 GCC concept. We can therefore reach here for types that are not 21978 vectors in the AAPCS64 sense. 21979 21980 We can't "fix" that for the traditional Advanced SIMD vector modes 21981 without breaking backwards compatibility. However, there's no such 21982 baggage for the structure modes, which were introduced in GCC 12. */ 21983 if (aarch64_advsimd_struct_mode_p (mode)) 21984 return false; 21985 21986 /* For similar reasons, rely only on the type, not the mode, when 21987 processing SVE types. */ 21988 if (type && aarch64_some_values_include_pst_objects_p (type)) 21989 /* Leave later code to report an error if SVE is disabled. */ 21990 gcc_assert (!TARGET_SVE || aarch64_sve_mode_p (mode)); 21991 else 21992 size = GET_MODE_SIZE (mode); 21993 } 21994 if (known_eq (size, 8) || known_eq (size, 16)) 21995 { 21996 /* 64-bit and 128-bit vectors should only acquire an SVE mode if 21997 they are being treated as scalable AAPCS64 types. */ 21998 gcc_assert (!aarch64_sve_mode_p (mode) 21999 && !aarch64_advsimd_struct_mode_p (mode)); 22000 return true; 22001 } 22002 return false; 22003 } 22004 22005 /* Return TRUE if the type, as described by TYPE and MODE, is a composite 22006 type as described in AAPCS64 \S 4.3. This includes aggregate, union and 22007 array types. The C99 floating-point complex types are also considered 22008 as composite types, according to AAPCS64 \S 7.1.1. The complex integer 22009 types, which are GCC extensions and out of the scope of AAPCS64, are 22010 treated as composite types here as well. 22011 22012 Note that MODE itself is not sufficient in determining whether a type 22013 is such a composite type or not. This is because 22014 stor-layout.cc:compute_record_mode may have already changed the MODE 22015 (BLKmode) of a RECORD_TYPE TYPE to some other mode. For example, a 22016 structure with only one field may have its MODE set to the mode of the 22017 field. Also an integer mode whose size matches the size of the 22018 RECORD_TYPE type may be used to substitute the original mode 22019 (i.e. BLKmode) in certain circumstances. In other words, MODE cannot be 22020 solely relied on. */ 22021 22022 static bool 22023 aarch64_composite_type_p (const_tree type, 22024 machine_mode mode) 22025 { 22026 if (aarch64_short_vector_p (type, mode)) 22027 return false; 22028 22029 if (type && (AGGREGATE_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE)) 22030 return true; 22031 22032 if (type 22033 && TREE_CODE (type) == BITINT_TYPE 22034 && int_size_in_bytes (type) > 16) 22035 return true; 22036 22037 if (mode == BLKmode 22038 || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT 22039 || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) 22040 return true; 22041 22042 return false; 22043 } 22044 22045 /* Return TRUE if an argument, whose type is described by TYPE and MODE, 22046 shall be passed or returned in simd/fp register(s) (providing these 22047 parameter passing registers are available). 22048 22049 Upon successful return, *COUNT returns the number of needed registers, 22050 *BASE_MODE returns the mode of the individual register and when IS_HA 22051 is not NULL, *IS_HA indicates whether or not the argument is a homogeneous 22052 floating-point aggregate or a homogeneous short-vector aggregate. 22053 22054 SILENT_P is true if the function should refrain from reporting any 22055 diagnostics. This should only be used if the caller is certain that 22056 any ABI decisions would eventually come through this function with 22057 SILENT_P set to false. */ 22058 22059 static bool 22060 aarch64_vfp_is_call_or_return_candidate (machine_mode mode, 22061 const_tree type, 22062 machine_mode *base_mode, 22063 int *count, 22064 bool *is_ha, 22065 bool silent_p) 22066 { 22067 if (is_ha != NULL) *is_ha = false; 22068 22069 machine_mode new_mode = VOIDmode; 22070 bool composite_p = aarch64_composite_type_p (type, mode); 22071 22072 if ((!composite_p 22073 && (GET_MODE_CLASS (mode) == MODE_FLOAT 22074 || GET_MODE_CLASS (mode) == MODE_DECIMAL_FLOAT)) 22075 || aarch64_short_vector_p (type, mode)) 22076 { 22077 *count = 1; 22078 new_mode = mode; 22079 } 22080 else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT) 22081 { 22082 if (is_ha != NULL) *is_ha = true; 22083 *count = 2; 22084 new_mode = GET_MODE_INNER (mode); 22085 } 22086 else if (type && composite_p) 22087 { 22088 unsigned int warn_psabi_flags = 0; 22089 int ag_count = aapcs_vfp_sub_candidate (type, &new_mode, 22090 &warn_psabi_flags); 22091 if (ag_count > 0 && ag_count <= HA_MAX_NUM_FLDS) 22092 { 22093 static unsigned last_reported_type_uid; 22094 unsigned uid = TYPE_UID (TYPE_MAIN_VARIANT (type)); 22095 int alt; 22096 if (!silent_p 22097 && warn_psabi 22098 && warn_psabi_flags 22099 && uid != last_reported_type_uid 22100 && ((alt = aapcs_vfp_sub_candidate (type, &new_mode, NULL)) 22101 != ag_count)) 22102 { 22103 const char *url10 22104 = CHANGES_ROOT_URL "gcc-10/changes.html#empty_base"; 22105 const char *url12 22106 = CHANGES_ROOT_URL "gcc-12/changes.html#zero_width_bitfields"; 22107 gcc_assert (alt == -1); 22108 last_reported_type_uid = uid; 22109 /* Use TYPE_MAIN_VARIANT to strip any redundant const 22110 qualification. */ 22111 if (warn_psabi_flags & WARN_PSABI_NO_UNIQUE_ADDRESS) 22112 inform (input_location, "parameter passing for argument of " 22113 "type %qT with %<[[no_unique_address]]%> members " 22114 "changed %{in GCC 10.1%}", 22115 TYPE_MAIN_VARIANT (type), url10); 22116 else if (warn_psabi_flags & WARN_PSABI_EMPTY_CXX17_BASE) 22117 inform (input_location, "parameter passing for argument of " 22118 "type %qT when C++17 is enabled changed to match " 22119 "C++14 %{in GCC 10.1%}", 22120 TYPE_MAIN_VARIANT (type), url10); 22121 else if (warn_psabi_flags & WARN_PSABI_ZERO_WIDTH_BITFIELD) 22122 inform (input_location, "parameter passing for argument of " 22123 "type %qT changed %{in GCC 12.1%}", 22124 TYPE_MAIN_VARIANT (type), url12); 22125 } 22126 22127 if (is_ha != NULL) *is_ha = true; 22128 *count = ag_count; 22129 } 22130 else 22131 return false; 22132 } 22133 else 22134 return false; 22135 22136 gcc_assert (!aarch64_sve_mode_p (new_mode)); 22137 *base_mode = new_mode; 22138 return true; 22139 } 22140 22141 /* Implement TARGET_STRUCT_VALUE_RTX. */ 22142 22143 static rtx 22144 aarch64_struct_value_rtx (tree fndecl ATTRIBUTE_UNUSED, 22145 int incoming ATTRIBUTE_UNUSED) 22146 { 22147 return gen_rtx_REG (Pmode, AARCH64_STRUCT_VALUE_REGNUM); 22148 } 22149 22150 /* Implements target hook vector_mode_supported_p. */ 22151 static bool 22152 aarch64_vector_mode_supported_p (machine_mode mode) 22153 { 22154 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 22155 return vec_flags != 0 && (vec_flags & VEC_STRUCT) == 0; 22156 } 22157 22158 /* Implements target hook vector_mode_supported_any_target_p. */ 22159 static bool 22160 aarch64_vector_mode_supported_any_target_p (machine_mode mode) 22161 { 22162 unsigned int vec_flags = aarch64_classify_vector_mode (mode, true); 22163 return vec_flags != 0 && (vec_flags & VEC_STRUCT) == 0; 22164 } 22165 22166 /* Return the full-width SVE vector mode for element mode MODE, if one 22167 exists. */ 22168 opt_machine_mode 22169 aarch64_full_sve_mode (scalar_mode mode) 22170 { 22171 switch (mode) 22172 { 22173 case E_DFmode: 22174 return VNx2DFmode; 22175 case E_SFmode: 22176 return VNx4SFmode; 22177 case E_HFmode: 22178 return VNx8HFmode; 22179 case E_BFmode: 22180 return VNx8BFmode; 22181 case E_DImode: 22182 return VNx2DImode; 22183 case E_SImode: 22184 return VNx4SImode; 22185 case E_HImode: 22186 return VNx8HImode; 22187 case E_QImode: 22188 return VNx16QImode; 22189 default: 22190 return opt_machine_mode (); 22191 } 22192 } 22193 22194 /* Return the 128-bit Advanced SIMD vector mode for element mode MODE, 22195 if it exists. */ 22196 opt_machine_mode 22197 aarch64_vq_mode (scalar_mode mode) 22198 { 22199 switch (mode) 22200 { 22201 case E_DFmode: 22202 return V2DFmode; 22203 case E_SFmode: 22204 return V4SFmode; 22205 case E_HFmode: 22206 return V8HFmode; 22207 case E_BFmode: 22208 return V8BFmode; 22209 case E_SImode: 22210 return V4SImode; 22211 case E_HImode: 22212 return V8HImode; 22213 case E_QImode: 22214 return V16QImode; 22215 case E_DImode: 22216 return V2DImode; 22217 default: 22218 return opt_machine_mode (); 22219 } 22220 } 22221 22222 /* Return appropriate SIMD container 22223 for MODE within a vector of WIDTH bits. */ 22224 static machine_mode 22225 aarch64_simd_container_mode (scalar_mode mode, poly_int64 width) 22226 { 22227 if (TARGET_SVE 22228 && maybe_ne (width, 128) 22229 && known_eq (width, BITS_PER_SVE_VECTOR)) 22230 return aarch64_full_sve_mode (mode).else_mode (word_mode); 22231 22232 gcc_assert (known_eq (width, 64) || known_eq (width, 128)); 22233 if (TARGET_BASE_SIMD) 22234 { 22235 if (known_eq (width, 128)) 22236 return aarch64_vq_mode (mode).else_mode (word_mode); 22237 else 22238 switch (mode) 22239 { 22240 case E_SFmode: 22241 return V2SFmode; 22242 case E_HFmode: 22243 return V4HFmode; 22244 case E_BFmode: 22245 return V4BFmode; 22246 case E_SImode: 22247 return V2SImode; 22248 case E_HImode: 22249 return V4HImode; 22250 case E_QImode: 22251 return V8QImode; 22252 default: 22253 break; 22254 } 22255 } 22256 return word_mode; 22257 } 22258 22259 /* Compare an SVE mode SVE_M and an Advanced SIMD mode ASIMD_M 22260 and return whether the SVE mode should be preferred over the 22261 Advanced SIMD one in aarch64_autovectorize_vector_modes. */ 22262 static bool 22263 aarch64_cmp_autovec_modes (machine_mode sve_m, machine_mode asimd_m) 22264 { 22265 /* Take into account the aarch64-autovec-preference param if non-zero. */ 22266 bool only_asimd_p = aarch64_autovec_preference == 1; 22267 bool only_sve_p = aarch64_autovec_preference == 2; 22268 22269 if (only_asimd_p) 22270 return false; 22271 if (only_sve_p) 22272 return true; 22273 22274 /* The preference in case of a tie in costs. */ 22275 bool prefer_asimd = aarch64_autovec_preference == 3; 22276 bool prefer_sve = aarch64_autovec_preference == 4; 22277 22278 poly_int64 nunits_sve = GET_MODE_NUNITS (sve_m); 22279 poly_int64 nunits_asimd = GET_MODE_NUNITS (asimd_m); 22280 /* If the CPU information does not have an SVE width registered use the 22281 generic poly_int comparison that prefers SVE. If a preference is 22282 explicitly requested avoid this path. */ 22283 if (aarch64_tune_params.sve_width == SVE_SCALABLE 22284 && !prefer_asimd 22285 && !prefer_sve) 22286 return maybe_gt (nunits_sve, nunits_asimd); 22287 22288 /* Otherwise estimate the runtime width of the modes involved. */ 22289 HOST_WIDE_INT est_sve = estimated_poly_value (nunits_sve); 22290 HOST_WIDE_INT est_asimd = estimated_poly_value (nunits_asimd); 22291 22292 /* Preferring SVE means picking it first unless the Advanced SIMD mode 22293 is clearly wider. */ 22294 if (prefer_sve) 22295 return est_sve >= est_asimd; 22296 /* Conversely, preferring Advanced SIMD means picking SVE only if SVE 22297 is clearly wider. */ 22298 if (prefer_asimd) 22299 return est_sve > est_asimd; 22300 22301 /* In the default case prefer Advanced SIMD over SVE in case of a tie. */ 22302 return est_sve > est_asimd; 22303 } 22304 22305 /* Return 128-bit container as the preferred SIMD mode for MODE. */ 22306 static machine_mode 22307 aarch64_preferred_simd_mode (scalar_mode mode) 22308 { 22309 /* Take into account explicit auto-vectorization ISA preferences through 22310 aarch64_cmp_autovec_modes. */ 22311 if (TARGET_SVE && aarch64_cmp_autovec_modes (VNx16QImode, V16QImode)) 22312 return aarch64_full_sve_mode (mode).else_mode (word_mode); 22313 if (TARGET_SIMD) 22314 return aarch64_vq_mode (mode).else_mode (word_mode); 22315 return word_mode; 22316 } 22317 22318 /* Return a list of possible vector sizes for the vectorizer 22319 to iterate over. */ 22320 static unsigned int 22321 aarch64_autovectorize_vector_modes (vector_modes *modes, bool) 22322 { 22323 static const machine_mode sve_modes[] = { 22324 /* Try using full vectors for all element types. */ 22325 VNx16QImode, 22326 22327 /* Try using 16-bit containers for 8-bit elements and full vectors 22328 for wider elements. */ 22329 VNx8QImode, 22330 22331 /* Try using 32-bit containers for 8-bit and 16-bit elements and 22332 full vectors for wider elements. */ 22333 VNx4QImode, 22334 22335 /* Try using 64-bit containers for all element types. */ 22336 VNx2QImode 22337 }; 22338 22339 static const machine_mode advsimd_modes[] = { 22340 /* Try using 128-bit vectors for all element types. */ 22341 V16QImode, 22342 22343 /* Try using 64-bit vectors for 8-bit elements and 128-bit vectors 22344 for wider elements. */ 22345 V8QImode, 22346 22347 /* Try using 64-bit vectors for 16-bit elements and 128-bit vectors 22348 for wider elements. 22349 22350 TODO: We could support a limited form of V4QImode too, so that 22351 we use 32-bit vectors for 8-bit elements. */ 22352 V4HImode, 22353 22354 /* Try using 64-bit vectors for 32-bit elements and 128-bit vectors 22355 for 64-bit elements. 22356 22357 TODO: We could similarly support limited forms of V2QImode and V2HImode 22358 for this case. */ 22359 V2SImode 22360 }; 22361 22362 /* Try using N-byte SVE modes only after trying N-byte Advanced SIMD mode. 22363 This is because: 22364 22365 - If we can't use N-byte Advanced SIMD vectors then the placement 22366 doesn't matter; we'll just continue as though the Advanced SIMD 22367 entry didn't exist. 22368 22369 - If an SVE main loop with N bytes ends up being cheaper than an 22370 Advanced SIMD main loop with N bytes then by default we'll replace 22371 the Advanced SIMD version with the SVE one. 22372 22373 - If an Advanced SIMD main loop with N bytes ends up being cheaper 22374 than an SVE main loop with N bytes then by default we'll try to 22375 use the SVE loop to vectorize the epilogue instead. */ 22376 22377 bool only_asimd_p = aarch64_autovec_preference == 1; 22378 bool only_sve_p = aarch64_autovec_preference == 2; 22379 22380 unsigned int sve_i = (TARGET_SVE && !only_asimd_p) ? 0 : ARRAY_SIZE (sve_modes); 22381 unsigned int advsimd_i = 0; 22382 22383 while (!only_sve_p && advsimd_i < ARRAY_SIZE (advsimd_modes)) 22384 { 22385 if (sve_i < ARRAY_SIZE (sve_modes) 22386 && aarch64_cmp_autovec_modes (sve_modes[sve_i], 22387 advsimd_modes[advsimd_i])) 22388 modes->safe_push (sve_modes[sve_i++]); 22389 else 22390 modes->safe_push (advsimd_modes[advsimd_i++]); 22391 } 22392 while (sve_i < ARRAY_SIZE (sve_modes)) 22393 modes->safe_push (sve_modes[sve_i++]); 22394 22395 unsigned int flags = 0; 22396 if (aarch64_vect_compare_costs) 22397 flags |= VECT_COMPARE_COSTS; 22398 return flags; 22399 } 22400 22401 /* Implement TARGET_MANGLE_TYPE. */ 22402 22403 static const char * 22404 aarch64_mangle_type (const_tree type) 22405 { 22406 /* The AArch64 ABI documents say that "__va_list" has to be 22407 mangled as if it is in the "std" namespace. */ 22408 if (lang_hooks.types_compatible_p (CONST_CAST_TREE (type), va_list_type)) 22409 return "St9__va_list"; 22410 22411 /* Half-precision floating point types. */ 22412 if (SCALAR_FLOAT_TYPE_P (type) && TYPE_PRECISION (type) == 16) 22413 { 22414 if (TYPE_MAIN_VARIANT (type) == float16_type_node) 22415 return NULL; 22416 if (TYPE_MODE (type) == BFmode) 22417 return "u6__bf16"; 22418 else 22419 return "Dh"; 22420 } 22421 22422 /* Mangle AArch64-specific internal types. TYPE_NAME is non-NULL_TREE for 22423 builtin types. */ 22424 if (TYPE_NAME (type) != NULL) 22425 { 22426 const char *res; 22427 if ((res = aarch64_general_mangle_builtin_type (type)) 22428 || (res = aarch64_sve::mangle_builtin_type (type))) 22429 return res; 22430 } 22431 22432 /* Use the default mangling. */ 22433 return NULL; 22434 } 22435 22436 /* Implement TARGET_VERIFY_TYPE_CONTEXT. */ 22437 22438 static bool 22439 aarch64_verify_type_context (location_t loc, type_context_kind context, 22440 const_tree type, bool silent_p) 22441 { 22442 return aarch64_sve::verify_type_context (loc, context, type, silent_p); 22443 } 22444 22445 /* Find the first rtx_insn before insn that will generate an assembly 22446 instruction. */ 22447 22448 static rtx_insn * 22449 aarch64_prev_real_insn (rtx_insn *insn) 22450 { 22451 if (!insn) 22452 return NULL; 22453 22454 do 22455 { 22456 insn = prev_real_insn (insn); 22457 } 22458 while (insn && recog_memoized (insn) < 0); 22459 22460 return insn; 22461 } 22462 22463 static bool 22464 is_madd_op (enum attr_type t1) 22465 { 22466 unsigned int i; 22467 /* A number of these may be AArch32 only. */ 22468 enum attr_type mlatypes[] = { 22469 TYPE_MLA, TYPE_MLAS, TYPE_SMLAD, TYPE_SMLADX, TYPE_SMLAL, TYPE_SMLALD, 22470 TYPE_SMLALS, TYPE_SMLALXY, TYPE_SMLAWX, TYPE_SMLAWY, TYPE_SMLAXY, 22471 TYPE_SMMLA, TYPE_UMLAL, TYPE_UMLALS,TYPE_SMLSD, TYPE_SMLSDX, TYPE_SMLSLD 22472 }; 22473 22474 for (i = 0; i < ARRAY_SIZE (mlatypes); i++) 22475 { 22476 if (t1 == mlatypes[i]) 22477 return true; 22478 } 22479 22480 return false; 22481 } 22482 22483 /* Check if there is a register dependency between a load and the insn 22484 for which we hold recog_data. */ 22485 22486 static bool 22487 dep_between_memop_and_curr (rtx memop) 22488 { 22489 rtx load_reg; 22490 int opno; 22491 22492 gcc_assert (GET_CODE (memop) == SET); 22493 22494 if (!REG_P (SET_DEST (memop))) 22495 return false; 22496 22497 load_reg = SET_DEST (memop); 22498 for (opno = 1; opno < recog_data.n_operands; opno++) 22499 { 22500 rtx operand = recog_data.operand[opno]; 22501 if (REG_P (operand) 22502 && reg_overlap_mentioned_p (load_reg, operand)) 22503 return true; 22504 22505 } 22506 return false; 22507 } 22508 22509 22510 /* When working around the Cortex-A53 erratum 835769, 22511 given rtx_insn INSN, return true if it is a 64-bit multiply-accumulate 22512 instruction and has a preceding memory instruction such that a NOP 22513 should be inserted between them. */ 22514 22515 bool 22516 aarch64_madd_needs_nop (rtx_insn* insn) 22517 { 22518 enum attr_type attr_type; 22519 rtx_insn *prev; 22520 rtx body; 22521 22522 if (!TARGET_FIX_ERR_A53_835769) 22523 return false; 22524 22525 if (!INSN_P (insn) || recog_memoized (insn) < 0) 22526 return false; 22527 22528 attr_type = get_attr_type (insn); 22529 if (!is_madd_op (attr_type)) 22530 return false; 22531 22532 prev = aarch64_prev_real_insn (insn); 22533 /* aarch64_prev_real_insn can call recog_memoized on insns other than INSN. 22534 Restore recog state to INSN to avoid state corruption. */ 22535 extract_constrain_insn_cached (insn); 22536 22537 if (!prev || !contains_mem_rtx_p (PATTERN (prev))) 22538 return false; 22539 22540 body = single_set (prev); 22541 22542 /* If the previous insn is a memory op and there is no dependency between 22543 it and the DImode madd, emit a NOP between them. If body is NULL then we 22544 have a complex memory operation, probably a load/store pair. 22545 Be conservative for now and emit a NOP. */ 22546 if (GET_MODE (recog_data.operand[0]) == DImode 22547 && (!body || !dep_between_memop_and_curr (body))) 22548 return true; 22549 22550 return false; 22551 22552 } 22553 22554 22555 /* Implement FINAL_PRESCAN_INSN. */ 22556 22557 void 22558 aarch64_final_prescan_insn (rtx_insn *insn) 22559 { 22560 if (aarch64_madd_needs_nop (insn)) 22561 fprintf (asm_out_file, "\tnop // between mem op and mult-accumulate\n"); 22562 } 22563 22564 22565 /* Return true if BASE_OR_STEP is a valid immediate operand for an SVE INDEX 22566 instruction. */ 22567 22568 bool 22569 aarch64_sve_index_immediate_p (rtx base_or_step) 22570 { 22571 return (CONST_INT_P (base_or_step) 22572 && IN_RANGE (INTVAL (base_or_step), -16, 15)); 22573 } 22574 22575 /* Return true if X is a valid immediate for the SVE ADD and SUB instructions 22576 when applied to mode MODE. Negate X first if NEGATE_P is true. */ 22577 22578 bool 22579 aarch64_sve_arith_immediate_p (machine_mode mode, rtx x, bool negate_p) 22580 { 22581 rtx elt = unwrap_const_vec_duplicate (x); 22582 if (!CONST_INT_P (elt)) 22583 return false; 22584 22585 HOST_WIDE_INT val = INTVAL (elt); 22586 if (negate_p) 22587 val = -val; 22588 val &= GET_MODE_MASK (GET_MODE_INNER (mode)); 22589 22590 if (val & 0xff) 22591 return IN_RANGE (val, 0, 0xff); 22592 return IN_RANGE (val, 0, 0xff00); 22593 } 22594 22595 /* Return true if X is a valid immediate for the SVE SQADD and SQSUB 22596 instructions when applied to mode MODE. Negate X first if NEGATE_P 22597 is true. */ 22598 22599 bool 22600 aarch64_sve_sqadd_sqsub_immediate_p (machine_mode mode, rtx x, bool negate_p) 22601 { 22602 if (!aarch64_sve_arith_immediate_p (mode, x, negate_p)) 22603 return false; 22604 22605 /* After the optional negation, the immediate must be nonnegative. 22606 E.g. a saturating add of -127 must be done via SQSUB Zn.B, Zn.B, #127 22607 instead of SQADD Zn.B, Zn.B, #129. */ 22608 rtx elt = unwrap_const_vec_duplicate (x); 22609 return negate_p == (INTVAL (elt) < 0); 22610 } 22611 22612 /* Return true if X is a valid immediate operand for an SVE logical 22613 instruction such as AND. */ 22614 22615 bool 22616 aarch64_sve_bitmask_immediate_p (rtx x) 22617 { 22618 rtx elt; 22619 22620 return (const_vec_duplicate_p (x, &elt) 22621 && CONST_INT_P (elt) 22622 && aarch64_bitmask_imm (INTVAL (elt), 22623 GET_MODE_INNER (GET_MODE (x)))); 22624 } 22625 22626 /* Return true if X is a valid immediate for the SVE DUP and CPY 22627 instructions. */ 22628 22629 bool 22630 aarch64_sve_dup_immediate_p (rtx x) 22631 { 22632 x = aarch64_bit_representation (unwrap_const_vec_duplicate (x)); 22633 if (!CONST_INT_P (x)) 22634 return false; 22635 22636 HOST_WIDE_INT val = INTVAL (x); 22637 if (val & 0xff) 22638 return IN_RANGE (val, -0x80, 0x7f); 22639 return IN_RANGE (val, -0x8000, 0x7f00); 22640 } 22641 22642 /* Return true if X is a valid immediate operand for an SVE CMP instruction. 22643 SIGNED_P says whether the operand is signed rather than unsigned. */ 22644 22645 bool 22646 aarch64_sve_cmp_immediate_p (rtx x, bool signed_p) 22647 { 22648 x = unwrap_const_vec_duplicate (x); 22649 return (CONST_INT_P (x) 22650 && (signed_p 22651 ? IN_RANGE (INTVAL (x), -16, 15) 22652 : IN_RANGE (INTVAL (x), 0, 127))); 22653 } 22654 22655 /* Return true if X is a valid immediate operand for an SVE FADD or FSUB 22656 instruction. Negate X first if NEGATE_P is true. */ 22657 22658 bool 22659 aarch64_sve_float_arith_immediate_p (rtx x, bool negate_p) 22660 { 22661 rtx elt; 22662 REAL_VALUE_TYPE r; 22663 22664 if (!const_vec_duplicate_p (x, &elt) 22665 || !CONST_DOUBLE_P (elt)) 22666 return false; 22667 22668 r = *CONST_DOUBLE_REAL_VALUE (elt); 22669 22670 if (negate_p) 22671 r = real_value_negate (&r); 22672 22673 if (real_equal (&r, &dconst1)) 22674 return true; 22675 if (real_equal (&r, &dconsthalf)) 22676 return true; 22677 return false; 22678 } 22679 22680 /* Return true if X is a valid immediate operand for an SVE FMUL 22681 instruction. */ 22682 22683 bool 22684 aarch64_sve_float_mul_immediate_p (rtx x) 22685 { 22686 rtx elt; 22687 22688 return (const_vec_duplicate_p (x, &elt) 22689 && CONST_DOUBLE_P (elt) 22690 && (real_equal (CONST_DOUBLE_REAL_VALUE (elt), &dconsthalf) 22691 || real_equal (CONST_DOUBLE_REAL_VALUE (elt), &dconst2))); 22692 } 22693 22694 /* Return true if replicating VAL32 is a valid 2-byte or 4-byte immediate 22695 for the Advanced SIMD operation described by WHICH and INSN. If INFO 22696 is nonnull, use it to describe valid immediates. */ 22697 static bool 22698 aarch64_advsimd_valid_immediate_hs (unsigned int val32, 22699 simd_immediate_info *info, 22700 enum simd_immediate_check which, 22701 simd_immediate_info::insn_type insn) 22702 { 22703 /* Try a 4-byte immediate with LSL. */ 22704 for (unsigned int shift = 0; shift < 32; shift += 8) 22705 if ((val32 & (0xff << shift)) == val32) 22706 { 22707 if (info) 22708 *info = simd_immediate_info (SImode, val32 >> shift, insn, 22709 simd_immediate_info::LSL, shift); 22710 return true; 22711 } 22712 22713 /* Try a 2-byte immediate with LSL. */ 22714 unsigned int imm16 = val32 & 0xffff; 22715 if (imm16 == (val32 >> 16)) 22716 for (unsigned int shift = 0; shift < 16; shift += 8) 22717 if ((imm16 & (0xff << shift)) == imm16) 22718 { 22719 if (info) 22720 *info = simd_immediate_info (HImode, imm16 >> shift, insn, 22721 simd_immediate_info::LSL, shift); 22722 return true; 22723 } 22724 22725 /* Try a 4-byte immediate with MSL, except for cases that MVN 22726 can handle. */ 22727 if (which == AARCH64_CHECK_MOV) 22728 for (unsigned int shift = 8; shift < 24; shift += 8) 22729 { 22730 unsigned int low = (1 << shift) - 1; 22731 if (((val32 & (0xff << shift)) | low) == val32) 22732 { 22733 if (info) 22734 *info = simd_immediate_info (SImode, val32 >> shift, insn, 22735 simd_immediate_info::MSL, shift); 22736 return true; 22737 } 22738 } 22739 22740 return false; 22741 } 22742 22743 /* Return true if replicating VAL64 is a valid immediate for the 22744 Advanced SIMD operation described by WHICH. If INFO is nonnull, 22745 use it to describe valid immediates. */ 22746 static bool 22747 aarch64_advsimd_valid_immediate (unsigned HOST_WIDE_INT val64, 22748 simd_immediate_info *info, 22749 enum simd_immediate_check which) 22750 { 22751 unsigned int val32 = val64 & 0xffffffff; 22752 unsigned int val16 = val64 & 0xffff; 22753 unsigned int val8 = val64 & 0xff; 22754 22755 if (val32 == (val64 >> 32)) 22756 { 22757 if ((which & AARCH64_CHECK_ORR) != 0 22758 && aarch64_advsimd_valid_immediate_hs (val32, info, which, 22759 simd_immediate_info::MOV)) 22760 return true; 22761 22762 if ((which & AARCH64_CHECK_BIC) != 0 22763 && aarch64_advsimd_valid_immediate_hs (~val32, info, which, 22764 simd_immediate_info::MVN)) 22765 return true; 22766 22767 /* Try using a replicated byte. */ 22768 if (which == AARCH64_CHECK_MOV 22769 && val16 == (val32 >> 16) 22770 && val8 == (val16 >> 8)) 22771 { 22772 if (info) 22773 *info = simd_immediate_info (QImode, val8); 22774 return true; 22775 } 22776 } 22777 22778 /* Try using a bit-to-bytemask. */ 22779 if (which == AARCH64_CHECK_MOV) 22780 { 22781 unsigned int i; 22782 for (i = 0; i < 64; i += 8) 22783 { 22784 unsigned char byte = (val64 >> i) & 0xff; 22785 if (byte != 0 && byte != 0xff) 22786 break; 22787 } 22788 if (i == 64) 22789 { 22790 if (info) 22791 *info = simd_immediate_info (DImode, val64); 22792 return true; 22793 } 22794 } 22795 return false; 22796 } 22797 22798 /* Return true if replicating VAL64 gives a valid immediate for an SVE MOV 22799 instruction. If INFO is nonnull, use it to describe valid immediates. */ 22800 22801 static bool 22802 aarch64_sve_valid_immediate (unsigned HOST_WIDE_INT val64, 22803 simd_immediate_info *info) 22804 { 22805 scalar_int_mode mode = DImode; 22806 unsigned int val32 = val64 & 0xffffffff; 22807 if (val32 == (val64 >> 32)) 22808 { 22809 mode = SImode; 22810 unsigned int val16 = val32 & 0xffff; 22811 if (val16 == (val32 >> 16)) 22812 { 22813 mode = HImode; 22814 unsigned int val8 = val16 & 0xff; 22815 if (val8 == (val16 >> 8)) 22816 mode = QImode; 22817 } 22818 } 22819 HOST_WIDE_INT val = trunc_int_for_mode (val64, mode); 22820 if (IN_RANGE (val, -0x80, 0x7f)) 22821 { 22822 /* DUP with no shift. */ 22823 if (info) 22824 *info = simd_immediate_info (mode, val); 22825 return true; 22826 } 22827 if ((val & 0xff) == 0 && IN_RANGE (val, -0x8000, 0x7f00)) 22828 { 22829 /* DUP with LSL #8. */ 22830 if (info) 22831 *info = simd_immediate_info (mode, val); 22832 return true; 22833 } 22834 if (aarch64_bitmask_imm (val64, mode)) 22835 { 22836 /* DUPM. */ 22837 if (info) 22838 *info = simd_immediate_info (mode, val); 22839 return true; 22840 } 22841 return false; 22842 } 22843 22844 /* Return true if X is an UNSPEC_PTRUE constant of the form: 22845 22846 (const (unspec [PATTERN ZERO] UNSPEC_PTRUE)) 22847 22848 where PATTERN is the svpattern as a CONST_INT and where ZERO 22849 is a zero constant of the required PTRUE mode (which can have 22850 fewer elements than X's mode, if zero bits are significant). 22851 22852 If so, and if INFO is nonnull, describe the immediate in INFO. */ 22853 bool 22854 aarch64_sve_ptrue_svpattern_p (rtx x, struct simd_immediate_info *info) 22855 { 22856 if (GET_CODE (x) != CONST) 22857 return false; 22858 22859 x = XEXP (x, 0); 22860 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_PTRUE) 22861 return false; 22862 22863 if (info) 22864 { 22865 aarch64_svpattern pattern 22866 = (aarch64_svpattern) INTVAL (XVECEXP (x, 0, 0)); 22867 machine_mode pred_mode = GET_MODE (XVECEXP (x, 0, 1)); 22868 scalar_int_mode int_mode = aarch64_sve_element_int_mode (pred_mode); 22869 *info = simd_immediate_info (int_mode, pattern); 22870 } 22871 return true; 22872 } 22873 22874 /* Return true if X is a valid SVE predicate. If INFO is nonnull, use 22875 it to describe valid immediates. */ 22876 22877 static bool 22878 aarch64_sve_pred_valid_immediate (rtx x, simd_immediate_info *info) 22879 { 22880 if (aarch64_sve_ptrue_svpattern_p (x, info)) 22881 return true; 22882 22883 if (x == CONST0_RTX (GET_MODE (x))) 22884 { 22885 if (info) 22886 *info = simd_immediate_info (DImode, 0); 22887 return true; 22888 } 22889 22890 /* Analyze the value as a VNx16BImode. This should be relatively 22891 efficient, since rtx_vector_builder has enough built-in capacity 22892 to store all VLA predicate constants without needing the heap. */ 22893 rtx_vector_builder builder; 22894 if (!aarch64_get_sve_pred_bits (builder, x)) 22895 return false; 22896 22897 unsigned int elt_size = aarch64_widest_sve_pred_elt_size (builder); 22898 if (int vl = aarch64_partial_ptrue_length (builder, elt_size)) 22899 { 22900 machine_mode mode = aarch64_sve_pred_mode (elt_size).require (); 22901 aarch64_svpattern pattern = aarch64_svpattern_for_vl (mode, vl); 22902 if (pattern != AARCH64_NUM_SVPATTERNS) 22903 { 22904 if (info) 22905 { 22906 scalar_int_mode int_mode = aarch64_sve_element_int_mode (mode); 22907 *info = simd_immediate_info (int_mode, pattern); 22908 } 22909 return true; 22910 } 22911 } 22912 return false; 22913 } 22914 22915 /* Return true if OP is a valid SIMD immediate for the operation 22916 described by WHICH. If INFO is nonnull, use it to describe valid 22917 immediates. */ 22918 bool 22919 aarch64_simd_valid_immediate (rtx op, simd_immediate_info *info, 22920 enum simd_immediate_check which) 22921 { 22922 machine_mode mode = GET_MODE (op); 22923 unsigned int vec_flags = aarch64_classify_vector_mode (mode); 22924 if (vec_flags == 0 || vec_flags == (VEC_ADVSIMD | VEC_STRUCT)) 22925 return false; 22926 22927 if ((vec_flags & VEC_ADVSIMD) && !TARGET_SIMD) 22928 return false; 22929 22930 if (vec_flags == (VEC_SVE_PRED | VEC_STRUCT)) 22931 return op == CONST0_RTX (mode) || op == CONSTM1_RTX (mode); 22932 22933 if (vec_flags & VEC_SVE_PRED) 22934 return aarch64_sve_pred_valid_immediate (op, info); 22935 22936 scalar_mode elt_mode = GET_MODE_INNER (mode); 22937 rtx base, step; 22938 unsigned int n_elts; 22939 if (CONST_VECTOR_P (op) 22940 && CONST_VECTOR_DUPLICATE_P (op)) 22941 n_elts = CONST_VECTOR_NPATTERNS (op); 22942 else if ((vec_flags & VEC_SVE_DATA) 22943 && const_vec_series_p (op, &base, &step)) 22944 { 22945 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT); 22946 if (!aarch64_sve_index_immediate_p (base) 22947 || !aarch64_sve_index_immediate_p (step)) 22948 return false; 22949 22950 if (info) 22951 { 22952 /* Get the corresponding container mode. E.g. an INDEX on V2SI 22953 should yield two integer values per 128-bit block, meaning 22954 that we need to treat it in the same way as V2DI and then 22955 ignore the upper 32 bits of each element. */ 22956 elt_mode = aarch64_sve_container_int_mode (mode); 22957 *info = simd_immediate_info (elt_mode, base, step); 22958 } 22959 return true; 22960 } 22961 else if (CONST_VECTOR_P (op) 22962 && CONST_VECTOR_NUNITS (op).is_constant (&n_elts)) 22963 /* N_ELTS set above. */; 22964 else 22965 return false; 22966 22967 scalar_float_mode elt_float_mode; 22968 if (n_elts == 1 22969 && is_a <scalar_float_mode> (elt_mode, &elt_float_mode)) 22970 { 22971 rtx elt = CONST_VECTOR_ENCODED_ELT (op, 0); 22972 if (aarch64_float_const_zero_rtx_p (elt) 22973 || aarch64_float_const_representable_p (elt)) 22974 { 22975 if (info) 22976 *info = simd_immediate_info (elt_float_mode, elt); 22977 return true; 22978 } 22979 } 22980 22981 /* If all elements in an SVE vector have the same value, we have a free 22982 choice between using the element mode and using the container mode. 22983 Using the element mode means that unused parts of the vector are 22984 duplicates of the used elements, while using the container mode means 22985 that the unused parts are an extension of the used elements. Using the 22986 element mode is better for (say) VNx4HI 0x101, since 0x01010101 is valid 22987 for its container mode VNx4SI while 0x00000101 isn't. 22988 22989 If not all elements in an SVE vector have the same value, we need the 22990 transition from one element to the next to occur at container boundaries. 22991 E.g. a fixed-length VNx4HI containing { 1, 2, 3, 4 } should be treated 22992 in the same way as a VNx4SI containing { 1, 2, 3, 4 }. */ 22993 scalar_int_mode elt_int_mode; 22994 if ((vec_flags & VEC_SVE_DATA) && n_elts > 1) 22995 elt_int_mode = aarch64_sve_container_int_mode (mode); 22996 else 22997 elt_int_mode = int_mode_for_mode (elt_mode).require (); 22998 22999 unsigned int elt_size = GET_MODE_SIZE (elt_int_mode); 23000 if (elt_size > 8) 23001 return false; 23002 23003 /* Expand the vector constant out into a byte vector, with the least 23004 significant byte of the register first. */ 23005 auto_vec<unsigned char, 16> bytes; 23006 bytes.reserve (n_elts * elt_size); 23007 for (unsigned int i = 0; i < n_elts; i++) 23008 { 23009 /* The vector is provided in gcc endian-neutral fashion. 23010 For aarch64_be Advanced SIMD, it must be laid out in the vector 23011 register in reverse order. */ 23012 bool swap_p = ((vec_flags & VEC_ADVSIMD) != 0 && BYTES_BIG_ENDIAN); 23013 rtx elt = CONST_VECTOR_ELT (op, swap_p ? (n_elts - 1 - i) : i); 23014 23015 if (elt_mode != elt_int_mode) 23016 elt = gen_lowpart (elt_int_mode, elt); 23017 23018 if (!CONST_INT_P (elt)) 23019 return false; 23020 23021 unsigned HOST_WIDE_INT elt_val = INTVAL (elt); 23022 for (unsigned int byte = 0; byte < elt_size; byte++) 23023 { 23024 bytes.quick_push (elt_val & 0xff); 23025 elt_val >>= BITS_PER_UNIT; 23026 } 23027 } 23028 23029 /* The immediate must repeat every eight bytes. */ 23030 unsigned int nbytes = bytes.length (); 23031 for (unsigned i = 8; i < nbytes; ++i) 23032 if (bytes[i] != bytes[i - 8]) 23033 return false; 23034 23035 /* Get the repeating 8-byte value as an integer. No endian correction 23036 is needed here because bytes is already in lsb-first order. */ 23037 unsigned HOST_WIDE_INT val64 = 0; 23038 for (unsigned int i = 0; i < 8; i++) 23039 val64 |= ((unsigned HOST_WIDE_INT) bytes[i % nbytes] 23040 << (i * BITS_PER_UNIT)); 23041 23042 if (vec_flags & VEC_SVE_DATA) 23043 return aarch64_sve_valid_immediate (val64, info); 23044 else 23045 return aarch64_advsimd_valid_immediate (val64, info, which); 23046 } 23047 23048 /* Check whether X is a VEC_SERIES-like constant that starts at 0 and 23049 has a step in the range of INDEX. Return the index expression if so, 23050 otherwise return null. */ 23051 rtx 23052 aarch64_check_zero_based_sve_index_immediate (rtx x) 23053 { 23054 rtx base, step; 23055 if (const_vec_series_p (x, &base, &step) 23056 && base == const0_rtx 23057 && aarch64_sve_index_immediate_p (step)) 23058 return step; 23059 return NULL_RTX; 23060 } 23061 23062 /* Check of immediate shift constants are within range. */ 23063 bool 23064 aarch64_simd_shift_imm_p (rtx x, machine_mode mode, bool left) 23065 { 23066 x = unwrap_const_vec_duplicate (x); 23067 if (!CONST_INT_P (x)) 23068 return false; 23069 int bit_width = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT; 23070 if (left) 23071 return IN_RANGE (INTVAL (x), 0, bit_width - 1); 23072 else 23073 return IN_RANGE (INTVAL (x), 1, bit_width); 23074 } 23075 23076 /* Return the bitmask CONST_INT to select the bits required by a zero extract 23077 operation of width WIDTH at bit position POS. */ 23078 23079 rtx 23080 aarch64_mask_from_zextract_ops (rtx width, rtx pos) 23081 { 23082 gcc_assert (CONST_INT_P (width)); 23083 gcc_assert (CONST_INT_P (pos)); 23084 23085 unsigned HOST_WIDE_INT mask 23086 = ((unsigned HOST_WIDE_INT) 1 << UINTVAL (width)) - 1; 23087 return GEN_INT (mask << UINTVAL (pos)); 23088 } 23089 23090 bool 23091 aarch64_mov_operand_p (rtx x, machine_mode mode) 23092 { 23093 if (GET_CODE (x) == HIGH 23094 && aarch64_valid_symref (XEXP (x, 0), GET_MODE (XEXP (x, 0)))) 23095 return true; 23096 23097 if (CONST_INT_P (x)) 23098 return true; 23099 23100 if (VECTOR_MODE_P (GET_MODE (x))) 23101 { 23102 /* Require predicate constants to be VNx16BI before RA, so that we 23103 force everything to have a canonical form. */ 23104 if (!lra_in_progress 23105 && !reload_completed 23106 && aarch64_sve_pred_mode_p (GET_MODE (x)) 23107 && known_eq (GET_MODE_SIZE (GET_MODE (x)), BYTES_PER_SVE_PRED) 23108 && GET_MODE (x) != VNx16BImode) 23109 return false; 23110 23111 return aarch64_simd_valid_immediate (x, NULL); 23112 } 23113 23114 /* Remove UNSPEC_SALT_ADDR before checking symbol reference. */ 23115 x = strip_salt (x); 23116 23117 /* GOT accesses are valid moves. */ 23118 if (SYMBOL_REF_P (x) 23119 && aarch64_classify_symbolic_expression (x) == SYMBOL_SMALL_GOT_4G) 23120 return true; 23121 23122 if (SYMBOL_REF_P (x) && mode == DImode && CONSTANT_ADDRESS_P (x)) 23123 return true; 23124 23125 if (TARGET_SVE 23126 && (aarch64_sve_cnt_immediate_p (x) 23127 || aarch64_sve_rdvl_immediate_p (x))) 23128 return true; 23129 23130 if (aarch64_rdsvl_immediate_p (x)) 23131 return true; 23132 23133 return aarch64_classify_symbolic_expression (x) 23134 == SYMBOL_TINY_ABSOLUTE; 23135 } 23136 23137 /* Return a function-invariant register that contains VALUE. *CACHED_INSN 23138 caches instructions that set up such registers, so that they can be 23139 reused by future calls. */ 23140 23141 static rtx 23142 aarch64_get_shareable_reg (rtx_insn **cached_insn, rtx value) 23143 { 23144 rtx_insn *insn = *cached_insn; 23145 if (insn && INSN_P (insn) && !insn->deleted ()) 23146 { 23147 rtx pat = PATTERN (insn); 23148 if (GET_CODE (pat) == SET) 23149 { 23150 rtx dest = SET_DEST (pat); 23151 if (REG_P (dest) 23152 && !HARD_REGISTER_P (dest) 23153 && rtx_equal_p (SET_SRC (pat), value)) 23154 return dest; 23155 } 23156 } 23157 rtx reg = gen_reg_rtx (GET_MODE (value)); 23158 *cached_insn = emit_insn_before (gen_rtx_SET (reg, value), 23159 function_beg_insn); 23160 return reg; 23161 } 23162 23163 /* Create a 0 constant that is based on V4SI to allow CSE to optimally share 23164 the constant creation. */ 23165 23166 rtx 23167 aarch64_gen_shareable_zero (machine_mode mode) 23168 { 23169 rtx reg = aarch64_get_shareable_reg (&cfun->machine->advsimd_zero_insn, 23170 CONST0_RTX (V4SImode)); 23171 return lowpart_subreg (mode, reg, GET_MODE (reg)); 23172 } 23173 23174 /* INSN is some form of extension or shift that can be split into a 23175 permutation involving a shared zero. Return true if we should 23176 perform such a split. 23177 23178 ??? For now, make sure that the split instruction executes more 23179 frequently than the zero that feeds it. In future it would be good 23180 to split without that restriction and instead recombine shared zeros 23181 if they turn out not to be worthwhile. This would allow splits in 23182 single-block functions and would also cope more naturally with 23183 rematerialization. */ 23184 23185 bool 23186 aarch64_split_simd_shift_p (rtx_insn *insn) 23187 { 23188 return (can_create_pseudo_p () 23189 && optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)) 23190 && (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count 23191 < BLOCK_FOR_INSN (insn)->count)); 23192 } 23193 23194 /* Return a const_int vector of VAL. */ 23195 rtx 23196 aarch64_simd_gen_const_vector_dup (machine_mode mode, HOST_WIDE_INT val) 23197 { 23198 rtx c = gen_int_mode (val, GET_MODE_INNER (mode)); 23199 return gen_const_vec_duplicate (mode, c); 23200 } 23201 23202 /* Check OP is a legal scalar immediate for the MOVI instruction. */ 23203 23204 bool 23205 aarch64_simd_scalar_immediate_valid_for_move (rtx op, scalar_int_mode mode) 23206 { 23207 machine_mode vmode; 23208 23209 vmode = aarch64_simd_container_mode (mode, 64); 23210 rtx op_v = aarch64_simd_gen_const_vector_dup (vmode, INTVAL (op)); 23211 return aarch64_simd_valid_immediate (op_v, NULL); 23212 } 23213 23214 /* Construct and return a PARALLEL RTX vector with elements numbering the 23215 lanes of either the high (HIGH == TRUE) or low (HIGH == FALSE) half of 23216 the vector - from the perspective of the architecture. This does not 23217 line up with GCC's perspective on lane numbers, so we end up with 23218 different masks depending on our target endian-ness. The diagram 23219 below may help. We must draw the distinction when building masks 23220 which select one half of the vector. An instruction selecting 23221 architectural low-lanes for a big-endian target, must be described using 23222 a mask selecting GCC high-lanes. 23223 23224 Big-Endian Little-Endian 23225 23226 GCC 0 1 2 3 3 2 1 0 23227 | x | x | x | x | | x | x | x | x | 23228 Architecture 3 2 1 0 3 2 1 0 23229 23230 Low Mask: { 2, 3 } { 0, 1 } 23231 High Mask: { 0, 1 } { 2, 3 } 23232 23233 MODE Is the mode of the vector and NUNITS is the number of units in it. */ 23234 23235 rtx 23236 aarch64_simd_vect_par_cnst_half (machine_mode mode, int nunits, bool high) 23237 { 23238 rtvec v = rtvec_alloc (nunits / 2); 23239 int high_base = nunits / 2; 23240 int low_base = 0; 23241 int base; 23242 rtx t1; 23243 int i; 23244 23245 if (BYTES_BIG_ENDIAN) 23246 base = high ? low_base : high_base; 23247 else 23248 base = high ? high_base : low_base; 23249 23250 for (i = 0; i < nunits / 2; i++) 23251 RTVEC_ELT (v, i) = GEN_INT (base + i); 23252 23253 t1 = gen_rtx_PARALLEL (mode, v); 23254 return t1; 23255 } 23256 23257 /* Check OP for validity as a PARALLEL RTX vector with elements 23258 numbering the lanes of either the high (HIGH == TRUE) or low lanes, 23259 from the perspective of the architecture. See the diagram above 23260 aarch64_simd_vect_par_cnst_half for more details. */ 23261 23262 bool 23263 aarch64_simd_check_vect_par_cnst_half (rtx op, machine_mode mode, 23264 bool high) 23265 { 23266 int nelts; 23267 if (!VECTOR_MODE_P (mode) || !GET_MODE_NUNITS (mode).is_constant (&nelts)) 23268 return false; 23269 23270 rtx ideal = aarch64_simd_vect_par_cnst_half (mode, nelts, high); 23271 HOST_WIDE_INT count_op = XVECLEN (op, 0); 23272 HOST_WIDE_INT count_ideal = XVECLEN (ideal, 0); 23273 int i = 0; 23274 23275 if (count_op != count_ideal) 23276 return false; 23277 23278 for (i = 0; i < count_ideal; i++) 23279 { 23280 rtx elt_op = XVECEXP (op, 0, i); 23281 rtx elt_ideal = XVECEXP (ideal, 0, i); 23282 23283 if (!CONST_INT_P (elt_op) 23284 || INTVAL (elt_ideal) != INTVAL (elt_op)) 23285 return false; 23286 } 23287 return true; 23288 } 23289 23290 /* Return a PARALLEL containing NELTS elements, with element I equal 23291 to BASE + I * STEP. */ 23292 23293 rtx 23294 aarch64_gen_stepped_int_parallel (unsigned int nelts, int base, int step) 23295 { 23296 rtvec vec = rtvec_alloc (nelts); 23297 for (unsigned int i = 0; i < nelts; ++i) 23298 RTVEC_ELT (vec, i) = gen_int_mode (base + i * step, DImode); 23299 return gen_rtx_PARALLEL (VOIDmode, vec); 23300 } 23301 23302 /* Return true if OP is a PARALLEL of CONST_INTs that form a linear 23303 series with step STEP. */ 23304 23305 bool 23306 aarch64_stepped_int_parallel_p (rtx op, int step) 23307 { 23308 if (GET_CODE (op) != PARALLEL || !CONST_INT_P (XVECEXP (op, 0, 0))) 23309 return false; 23310 23311 unsigned HOST_WIDE_INT base = UINTVAL (XVECEXP (op, 0, 0)); 23312 for (int i = 1; i < XVECLEN (op, 0); ++i) 23313 if (!CONST_INT_P (XVECEXP (op, 0, i)) 23314 || UINTVAL (XVECEXP (op, 0, i)) != base + i * step) 23315 return false; 23316 23317 return true; 23318 } 23319 23320 /* Return true if OPERANDS[0] to OPERANDS[NUM_OPERANDS - 1] form a 23321 sequence of strided registers, with the stride being equal STRIDE. 23322 The operands are already known to be FPRs. */ 23323 bool 23324 aarch64_strided_registers_p (rtx *operands, unsigned int num_operands, 23325 unsigned int stride) 23326 { 23327 for (unsigned int i = 1; i < num_operands; ++i) 23328 if (REGNO (operands[i]) != REGNO (operands[0]) + i * stride) 23329 return false; 23330 return true; 23331 } 23332 23333 /* Bounds-check lanes. Ensure OPERAND lies between LOW (inclusive) and 23334 HIGH (exclusive). */ 23335 void 23336 aarch64_simd_lane_bounds (rtx operand, HOST_WIDE_INT low, HOST_WIDE_INT high, 23337 const_tree exp) 23338 { 23339 HOST_WIDE_INT lane; 23340 gcc_assert (CONST_INT_P (operand)); 23341 lane = INTVAL (operand); 23342 23343 if (lane < low || lane >= high) 23344 { 23345 if (exp) 23346 error_at (EXPR_LOCATION (exp), "lane %wd out of range %wd - %wd", 23347 lane, low, high - 1); 23348 else 23349 error ("lane %wd out of range %wd - %wd", lane, low, high - 1); 23350 } 23351 } 23352 23353 /* Peform endian correction on lane number N, which indexes a vector 23354 of mode MODE, and return the result as an SImode rtx. */ 23355 23356 rtx 23357 aarch64_endian_lane_rtx (machine_mode mode, unsigned int n) 23358 { 23359 return gen_int_mode (ENDIAN_LANE_N (GET_MODE_NUNITS (mode), n), SImode); 23360 } 23361 23362 /* Return TRUE if OP is a valid vector addressing mode. */ 23363 23364 bool 23365 aarch64_simd_mem_operand_p (rtx op) 23366 { 23367 return MEM_P (op) && (GET_CODE (XEXP (op, 0)) == POST_INC 23368 || REG_P (XEXP (op, 0))); 23369 } 23370 23371 /* Return true if OP is a valid MEM operand for an SVE LD1R instruction. */ 23372 23373 bool 23374 aarch64_sve_ld1r_operand_p (rtx op) 23375 { 23376 struct aarch64_address_info addr; 23377 scalar_mode mode; 23378 23379 return (MEM_P (op) 23380 && is_a <scalar_mode> (GET_MODE (op), &mode) 23381 && aarch64_classify_address (&addr, XEXP (op, 0), mode, false) 23382 && addr.type == ADDRESS_REG_IMM 23383 && offset_6bit_unsigned_scaled_p (mode, addr.const_offset)); 23384 } 23385 23386 /* Return true if OP is a valid MEM operand for an SVE LD1R{Q,O} instruction 23387 where the size of the read data is specified by `mode` and the size of the 23388 vector elements are specified by `elem_mode`. */ 23389 bool 23390 aarch64_sve_ld1rq_ld1ro_operand_p (rtx op, machine_mode mode, 23391 scalar_mode elem_mode) 23392 { 23393 struct aarch64_address_info addr; 23394 if (!MEM_P (op) 23395 || !aarch64_classify_address (&addr, XEXP (op, 0), elem_mode, false)) 23396 return false; 23397 23398 if (addr.type == ADDRESS_REG_IMM) 23399 return offset_4bit_signed_scaled_p (mode, addr.const_offset); 23400 23401 if (addr.type == ADDRESS_REG_REG) 23402 return (1U << addr.shift) == GET_MODE_SIZE (elem_mode); 23403 23404 return false; 23405 } 23406 23407 /* Return true if OP is a valid MEM operand for an SVE LD1RQ instruction. */ 23408 bool 23409 aarch64_sve_ld1rq_operand_p (rtx op) 23410 { 23411 return aarch64_sve_ld1rq_ld1ro_operand_p (op, TImode, 23412 GET_MODE_INNER (GET_MODE (op))); 23413 } 23414 23415 /* Return true if OP is a valid MEM operand for an SVE LD1RO instruction for 23416 accessing a vector where the element size is specified by `elem_mode`. */ 23417 bool 23418 aarch64_sve_ld1ro_operand_p (rtx op, scalar_mode elem_mode) 23419 { 23420 return aarch64_sve_ld1rq_ld1ro_operand_p (op, OImode, elem_mode); 23421 } 23422 23423 /* Return true if OP is a valid MEM operand for an SVE LDFF1 instruction. */ 23424 bool 23425 aarch64_sve_ldff1_operand_p (rtx op) 23426 { 23427 if (!MEM_P (op)) 23428 return false; 23429 23430 struct aarch64_address_info addr; 23431 if (!aarch64_classify_address (&addr, XEXP (op, 0), GET_MODE (op), false)) 23432 return false; 23433 23434 if (addr.type == ADDRESS_REG_IMM) 23435 return known_eq (addr.const_offset, 0); 23436 23437 return addr.type == ADDRESS_REG_REG; 23438 } 23439 23440 /* Return true if OP is a valid MEM operand for an SVE LDNF1 instruction. */ 23441 bool 23442 aarch64_sve_ldnf1_operand_p (rtx op) 23443 { 23444 struct aarch64_address_info addr; 23445 23446 return (MEM_P (op) 23447 && aarch64_classify_address (&addr, XEXP (op, 0), 23448 GET_MODE (op), false) 23449 && addr.type == ADDRESS_REG_IMM); 23450 } 23451 23452 /* Return true if OP is a valid MEM operand for an SVE LDR instruction. 23453 The conditions for STR are the same. */ 23454 bool 23455 aarch64_sve_ldr_operand_p (rtx op) 23456 { 23457 struct aarch64_address_info addr; 23458 23459 return (MEM_P (op) 23460 && aarch64_classify_address (&addr, XEXP (op, 0), GET_MODE (op), 23461 false, ADDR_QUERY_ANY) 23462 && addr.type == ADDRESS_REG_IMM); 23463 } 23464 23465 /* Return true if OP is a valid address for an SVE PRF[BHWD] instruction, 23466 addressing memory of mode MODE. */ 23467 bool 23468 aarch64_sve_prefetch_operand_p (rtx op, machine_mode mode) 23469 { 23470 struct aarch64_address_info addr; 23471 if (!aarch64_classify_address (&addr, op, mode, false, ADDR_QUERY_ANY)) 23472 return false; 23473 23474 if (addr.type == ADDRESS_REG_IMM) 23475 return offset_6bit_signed_scaled_p (mode, addr.const_offset); 23476 23477 return addr.type == ADDRESS_REG_REG; 23478 } 23479 23480 /* Return true if OP is a valid MEM operand for an SVE_STRUCT mode. 23481 We need to be able to access the individual pieces, so the range 23482 is different from LD[234] and ST[234]. */ 23483 bool 23484 aarch64_sve_struct_memory_operand_p (rtx op) 23485 { 23486 if (!MEM_P (op)) 23487 return false; 23488 23489 machine_mode mode = GET_MODE (op); 23490 struct aarch64_address_info addr; 23491 if (!aarch64_classify_address (&addr, XEXP (op, 0), SVE_BYTE_MODE, false, 23492 ADDR_QUERY_ANY) 23493 || addr.type != ADDRESS_REG_IMM) 23494 return false; 23495 23496 poly_int64 first = addr.const_offset; 23497 poly_int64 last = first + GET_MODE_SIZE (mode) - BYTES_PER_SVE_VECTOR; 23498 return (offset_4bit_signed_scaled_p (SVE_BYTE_MODE, first) 23499 && offset_4bit_signed_scaled_p (SVE_BYTE_MODE, last)); 23500 } 23501 23502 /* Return true if OFFSET is a constant integer and if VNUM is 23503 OFFSET * the number of bytes in an SVE vector. This is the requirement 23504 that exists in SME LDR and STR instructions, where the VL offset must 23505 equal the ZA slice offset. */ 23506 bool 23507 aarch64_sme_ldr_vnum_offset_p (rtx offset, rtx vnum) 23508 { 23509 if (!CONST_INT_P (offset) || !IN_RANGE (INTVAL (offset), 0, 15)) 23510 return false; 23511 23512 if (TARGET_STREAMING) 23513 { 23514 poly_int64 const_vnum; 23515 return (poly_int_rtx_p (vnum, &const_vnum) 23516 && known_eq (const_vnum, 23517 INTVAL (offset) * BYTES_PER_SVE_VECTOR)); 23518 } 23519 else 23520 { 23521 HOST_WIDE_INT factor; 23522 return (aarch64_sme_vq_unspec_p (vnum, &factor) 23523 && factor == INTVAL (offset) * 16); 23524 } 23525 } 23526 23527 /* Emit a register copy from operand to operand, taking care not to 23528 early-clobber source registers in the process. 23529 23530 COUNT is the number of components into which the copy needs to be 23531 decomposed. */ 23532 void 23533 aarch64_simd_emit_reg_reg_move (rtx *operands, machine_mode mode, 23534 unsigned int count) 23535 { 23536 unsigned int i; 23537 int rdest = REGNO (operands[0]); 23538 int rsrc = REGNO (operands[1]); 23539 23540 if (!reg_overlap_mentioned_p (operands[0], operands[1]) 23541 || rdest < rsrc) 23542 for (i = 0; i < count; i++) 23543 emit_move_insn (gen_rtx_REG (mode, rdest + i), 23544 gen_rtx_REG (mode, rsrc + i)); 23545 else 23546 for (i = 0; i < count; i++) 23547 emit_move_insn (gen_rtx_REG (mode, rdest + count - i - 1), 23548 gen_rtx_REG (mode, rsrc + count - i - 1)); 23549 } 23550 23551 /* Compute and return the length of aarch64_simd_reglist<mode>, where <mode> is 23552 one of VSTRUCT modes: OI, CI, or XI. */ 23553 int 23554 aarch64_simd_attr_length_rglist (machine_mode mode) 23555 { 23556 /* This is only used (and only meaningful) for Advanced SIMD, not SVE. */ 23557 return (GET_MODE_SIZE (mode).to_constant () / UNITS_PER_VREG) * 4; 23558 } 23559 23560 /* Implement target hook TARGET_VECTOR_ALIGNMENT. The AAPCS64 sets the maximum 23561 alignment of a vector to 128 bits. SVE predicates have an alignment of 23562 16 bits. */ 23563 static HOST_WIDE_INT 23564 aarch64_simd_vector_alignment (const_tree type) 23565 { 23566 /* ??? Checking the mode isn't ideal, but VECTOR_BOOLEAN_TYPE_P can 23567 be set for non-predicate vectors of booleans. Modes are the most 23568 direct way we have of identifying real SVE predicate types. */ 23569 if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_VECTOR_BOOL) 23570 return 16; 23571 widest_int min_size 23572 = constant_lower_bound (wi::to_poly_widest (TYPE_SIZE (type))); 23573 return wi::umin (min_size, 128).to_uhwi (); 23574 } 23575 23576 /* Implement target hook TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT. */ 23577 static poly_uint64 23578 aarch64_vectorize_preferred_vector_alignment (const_tree type) 23579 { 23580 if (aarch64_sve_data_mode_p (TYPE_MODE (type))) 23581 { 23582 /* If the length of the vector is a fixed power of 2, try to align 23583 to that length, otherwise don't try to align at all. */ 23584 HOST_WIDE_INT result; 23585 if (!GET_MODE_BITSIZE (TYPE_MODE (type)).is_constant (&result) 23586 || !pow2p_hwi (result)) 23587 result = TYPE_ALIGN (TREE_TYPE (type)); 23588 return result; 23589 } 23590 return TYPE_ALIGN (type); 23591 } 23592 23593 /* Implement target hook TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE. */ 23594 static bool 23595 aarch64_simd_vector_alignment_reachable (const_tree type, bool is_packed) 23596 { 23597 if (is_packed) 23598 return false; 23599 23600 /* For fixed-length vectors, check that the vectorizer will aim for 23601 full-vector alignment. This isn't true for generic GCC vectors 23602 that are wider than the ABI maximum of 128 bits. */ 23603 poly_uint64 preferred_alignment = 23604 aarch64_vectorize_preferred_vector_alignment (type); 23605 if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST 23606 && maybe_ne (wi::to_widest (TYPE_SIZE (type)), 23607 preferred_alignment)) 23608 return false; 23609 23610 /* Vectors whose size is <= BIGGEST_ALIGNMENT are naturally aligned. */ 23611 return true; 23612 } 23613 23614 /* Return true if the vector misalignment factor is supported by the 23615 target. */ 23616 static bool 23617 aarch64_builtin_support_vector_misalignment (machine_mode mode, 23618 const_tree type, int misalignment, 23619 bool is_packed) 23620 { 23621 if (TARGET_SIMD && STRICT_ALIGNMENT) 23622 { 23623 /* Return if movmisalign pattern is not supported for this mode. */ 23624 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing) 23625 return false; 23626 23627 /* Misalignment factor is unknown at compile time. */ 23628 if (misalignment == -1) 23629 return false; 23630 } 23631 return default_builtin_support_vector_misalignment (mode, type, misalignment, 23632 is_packed); 23633 } 23634 23635 /* If VALS is a vector constant that can be loaded into a register 23636 using DUP, generate instructions to do so and return an RTX to 23637 assign to the register. Otherwise return NULL_RTX. */ 23638 static rtx 23639 aarch64_simd_dup_constant (rtx vals) 23640 { 23641 machine_mode mode = GET_MODE (vals); 23642 machine_mode inner_mode = GET_MODE_INNER (mode); 23643 rtx x; 23644 23645 if (!const_vec_duplicate_p (vals, &x)) 23646 return NULL_RTX; 23647 23648 /* We can load this constant by using DUP and a constant in a 23649 single ARM register. This will be cheaper than a vector 23650 load. */ 23651 x = force_reg (inner_mode, x); 23652 return gen_vec_duplicate (mode, x); 23653 } 23654 23655 23656 /* Generate code to load VALS, which is a PARALLEL containing only 23657 constants (for vec_init) or CONST_VECTOR, efficiently into a 23658 register. Returns an RTX to copy into the register, or NULL_RTX 23659 for a PARALLEL that cannot be converted into a CONST_VECTOR. */ 23660 static rtx 23661 aarch64_simd_make_constant (rtx vals) 23662 { 23663 machine_mode mode = GET_MODE (vals); 23664 rtx const_dup; 23665 rtx const_vec = NULL_RTX; 23666 int n_const = 0; 23667 int i; 23668 23669 if (CONST_VECTOR_P (vals)) 23670 const_vec = vals; 23671 else if (GET_CODE (vals) == PARALLEL) 23672 { 23673 /* A CONST_VECTOR must contain only CONST_INTs and 23674 CONST_DOUBLEs, but CONSTANT_P allows more (e.g. SYMBOL_REF). 23675 Only store valid constants in a CONST_VECTOR. */ 23676 int n_elts = XVECLEN (vals, 0); 23677 for (i = 0; i < n_elts; ++i) 23678 { 23679 rtx x = XVECEXP (vals, 0, i); 23680 if (CONST_INT_P (x) || CONST_DOUBLE_P (x)) 23681 n_const++; 23682 } 23683 if (n_const == n_elts) 23684 const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)); 23685 } 23686 else 23687 gcc_unreachable (); 23688 23689 if (const_vec != NULL_RTX 23690 && aarch64_simd_valid_immediate (const_vec, NULL)) 23691 /* Load using MOVI/MVNI. */ 23692 return const_vec; 23693 else if ((const_dup = aarch64_simd_dup_constant (vals)) != NULL_RTX) 23694 /* Loaded using DUP. */ 23695 return const_dup; 23696 else if (const_vec != NULL_RTX) 23697 /* Load from constant pool. We cannot take advantage of single-cycle 23698 LD1 because we need a PC-relative addressing mode. */ 23699 return const_vec; 23700 else 23701 /* A PARALLEL containing something not valid inside CONST_VECTOR. 23702 We cannot construct an initializer. */ 23703 return NULL_RTX; 23704 } 23705 23706 /* A subroutine of aarch64_expand_vector_init, with the same interface. 23707 The caller has already tried a divide-and-conquer approach, so do 23708 not consider that case here. */ 23709 23710 void 23711 aarch64_expand_vector_init_fallback (rtx target, rtx vals) 23712 { 23713 machine_mode mode = GET_MODE (target); 23714 scalar_mode inner_mode = GET_MODE_INNER (mode); 23715 /* The number of vector elements. */ 23716 int n_elts = XVECLEN (vals, 0); 23717 /* The number of vector elements which are not constant. */ 23718 int n_var = 0; 23719 rtx any_const = NULL_RTX; 23720 /* The first element of vals. */ 23721 rtx v0 = XVECEXP (vals, 0, 0); 23722 bool all_same = true; 23723 23724 /* This is a special vec_init<M><N> where N is not an element mode but a 23725 vector mode with half the elements of M. We expect to find two entries 23726 of mode N in VALS and we must put their concatentation into TARGET. */ 23727 if (XVECLEN (vals, 0) == 2 && VECTOR_MODE_P (GET_MODE (XVECEXP (vals, 0, 0)))) 23728 { 23729 machine_mode narrow_mode = GET_MODE (XVECEXP (vals, 0, 0)); 23730 gcc_assert (GET_MODE_INNER (narrow_mode) == inner_mode 23731 && known_eq (GET_MODE_SIZE (mode), 23732 2 * GET_MODE_SIZE (narrow_mode))); 23733 emit_insn (gen_aarch64_vec_concat (narrow_mode, target, 23734 XVECEXP (vals, 0, 0), 23735 XVECEXP (vals, 0, 1))); 23736 return; 23737 } 23738 23739 /* Count the number of variable elements to initialise. */ 23740 for (int i = 0; i < n_elts; ++i) 23741 { 23742 rtx x = XVECEXP (vals, 0, i); 23743 if (!(CONST_INT_P (x) || CONST_DOUBLE_P (x))) 23744 ++n_var; 23745 else 23746 any_const = x; 23747 23748 all_same &= rtx_equal_p (x, v0); 23749 } 23750 23751 /* No variable elements, hand off to aarch64_simd_make_constant which knows 23752 how best to handle this. */ 23753 if (n_var == 0) 23754 { 23755 rtx constant = aarch64_simd_make_constant (vals); 23756 if (constant != NULL_RTX) 23757 { 23758 emit_move_insn (target, constant); 23759 return; 23760 } 23761 } 23762 23763 /* Splat a single non-constant element if we can. */ 23764 if (all_same) 23765 { 23766 rtx x = force_reg (inner_mode, v0); 23767 aarch64_emit_move (target, gen_vec_duplicate (mode, x)); 23768 return; 23769 } 23770 23771 enum insn_code icode = optab_handler (vec_set_optab, mode); 23772 gcc_assert (icode != CODE_FOR_nothing); 23773 23774 /* If there are only variable elements, try to optimize 23775 the insertion using dup for the most common element 23776 followed by insertions. */ 23777 23778 /* The algorithm will fill matches[*][0] with the earliest matching element, 23779 and matches[X][1] with the count of duplicate elements (if X is the 23780 earliest element which has duplicates). */ 23781 23782 if (n_var >= n_elts - 1 && n_elts <= 16) 23783 { 23784 int matches[16][2] = {0}; 23785 for (int i = 0; i < n_elts; i++) 23786 { 23787 for (int j = 0; j <= i; j++) 23788 { 23789 if (rtx_equal_p (XVECEXP (vals, 0, i), XVECEXP (vals, 0, j))) 23790 { 23791 matches[i][0] = j; 23792 matches[j][1]++; 23793 break; 23794 } 23795 } 23796 } 23797 int maxelement = 0; 23798 int maxv = 0; 23799 rtx const_elem = NULL_RTX; 23800 int const_elem_pos = 0; 23801 23802 for (int i = 0; i < n_elts; i++) 23803 { 23804 if (matches[i][1] > maxv) 23805 { 23806 maxelement = i; 23807 maxv = matches[i][1]; 23808 } 23809 if (CONST_INT_P (XVECEXP (vals, 0, i)) 23810 || CONST_DOUBLE_P (XVECEXP (vals, 0, i))) 23811 { 23812 const_elem_pos = i; 23813 const_elem = XVECEXP (vals, 0, i); 23814 } 23815 } 23816 23817 /* Create a duplicate of the most common element, unless all elements 23818 are equally useless to us, in which case just immediately set the 23819 vector register using the first element. */ 23820 23821 if (maxv == 1) 23822 { 23823 /* For vectors of two 64-bit elements, we can do even better. */ 23824 if (n_elts == 2 23825 && (inner_mode == E_DImode 23826 || inner_mode == E_DFmode)) 23827 23828 { 23829 rtx x0 = XVECEXP (vals, 0, 0); 23830 rtx x1 = XVECEXP (vals, 0, 1); 23831 /* Combine can pick up this case, but handling it directly 23832 here leaves clearer RTL. 23833 23834 This is load_pair_lanes<mode>, and also gives us a clean-up 23835 for store_pair_lanes<mode>. */ 23836 if (memory_operand (x0, inner_mode) 23837 && memory_operand (x1, inner_mode) 23838 && aarch64_mergeable_load_pair_p (mode, x0, x1)) 23839 { 23840 rtx t; 23841 if (inner_mode == DFmode) 23842 t = gen_load_pair_lanesdf (target, x0, x1); 23843 else 23844 t = gen_load_pair_lanesdi (target, x0, x1); 23845 emit_insn (t); 23846 return; 23847 } 23848 } 23849 /* The subreg-move sequence below will move into lane zero of the 23850 vector register. For big-endian we want that position to hold 23851 the last element of VALS. */ 23852 maxelement = BYTES_BIG_ENDIAN ? n_elts - 1 : 0; 23853 23854 /* If we have a single constant element, use that for duplicating 23855 instead. */ 23856 if (const_elem) 23857 { 23858 maxelement = const_elem_pos; 23859 aarch64_emit_move (target, gen_vec_duplicate (mode, const_elem)); 23860 } 23861 else 23862 { 23863 rtx x = force_reg (inner_mode, XVECEXP (vals, 0, maxelement)); 23864 aarch64_emit_move (target, lowpart_subreg (mode, x, inner_mode)); 23865 } 23866 } 23867 else 23868 { 23869 rtx x = force_reg (inner_mode, XVECEXP (vals, 0, maxelement)); 23870 aarch64_emit_move (target, gen_vec_duplicate (mode, x)); 23871 } 23872 23873 /* Insert the rest. */ 23874 for (int i = 0; i < n_elts; i++) 23875 { 23876 rtx x = XVECEXP (vals, 0, i); 23877 if (matches[i][0] == maxelement) 23878 continue; 23879 x = force_reg (inner_mode, x); 23880 emit_insn (GEN_FCN (icode) (target, x, GEN_INT (i))); 23881 } 23882 return; 23883 } 23884 23885 /* Initialise a vector which is part-variable. We want to first try 23886 to build those lanes which are constant in the most efficient way we 23887 can. */ 23888 if (n_var != n_elts) 23889 { 23890 rtx copy = copy_rtx (vals); 23891 23892 /* Load constant part of vector. We really don't care what goes into the 23893 parts we will overwrite, but we're more likely to be able to load the 23894 constant efficiently if it has fewer, larger, repeating parts 23895 (see aarch64_simd_valid_immediate). */ 23896 for (int i = 0; i < n_elts; i++) 23897 { 23898 rtx x = XVECEXP (vals, 0, i); 23899 if (CONST_INT_P (x) || CONST_DOUBLE_P (x)) 23900 continue; 23901 rtx subst = any_const; 23902 for (int bit = n_elts / 2; bit > 0; bit /= 2) 23903 { 23904 /* Look in the copied vector, as more elements are const. */ 23905 rtx test = XVECEXP (copy, 0, i ^ bit); 23906 if (CONST_INT_P (test) || CONST_DOUBLE_P (test)) 23907 { 23908 subst = test; 23909 break; 23910 } 23911 } 23912 XVECEXP (copy, 0, i) = subst; 23913 } 23914 aarch64_expand_vector_init_fallback (target, copy); 23915 } 23916 23917 /* Insert the variable lanes directly. */ 23918 for (int i = 0; i < n_elts; i++) 23919 { 23920 rtx x = XVECEXP (vals, 0, i); 23921 if (CONST_INT_P (x) || CONST_DOUBLE_P (x)) 23922 continue; 23923 x = force_reg (inner_mode, x); 23924 emit_insn (GEN_FCN (icode) (target, x, GEN_INT (i))); 23925 } 23926 } 23927 23928 /* Return even or odd half of VALS depending on EVEN_P. */ 23929 23930 static rtx 23931 aarch64_unzip_vector_init (machine_mode mode, rtx vals, bool even_p) 23932 { 23933 int n = XVECLEN (vals, 0); 23934 machine_mode new_mode 23935 = aarch64_simd_container_mode (GET_MODE_INNER (mode), 23936 GET_MODE_BITSIZE (mode).to_constant () / 2); 23937 rtvec vec = rtvec_alloc (n / 2); 23938 for (int i = 0; i < n / 2; i++) 23939 RTVEC_ELT (vec, i) = (even_p) ? XVECEXP (vals, 0, 2 * i) 23940 : XVECEXP (vals, 0, 2 * i + 1); 23941 return gen_rtx_PARALLEL (new_mode, vec); 23942 } 23943 23944 /* Return true if SET is a scalar move. */ 23945 23946 static bool 23947 scalar_move_insn_p (rtx set) 23948 { 23949 rtx src = SET_SRC (set); 23950 rtx dest = SET_DEST (set); 23951 return (is_a<scalar_mode> (GET_MODE (dest)) 23952 && aarch64_mov_operand (src, GET_MODE (dest))); 23953 } 23954 23955 /* Similar to seq_cost, but ignore cost for scalar moves. */ 23956 23957 static unsigned 23958 seq_cost_ignoring_scalar_moves (const rtx_insn *seq, bool speed) 23959 { 23960 unsigned cost = 0; 23961 23962 for (; seq; seq = NEXT_INSN (seq)) 23963 if (NONDEBUG_INSN_P (seq)) 23964 { 23965 if (rtx set = single_set (seq)) 23966 { 23967 if (!scalar_move_insn_p (set)) 23968 cost += set_rtx_cost (set, speed); 23969 } 23970 else 23971 { 23972 int this_cost = insn_cost (CONST_CAST_RTX_INSN (seq), speed); 23973 if (this_cost > 0) 23974 cost += this_cost; 23975 else 23976 cost++; 23977 } 23978 } 23979 23980 return cost; 23981 } 23982 23983 /* Expand a vector initialization sequence, such that TARGET is 23984 initialized to contain VALS. */ 23985 23986 void 23987 aarch64_expand_vector_init (rtx target, rtx vals) 23988 { 23989 /* Try decomposing the initializer into even and odd halves and 23990 then ZIP them together. Use the resulting sequence if it is 23991 strictly cheaper than loading VALS directly. 23992 23993 Prefer the fallback sequence in the event of a tie, since it 23994 will tend to use fewer registers. */ 23995 23996 machine_mode mode = GET_MODE (target); 23997 int n_elts = XVECLEN (vals, 0); 23998 23999 if (n_elts < 4 24000 || maybe_ne (GET_MODE_BITSIZE (mode), 128)) 24001 { 24002 aarch64_expand_vector_init_fallback (target, vals); 24003 return; 24004 } 24005 24006 start_sequence (); 24007 rtx halves[2]; 24008 unsigned costs[2]; 24009 for (int i = 0; i < 2; i++) 24010 { 24011 start_sequence (); 24012 rtx new_vals = aarch64_unzip_vector_init (mode, vals, i == 0); 24013 rtx tmp_reg = gen_reg_rtx (GET_MODE (new_vals)); 24014 aarch64_expand_vector_init (tmp_reg, new_vals); 24015 halves[i] = gen_rtx_SUBREG (mode, tmp_reg, 0); 24016 rtx_insn *rec_seq = get_insns (); 24017 end_sequence (); 24018 costs[i] = seq_cost_ignoring_scalar_moves (rec_seq, !optimize_size); 24019 emit_insn (rec_seq); 24020 } 24021 24022 /* The two halves should (by induction) be individually endian-correct. 24023 However, in the memory layout provided by VALS, the nth element of 24024 HALVES[0] comes immediately before the nth element HALVES[1]. 24025 This means that, on big-endian targets, the nth element of HALVES[0] 24026 is more significant than the nth element HALVES[1]. */ 24027 if (BYTES_BIG_ENDIAN) 24028 std::swap (halves[0], halves[1]); 24029 rtvec v = gen_rtvec (2, halves[0], halves[1]); 24030 rtx_insn *zip1_insn 24031 = emit_set_insn (target, gen_rtx_UNSPEC (mode, v, UNSPEC_ZIP1)); 24032 unsigned seq_total_cost 24033 = (!optimize_size) ? std::max (costs[0], costs[1]) : costs[0] + costs[1]; 24034 seq_total_cost += insn_cost (zip1_insn, !optimize_size); 24035 24036 rtx_insn *seq = get_insns (); 24037 end_sequence (); 24038 24039 start_sequence (); 24040 aarch64_expand_vector_init_fallback (target, vals); 24041 rtx_insn *fallback_seq = get_insns (); 24042 unsigned fallback_seq_cost 24043 = seq_cost_ignoring_scalar_moves (fallback_seq, !optimize_size); 24044 end_sequence (); 24045 24046 emit_insn (seq_total_cost < fallback_seq_cost ? seq : fallback_seq); 24047 } 24048 24049 /* Emit RTL corresponding to: 24050 insr TARGET, ELEM. */ 24051 24052 static void 24053 emit_insr (rtx target, rtx elem) 24054 { 24055 machine_mode mode = GET_MODE (target); 24056 scalar_mode elem_mode = GET_MODE_INNER (mode); 24057 elem = force_reg (elem_mode, elem); 24058 24059 insn_code icode = optab_handler (vec_shl_insert_optab, mode); 24060 gcc_assert (icode != CODE_FOR_nothing); 24061 emit_insn (GEN_FCN (icode) (target, target, elem)); 24062 } 24063 24064 /* Subroutine of aarch64_sve_expand_vector_init for handling 24065 trailing constants. 24066 This function works as follows: 24067 (a) Create a new vector consisting of trailing constants. 24068 (b) Initialize TARGET with the constant vector using emit_move_insn. 24069 (c) Insert remaining elements in TARGET using insr. 24070 NELTS is the total number of elements in original vector while 24071 while NELTS_REQD is the number of elements that are actually 24072 significant. 24073 24074 ??? The heuristic used is to do above only if number of constants 24075 is at least half the total number of elements. May need fine tuning. */ 24076 24077 static bool 24078 aarch64_sve_expand_vector_init_handle_trailing_constants 24079 (rtx target, const rtx_vector_builder &builder, int nelts, int nelts_reqd) 24080 { 24081 machine_mode mode = GET_MODE (target); 24082 scalar_mode elem_mode = GET_MODE_INNER (mode); 24083 int n_trailing_constants = 0; 24084 24085 for (int i = nelts_reqd - 1; 24086 i >= 0 && valid_for_const_vector_p (elem_mode, builder.elt (i)); 24087 i--) 24088 n_trailing_constants++; 24089 24090 if (n_trailing_constants >= nelts_reqd / 2) 24091 { 24092 /* Try to use the natural pattern of BUILDER to extend the trailing 24093 constant elements to a full vector. Replace any variables in the 24094 extra elements with zeros. 24095 24096 ??? It would be better if the builders supported "don't care" 24097 elements, with the builder filling in whichever elements 24098 give the most compact encoding. */ 24099 rtx_vector_builder v (mode, nelts, 1); 24100 for (int i = 0; i < nelts; i++) 24101 { 24102 rtx x = builder.elt (i + nelts_reqd - n_trailing_constants); 24103 if (!valid_for_const_vector_p (elem_mode, x)) 24104 x = CONST0_RTX (elem_mode); 24105 v.quick_push (x); 24106 } 24107 rtx const_vec = v.build (); 24108 emit_move_insn (target, const_vec); 24109 24110 for (int i = nelts_reqd - n_trailing_constants - 1; i >= 0; i--) 24111 emit_insr (target, builder.elt (i)); 24112 24113 return true; 24114 } 24115 24116 return false; 24117 } 24118 24119 /* Subroutine of aarch64_sve_expand_vector_init. 24120 Works as follows: 24121 (a) Initialize TARGET by broadcasting element NELTS_REQD - 1 of BUILDER. 24122 (b) Skip trailing elements from BUILDER, which are the same as 24123 element NELTS_REQD - 1. 24124 (c) Insert earlier elements in reverse order in TARGET using insr. */ 24125 24126 static void 24127 aarch64_sve_expand_vector_init_insert_elems (rtx target, 24128 const rtx_vector_builder &builder, 24129 int nelts_reqd) 24130 { 24131 machine_mode mode = GET_MODE (target); 24132 scalar_mode elem_mode = GET_MODE_INNER (mode); 24133 24134 struct expand_operand ops[2]; 24135 enum insn_code icode = optab_handler (vec_duplicate_optab, mode); 24136 gcc_assert (icode != CODE_FOR_nothing); 24137 24138 create_output_operand (&ops[0], target, mode); 24139 create_input_operand (&ops[1], builder.elt (nelts_reqd - 1), elem_mode); 24140 expand_insn (icode, 2, ops); 24141 24142 int ndups = builder.count_dups (nelts_reqd - 1, -1, -1); 24143 for (int i = nelts_reqd - ndups - 1; i >= 0; i--) 24144 emit_insr (target, builder.elt (i)); 24145 } 24146 24147 /* Subroutine of aarch64_sve_expand_vector_init to handle case 24148 when all trailing elements of builder are same. 24149 This works as follows: 24150 (a) Use expand_insn interface to broadcast last vector element in TARGET. 24151 (b) Insert remaining elements in TARGET using insr. 24152 24153 ??? The heuristic used is to do above if number of same trailing elements 24154 is at least 3/4 of total number of elements, loosely based on 24155 heuristic from mostly_zeros_p. May need fine-tuning. */ 24156 24157 static bool 24158 aarch64_sve_expand_vector_init_handle_trailing_same_elem 24159 (rtx target, const rtx_vector_builder &builder, int nelts_reqd) 24160 { 24161 int ndups = builder.count_dups (nelts_reqd - 1, -1, -1); 24162 if (ndups >= (3 * nelts_reqd) / 4) 24163 { 24164 aarch64_sve_expand_vector_init_insert_elems (target, builder, 24165 nelts_reqd - ndups + 1); 24166 return true; 24167 } 24168 24169 return false; 24170 } 24171 24172 /* Initialize register TARGET from BUILDER. NELTS is the constant number 24173 of elements in BUILDER. 24174 24175 The function tries to initialize TARGET from BUILDER if it fits one 24176 of the special cases outlined below. 24177 24178 Failing that, the function divides BUILDER into two sub-vectors: 24179 v_even = even elements of BUILDER; 24180 v_odd = odd elements of BUILDER; 24181 24182 and recursively calls itself with v_even and v_odd. 24183 24184 if (recursive call succeeded for v_even or v_odd) 24185 TARGET = zip (v_even, v_odd) 24186 24187 The function returns true if it managed to build TARGET from BUILDER 24188 with one of the special cases, false otherwise. 24189 24190 Example: {a, 1, b, 2, c, 3, d, 4} 24191 24192 The vector gets divided into: 24193 v_even = {a, b, c, d} 24194 v_odd = {1, 2, 3, 4} 24195 24196 aarch64_sve_expand_vector_init(v_odd) hits case 1 and 24197 initialize tmp2 from constant vector v_odd using emit_move_insn. 24198 24199 aarch64_sve_expand_vector_init(v_even) fails since v_even contains 24200 4 elements, so we construct tmp1 from v_even using insr: 24201 tmp1 = dup(d) 24202 insr tmp1, c 24203 insr tmp1, b 24204 insr tmp1, a 24205 24206 And finally: 24207 TARGET = zip (tmp1, tmp2) 24208 which sets TARGET to {a, 1, b, 2, c, 3, d, 4}. */ 24209 24210 static bool 24211 aarch64_sve_expand_vector_init (rtx target, const rtx_vector_builder &builder, 24212 int nelts, int nelts_reqd) 24213 { 24214 machine_mode mode = GET_MODE (target); 24215 24216 /* Case 1: Vector contains trailing constants. */ 24217 24218 if (aarch64_sve_expand_vector_init_handle_trailing_constants 24219 (target, builder, nelts, nelts_reqd)) 24220 return true; 24221 24222 /* Case 2: Vector contains leading constants. */ 24223 24224 rtx_vector_builder rev_builder (mode, nelts_reqd, 1); 24225 for (int i = 0; i < nelts_reqd; i++) 24226 rev_builder.quick_push (builder.elt (nelts_reqd - i - 1)); 24227 rev_builder.finalize (); 24228 24229 if (aarch64_sve_expand_vector_init_handle_trailing_constants 24230 (target, rev_builder, nelts, nelts_reqd)) 24231 { 24232 emit_insn (gen_aarch64_sve_rev (mode, target, target)); 24233 return true; 24234 } 24235 24236 /* Case 3: Vector contains trailing same element. */ 24237 24238 if (aarch64_sve_expand_vector_init_handle_trailing_same_elem 24239 (target, builder, nelts_reqd)) 24240 return true; 24241 24242 /* Case 4: Vector contains leading same element. */ 24243 24244 if (aarch64_sve_expand_vector_init_handle_trailing_same_elem 24245 (target, rev_builder, nelts_reqd) && nelts_reqd == nelts) 24246 { 24247 emit_insn (gen_aarch64_sve_rev (mode, target, target)); 24248 return true; 24249 } 24250 24251 /* Avoid recursing below 4-elements. 24252 ??? The threshold 4 may need fine-tuning. */ 24253 24254 if (nelts_reqd <= 4) 24255 return false; 24256 24257 rtx_vector_builder v_even (mode, nelts, 1); 24258 rtx_vector_builder v_odd (mode, nelts, 1); 24259 24260 for (int i = 0; i < nelts * 2; i += 2) 24261 { 24262 v_even.quick_push (builder.elt (i)); 24263 v_odd.quick_push (builder.elt (i + 1)); 24264 } 24265 24266 v_even.finalize (); 24267 v_odd.finalize (); 24268 24269 rtx tmp1 = gen_reg_rtx (mode); 24270 bool did_even_p = aarch64_sve_expand_vector_init (tmp1, v_even, 24271 nelts, nelts_reqd / 2); 24272 24273 rtx tmp2 = gen_reg_rtx (mode); 24274 bool did_odd_p = aarch64_sve_expand_vector_init (tmp2, v_odd, 24275 nelts, nelts_reqd / 2); 24276 24277 if (!did_even_p && !did_odd_p) 24278 return false; 24279 24280 /* Initialize v_even and v_odd using INSR if it didn't match any of the 24281 special cases and zip v_even, v_odd. */ 24282 24283 if (!did_even_p) 24284 aarch64_sve_expand_vector_init_insert_elems (tmp1, v_even, nelts_reqd / 2); 24285 24286 if (!did_odd_p) 24287 aarch64_sve_expand_vector_init_insert_elems (tmp2, v_odd, nelts_reqd / 2); 24288 24289 rtvec v = gen_rtvec (2, tmp1, tmp2); 24290 emit_set_insn (target, gen_rtx_UNSPEC (mode, v, UNSPEC_ZIP1)); 24291 return true; 24292 } 24293 24294 /* Initialize register TARGET from the elements in PARALLEL rtx VALS. */ 24295 24296 void 24297 aarch64_sve_expand_vector_init (rtx target, rtx vals) 24298 { 24299 machine_mode mode = GET_MODE (target); 24300 int nelts = XVECLEN (vals, 0); 24301 24302 rtx_vector_builder v (mode, nelts, 1); 24303 for (int i = 0; i < nelts; i++) 24304 v.quick_push (XVECEXP (vals, 0, i)); 24305 v.finalize (); 24306 24307 /* If neither sub-vectors of v could be initialized specially, 24308 then use INSR to insert all elements from v into TARGET. 24309 ??? This might not be optimal for vectors with large 24310 initializers like 16-element or above. 24311 For nelts < 4, it probably isn't useful to handle specially. */ 24312 24313 if (nelts < 4 24314 || !aarch64_sve_expand_vector_init (target, v, nelts, nelts)) 24315 aarch64_sve_expand_vector_init_insert_elems (target, v, nelts); 24316 } 24317 24318 /* Check whether VALUE is a vector constant in which every element 24319 is either a power of 2 or a negated power of 2. If so, return 24320 a constant vector of log2s, and flip CODE between PLUS and MINUS 24321 if VALUE contains negated powers of 2. Return NULL_RTX otherwise. */ 24322 24323 static rtx 24324 aarch64_convert_mult_to_shift (rtx value, rtx_code &code) 24325 { 24326 if (!CONST_VECTOR_P (value)) 24327 return NULL_RTX; 24328 24329 rtx_vector_builder builder; 24330 if (!builder.new_unary_operation (GET_MODE (value), value, false)) 24331 return NULL_RTX; 24332 24333 scalar_mode int_mode = GET_MODE_INNER (GET_MODE (value)); 24334 /* 1 if the result of the multiplication must be negated, 24335 0 if it mustn't, or -1 if we don't yet care. */ 24336 int negate = -1; 24337 unsigned int encoded_nelts = const_vector_encoded_nelts (value); 24338 for (unsigned int i = 0; i < encoded_nelts; ++i) 24339 { 24340 rtx elt = CONST_VECTOR_ENCODED_ELT (value, i); 24341 if (!CONST_SCALAR_INT_P (elt)) 24342 return NULL_RTX; 24343 rtx_mode_t val (elt, int_mode); 24344 wide_int pow2 = wi::neg (val); 24345 if (val != pow2) 24346 { 24347 /* It matters whether we negate or not. Make that choice, 24348 and make sure that it's consistent with previous elements. */ 24349 if (negate == !wi::neg_p (val)) 24350 return NULL_RTX; 24351 negate = wi::neg_p (val); 24352 if (!negate) 24353 pow2 = val; 24354 } 24355 /* POW2 is now the value that we want to be a power of 2. */ 24356 int shift = wi::exact_log2 (pow2); 24357 if (shift < 0) 24358 return NULL_RTX; 24359 builder.quick_push (gen_int_mode (shift, int_mode)); 24360 } 24361 if (negate == -1) 24362 /* PLUS and MINUS are equivalent; canonicalize on PLUS. */ 24363 code = PLUS; 24364 else if (negate == 1) 24365 code = code == PLUS ? MINUS : PLUS; 24366 return builder.build (); 24367 } 24368 24369 /* Prepare for an integer SVE multiply-add or multiply-subtract pattern; 24370 CODE is PLUS for the former and MINUS for the latter. OPERANDS is the 24371 operands array, in the same order as for fma_optab. Return true if 24372 the function emitted all the necessary instructions, false if the caller 24373 should generate the pattern normally with the new OPERANDS array. */ 24374 24375 bool 24376 aarch64_prepare_sve_int_fma (rtx *operands, rtx_code code) 24377 { 24378 machine_mode mode = GET_MODE (operands[0]); 24379 if (rtx shifts = aarch64_convert_mult_to_shift (operands[2], code)) 24380 { 24381 rtx product = expand_binop (mode, vashl_optab, operands[1], shifts, 24382 NULL_RTX, true, OPTAB_DIRECT); 24383 force_expand_binop (mode, code == PLUS ? add_optab : sub_optab, 24384 operands[3], product, operands[0], true, 24385 OPTAB_DIRECT); 24386 return true; 24387 } 24388 operands[2] = force_reg (mode, operands[2]); 24389 return false; 24390 } 24391 24392 /* Likewise, but for a conditional pattern. */ 24393 24394 bool 24395 aarch64_prepare_sve_cond_int_fma (rtx *operands, rtx_code code) 24396 { 24397 machine_mode mode = GET_MODE (operands[0]); 24398 if (rtx shifts = aarch64_convert_mult_to_shift (operands[3], code)) 24399 { 24400 rtx product = expand_binop (mode, vashl_optab, operands[2], shifts, 24401 NULL_RTX, true, OPTAB_DIRECT); 24402 emit_insn (gen_cond (code, mode, operands[0], operands[1], 24403 operands[4], product, operands[5])); 24404 return true; 24405 } 24406 operands[3] = force_reg (mode, operands[3]); 24407 return false; 24408 } 24409 24410 static unsigned HOST_WIDE_INT 24411 aarch64_shift_truncation_mask (machine_mode mode) 24412 { 24413 if (!SHIFT_COUNT_TRUNCATED || aarch64_vector_data_mode_p (mode)) 24414 return 0; 24415 return GET_MODE_UNIT_BITSIZE (mode) - 1; 24416 } 24417 24418 /* Select a format to encode pointers in exception handling data. */ 24419 int 24420 aarch64_asm_preferred_eh_data_format (int code ATTRIBUTE_UNUSED, int global) 24421 { 24422 int type; 24423 switch (aarch64_cmodel) 24424 { 24425 case AARCH64_CMODEL_TINY: 24426 case AARCH64_CMODEL_TINY_PIC: 24427 case AARCH64_CMODEL_SMALL: 24428 case AARCH64_CMODEL_SMALL_PIC: 24429 case AARCH64_CMODEL_SMALL_SPIC: 24430 /* text+got+data < 4Gb. 4-byte signed relocs are sufficient 24431 for everything. */ 24432 type = DW_EH_PE_sdata4; 24433 break; 24434 default: 24435 /* No assumptions here. 8-byte relocs required. */ 24436 type = DW_EH_PE_sdata8; 24437 break; 24438 } 24439 return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | type; 24440 } 24441 24442 /* Output .variant_pcs for aarch64_vector_pcs function symbols. */ 24443 24444 static void 24445 aarch64_asm_output_variant_pcs (FILE *stream, const tree decl, const char* name) 24446 { 24447 if (TREE_CODE (decl) == FUNCTION_DECL) 24448 { 24449 arm_pcs pcs = (arm_pcs) fndecl_abi (decl).id (); 24450 if (pcs == ARM_PCS_SIMD || pcs == ARM_PCS_SVE) 24451 { 24452 fprintf (stream, "\t.variant_pcs\t"); 24453 assemble_name (stream, name); 24454 fprintf (stream, "\n"); 24455 } 24456 } 24457 } 24458 24459 /* The last .arch and .tune assembly strings that we printed. */ 24460 static std::string aarch64_last_printed_arch_string; 24461 static std::string aarch64_last_printed_tune_string; 24462 24463 /* Implement ASM_DECLARE_FUNCTION_NAME. Output the ISA features used 24464 by the function fndecl. */ 24465 24466 void 24467 aarch64_declare_function_name (FILE *stream, const char* name, 24468 tree fndecl) 24469 { 24470 tree target_parts = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); 24471 24472 struct cl_target_option *targ_options; 24473 if (target_parts) 24474 targ_options = TREE_TARGET_OPTION (target_parts); 24475 else 24476 targ_options = TREE_TARGET_OPTION (target_option_current_node); 24477 gcc_assert (targ_options); 24478 24479 const struct processor *this_arch 24480 = aarch64_get_arch (targ_options->x_selected_arch); 24481 24482 auto isa_flags = targ_options->x_aarch64_asm_isa_flags; 24483 std::string extension 24484 = aarch64_get_extension_string_for_isa_flags (isa_flags, 24485 this_arch->flags); 24486 /* Only update the assembler .arch string if it is distinct from the last 24487 such string we printed. */ 24488 std::string to_print = this_arch->name + extension; 24489 if (to_print != aarch64_last_printed_arch_string) 24490 { 24491 asm_fprintf (asm_out_file, "\t.arch %s\n", to_print.c_str ()); 24492 aarch64_last_printed_arch_string = to_print; 24493 } 24494 24495 /* Print the cpu name we're tuning for in the comments, might be 24496 useful to readers of the generated asm. Do it only when it changes 24497 from function to function and verbose assembly is requested. */ 24498 const struct processor *this_tune 24499 = aarch64_get_tune_cpu (targ_options->x_selected_tune); 24500 24501 if (flag_debug_asm && aarch64_last_printed_tune_string != this_tune->name) 24502 { 24503 asm_fprintf (asm_out_file, "\t" ASM_COMMENT_START ".tune %s\n", 24504 this_tune->name); 24505 aarch64_last_printed_tune_string = this_tune->name; 24506 } 24507 24508 aarch64_asm_output_variant_pcs (stream, fndecl, name); 24509 24510 /* Don't forget the type directive for ELF. */ 24511 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function"); 24512 ASM_OUTPUT_FUNCTION_LABEL (stream, name, fndecl); 24513 24514 cfun->machine->label_is_assembled = true; 24515 } 24516 24517 /* Implement PRINT_PATCHABLE_FUNCTION_ENTRY. */ 24518 24519 void 24520 aarch64_print_patchable_function_entry (FILE *file, 24521 unsigned HOST_WIDE_INT patch_area_size, 24522 bool record_p) 24523 { 24524 if (!cfun->machine->label_is_assembled) 24525 { 24526 /* Emit the patching area before the entry label, if any. */ 24527 default_print_patchable_function_entry (file, patch_area_size, 24528 record_p); 24529 return; 24530 } 24531 24532 rtx pa = gen_patchable_area (GEN_INT (patch_area_size), 24533 GEN_INT (record_p)); 24534 basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; 24535 24536 if (!aarch_bti_enabled () 24537 || cgraph_node::get (cfun->decl)->only_called_directly_p ()) 24538 { 24539 /* Emit the patchable_area at the beginning of the function. */ 24540 rtx_insn *insn = emit_insn_before (pa, BB_HEAD (bb)); 24541 INSN_ADDRESSES_NEW (insn, -1); 24542 return; 24543 } 24544 24545 rtx_insn *insn = next_real_nondebug_insn (get_insns ()); 24546 if (!insn 24547 || !INSN_P (insn) 24548 || GET_CODE (PATTERN (insn)) != UNSPEC_VOLATILE 24549 || XINT (PATTERN (insn), 1) != UNSPECV_BTI_C) 24550 { 24551 /* Emit a BTI_C. */ 24552 insn = emit_insn_before (gen_bti_c (), BB_HEAD (bb)); 24553 } 24554 24555 /* Emit the patchable_area after BTI_C. */ 24556 insn = emit_insn_after (pa, insn); 24557 INSN_ADDRESSES_NEW (insn, -1); 24558 } 24559 24560 /* Output patchable area. */ 24561 24562 void 24563 aarch64_output_patchable_area (unsigned int patch_area_size, bool record_p) 24564 { 24565 default_print_patchable_function_entry (asm_out_file, patch_area_size, 24566 record_p); 24567 } 24568 24569 /* Implement ASM_OUTPUT_DEF_FROM_DECLS. Output .variant_pcs for aliases. */ 24570 24571 void 24572 aarch64_asm_output_alias (FILE *stream, const tree decl, const tree target) 24573 { 24574 const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0); 24575 const char *value = IDENTIFIER_POINTER (target); 24576 aarch64_asm_output_variant_pcs (stream, decl, name); 24577 ASM_OUTPUT_DEF (stream, name, value); 24578 } 24579 24580 /* Implement ASM_OUTPUT_EXTERNAL. Output .variant_pcs for undefined 24581 function symbol references. */ 24582 24583 void 24584 aarch64_asm_output_external (FILE *stream, tree decl, const char* name) 24585 { 24586 default_elf_asm_output_external (stream, decl, name); 24587 aarch64_asm_output_variant_pcs (stream, decl, name); 24588 } 24589 24590 /* Triggered after a .cfi_startproc directive is emitted into the assembly file. 24591 Used to output the .cfi_b_key_frame directive when signing the current 24592 function with the B key. */ 24593 24594 void 24595 aarch64_post_cfi_startproc (FILE *f, tree ignored ATTRIBUTE_UNUSED) 24596 { 24597 if (cfun->machine->frame.laid_out && aarch64_return_address_signing_enabled () 24598 && aarch64_ra_sign_key == AARCH64_KEY_B) 24599 asm_fprintf (f, "\t.cfi_b_key_frame\n"); 24600 } 24601 24602 /* Implements TARGET_ASM_FILE_START. Output the assembly header. */ 24603 24604 static void 24605 aarch64_start_file (void) 24606 { 24607 struct cl_target_option *default_options 24608 = TREE_TARGET_OPTION (target_option_default_node); 24609 24610 const struct processor *default_arch 24611 = aarch64_get_arch (default_options->x_selected_arch); 24612 auto default_isa_flags = default_options->x_aarch64_asm_isa_flags; 24613 std::string extension 24614 = aarch64_get_extension_string_for_isa_flags (default_isa_flags, 24615 default_arch->flags); 24616 24617 aarch64_last_printed_arch_string = default_arch->name + extension; 24618 aarch64_last_printed_tune_string = ""; 24619 asm_fprintf (asm_out_file, "\t.arch %s\n", 24620 aarch64_last_printed_arch_string.c_str ()); 24621 24622 default_file_start (); 24623 } 24624 24625 /* Emit load exclusive. */ 24626 24627 static void 24628 aarch64_emit_load_exclusive (machine_mode mode, rtx rval, 24629 rtx mem, rtx model_rtx) 24630 { 24631 if (mode == TImode) 24632 emit_insn (gen_aarch64_load_exclusive_pair (gen_lowpart (DImode, rval), 24633 gen_highpart (DImode, rval), 24634 mem, model_rtx)); 24635 else 24636 emit_insn (gen_aarch64_load_exclusive (mode, rval, mem, model_rtx)); 24637 } 24638 24639 /* Emit store exclusive. */ 24640 24641 static void 24642 aarch64_emit_store_exclusive (machine_mode mode, rtx bval, 24643 rtx mem, rtx rval, rtx model_rtx) 24644 { 24645 if (mode == TImode) 24646 emit_insn (gen_aarch64_store_exclusive_pair 24647 (bval, mem, operand_subword (rval, 0, 0, TImode), 24648 operand_subword (rval, 1, 0, TImode), model_rtx)); 24649 else 24650 emit_insn (gen_aarch64_store_exclusive (mode, bval, mem, rval, model_rtx)); 24651 } 24652 24653 /* Mark the previous jump instruction as unlikely. */ 24654 24655 static void 24656 aarch64_emit_unlikely_jump (rtx insn) 24657 { 24658 rtx_insn *jump = emit_jump_insn (insn); 24659 add_reg_br_prob_note (jump, profile_probability::very_unlikely ()); 24660 } 24661 24662 /* We store the names of the various atomic helpers in a 5x5 array. 24663 Return the libcall function given MODE, MODEL and NAMES. */ 24664 24665 rtx 24666 aarch64_atomic_ool_func(machine_mode mode, rtx model_rtx, 24667 const atomic_ool_names *names) 24668 { 24669 memmodel model = memmodel_from_int (INTVAL (model_rtx)); 24670 int mode_idx, model_idx; 24671 24672 switch (mode) 24673 { 24674 case E_QImode: 24675 mode_idx = 0; 24676 break; 24677 case E_HImode: 24678 mode_idx = 1; 24679 break; 24680 case E_SImode: 24681 mode_idx = 2; 24682 break; 24683 case E_DImode: 24684 mode_idx = 3; 24685 break; 24686 case E_TImode: 24687 mode_idx = 4; 24688 break; 24689 default: 24690 gcc_unreachable (); 24691 } 24692 24693 switch (model) 24694 { 24695 case MEMMODEL_RELAXED: 24696 model_idx = 0; 24697 break; 24698 case MEMMODEL_CONSUME: 24699 case MEMMODEL_ACQUIRE: 24700 model_idx = 1; 24701 break; 24702 case MEMMODEL_RELEASE: 24703 model_idx = 2; 24704 break; 24705 case MEMMODEL_ACQ_REL: 24706 case MEMMODEL_SEQ_CST: 24707 model_idx = 3; 24708 break; 24709 case MEMMODEL_SYNC_ACQUIRE: 24710 case MEMMODEL_SYNC_RELEASE: 24711 case MEMMODEL_SYNC_SEQ_CST: 24712 model_idx = 4; 24713 break; 24714 default: 24715 gcc_unreachable (); 24716 } 24717 24718 return init_one_libfunc_visibility (names->str[mode_idx][model_idx], 24719 VISIBILITY_HIDDEN); 24720 } 24721 24722 #define DEF0(B, N) \ 24723 { "__aarch64_" #B #N "_relax", \ 24724 "__aarch64_" #B #N "_acq", \ 24725 "__aarch64_" #B #N "_rel", \ 24726 "__aarch64_" #B #N "_acq_rel", \ 24727 "__aarch64_" #B #N "_sync" } 24728 24729 #define DEF4(B) DEF0(B, 1), DEF0(B, 2), DEF0(B, 4), DEF0(B, 8), \ 24730 { NULL, NULL, NULL, NULL } 24731 #define DEF5(B) DEF0(B, 1), DEF0(B, 2), DEF0(B, 4), DEF0(B, 8), DEF0(B, 16) 24732 24733 static const atomic_ool_names aarch64_ool_cas_names = { { DEF5(cas) } }; 24734 const atomic_ool_names aarch64_ool_swp_names = { { DEF4(swp) } }; 24735 const atomic_ool_names aarch64_ool_ldadd_names = { { DEF4(ldadd) } }; 24736 const atomic_ool_names aarch64_ool_ldset_names = { { DEF4(ldset) } }; 24737 const atomic_ool_names aarch64_ool_ldclr_names = { { DEF4(ldclr) } }; 24738 const atomic_ool_names aarch64_ool_ldeor_names = { { DEF4(ldeor) } }; 24739 24740 #undef DEF0 24741 #undef DEF4 24742 #undef DEF5 24743 24744 /* Expand a compare and swap pattern. */ 24745 24746 void 24747 aarch64_expand_compare_and_swap (rtx operands[]) 24748 { 24749 rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x, cc_reg; 24750 machine_mode mode, r_mode; 24751 24752 bval = operands[0]; 24753 rval = operands[1]; 24754 mem = operands[2]; 24755 oldval = operands[3]; 24756 newval = operands[4]; 24757 is_weak = operands[5]; 24758 mod_s = operands[6]; 24759 mod_f = operands[7]; 24760 mode = GET_MODE (mem); 24761 24762 /* Normally the succ memory model must be stronger than fail, but in the 24763 unlikely event of fail being ACQUIRE and succ being RELEASE we need to 24764 promote succ to ACQ_REL so that we don't lose the acquire semantics. */ 24765 if (is_mm_acquire (memmodel_from_int (INTVAL (mod_f))) 24766 && is_mm_release (memmodel_from_int (INTVAL (mod_s)))) 24767 mod_s = GEN_INT (MEMMODEL_ACQ_REL); 24768 24769 r_mode = mode; 24770 if (mode == QImode || mode == HImode) 24771 { 24772 r_mode = SImode; 24773 rval = gen_reg_rtx (r_mode); 24774 } 24775 24776 if (TARGET_LSE) 24777 { 24778 /* The CAS insn requires oldval and rval overlap, but we need to 24779 have a copy of oldval saved across the operation to tell if 24780 the operation is successful. */ 24781 if (reg_overlap_mentioned_p (rval, oldval)) 24782 rval = copy_to_mode_reg (r_mode, oldval); 24783 else 24784 emit_move_insn (rval, gen_lowpart (r_mode, oldval)); 24785 if (mode == TImode) 24786 newval = force_reg (mode, newval); 24787 24788 emit_insn (gen_aarch64_compare_and_swap_lse (mode, rval, mem, 24789 newval, mod_s)); 24790 cc_reg = aarch64_gen_compare_reg_maybe_ze (NE, rval, oldval, mode); 24791 } 24792 else if (TARGET_OUTLINE_ATOMICS) 24793 { 24794 /* Oldval must satisfy compare afterward. */ 24795 if (!aarch64_plus_operand (oldval, mode)) 24796 oldval = force_reg (mode, oldval); 24797 rtx func = aarch64_atomic_ool_func (mode, mod_s, &aarch64_ool_cas_names); 24798 rval = emit_library_call_value (func, NULL_RTX, LCT_NORMAL, r_mode, 24799 oldval, mode, newval, mode, 24800 XEXP (mem, 0), Pmode); 24801 cc_reg = aarch64_gen_compare_reg_maybe_ze (NE, rval, oldval, mode); 24802 } 24803 else 24804 { 24805 /* The oldval predicate varies by mode. Test it and force to reg. */ 24806 insn_code code = code_for_aarch64_compare_and_swap (mode); 24807 if (!insn_data[code].operand[2].predicate (oldval, mode)) 24808 oldval = force_reg (mode, oldval); 24809 24810 emit_insn (GEN_FCN (code) (rval, mem, oldval, newval, 24811 is_weak, mod_s, mod_f)); 24812 cc_reg = gen_rtx_REG (CCmode, CC_REGNUM); 24813 } 24814 24815 if (r_mode != mode) 24816 rval = gen_lowpart (mode, rval); 24817 emit_move_insn (operands[1], rval); 24818 24819 x = gen_rtx_EQ (SImode, cc_reg, const0_rtx); 24820 emit_insn (gen_rtx_SET (bval, x)); 24821 } 24822 24823 /* Emit a barrier, that is appropriate for memory model MODEL, at the end of a 24824 sequence implementing an atomic operation. */ 24825 24826 static void 24827 aarch64_emit_post_barrier (enum memmodel model) 24828 { 24829 const enum memmodel base_model = memmodel_base (model); 24830 24831 if (is_mm_sync (model) 24832 && (base_model == MEMMODEL_ACQUIRE 24833 || base_model == MEMMODEL_ACQ_REL 24834 || base_model == MEMMODEL_SEQ_CST)) 24835 { 24836 emit_insn (gen_mem_thread_fence (GEN_INT (MEMMODEL_SEQ_CST))); 24837 } 24838 } 24839 24840 /* Split a compare and swap pattern. */ 24841 24842 void 24843 aarch64_split_compare_and_swap (rtx operands[]) 24844 { 24845 /* Split after prolog/epilog to avoid interactions with shrinkwrapping. */ 24846 gcc_assert (epilogue_completed); 24847 24848 rtx rval, mem, oldval, newval, scratch, x, model_rtx; 24849 machine_mode mode; 24850 bool is_weak; 24851 rtx_code_label *label1, *label2; 24852 enum memmodel model; 24853 24854 rval = operands[0]; 24855 mem = operands[1]; 24856 oldval = operands[2]; 24857 newval = operands[3]; 24858 model_rtx = operands[5]; 24859 scratch = operands[7]; 24860 mode = GET_MODE (mem); 24861 model = memmodel_from_int (INTVAL (model_rtx)); 24862 is_weak = operands[4] != const0_rtx && mode != TImode; 24863 24864 /* When OLDVAL is zero and we want the strong version we can emit a tighter 24865 loop: 24866 .label1: 24867 LD[A]XR rval, [mem] 24868 CBNZ rval, .label2 24869 ST[L]XR scratch, newval, [mem] 24870 CBNZ scratch, .label1 24871 .label2: 24872 CMP rval, 0. */ 24873 bool strong_zero_p = (!is_weak && !aarch64_track_speculation && 24874 oldval == const0_rtx && mode != TImode); 24875 24876 label1 = NULL; 24877 if (!is_weak) 24878 { 24879 label1 = gen_label_rtx (); 24880 emit_label (label1); 24881 } 24882 label2 = gen_label_rtx (); 24883 24884 /* The initial load can be relaxed for a __sync operation since a final 24885 barrier will be emitted to stop code hoisting. */ 24886 if (is_mm_sync (model)) 24887 aarch64_emit_load_exclusive (mode, rval, mem, GEN_INT (MEMMODEL_RELAXED)); 24888 else 24889 aarch64_emit_load_exclusive (mode, rval, mem, model_rtx); 24890 24891 if (strong_zero_p) 24892 x = gen_rtx_NE (VOIDmode, rval, const0_rtx); 24893 else 24894 { 24895 rtx cc_reg = aarch64_gen_compare_reg_maybe_ze (NE, rval, oldval, mode); 24896 x = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx); 24897 } 24898 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, 24899 gen_rtx_LABEL_REF (Pmode, label2), pc_rtx); 24900 aarch64_emit_unlikely_jump (gen_rtx_SET (pc_rtx, x)); 24901 24902 aarch64_emit_store_exclusive (mode, scratch, mem, newval, model_rtx); 24903 24904 if (!is_weak) 24905 { 24906 x = aarch64_gen_compare_zero_and_branch (NE, scratch, label1); 24907 aarch64_emit_unlikely_jump (x); 24908 } 24909 else 24910 aarch64_gen_compare_reg (NE, scratch, const0_rtx); 24911 24912 /* 128-bit LDAXP is not atomic unless STLXP succeeds. So for a mismatch, 24913 store the returned value and loop if the STLXP fails. */ 24914 if (mode == TImode) 24915 { 24916 rtx_code_label *label3 = gen_label_rtx (); 24917 emit_jump_insn (gen_rtx_SET (pc_rtx, gen_rtx_LABEL_REF (Pmode, label3))); 24918 emit_barrier (); 24919 24920 emit_label (label2); 24921 aarch64_emit_store_exclusive (mode, scratch, mem, rval, model_rtx); 24922 24923 x = aarch64_gen_compare_zero_and_branch (NE, scratch, label1); 24924 aarch64_emit_unlikely_jump (x); 24925 24926 label2 = label3; 24927 } 24928 24929 emit_label (label2); 24930 24931 /* If we used a CBNZ in the exchange loop emit an explicit compare with RVAL 24932 to set the condition flags. If this is not used it will be removed by 24933 later passes. */ 24934 if (strong_zero_p) 24935 aarch64_gen_compare_reg (NE, rval, const0_rtx); 24936 24937 /* Emit any final barrier needed for a __sync operation. */ 24938 if (is_mm_sync (model)) 24939 aarch64_emit_post_barrier (model); 24940 } 24941 24942 /* Split an atomic operation. */ 24943 24944 void 24945 aarch64_split_atomic_op (enum rtx_code code, rtx old_out, rtx new_out, rtx mem, 24946 rtx value, rtx model_rtx, rtx cond) 24947 { 24948 /* Split after prolog/epilog to avoid interactions with shrinkwrapping. */ 24949 gcc_assert (epilogue_completed); 24950 24951 machine_mode mode = GET_MODE (mem); 24952 machine_mode wmode = (mode == DImode ? DImode : SImode); 24953 const enum memmodel model = memmodel_from_int (INTVAL (model_rtx)); 24954 const bool is_sync = is_mm_sync (model); 24955 rtx_code_label *label; 24956 rtx x; 24957 24958 /* Split the atomic operation into a sequence. */ 24959 label = gen_label_rtx (); 24960 emit_label (label); 24961 24962 if (new_out) 24963 new_out = gen_lowpart (wmode, new_out); 24964 if (old_out) 24965 old_out = gen_lowpart (wmode, old_out); 24966 else 24967 old_out = new_out; 24968 value = simplify_gen_subreg (wmode, value, mode, 0); 24969 24970 /* The initial load can be relaxed for a __sync operation since a final 24971 barrier will be emitted to stop code hoisting. */ 24972 if (is_sync) 24973 aarch64_emit_load_exclusive (mode, old_out, mem, 24974 GEN_INT (MEMMODEL_RELAXED)); 24975 else 24976 aarch64_emit_load_exclusive (mode, old_out, mem, model_rtx); 24977 24978 switch (code) 24979 { 24980 case SET: 24981 new_out = value; 24982 break; 24983 24984 case NOT: 24985 x = gen_rtx_AND (wmode, old_out, value); 24986 emit_insn (gen_rtx_SET (new_out, x)); 24987 x = gen_rtx_NOT (wmode, new_out); 24988 emit_insn (gen_rtx_SET (new_out, x)); 24989 break; 24990 24991 case MINUS: 24992 if (CONST_INT_P (value)) 24993 { 24994 value = GEN_INT (-UINTVAL (value)); 24995 code = PLUS; 24996 } 24997 /* Fall through. */ 24998 24999 default: 25000 x = gen_rtx_fmt_ee (code, wmode, old_out, value); 25001 emit_insn (gen_rtx_SET (new_out, x)); 25002 break; 25003 } 25004 25005 aarch64_emit_store_exclusive (mode, cond, mem, 25006 gen_lowpart (mode, new_out), model_rtx); 25007 25008 x = aarch64_gen_compare_zero_and_branch (NE, cond, label); 25009 aarch64_emit_unlikely_jump (x); 25010 25011 /* Emit any final barrier needed for a __sync operation. */ 25012 if (is_sync) 25013 aarch64_emit_post_barrier (model); 25014 } 25015 25016 static void 25017 aarch64_init_libfuncs (void) 25018 { 25019 /* Half-precision float operations. The compiler handles all operations 25020 with NULL libfuncs by converting to SFmode. */ 25021 25022 /* Conversions. */ 25023 set_conv_libfunc (trunc_optab, HFmode, SFmode, "__gnu_f2h_ieee"); 25024 set_conv_libfunc (sext_optab, SFmode, HFmode, "__gnu_h2f_ieee"); 25025 25026 /* Arithmetic. */ 25027 set_optab_libfunc (add_optab, HFmode, NULL); 25028 set_optab_libfunc (sdiv_optab, HFmode, NULL); 25029 set_optab_libfunc (smul_optab, HFmode, NULL); 25030 set_optab_libfunc (neg_optab, HFmode, NULL); 25031 set_optab_libfunc (sub_optab, HFmode, NULL); 25032 25033 /* Comparisons. */ 25034 set_optab_libfunc (eq_optab, HFmode, NULL); 25035 set_optab_libfunc (ne_optab, HFmode, NULL); 25036 set_optab_libfunc (lt_optab, HFmode, NULL); 25037 set_optab_libfunc (le_optab, HFmode, NULL); 25038 set_optab_libfunc (ge_optab, HFmode, NULL); 25039 set_optab_libfunc (gt_optab, HFmode, NULL); 25040 set_optab_libfunc (unord_optab, HFmode, NULL); 25041 } 25042 25043 /* Target hook for c_mode_for_suffix. */ 25044 static machine_mode 25045 aarch64_c_mode_for_suffix (char suffix) 25046 { 25047 if (suffix == 'q') 25048 return TFmode; 25049 25050 return VOIDmode; 25051 } 25052 25053 /* We can only represent floating point constants which will fit in 25054 "quarter-precision" values. These values are characterised by 25055 a sign bit, a 4-bit mantissa and a 3-bit exponent. And are given 25056 by: 25057 25058 (-1)^s * (n/16) * 2^r 25059 25060 Where: 25061 's' is the sign bit. 25062 'n' is an integer in the range 16 <= n <= 31. 25063 'r' is an integer in the range -3 <= r <= 4. */ 25064 25065 /* Return true iff X can be represented by a quarter-precision 25066 floating point immediate operand X. Note, we cannot represent 0.0. */ 25067 bool 25068 aarch64_float_const_representable_p (rtx x) 25069 { 25070 /* This represents our current view of how many bits 25071 make up the mantissa. */ 25072 int point_pos = 2 * HOST_BITS_PER_WIDE_INT - 1; 25073 int exponent; 25074 unsigned HOST_WIDE_INT mantissa, mask; 25075 REAL_VALUE_TYPE r, m; 25076 bool fail; 25077 25078 x = unwrap_const_vec_duplicate (x); 25079 if (!CONST_DOUBLE_P (x)) 25080 return false; 25081 25082 if (GET_MODE (x) == VOIDmode 25083 || (GET_MODE (x) == HFmode && !TARGET_FP_F16INST)) 25084 return false; 25085 25086 r = *CONST_DOUBLE_REAL_VALUE (x); 25087 25088 /* We cannot represent infinities, NaNs or +/-zero. We won't 25089 know if we have +zero until we analyse the mantissa, but we 25090 can reject the other invalid values. */ 25091 if (REAL_VALUE_ISINF (r) || REAL_VALUE_ISNAN (r) 25092 || REAL_VALUE_MINUS_ZERO (r)) 25093 return false; 25094 25095 /* For BFmode, only handle 0.0. */ 25096 if (GET_MODE (x) == BFmode) 25097 return real_iszero (&r, false); 25098 25099 /* Extract exponent. */ 25100 r = real_value_abs (&r); 25101 exponent = REAL_EXP (&r); 25102 25103 /* For the mantissa, we expand into two HOST_WIDE_INTS, apart from the 25104 highest (sign) bit, with a fixed binary point at bit point_pos. 25105 m1 holds the low part of the mantissa, m2 the high part. 25106 WARNING: If we ever have a representation using more than 2 * H_W_I - 1 25107 bits for the mantissa, this can fail (low bits will be lost). */ 25108 real_ldexp (&m, &r, point_pos - exponent); 25109 wide_int w = real_to_integer (&m, &fail, HOST_BITS_PER_WIDE_INT * 2); 25110 25111 /* If the low part of the mantissa has bits set we cannot represent 25112 the value. */ 25113 if (w.ulow () != 0) 25114 return false; 25115 /* We have rejected the lower HOST_WIDE_INT, so update our 25116 understanding of how many bits lie in the mantissa and 25117 look only at the high HOST_WIDE_INT. */ 25118 mantissa = w.elt (1); 25119 point_pos -= HOST_BITS_PER_WIDE_INT; 25120 25121 /* We can only represent values with a mantissa of the form 1.xxxx. */ 25122 mask = ((unsigned HOST_WIDE_INT)1 << (point_pos - 5)) - 1; 25123 if ((mantissa & mask) != 0) 25124 return false; 25125 25126 /* Having filtered unrepresentable values, we may now remove all 25127 but the highest 5 bits. */ 25128 mantissa >>= point_pos - 5; 25129 25130 /* We cannot represent the value 0.0, so reject it. This is handled 25131 elsewhere. */ 25132 if (mantissa == 0) 25133 return false; 25134 25135 /* Then, as bit 4 is always set, we can mask it off, leaving 25136 the mantissa in the range [0, 15]. */ 25137 mantissa &= ~(1 << 4); 25138 gcc_assert (mantissa <= 15); 25139 25140 /* GCC internally does not use IEEE754-like encoding (where normalized 25141 significands are in the range [1, 2). GCC uses [0.5, 1) (see real.cc). 25142 Our mantissa values are shifted 4 places to the left relative to 25143 normalized IEEE754 so we must modify the exponent returned by REAL_EXP 25144 by 5 places to correct for GCC's representation. */ 25145 exponent = 5 - exponent; 25146 25147 return (exponent >= 0 && exponent <= 7); 25148 } 25149 25150 /* Returns the string with the instruction for AdvSIMD MOVI, MVNI, ORR or BIC 25151 immediate with a CONST_VECTOR of MODE and WIDTH. WHICH selects whether to 25152 output MOVI/MVNI, ORR or BIC immediate. */ 25153 char* 25154 aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width, 25155 enum simd_immediate_check which) 25156 { 25157 bool is_valid; 25158 static char templ[40]; 25159 const char *mnemonic; 25160 const char *shift_op; 25161 unsigned int lane_count = 0; 25162 char element_char; 25163 25164 struct simd_immediate_info info; 25165 25166 /* This will return true to show const_vector is legal for use as either 25167 a AdvSIMD MOVI instruction (or, implicitly, MVNI), ORR or BIC immediate. 25168 It will also update INFO to show how the immediate should be generated. 25169 WHICH selects whether to check for MOVI/MVNI, ORR or BIC. */ 25170 is_valid = aarch64_simd_valid_immediate (const_vector, &info, which); 25171 gcc_assert (is_valid); 25172 25173 element_char = sizetochar (GET_MODE_BITSIZE (info.elt_mode)); 25174 lane_count = width / GET_MODE_BITSIZE (info.elt_mode); 25175 25176 if (GET_MODE_CLASS (info.elt_mode) == MODE_FLOAT) 25177 { 25178 gcc_assert (info.insn == simd_immediate_info::MOV 25179 && info.u.mov.shift == 0); 25180 /* For FP zero change it to a CONST_INT 0 and use the integer SIMD 25181 move immediate path. */ 25182 if (aarch64_float_const_zero_rtx_p (info.u.mov.value)) 25183 info.u.mov.value = GEN_INT (0); 25184 else 25185 { 25186 const unsigned int buf_size = 20; 25187 char float_buf[buf_size] = {'\0'}; 25188 real_to_decimal_for_mode (float_buf, 25189 CONST_DOUBLE_REAL_VALUE (info.u.mov.value), 25190 buf_size, buf_size, 1, info.elt_mode); 25191 25192 if (lane_count == 1) 25193 snprintf (templ, sizeof (templ), "fmov\t%%d0, %s", float_buf); 25194 else 25195 snprintf (templ, sizeof (templ), "fmov\t%%0.%d%c, %s", 25196 lane_count, element_char, float_buf); 25197 return templ; 25198 } 25199 } 25200 25201 gcc_assert (CONST_INT_P (info.u.mov.value)); 25202 25203 if (which == AARCH64_CHECK_MOV) 25204 { 25205 mnemonic = info.insn == simd_immediate_info::MVN ? "mvni" : "movi"; 25206 shift_op = (info.u.mov.modifier == simd_immediate_info::MSL 25207 ? "msl" : "lsl"); 25208 if (lane_count == 1) 25209 snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX, 25210 mnemonic, UINTVAL (info.u.mov.value)); 25211 else if (info.u.mov.shift) 25212 snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " 25213 HOST_WIDE_INT_PRINT_HEX ", %s %d", mnemonic, lane_count, 25214 element_char, UINTVAL (info.u.mov.value), shift_op, 25215 info.u.mov.shift); 25216 else 25217 snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, " 25218 HOST_WIDE_INT_PRINT_HEX, mnemonic, lane_count, 25219 element_char, UINTVAL (info.u.mov.value)); 25220 } 25221 else 25222 { 25223 /* For AARCH64_CHECK_BIC and AARCH64_CHECK_ORR. */ 25224 mnemonic = info.insn == simd_immediate_info::MVN ? "bic" : "orr"; 25225 if (info.u.mov.shift) 25226 snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #" 25227 HOST_WIDE_INT_PRINT_DEC ", %s #%d", mnemonic, lane_count, 25228 element_char, UINTVAL (info.u.mov.value), "lsl", 25229 info.u.mov.shift); 25230 else 25231 snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #" 25232 HOST_WIDE_INT_PRINT_DEC, mnemonic, lane_count, 25233 element_char, UINTVAL (info.u.mov.value)); 25234 } 25235 return templ; 25236 } 25237 25238 char* 25239 aarch64_output_scalar_simd_mov_immediate (rtx immediate, scalar_int_mode mode) 25240 { 25241 25242 /* If a floating point number was passed and we desire to use it in an 25243 integer mode do the conversion to integer. */ 25244 if (CONST_DOUBLE_P (immediate) && GET_MODE_CLASS (mode) == MODE_INT) 25245 { 25246 unsigned HOST_WIDE_INT ival; 25247 if (!aarch64_reinterpret_float_as_int (immediate, &ival)) 25248 gcc_unreachable (); 25249 immediate = gen_int_mode (ival, mode); 25250 } 25251 25252 machine_mode vmode; 25253 /* use a 64 bit mode for everything except for DI/DF/DD mode, where we use 25254 a 128 bit vector mode. */ 25255 int width = GET_MODE_BITSIZE (mode) == 64 ? 128 : 64; 25256 25257 vmode = aarch64_simd_container_mode (mode, width); 25258 rtx v_op = aarch64_simd_gen_const_vector_dup (vmode, INTVAL (immediate)); 25259 return aarch64_output_simd_mov_immediate (v_op, width); 25260 } 25261 25262 /* Return the output string to use for moving immediate CONST_VECTOR 25263 into an SVE register. */ 25264 25265 char * 25266 aarch64_output_sve_mov_immediate (rtx const_vector) 25267 { 25268 static char templ[40]; 25269 struct simd_immediate_info info; 25270 char element_char; 25271 25272 bool is_valid = aarch64_simd_valid_immediate (const_vector, &info); 25273 gcc_assert (is_valid); 25274 25275 element_char = sizetochar (GET_MODE_BITSIZE (info.elt_mode)); 25276 25277 machine_mode vec_mode = GET_MODE (const_vector); 25278 if (aarch64_sve_pred_mode_p (vec_mode)) 25279 { 25280 static char buf[sizeof ("ptrue\t%0.N, vlNNNNN")]; 25281 if (info.insn == simd_immediate_info::MOV) 25282 { 25283 gcc_assert (info.u.mov.value == const0_rtx); 25284 snprintf (buf, sizeof (buf), "pfalse\t%%0.b"); 25285 } 25286 else 25287 { 25288 gcc_assert (info.insn == simd_immediate_info::PTRUE); 25289 unsigned int total_bytes; 25290 if (info.u.pattern == AARCH64_SV_ALL 25291 && BYTES_PER_SVE_VECTOR.is_constant (&total_bytes)) 25292 snprintf (buf, sizeof (buf), "ptrue\t%%0.%c, vl%d", element_char, 25293 total_bytes / GET_MODE_SIZE (info.elt_mode)); 25294 else 25295 snprintf (buf, sizeof (buf), "ptrue\t%%0.%c, %s", element_char, 25296 svpattern_token (info.u.pattern)); 25297 } 25298 return buf; 25299 } 25300 25301 if (info.insn == simd_immediate_info::INDEX) 25302 { 25303 snprintf (templ, sizeof (templ), "index\t%%0.%c, #" 25304 HOST_WIDE_INT_PRINT_DEC ", #" HOST_WIDE_INT_PRINT_DEC, 25305 element_char, INTVAL (info.u.index.base), 25306 INTVAL (info.u.index.step)); 25307 return templ; 25308 } 25309 25310 if (GET_MODE_CLASS (info.elt_mode) == MODE_FLOAT) 25311 { 25312 if (aarch64_float_const_zero_rtx_p (info.u.mov.value)) 25313 info.u.mov.value = GEN_INT (0); 25314 else 25315 { 25316 const int buf_size = 20; 25317 char float_buf[buf_size] = {}; 25318 real_to_decimal_for_mode (float_buf, 25319 CONST_DOUBLE_REAL_VALUE (info.u.mov.value), 25320 buf_size, buf_size, 1, info.elt_mode); 25321 25322 snprintf (templ, sizeof (templ), "fmov\t%%0.%c, #%s", 25323 element_char, float_buf); 25324 return templ; 25325 } 25326 } 25327 25328 snprintf (templ, sizeof (templ), "mov\t%%0.%c, #" HOST_WIDE_INT_PRINT_DEC, 25329 element_char, INTVAL (info.u.mov.value)); 25330 return templ; 25331 } 25332 25333 /* Return the asm template for a PTRUES. CONST_UNSPEC is the 25334 aarch64_sve_ptrue_svpattern_immediate that describes the predicate 25335 pattern. */ 25336 25337 char * 25338 aarch64_output_sve_ptrues (rtx const_unspec) 25339 { 25340 static char templ[40]; 25341 25342 struct simd_immediate_info info; 25343 bool is_valid = aarch64_simd_valid_immediate (const_unspec, &info); 25344 gcc_assert (is_valid && info.insn == simd_immediate_info::PTRUE); 25345 25346 char element_char = sizetochar (GET_MODE_BITSIZE (info.elt_mode)); 25347 snprintf (templ, sizeof (templ), "ptrues\t%%0.%c, %s", element_char, 25348 svpattern_token (info.u.pattern)); 25349 return templ; 25350 } 25351 25352 /* Split operands into moves from op[1] + op[2] into op[0]. */ 25353 25354 void 25355 aarch64_split_combinev16qi (rtx operands[3]) 25356 { 25357 machine_mode halfmode = GET_MODE (operands[1]); 25358 25359 gcc_assert (halfmode == V16QImode); 25360 25361 rtx destlo = simplify_gen_subreg (halfmode, operands[0], 25362 GET_MODE (operands[0]), 0); 25363 rtx desthi = simplify_gen_subreg (halfmode, operands[0], 25364 GET_MODE (operands[0]), 25365 GET_MODE_SIZE (halfmode)); 25366 25367 bool skiplo = rtx_equal_p (destlo, operands[1]); 25368 bool skiphi = rtx_equal_p (desthi, operands[2]); 25369 25370 if (skiplo && skiphi) 25371 { 25372 /* No-op move. Can't split to nothing; emit something. */ 25373 emit_note (NOTE_INSN_DELETED); 25374 return; 25375 } 25376 25377 /* Special case of reversed high/low parts. */ 25378 if (reg_overlap_mentioned_p (operands[2], destlo) 25379 && reg_overlap_mentioned_p (operands[1], desthi)) 25380 { 25381 emit_insn (gen_xorv16qi3 (operands[1], operands[1], operands[2])); 25382 emit_insn (gen_xorv16qi3 (operands[2], operands[1], operands[2])); 25383 emit_insn (gen_xorv16qi3 (operands[1], operands[1], operands[2])); 25384 } 25385 else if (!reg_overlap_mentioned_p (operands[2], destlo)) 25386 { 25387 /* Try to avoid unnecessary moves if part of the result 25388 is in the right place already. */ 25389 if (!skiplo) 25390 emit_move_insn (destlo, operands[1]); 25391 if (!skiphi) 25392 emit_move_insn (desthi, operands[2]); 25393 } 25394 else 25395 { 25396 if (!skiphi) 25397 emit_move_insn (desthi, operands[2]); 25398 if (!skiplo) 25399 emit_move_insn (destlo, operands[1]); 25400 } 25401 } 25402 25403 /* vec_perm support. */ 25404 25405 struct expand_vec_perm_d 25406 { 25407 rtx target, op0, op1; 25408 vec_perm_indices perm; 25409 machine_mode vmode; 25410 machine_mode op_mode; 25411 unsigned int vec_flags; 25412 unsigned int op_vec_flags; 25413 bool one_vector_p; 25414 bool testing_p; 25415 }; 25416 25417 static bool aarch64_expand_vec_perm_const_1 (struct expand_vec_perm_d *d); 25418 25419 /* Generate a variable permutation. */ 25420 25421 static void 25422 aarch64_expand_vec_perm_1 (rtx target, rtx op0, rtx op1, rtx sel) 25423 { 25424 machine_mode vmode = GET_MODE (target); 25425 bool one_vector_p = rtx_equal_p (op0, op1); 25426 25427 gcc_checking_assert (vmode == V8QImode || vmode == V16QImode); 25428 gcc_checking_assert (GET_MODE (op0) == vmode); 25429 gcc_checking_assert (GET_MODE (op1) == vmode); 25430 gcc_checking_assert (GET_MODE (sel) == vmode); 25431 gcc_checking_assert (TARGET_SIMD); 25432 25433 if (one_vector_p) 25434 { 25435 if (vmode == V8QImode) 25436 { 25437 /* Expand the argument to a V16QI mode by duplicating it. */ 25438 rtx pair = gen_reg_rtx (V16QImode); 25439 emit_insn (gen_aarch64_combinev8qi (pair, op0, op0)); 25440 emit_insn (gen_aarch64_qtbl1v8qi (target, pair, sel)); 25441 } 25442 else 25443 { 25444 emit_insn (gen_aarch64_qtbl1v16qi (target, op0, sel)); 25445 } 25446 } 25447 else 25448 { 25449 rtx pair; 25450 25451 if (vmode == V8QImode) 25452 { 25453 pair = gen_reg_rtx (V16QImode); 25454 emit_insn (gen_aarch64_combinev8qi (pair, op0, op1)); 25455 emit_insn (gen_aarch64_qtbl1v8qi (target, pair, sel)); 25456 } 25457 else 25458 { 25459 pair = gen_reg_rtx (V2x16QImode); 25460 emit_insn (gen_aarch64_combinev16qi (pair, op0, op1)); 25461 emit_insn (gen_aarch64_qtbl2v16qi (target, pair, sel)); 25462 } 25463 } 25464 } 25465 25466 /* Expand a vec_perm with the operands given by TARGET, OP0, OP1 and SEL. 25467 NELT is the number of elements in the vector. */ 25468 25469 void 25470 aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel, 25471 unsigned int nelt) 25472 { 25473 machine_mode vmode = GET_MODE (target); 25474 bool one_vector_p = rtx_equal_p (op0, op1); 25475 rtx mask; 25476 25477 /* The TBL instruction does not use a modulo index, so we must take care 25478 of that ourselves. */ 25479 mask = aarch64_simd_gen_const_vector_dup (vmode, 25480 one_vector_p ? nelt - 1 : 2 * nelt - 1); 25481 sel = expand_simple_binop (vmode, AND, sel, mask, NULL, 0, OPTAB_LIB_WIDEN); 25482 25483 /* For big-endian, we also need to reverse the index within the vector 25484 (but not which vector). */ 25485 if (BYTES_BIG_ENDIAN) 25486 { 25487 /* If one_vector_p, mask is a vector of (nelt - 1)'s already. */ 25488 if (!one_vector_p) 25489 mask = aarch64_simd_gen_const_vector_dup (vmode, nelt - 1); 25490 sel = expand_simple_binop (vmode, XOR, sel, mask, 25491 NULL, 0, OPTAB_LIB_WIDEN); 25492 } 25493 aarch64_expand_vec_perm_1 (target, op0, op1, sel); 25494 } 25495 25496 /* Generate (set TARGET (unspec [OP0 OP1] CODE)). */ 25497 25498 static void 25499 emit_unspec2 (rtx target, int code, rtx op0, rtx op1) 25500 { 25501 emit_insn (gen_rtx_SET (target, 25502 gen_rtx_UNSPEC (GET_MODE (target), 25503 gen_rtvec (2, op0, op1), code))); 25504 } 25505 25506 /* Expand an SVE vec_perm with the given operands. */ 25507 25508 void 25509 aarch64_expand_sve_vec_perm (rtx target, rtx op0, rtx op1, rtx sel) 25510 { 25511 machine_mode data_mode = GET_MODE (target); 25512 machine_mode sel_mode = GET_MODE (sel); 25513 /* Enforced by the pattern condition. */ 25514 int nunits = GET_MODE_NUNITS (sel_mode).to_constant (); 25515 25516 /* Note: vec_perm indices are supposed to wrap when they go beyond the 25517 size of the two value vectors, i.e. the upper bits of the indices 25518 are effectively ignored. SVE TBL instead produces 0 for any 25519 out-of-range indices, so we need to modulo all the vec_perm indices 25520 to ensure they are all in range. */ 25521 rtx sel_reg = force_reg (sel_mode, sel); 25522 25523 /* Check if the sel only references the first values vector. */ 25524 if (CONST_VECTOR_P (sel) 25525 && aarch64_const_vec_all_in_range_p (sel, 0, nunits - 1)) 25526 { 25527 emit_unspec2 (target, UNSPEC_TBL, op0, sel_reg); 25528 return; 25529 } 25530 25531 /* Check if the two values vectors are the same. */ 25532 if (rtx_equal_p (op0, op1)) 25533 { 25534 rtx max_sel = aarch64_simd_gen_const_vector_dup (sel_mode, nunits - 1); 25535 rtx sel_mod = expand_simple_binop (sel_mode, AND, sel_reg, max_sel, 25536 NULL, 0, OPTAB_DIRECT); 25537 emit_unspec2 (target, UNSPEC_TBL, op0, sel_mod); 25538 return; 25539 } 25540 25541 /* Run TBL on for each value vector and combine the results. */ 25542 25543 rtx res0 = gen_reg_rtx (data_mode); 25544 rtx res1 = gen_reg_rtx (data_mode); 25545 rtx neg_num_elems = aarch64_simd_gen_const_vector_dup (sel_mode, -nunits); 25546 if (!CONST_VECTOR_P (sel) 25547 || !aarch64_const_vec_all_in_range_p (sel, 0, 2 * nunits - 1)) 25548 { 25549 rtx max_sel = aarch64_simd_gen_const_vector_dup (sel_mode, 25550 2 * nunits - 1); 25551 sel_reg = expand_simple_binop (sel_mode, AND, sel_reg, max_sel, 25552 NULL, 0, OPTAB_DIRECT); 25553 } 25554 emit_unspec2 (res0, UNSPEC_TBL, op0, sel_reg); 25555 rtx sel_sub = expand_simple_binop (sel_mode, PLUS, sel_reg, neg_num_elems, 25556 NULL, 0, OPTAB_DIRECT); 25557 emit_unspec2 (res1, UNSPEC_TBL, op1, sel_sub); 25558 if (GET_MODE_CLASS (data_mode) == MODE_VECTOR_INT) 25559 emit_insn (gen_rtx_SET (target, gen_rtx_IOR (data_mode, res0, res1))); 25560 else 25561 emit_unspec2 (target, UNSPEC_IORF, res0, res1); 25562 } 25563 25564 /* Recognize patterns suitable for the TRN instructions. */ 25565 static bool 25566 aarch64_evpc_trn (struct expand_vec_perm_d *d) 25567 { 25568 HOST_WIDE_INT odd; 25569 poly_uint64 nelt = d->perm.length (); 25570 rtx out, in0, in1; 25571 machine_mode vmode = d->vmode; 25572 25573 if (GET_MODE_UNIT_SIZE (vmode) > 8) 25574 return false; 25575 25576 /* Note that these are little-endian tests. 25577 We correct for big-endian later. */ 25578 if (!d->perm[0].is_constant (&odd) 25579 || (odd != 0 && odd != 1) 25580 || !d->perm.series_p (0, 2, odd, 2) 25581 || !d->perm.series_p (1, 2, nelt + odd, 2)) 25582 return false; 25583 25584 /* Success! */ 25585 if (d->testing_p) 25586 return true; 25587 25588 in0 = d->op0; 25589 in1 = d->op1; 25590 /* We don't need a big-endian lane correction for SVE; see the comment 25591 at the head of aarch64-sve.md for details. */ 25592 if (BYTES_BIG_ENDIAN && d->vec_flags == VEC_ADVSIMD) 25593 { 25594 std::swap (in0, in1); 25595 odd = !odd; 25596 } 25597 out = d->target; 25598 25599 emit_set_insn (out, gen_rtx_UNSPEC (vmode, gen_rtvec (2, in0, in1), 25600 odd ? UNSPEC_TRN2 : UNSPEC_TRN1)); 25601 return true; 25602 } 25603 25604 /* Try to re-encode the PERM constant so it combines odd and even elements. 25605 This rewrites constants such as {0, 1, 4, 5}/V4SF to {0, 2}/V2DI. 25606 We retry with this new constant with the full suite of patterns. */ 25607 static bool 25608 aarch64_evpc_reencode (struct expand_vec_perm_d *d) 25609 { 25610 expand_vec_perm_d newd; 25611 unsigned HOST_WIDE_INT nelt; 25612 25613 if (d->vec_flags != VEC_ADVSIMD) 25614 return false; 25615 25616 /* Get the new mode. Always twice the size of the inner 25617 and half the elements. */ 25618 poly_uint64 vec_bits = GET_MODE_BITSIZE (d->vmode); 25619 unsigned int new_elt_bits = GET_MODE_UNIT_BITSIZE (d->vmode) * 2; 25620 auto new_elt_mode = int_mode_for_size (new_elt_bits, false).require (); 25621 machine_mode new_mode = aarch64_simd_container_mode (new_elt_mode, vec_bits); 25622 25623 if (new_mode == word_mode) 25624 return false; 25625 25626 /* to_constant is safe since this routine is specific to Advanced SIMD 25627 vectors. */ 25628 nelt = d->perm.length ().to_constant (); 25629 25630 vec_perm_builder newpermconst; 25631 newpermconst.new_vector (nelt / 2, nelt / 2, 1); 25632 25633 /* Convert the perm constant if we can. Require even, odd as the pairs. */ 25634 for (unsigned int i = 0; i < nelt; i += 2) 25635 { 25636 poly_int64 elt0 = d->perm[i]; 25637 poly_int64 elt1 = d->perm[i + 1]; 25638 poly_int64 newelt; 25639 if (!multiple_p (elt0, 2, &newelt) || maybe_ne (elt0 + 1, elt1)) 25640 return false; 25641 newpermconst.quick_push (newelt.to_constant ()); 25642 } 25643 newpermconst.finalize (); 25644 25645 newd.vmode = new_mode; 25646 newd.vec_flags = VEC_ADVSIMD; 25647 newd.op_mode = newd.vmode; 25648 newd.op_vec_flags = newd.vec_flags; 25649 newd.target = d->target ? gen_lowpart (new_mode, d->target) : NULL; 25650 newd.op0 = d->op0 ? gen_lowpart (new_mode, d->op0) : NULL; 25651 newd.op1 = d->op1 ? gen_lowpart (new_mode, d->op1) : NULL; 25652 newd.testing_p = d->testing_p; 25653 newd.one_vector_p = d->one_vector_p; 25654 25655 newd.perm.new_vector (newpermconst, newd.one_vector_p ? 1 : 2, nelt / 2); 25656 return aarch64_expand_vec_perm_const_1 (&newd); 25657 } 25658 25659 /* Recognize patterns suitable for the UZP instructions. */ 25660 static bool 25661 aarch64_evpc_uzp (struct expand_vec_perm_d *d) 25662 { 25663 HOST_WIDE_INT odd; 25664 rtx out, in0, in1; 25665 machine_mode vmode = d->vmode; 25666 25667 if (GET_MODE_UNIT_SIZE (vmode) > 8) 25668 return false; 25669 25670 /* Note that these are little-endian tests. 25671 We correct for big-endian later. */ 25672 if (!d->perm[0].is_constant (&odd) 25673 || (odd != 0 && odd != 1) 25674 || !d->perm.series_p (0, 1, odd, 2)) 25675 return false; 25676 25677 /* Success! */ 25678 if (d->testing_p) 25679 return true; 25680 25681 in0 = d->op0; 25682 in1 = d->op1; 25683 /* We don't need a big-endian lane correction for SVE; see the comment 25684 at the head of aarch64-sve.md for details. */ 25685 if (BYTES_BIG_ENDIAN && d->vec_flags == VEC_ADVSIMD) 25686 { 25687 std::swap (in0, in1); 25688 odd = !odd; 25689 } 25690 out = d->target; 25691 25692 emit_set_insn (out, gen_rtx_UNSPEC (vmode, gen_rtvec (2, in0, in1), 25693 odd ? UNSPEC_UZP2 : UNSPEC_UZP1)); 25694 return true; 25695 } 25696 25697 /* Recognize patterns suitable for the ZIP instructions. */ 25698 static bool 25699 aarch64_evpc_zip (struct expand_vec_perm_d *d) 25700 { 25701 unsigned int high; 25702 poly_uint64 nelt = d->perm.length (); 25703 rtx out, in0, in1; 25704 machine_mode vmode = d->vmode; 25705 25706 if (GET_MODE_UNIT_SIZE (vmode) > 8) 25707 return false; 25708 25709 /* Note that these are little-endian tests. 25710 We correct for big-endian later. */ 25711 poly_uint64 first = d->perm[0]; 25712 if ((maybe_ne (first, 0U) && maybe_ne (first * 2, nelt)) 25713 || !d->perm.series_p (0, 2, first, 1) 25714 || !d->perm.series_p (1, 2, first + nelt, 1)) 25715 return false; 25716 high = maybe_ne (first, 0U); 25717 25718 /* Success! */ 25719 if (d->testing_p) 25720 return true; 25721 25722 in0 = d->op0; 25723 in1 = d->op1; 25724 /* We don't need a big-endian lane correction for SVE; see the comment 25725 at the head of aarch64-sve.md for details. */ 25726 if (BYTES_BIG_ENDIAN && d->vec_flags == VEC_ADVSIMD) 25727 { 25728 std::swap (in0, in1); 25729 high = !high; 25730 } 25731 out = d->target; 25732 25733 emit_set_insn (out, gen_rtx_UNSPEC (vmode, gen_rtvec (2, in0, in1), 25734 high ? UNSPEC_ZIP2 : UNSPEC_ZIP1)); 25735 return true; 25736 } 25737 25738 /* Recognize patterns for the EXT insn. */ 25739 25740 static bool 25741 aarch64_evpc_ext (struct expand_vec_perm_d *d) 25742 { 25743 HOST_WIDE_INT location; 25744 rtx offset; 25745 25746 /* The first element always refers to the first vector. 25747 Check if the extracted indices are increasing by one. */ 25748 if ((d->vec_flags & VEC_SVE_PRED) 25749 || !d->perm[0].is_constant (&location) 25750 || !d->perm.series_p (0, 1, location, 1)) 25751 return false; 25752 25753 /* Success! */ 25754 if (d->testing_p) 25755 return true; 25756 25757 /* The case where (location == 0) is a no-op for both big- and little-endian, 25758 and is removed by the mid-end at optimization levels -O1 and higher. 25759 25760 We don't need a big-endian lane correction for SVE; see the comment 25761 at the head of aarch64-sve.md for details. */ 25762 if (BYTES_BIG_ENDIAN && location != 0 && d->vec_flags == VEC_ADVSIMD) 25763 { 25764 /* After setup, we want the high elements of the first vector (stored 25765 at the LSB end of the register), and the low elements of the second 25766 vector (stored at the MSB end of the register). So swap. */ 25767 std::swap (d->op0, d->op1); 25768 /* location != 0 (above), so safe to assume (nelt - location) < nelt. 25769 to_constant () is safe since this is restricted to Advanced SIMD 25770 vectors. */ 25771 location = d->perm.length ().to_constant () - location; 25772 } 25773 25774 offset = GEN_INT (location); 25775 emit_set_insn (d->target, 25776 gen_rtx_UNSPEC (d->vmode, 25777 gen_rtvec (3, d->op0, d->op1, offset), 25778 UNSPEC_EXT)); 25779 return true; 25780 } 25781 25782 /* Recognize patterns for the REV{64,32,16} insns, which reverse elements 25783 within each 64-bit, 32-bit or 16-bit granule. */ 25784 25785 static bool 25786 aarch64_evpc_rev_local (struct expand_vec_perm_d *d) 25787 { 25788 HOST_WIDE_INT diff; 25789 unsigned int i, size, unspec; 25790 machine_mode pred_mode; 25791 25792 if ((d->vec_flags & VEC_SVE_PRED) 25793 || !d->one_vector_p 25794 || !d->perm[0].is_constant (&diff) 25795 || !diff) 25796 return false; 25797 25798 if (d->vec_flags & VEC_SVE_DATA) 25799 size = (diff + 1) * aarch64_sve_container_bits (d->vmode); 25800 else 25801 size = (diff + 1) * GET_MODE_UNIT_BITSIZE (d->vmode); 25802 if (size == 64) 25803 { 25804 unspec = UNSPEC_REV64; 25805 pred_mode = VNx2BImode; 25806 } 25807 else if (size == 32) 25808 { 25809 unspec = UNSPEC_REV32; 25810 pred_mode = VNx4BImode; 25811 } 25812 else if (size == 16) 25813 { 25814 unspec = UNSPEC_REV16; 25815 pred_mode = VNx8BImode; 25816 } 25817 else 25818 return false; 25819 25820 unsigned int step = diff + 1; 25821 for (i = 0; i < step; ++i) 25822 if (!d->perm.series_p (i, step, diff - i, step)) 25823 return false; 25824 25825 /* Success! */ 25826 if (d->testing_p) 25827 return true; 25828 25829 if (d->vec_flags & VEC_SVE_DATA) 25830 { 25831 rtx pred = aarch64_ptrue_reg (pred_mode); 25832 emit_insn (gen_aarch64_sve_revbhw (d->vmode, pred_mode, 25833 d->target, pred, d->op0)); 25834 return true; 25835 } 25836 rtx src = gen_rtx_UNSPEC (d->vmode, gen_rtvec (1, d->op0), unspec); 25837 emit_set_insn (d->target, src); 25838 return true; 25839 } 25840 25841 /* Recognize patterns for the REV insn, which reverses elements within 25842 a full vector. */ 25843 25844 static bool 25845 aarch64_evpc_rev_global (struct expand_vec_perm_d *d) 25846 { 25847 poly_uint64 nelt = d->perm.length (); 25848 25849 if (!d->one_vector_p || d->vec_flags == VEC_ADVSIMD) 25850 return false; 25851 25852 if (!d->perm.series_p (0, 1, nelt - 1, -1)) 25853 return false; 25854 25855 /* Success! */ 25856 if (d->testing_p) 25857 return true; 25858 25859 rtx src = gen_rtx_UNSPEC (d->vmode, gen_rtvec (1, d->op0), UNSPEC_REV); 25860 emit_set_insn (d->target, src); 25861 return true; 25862 } 25863 25864 static bool 25865 aarch64_evpc_dup (struct expand_vec_perm_d *d) 25866 { 25867 rtx out = d->target; 25868 rtx in0; 25869 HOST_WIDE_INT elt; 25870 machine_mode vmode = d->vmode; 25871 rtx lane; 25872 25873 if ((d->vec_flags & VEC_SVE_PRED) 25874 || d->perm.encoding ().encoded_nelts () != 1 25875 || !d->perm[0].is_constant (&elt)) 25876 return false; 25877 25878 if ((d->vec_flags & VEC_SVE_DATA) 25879 && elt * (aarch64_sve_container_bits (vmode) / 8) >= 64) 25880 return false; 25881 25882 /* Success! */ 25883 if (d->testing_p) 25884 return true; 25885 25886 /* The generic preparation in aarch64_expand_vec_perm_const_1 25887 swaps the operand order and the permute indices if it finds 25888 d->perm[0] to be in the second operand. Thus, we can always 25889 use d->op0 and need not do any extra arithmetic to get the 25890 correct lane number. */ 25891 in0 = d->op0; 25892 lane = GEN_INT (elt); /* The pattern corrects for big-endian. */ 25893 25894 rtx parallel = gen_rtx_PARALLEL (vmode, gen_rtvec (1, lane)); 25895 rtx select = gen_rtx_VEC_SELECT (GET_MODE_INNER (vmode), in0, parallel); 25896 emit_set_insn (out, gen_rtx_VEC_DUPLICATE (vmode, select)); 25897 return true; 25898 } 25899 25900 static bool 25901 aarch64_evpc_tbl (struct expand_vec_perm_d *d) 25902 { 25903 rtx rperm[MAX_COMPILE_TIME_VEC_BYTES], sel; 25904 machine_mode vmode = d->vmode; 25905 25906 /* Make sure that the indices are constant. */ 25907 unsigned int encoded_nelts = d->perm.encoding ().encoded_nelts (); 25908 for (unsigned int i = 0; i < encoded_nelts; ++i) 25909 if (!d->perm[i].is_constant ()) 25910 return false; 25911 25912 if (d->testing_p) 25913 return true; 25914 25915 /* Generic code will try constant permutation twice. Once with the 25916 original mode and again with the elements lowered to QImode. 25917 So wait and don't do the selector expansion ourselves. */ 25918 if (vmode != V8QImode && vmode != V16QImode) 25919 return false; 25920 25921 /* to_constant is safe since this routine is specific to Advanced SIMD 25922 vectors. */ 25923 unsigned int nelt = d->perm.length ().to_constant (); 25924 for (unsigned int i = 0; i < nelt; ++i) 25925 /* If big-endian and two vectors we end up with a weird mixed-endian 25926 mode on NEON. Reverse the index within each word but not the word 25927 itself. to_constant is safe because we checked is_constant above. */ 25928 rperm[i] = GEN_INT (BYTES_BIG_ENDIAN 25929 ? d->perm[i].to_constant () ^ (nelt - 1) 25930 : d->perm[i].to_constant ()); 25931 25932 sel = gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (nelt, rperm)); 25933 sel = force_reg (vmode, sel); 25934 25935 aarch64_expand_vec_perm_1 (d->target, d->op0, d->op1, sel); 25936 return true; 25937 } 25938 25939 /* Try to implement D using an SVE TBL instruction. */ 25940 25941 static bool 25942 aarch64_evpc_sve_tbl (struct expand_vec_perm_d *d) 25943 { 25944 unsigned HOST_WIDE_INT nelt; 25945 25946 /* Permuting two variable-length vectors could overflow the 25947 index range. */ 25948 if (!d->one_vector_p && !d->perm.length ().is_constant (&nelt)) 25949 return false; 25950 25951 if (d->testing_p) 25952 return true; 25953 25954 machine_mode sel_mode = related_int_vector_mode (d->vmode).require (); 25955 rtx sel = vec_perm_indices_to_rtx (sel_mode, d->perm); 25956 if (d->one_vector_p) 25957 emit_unspec2 (d->target, UNSPEC_TBL, d->op0, force_reg (sel_mode, sel)); 25958 else 25959 aarch64_expand_sve_vec_perm (d->target, d->op0, d->op1, sel); 25960 return true; 25961 } 25962 25963 /* Try to implement D using SVE dup instruction. */ 25964 25965 static bool 25966 aarch64_evpc_sve_dup (struct expand_vec_perm_d *d) 25967 { 25968 if (BYTES_BIG_ENDIAN 25969 || !d->one_vector_p 25970 || d->vec_flags != VEC_SVE_DATA 25971 || d->op_vec_flags != VEC_ADVSIMD 25972 || d->perm.encoding ().nelts_per_pattern () != 1 25973 || !known_eq (d->perm.encoding ().npatterns (), 25974 GET_MODE_NUNITS (d->op_mode)) 25975 || !known_eq (GET_MODE_BITSIZE (d->op_mode), 128)) 25976 return false; 25977 25978 int npatterns = d->perm.encoding ().npatterns (); 25979 for (int i = 0; i < npatterns; i++) 25980 if (!known_eq (d->perm[i], i)) 25981 return false; 25982 25983 if (d->testing_p) 25984 return true; 25985 25986 aarch64_expand_sve_dupq (d->target, GET_MODE (d->target), d->op0); 25987 return true; 25988 } 25989 25990 /* Try to implement D using SVE SEL instruction. */ 25991 25992 static bool 25993 aarch64_evpc_sel (struct expand_vec_perm_d *d) 25994 { 25995 machine_mode vmode = d->vmode; 25996 int unit_size = GET_MODE_UNIT_SIZE (vmode); 25997 25998 if (d->vec_flags != VEC_SVE_DATA 25999 || unit_size > 8) 26000 return false; 26001 26002 int n_patterns = d->perm.encoding ().npatterns (); 26003 poly_int64 vec_len = d->perm.length (); 26004 26005 for (int i = 0; i < n_patterns; ++i) 26006 if (!known_eq (d->perm[i], i) 26007 && !known_eq (d->perm[i], vec_len + i)) 26008 return false; 26009 26010 for (int i = n_patterns; i < n_patterns * 2; i++) 26011 if (!d->perm.series_p (i, n_patterns, i, n_patterns) 26012 && !d->perm.series_p (i, n_patterns, vec_len + i, n_patterns)) 26013 return false; 26014 26015 if (d->testing_p) 26016 return true; 26017 26018 machine_mode pred_mode = aarch64_sve_pred_mode (vmode); 26019 26020 /* Build a predicate that is true when op0 elements should be used. */ 26021 rtx_vector_builder builder (pred_mode, n_patterns, 2); 26022 for (int i = 0; i < n_patterns * 2; i++) 26023 { 26024 rtx elem = known_eq (d->perm[i], i) ? CONST1_RTX (BImode) 26025 : CONST0_RTX (BImode); 26026 builder.quick_push (elem); 26027 } 26028 26029 rtx const_vec = builder.build (); 26030 rtx pred = force_reg (pred_mode, const_vec); 26031 /* TARGET = PRED ? OP0 : OP1. */ 26032 emit_insn (gen_vcond_mask (vmode, vmode, d->target, d->op0, d->op1, pred)); 26033 return true; 26034 } 26035 26036 /* Recognize patterns suitable for the INS instructions. */ 26037 static bool 26038 aarch64_evpc_ins (struct expand_vec_perm_d *d) 26039 { 26040 machine_mode mode = d->vmode; 26041 unsigned HOST_WIDE_INT nelt; 26042 26043 if (d->vec_flags != VEC_ADVSIMD) 26044 return false; 26045 26046 /* to_constant is safe since this routine is specific to Advanced SIMD 26047 vectors. */ 26048 nelt = d->perm.length ().to_constant (); 26049 rtx insv = d->op0; 26050 26051 HOST_WIDE_INT idx = -1; 26052 26053 for (unsigned HOST_WIDE_INT i = 0; i < nelt; i++) 26054 { 26055 HOST_WIDE_INT elt; 26056 if (!d->perm[i].is_constant (&elt)) 26057 return false; 26058 if (elt == (HOST_WIDE_INT) i) 26059 continue; 26060 if (idx != -1) 26061 { 26062 idx = -1; 26063 break; 26064 } 26065 idx = i; 26066 } 26067 26068 if (idx == -1) 26069 { 26070 insv = d->op1; 26071 for (unsigned HOST_WIDE_INT i = 0; i < nelt; i++) 26072 { 26073 if (d->perm[i].to_constant () == (HOST_WIDE_INT) (i + nelt)) 26074 continue; 26075 if (idx != -1) 26076 return false; 26077 idx = i; 26078 } 26079 26080 if (idx == -1) 26081 return false; 26082 } 26083 26084 if (d->testing_p) 26085 return true; 26086 26087 gcc_assert (idx != -1); 26088 26089 unsigned extractindex = d->perm[idx].to_constant (); 26090 rtx extractv = d->op0; 26091 if (extractindex >= nelt) 26092 { 26093 extractv = d->op1; 26094 extractindex -= nelt; 26095 } 26096 gcc_assert (extractindex < nelt); 26097 26098 insn_code icode = code_for_aarch64_simd_vec_copy_lane (mode); 26099 expand_operand ops[5]; 26100 create_output_operand (&ops[0], d->target, mode); 26101 create_input_operand (&ops[1], insv, mode); 26102 create_integer_operand (&ops[2], 1 << idx); 26103 create_input_operand (&ops[3], extractv, mode); 26104 create_integer_operand (&ops[4], extractindex); 26105 expand_insn (icode, 5, ops); 26106 26107 return true; 26108 } 26109 26110 static bool 26111 aarch64_expand_vec_perm_const_1 (struct expand_vec_perm_d *d) 26112 { 26113 gcc_assert (d->op_mode != E_VOIDmode); 26114 26115 /* The pattern matching functions above are written to look for a small 26116 number to begin the sequence (0, 1, N/2). If we begin with an index 26117 from the second operand, we can swap the operands. */ 26118 poly_int64 nelt = d->perm.length (); 26119 if (known_ge (d->perm[0], nelt)) 26120 { 26121 d->perm.rotate_inputs (1); 26122 std::swap (d->op0, d->op1); 26123 } 26124 26125 if (((d->vec_flags == VEC_ADVSIMD && TARGET_SIMD) 26126 || d->vec_flags == VEC_SVE_DATA 26127 || d->vec_flags == (VEC_SVE_DATA | VEC_PARTIAL) 26128 || d->vec_flags == VEC_SVE_PRED) 26129 && known_gt (nelt, 1)) 26130 { 26131 if (d->vmode == d->op_mode) 26132 { 26133 if (aarch64_evpc_rev_local (d)) 26134 return true; 26135 else if (aarch64_evpc_rev_global (d)) 26136 return true; 26137 else if (aarch64_evpc_ext (d)) 26138 return true; 26139 else if (aarch64_evpc_dup (d)) 26140 return true; 26141 else if (aarch64_evpc_zip (d)) 26142 return true; 26143 else if (aarch64_evpc_uzp (d)) 26144 return true; 26145 else if (aarch64_evpc_trn (d)) 26146 return true; 26147 else if (aarch64_evpc_sel (d)) 26148 return true; 26149 else if (aarch64_evpc_ins (d)) 26150 return true; 26151 else if (aarch64_evpc_reencode (d)) 26152 return true; 26153 26154 if (d->vec_flags == VEC_SVE_DATA) 26155 return aarch64_evpc_sve_tbl (d); 26156 else if (d->vec_flags == VEC_ADVSIMD) 26157 return aarch64_evpc_tbl (d); 26158 } 26159 else 26160 { 26161 if (aarch64_evpc_sve_dup (d)) 26162 return true; 26163 } 26164 } 26165 return false; 26166 } 26167 26168 /* Implement TARGET_VECTORIZE_VEC_PERM_CONST. */ 26169 26170 static bool 26171 aarch64_vectorize_vec_perm_const (machine_mode vmode, machine_mode op_mode, 26172 rtx target, rtx op0, rtx op1, 26173 const vec_perm_indices &sel) 26174 { 26175 struct expand_vec_perm_d d; 26176 26177 /* Check whether the mask can be applied to a single vector. */ 26178 if (sel.ninputs () == 1 26179 || (op0 && rtx_equal_p (op0, op1))) 26180 d.one_vector_p = true; 26181 else if (sel.all_from_input_p (0)) 26182 { 26183 d.one_vector_p = true; 26184 op1 = op0; 26185 } 26186 else if (sel.all_from_input_p (1)) 26187 { 26188 d.one_vector_p = true; 26189 op0 = op1; 26190 } 26191 else 26192 d.one_vector_p = false; 26193 26194 d.perm.new_vector (sel.encoding (), d.one_vector_p ? 1 : 2, 26195 sel.nelts_per_input ()); 26196 d.vmode = vmode; 26197 d.vec_flags = aarch64_classify_vector_mode (d.vmode); 26198 d.op_mode = op_mode; 26199 d.op_vec_flags = aarch64_classify_vector_mode (d.op_mode); 26200 d.target = target; 26201 d.op0 = op0 ? force_reg (op_mode, op0) : NULL_RTX; 26202 if (op0 && d.one_vector_p) 26203 d.op1 = copy_rtx (d.op0); 26204 else 26205 d.op1 = op1 ? force_reg (op_mode, op1) : NULL_RTX; 26206 d.testing_p = !target; 26207 26208 if (!d.testing_p) 26209 return aarch64_expand_vec_perm_const_1 (&d); 26210 26211 rtx_insn *last = get_last_insn (); 26212 bool ret = aarch64_expand_vec_perm_const_1 (&d); 26213 gcc_assert (last == get_last_insn ()); 26214 26215 return ret; 26216 } 26217 /* Generate a byte permute mask for a register of mode MODE, 26218 which has NUNITS units. */ 26219 26220 rtx 26221 aarch64_reverse_mask (machine_mode mode, unsigned int nunits) 26222 { 26223 /* We have to reverse each vector because we dont have 26224 a permuted load that can reverse-load according to ABI rules. */ 26225 rtx mask; 26226 rtvec v = rtvec_alloc (16); 26227 unsigned int i, j; 26228 unsigned int usize = GET_MODE_UNIT_SIZE (mode); 26229 26230 gcc_assert (BYTES_BIG_ENDIAN); 26231 gcc_assert (AARCH64_VALID_SIMD_QREG_MODE (mode)); 26232 26233 for (i = 0; i < nunits; i++) 26234 for (j = 0; j < usize; j++) 26235 RTVEC_ELT (v, i * usize + j) = GEN_INT ((i + 1) * usize - 1 - j); 26236 mask = gen_rtx_CONST_VECTOR (V16QImode, v); 26237 return force_reg (V16QImode, mask); 26238 } 26239 26240 /* Expand an SVE integer comparison using the SVE equivalent of: 26241 26242 (set TARGET (CODE OP0 OP1)). */ 26243 26244 void 26245 aarch64_expand_sve_vec_cmp_int (rtx target, rtx_code code, rtx op0, rtx op1) 26246 { 26247 machine_mode pred_mode = GET_MODE (target); 26248 machine_mode data_mode = GET_MODE (op0); 26249 rtx res = aarch64_sve_emit_int_cmp (target, pred_mode, code, data_mode, 26250 op0, op1); 26251 if (!rtx_equal_p (target, res)) 26252 emit_move_insn (target, res); 26253 } 26254 26255 /* Return the UNSPEC_COND_* code for comparison CODE. */ 26256 26257 static unsigned int 26258 aarch64_unspec_cond_code (rtx_code code) 26259 { 26260 switch (code) 26261 { 26262 case NE: 26263 return UNSPEC_COND_FCMNE; 26264 case EQ: 26265 return UNSPEC_COND_FCMEQ; 26266 case LT: 26267 return UNSPEC_COND_FCMLT; 26268 case GT: 26269 return UNSPEC_COND_FCMGT; 26270 case LE: 26271 return UNSPEC_COND_FCMLE; 26272 case GE: 26273 return UNSPEC_COND_FCMGE; 26274 case UNORDERED: 26275 return UNSPEC_COND_FCMUO; 26276 default: 26277 gcc_unreachable (); 26278 } 26279 } 26280 26281 /* Emit: 26282 26283 (set TARGET (unspec [PRED KNOWN_PTRUE_P OP0 OP1] UNSPEC_COND_<X>)) 26284 26285 where <X> is the operation associated with comparison CODE. 26286 KNOWN_PTRUE_P is true if PRED is known to be a PTRUE. */ 26287 26288 static void 26289 aarch64_emit_sve_fp_cond (rtx target, rtx_code code, rtx pred, 26290 bool known_ptrue_p, rtx op0, rtx op1) 26291 { 26292 rtx flag = gen_int_mode (known_ptrue_p, SImode); 26293 rtx unspec = gen_rtx_UNSPEC (GET_MODE (pred), 26294 gen_rtvec (4, pred, flag, op0, op1), 26295 aarch64_unspec_cond_code (code)); 26296 emit_set_insn (target, unspec); 26297 } 26298 26299 /* Emit the SVE equivalent of: 26300 26301 (set TMP1 (unspec [PRED KNOWN_PTRUE_P OP0 OP1] UNSPEC_COND_<X1>)) 26302 (set TMP2 (unspec [PRED KNOWN_PTRUE_P OP0 OP1] UNSPEC_COND_<X2>)) 26303 (set TARGET (ior:PRED_MODE TMP1 TMP2)) 26304 26305 where <Xi> is the operation associated with comparison CODEi. 26306 KNOWN_PTRUE_P is true if PRED is known to be a PTRUE. */ 26307 26308 static void 26309 aarch64_emit_sve_or_fp_conds (rtx target, rtx_code code1, rtx_code code2, 26310 rtx pred, bool known_ptrue_p, rtx op0, rtx op1) 26311 { 26312 machine_mode pred_mode = GET_MODE (pred); 26313 rtx tmp1 = gen_reg_rtx (pred_mode); 26314 aarch64_emit_sve_fp_cond (tmp1, code1, pred, known_ptrue_p, op0, op1); 26315 rtx tmp2 = gen_reg_rtx (pred_mode); 26316 aarch64_emit_sve_fp_cond (tmp2, code2, pred, known_ptrue_p, op0, op1); 26317 aarch64_emit_binop (target, ior_optab, tmp1, tmp2); 26318 } 26319 26320 /* Emit the SVE equivalent of: 26321 26322 (set TMP (unspec [PRED KNOWN_PTRUE_P OP0 OP1] UNSPEC_COND_<X>)) 26323 (set TARGET (not TMP)) 26324 26325 where <X> is the operation associated with comparison CODE. 26326 KNOWN_PTRUE_P is true if PRED is known to be a PTRUE. */ 26327 26328 static void 26329 aarch64_emit_sve_invert_fp_cond (rtx target, rtx_code code, rtx pred, 26330 bool known_ptrue_p, rtx op0, rtx op1) 26331 { 26332 machine_mode pred_mode = GET_MODE (pred); 26333 rtx tmp = gen_reg_rtx (pred_mode); 26334 aarch64_emit_sve_fp_cond (tmp, code, pred, known_ptrue_p, op0, op1); 26335 aarch64_emit_unop (target, one_cmpl_optab, tmp); 26336 } 26337 26338 /* Expand an SVE floating-point comparison using the SVE equivalent of: 26339 26340 (set TARGET (CODE OP0 OP1)) 26341 26342 If CAN_INVERT_P is true, the caller can also handle inverted results; 26343 return true if the result is in fact inverted. */ 26344 26345 bool 26346 aarch64_expand_sve_vec_cmp_float (rtx target, rtx_code code, 26347 rtx op0, rtx op1, bool can_invert_p) 26348 { 26349 machine_mode pred_mode = GET_MODE (target); 26350 machine_mode data_mode = GET_MODE (op0); 26351 26352 rtx ptrue = aarch64_ptrue_reg (pred_mode); 26353 switch (code) 26354 { 26355 case UNORDERED: 26356 /* UNORDERED has no immediate form. */ 26357 op1 = force_reg (data_mode, op1); 26358 /* fall through */ 26359 case LT: 26360 case LE: 26361 case GT: 26362 case GE: 26363 case EQ: 26364 case NE: 26365 { 26366 /* There is native support for the comparison. */ 26367 aarch64_emit_sve_fp_cond (target, code, ptrue, true, op0, op1); 26368 return false; 26369 } 26370 26371 case LTGT: 26372 /* This is a trapping operation (LT or GT). */ 26373 aarch64_emit_sve_or_fp_conds (target, LT, GT, ptrue, true, op0, op1); 26374 return false; 26375 26376 case UNEQ: 26377 if (!flag_trapping_math) 26378 { 26379 /* This would trap for signaling NaNs. */ 26380 op1 = force_reg (data_mode, op1); 26381 aarch64_emit_sve_or_fp_conds (target, UNORDERED, EQ, 26382 ptrue, true, op0, op1); 26383 return false; 26384 } 26385 /* fall through */ 26386 case UNLT: 26387 case UNLE: 26388 case UNGT: 26389 case UNGE: 26390 if (flag_trapping_math) 26391 { 26392 /* Work out which elements are ordered. */ 26393 rtx ordered = gen_reg_rtx (pred_mode); 26394 op1 = force_reg (data_mode, op1); 26395 aarch64_emit_sve_invert_fp_cond (ordered, UNORDERED, 26396 ptrue, true, op0, op1); 26397 26398 /* Test the opposite condition for the ordered elements, 26399 then invert the result. */ 26400 if (code == UNEQ) 26401 code = NE; 26402 else 26403 code = reverse_condition_maybe_unordered (code); 26404 if (can_invert_p) 26405 { 26406 aarch64_emit_sve_fp_cond (target, code, 26407 ordered, false, op0, op1); 26408 return true; 26409 } 26410 aarch64_emit_sve_invert_fp_cond (target, code, 26411 ordered, false, op0, op1); 26412 return false; 26413 } 26414 break; 26415 26416 case ORDERED: 26417 /* ORDERED has no immediate form. */ 26418 op1 = force_reg (data_mode, op1); 26419 break; 26420 26421 default: 26422 gcc_unreachable (); 26423 } 26424 26425 /* There is native support for the inverse comparison. */ 26426 code = reverse_condition_maybe_unordered (code); 26427 if (can_invert_p) 26428 { 26429 aarch64_emit_sve_fp_cond (target, code, ptrue, true, op0, op1); 26430 return true; 26431 } 26432 aarch64_emit_sve_invert_fp_cond (target, code, ptrue, true, op0, op1); 26433 return false; 26434 } 26435 26436 /* Expand an SVE vcond pattern with operands OPS. DATA_MODE is the mode 26437 of the data being selected and CMP_MODE is the mode of the values being 26438 compared. */ 26439 26440 void 26441 aarch64_expand_sve_vcond (machine_mode data_mode, machine_mode cmp_mode, 26442 rtx *ops) 26443 { 26444 machine_mode pred_mode = aarch64_get_mask_mode (cmp_mode).require (); 26445 rtx pred = gen_reg_rtx (pred_mode); 26446 if (FLOAT_MODE_P (cmp_mode)) 26447 { 26448 if (aarch64_expand_sve_vec_cmp_float (pred, GET_CODE (ops[3]), 26449 ops[4], ops[5], true)) 26450 std::swap (ops[1], ops[2]); 26451 } 26452 else 26453 aarch64_expand_sve_vec_cmp_int (pred, GET_CODE (ops[3]), ops[4], ops[5]); 26454 26455 if (!aarch64_sve_reg_or_dup_imm (ops[1], data_mode)) 26456 ops[1] = force_reg (data_mode, ops[1]); 26457 /* The "false" value can only be zero if the "true" value is a constant. */ 26458 if (register_operand (ops[1], data_mode) 26459 || !aarch64_simd_reg_or_zero (ops[2], data_mode)) 26460 ops[2] = force_reg (data_mode, ops[2]); 26461 26462 rtvec vec = gen_rtvec (3, pred, ops[1], ops[2]); 26463 emit_set_insn (ops[0], gen_rtx_UNSPEC (data_mode, vec, UNSPEC_SEL)); 26464 } 26465 26466 /* Return true if: 26467 26468 (a) MODE1 and MODE2 use the same layout for bytes that are common 26469 to both modes; 26470 26471 (b) subregs involving the two modes behave as the target-independent 26472 subreg rules require; and 26473 26474 (c) there is at least one register that can hold both modes. 26475 26476 Return false otherwise. */ 26477 26478 static bool 26479 aarch64_modes_compatible_p (machine_mode mode1, machine_mode mode2) 26480 { 26481 unsigned int flags1 = aarch64_classify_vector_mode (mode1); 26482 unsigned int flags2 = aarch64_classify_vector_mode (mode2); 26483 26484 bool sve1_p = (flags1 & VEC_ANY_SVE); 26485 bool sve2_p = (flags2 & VEC_ANY_SVE); 26486 26487 bool partial_sve1_p = sve1_p && (flags1 & VEC_PARTIAL); 26488 bool partial_sve2_p = sve2_p && (flags2 & VEC_PARTIAL); 26489 26490 bool pred1_p = (flags1 & VEC_SVE_PRED); 26491 bool pred2_p = (flags2 & VEC_SVE_PRED); 26492 26493 bool partial_advsimd_struct1_p = (flags1 == (VEC_ADVSIMD | VEC_STRUCT 26494 | VEC_PARTIAL)); 26495 bool partial_advsimd_struct2_p = (flags2 == (VEC_ADVSIMD | VEC_STRUCT 26496 | VEC_PARTIAL)); 26497 26498 /* Don't allow changes between predicate modes and other modes. 26499 Only predicate registers can hold predicate modes and only 26500 non-predicate registers can hold non-predicate modes, so any 26501 attempt to mix them would require a round trip through memory. */ 26502 if (pred1_p != pred2_p) 26503 return false; 26504 26505 /* The contents of partial SVE modes are distributed evenly across 26506 the register, whereas GCC expects them to be clustered together. 26507 We therefore need to be careful about mode changes involving them. */ 26508 if (partial_sve1_p && partial_sve2_p) 26509 { 26510 /* Reject changes between partial SVE modes that have different 26511 patterns of significant and insignificant bits. */ 26512 if ((aarch64_sve_container_bits (mode1) 26513 != aarch64_sve_container_bits (mode2)) 26514 || GET_MODE_UNIT_SIZE (mode1) != GET_MODE_UNIT_SIZE (mode2)) 26515 return false; 26516 } 26517 else if (partial_sve1_p) 26518 { 26519 /* The first lane of MODE1 is where GCC expects it, but anything 26520 bigger than that is not. */ 26521 if (maybe_gt (GET_MODE_SIZE (mode2), GET_MODE_UNIT_SIZE (mode1))) 26522 return false; 26523 } 26524 else if (partial_sve2_p) 26525 { 26526 /* Similarly in reverse. */ 26527 if (maybe_gt (GET_MODE_SIZE (mode1), GET_MODE_UNIT_SIZE (mode2))) 26528 return false; 26529 } 26530 26531 /* Don't allow changes between partial Advanced SIMD structure modes 26532 and other modes that are bigger than 8 bytes. E.g. V16QI and V2x8QI 26533 are the same size, but the former occupies one Q register while the 26534 latter occupies two D registers. */ 26535 if (partial_advsimd_struct1_p != partial_advsimd_struct2_p 26536 && maybe_gt (GET_MODE_SIZE (mode1), 8) 26537 && maybe_gt (GET_MODE_SIZE (mode2), 8)) 26538 return false; 26539 26540 if (maybe_ne (BITS_PER_SVE_VECTOR, 128u)) 26541 { 26542 /* Don't allow changes between SVE modes and other modes that might 26543 be bigger than 128 bits. In particular, OImode, CImode and XImode 26544 divide into 128-bit quantities while SVE modes divide into 26545 BITS_PER_SVE_VECTOR quantities. */ 26546 if (sve1_p && !sve2_p && maybe_gt (GET_MODE_BITSIZE (mode2), 128)) 26547 return false; 26548 if (sve2_p && !sve1_p && maybe_gt (GET_MODE_BITSIZE (mode1), 128)) 26549 return false; 26550 } 26551 26552 if (BYTES_BIG_ENDIAN) 26553 { 26554 /* Don't allow changes between SVE data modes and non-SVE modes. 26555 See the comment at the head of aarch64-sve.md for details. */ 26556 if (sve1_p != sve2_p) 26557 return false; 26558 26559 /* Don't allow changes in element size: lane 0 of the new vector 26560 would not then be lane 0 of the old vector. See the comment 26561 above aarch64_maybe_expand_sve_subreg_move for a more detailed 26562 description. 26563 26564 In the worst case, this forces a register to be spilled in 26565 one mode and reloaded in the other, which handles the 26566 endianness correctly. */ 26567 if (sve1_p && GET_MODE_UNIT_SIZE (mode1) != GET_MODE_UNIT_SIZE (mode2)) 26568 return false; 26569 } 26570 return true; 26571 } 26572 26573 /* Implement TARGET_MODES_TIEABLE_P. In principle we should always defer 26574 to aarch64_modes_compatible_p. However due to issues with register 26575 allocation it is preferable to avoid tieing integer scalar and FP 26576 scalar modes. Executing integer operations in general registers is 26577 better than treating them as scalar vector operations. This reduces 26578 latency and avoids redundant int<->FP moves. So tie modes if they 26579 are either the same class, or one of them is a vector mode. */ 26580 26581 static bool 26582 aarch64_modes_tieable_p (machine_mode mode1, machine_mode mode2) 26583 { 26584 if (aarch64_modes_compatible_p (mode1, mode2)) 26585 { 26586 if (GET_MODE_CLASS (mode1) == GET_MODE_CLASS (mode2)) 26587 return true; 26588 if (VECTOR_MODE_P (mode1) || VECTOR_MODE_P (mode2)) 26589 return true; 26590 } 26591 return false; 26592 } 26593 26594 /* Return a new RTX holding the result of moving POINTER forward by 26595 AMOUNT bytes. */ 26596 26597 static rtx 26598 aarch64_move_pointer (rtx pointer, poly_int64 amount) 26599 { 26600 rtx next = plus_constant (Pmode, XEXP (pointer, 0), amount); 26601 26602 return adjust_automodify_address (pointer, GET_MODE (pointer), 26603 next, amount); 26604 } 26605 26606 /* Return a new RTX holding the result of moving POINTER forward by the 26607 size of the mode it points to. */ 26608 26609 static rtx 26610 aarch64_progress_pointer (rtx pointer) 26611 { 26612 return aarch64_move_pointer (pointer, GET_MODE_SIZE (GET_MODE (pointer))); 26613 } 26614 26615 /* Expand a cpymem/movmem using the MOPS extension. OPERANDS are taken 26616 from the cpymem/movmem pattern. IS_MEMMOVE is true if this is a memmove 26617 rather than memcpy. Return true iff we succeeded. */ 26618 bool 26619 aarch64_expand_cpymem_mops (rtx *operands, bool is_memmove) 26620 { 26621 if (!TARGET_MOPS) 26622 return false; 26623 26624 /* All three registers are changed by the instruction, so each one 26625 must be a fresh pseudo. */ 26626 rtx dst_addr = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); 26627 rtx src_addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 26628 rtx dst_mem = replace_equiv_address (operands[0], dst_addr); 26629 rtx src_mem = replace_equiv_address (operands[1], src_addr); 26630 rtx sz_reg = copy_to_mode_reg (DImode, operands[2]); 26631 if (is_memmove) 26632 emit_insn (gen_aarch64_movmemdi (dst_mem, src_mem, sz_reg)); 26633 else 26634 emit_insn (gen_aarch64_cpymemdi (dst_mem, src_mem, sz_reg)); 26635 return true; 26636 } 26637 26638 /* Expand cpymem/movmem, as if from a __builtin_memcpy/memmove. 26639 OPERANDS are taken from the cpymem/movmem pattern. IS_MEMMOVE is true 26640 if this is a memmove rather than memcpy. Return true if we succeed, 26641 otherwise return false, indicating that a libcall should be emitted. */ 26642 bool 26643 aarch64_expand_cpymem (rtx *operands, bool is_memmove) 26644 { 26645 int mode_bytes; 26646 rtx dst = operands[0]; 26647 rtx src = operands[1]; 26648 unsigned align = UINTVAL (operands[3]); 26649 rtx base; 26650 machine_mode mode = BLKmode, next_mode; 26651 26652 /* Variable-sized or strict-align copies may use the MOPS expansion. */ 26653 if (!CONST_INT_P (operands[2]) || (STRICT_ALIGNMENT && align < 16)) 26654 return aarch64_expand_cpymem_mops (operands, is_memmove); 26655 26656 unsigned HOST_WIDE_INT size = UINTVAL (operands[2]); 26657 bool use_ldpq = TARGET_SIMD && !(aarch64_tune_params.extra_tuning_flags 26658 & AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS); 26659 26660 /* Set inline limits for memmove/memcpy. MOPS has a separate threshold. */ 26661 unsigned max_copy_size = use_ldpq ? 256 : 128; 26662 unsigned mops_threshold = is_memmove ? aarch64_mops_memmove_size_threshold 26663 : aarch64_mops_memcpy_size_threshold; 26664 26665 /* Reduce the maximum size with -Os. */ 26666 if (optimize_function_for_size_p (cfun)) 26667 max_copy_size /= 4; 26668 26669 /* Large copies use MOPS when available or a library call. */ 26670 if (size > max_copy_size || (TARGET_MOPS && size > mops_threshold)) 26671 return aarch64_expand_cpymem_mops (operands, is_memmove); 26672 26673 /* Default to 32-byte LDP/STP on large copies, however small copies or 26674 no SIMD support fall back to 16-byte chunks. 26675 ??? Although it would be possible to use LDP/STP Qn in streaming mode 26676 (so using TARGET_BASE_SIMD instead of TARGET_SIMD), it isn't clear 26677 whether that would improve performance. */ 26678 bool use_qregs = size > 24 && TARGET_SIMD; 26679 26680 base = copy_to_mode_reg (Pmode, XEXP (dst, 0)); 26681 dst = adjust_automodify_address (dst, VOIDmode, base, 0); 26682 26683 base = copy_to_mode_reg (Pmode, XEXP (src, 0)); 26684 src = adjust_automodify_address (src, VOIDmode, base, 0); 26685 26686 auto_vec<std::pair<rtx, rtx>, 16> ops; 26687 int offset = 0; 26688 26689 while (size > 0) 26690 { 26691 /* Find the largest mode in which to do the copy in without over reading 26692 or writing. */ 26693 opt_scalar_int_mode mode_iter; 26694 FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT) 26695 if (GET_MODE_SIZE (mode_iter.require ()) <= MIN (size, 16)) 26696 mode = mode_iter.require (); 26697 26698 gcc_assert (mode != BLKmode); 26699 26700 mode_bytes = GET_MODE_SIZE (mode).to_constant (); 26701 26702 /* Prefer Q-register accesses. */ 26703 if (mode_bytes == 16 && use_qregs) 26704 mode = V4SImode; 26705 26706 rtx reg = gen_reg_rtx (mode); 26707 rtx load = gen_move_insn (reg, adjust_address (src, mode, offset)); 26708 rtx store = gen_move_insn (adjust_address (dst, mode, offset), reg); 26709 ops.safe_push ({ load, store }); 26710 size -= mode_bytes; 26711 offset += mode_bytes; 26712 26713 /* Emit trailing copies using overlapping unaligned accesses 26714 (when !STRICT_ALIGNMENT) - this is smaller and faster. */ 26715 if (size > 0 && size < 16 && !STRICT_ALIGNMENT) 26716 { 26717 next_mode = smallest_mode_for_size (size * BITS_PER_UNIT, MODE_INT); 26718 int n_bytes = GET_MODE_SIZE (next_mode).to_constant (); 26719 gcc_assert (n_bytes <= mode_bytes); 26720 offset -= n_bytes - size; 26721 size = n_bytes; 26722 } 26723 } 26724 26725 /* Memcpy interleaves loads with stores, memmove emits all loads first. */ 26726 int nops = ops.length(); 26727 int inc = is_memmove || nops <= 8 ? nops : 6; 26728 26729 for (int i = 0; i < nops; i += inc) 26730 { 26731 int m = MIN (nops, i + inc); 26732 /* Emit loads. */ 26733 for (int j = i; j < m; j++) 26734 emit_insn (ops[j].first); 26735 /* Emit stores. */ 26736 for (int j = i; j < m; j++) 26737 emit_insn (ops[j].second); 26738 } 26739 return true; 26740 } 26741 26742 /* Like aarch64_copy_one_block_and_progress_pointers, except for memset where 26743 SRC is a register we have created with the duplicated value to be set. */ 26744 static void 26745 aarch64_set_one_block_and_progress_pointer (rtx src, rtx *dst, 26746 machine_mode mode) 26747 { 26748 /* If we are copying 128bits or 256bits, we can do that straight from 26749 the SIMD register we prepared. */ 26750 if (known_eq (GET_MODE_BITSIZE (mode), 256)) 26751 { 26752 mode = GET_MODE (src); 26753 /* "Cast" the *dst to the correct mode. */ 26754 *dst = adjust_address (*dst, mode, 0); 26755 /* Emit the memset. */ 26756 emit_move_insn (*dst, src); 26757 emit_move_insn (aarch64_move_pointer (*dst, 16), src); 26758 26759 /* Move the pointers forward. */ 26760 *dst = aarch64_move_pointer (*dst, 32); 26761 return; 26762 } 26763 if (known_eq (GET_MODE_BITSIZE (mode), 128)) 26764 { 26765 /* "Cast" the *dst to the correct mode. */ 26766 *dst = adjust_address (*dst, GET_MODE (src), 0); 26767 /* Emit the memset. */ 26768 emit_move_insn (*dst, src); 26769 /* Move the pointers forward. */ 26770 *dst = aarch64_move_pointer (*dst, 16); 26771 return; 26772 } 26773 /* For copying less, we have to extract the right amount from src. */ 26774 rtx reg = lowpart_subreg (mode, src, GET_MODE (src)); 26775 26776 /* "Cast" the *dst to the correct mode. */ 26777 *dst = adjust_address (*dst, mode, 0); 26778 /* Emit the memset. */ 26779 emit_move_insn (*dst, reg); 26780 /* Move the pointer forward. */ 26781 *dst = aarch64_progress_pointer (*dst); 26782 } 26783 26784 /* Expand a setmem using the MOPS instructions. OPERANDS are the same 26785 as for the setmem pattern. Return true iff we succeed. */ 26786 static bool 26787 aarch64_expand_setmem_mops (rtx *operands) 26788 { 26789 if (!TARGET_MOPS) 26790 return false; 26791 26792 /* The first two registers are changed by the instruction, so both 26793 of them must be a fresh pseudo. */ 26794 rtx dst_addr = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); 26795 rtx dst_mem = replace_equiv_address (operands[0], dst_addr); 26796 rtx sz_reg = copy_to_mode_reg (DImode, operands[1]); 26797 rtx val = operands[2]; 26798 if (val != CONST0_RTX (QImode)) 26799 val = force_reg (QImode, val); 26800 emit_insn (gen_aarch64_setmemdi (dst_mem, val, sz_reg)); 26801 return true; 26802 } 26803 26804 /* Expand setmem, as if from a __builtin_memset. Return true if 26805 we succeed, otherwise return false. */ 26806 26807 bool 26808 aarch64_expand_setmem (rtx *operands) 26809 { 26810 int n, mode_bits; 26811 unsigned HOST_WIDE_INT len; 26812 rtx dst = operands[0]; 26813 rtx val = operands[2], src; 26814 unsigned align = UINTVAL (operands[3]); 26815 rtx base; 26816 machine_mode cur_mode = BLKmode, next_mode; 26817 26818 /* Variable-sized or strict-align memset may use the MOPS expansion. */ 26819 if (!CONST_INT_P (operands[1]) || !TARGET_SIMD 26820 || (STRICT_ALIGNMENT && align < 16)) 26821 return aarch64_expand_setmem_mops (operands); 26822 26823 bool size_p = optimize_function_for_size_p (cfun); 26824 26825 /* Default the maximum to 256-bytes when considering only libcall vs 26826 SIMD broadcast sequence. */ 26827 unsigned max_set_size = 256; 26828 unsigned mops_threshold = aarch64_mops_memset_size_threshold; 26829 26830 len = UINTVAL (operands[1]); 26831 26832 /* Large memset uses MOPS when available or a library call. */ 26833 if (len > max_set_size || (TARGET_MOPS && len > mops_threshold)) 26834 return aarch64_expand_setmem_mops (operands); 26835 26836 int cst_val = !!(CONST_INT_P (val) && (INTVAL (val) != 0)); 26837 /* The MOPS sequence takes: 26838 3 instructions for the memory storing 26839 + 1 to move the constant size into a reg 26840 + 1 if VAL is a non-zero constant to move into a reg 26841 (zero constants can use XZR directly). */ 26842 unsigned mops_cost = 3 + 1 + cst_val; 26843 /* A libcall to memset in the worst case takes 3 instructions to prepare 26844 the arguments + 1 for the call. */ 26845 unsigned libcall_cost = 4; 26846 26847 /* Attempt a sequence with a vector broadcast followed by stores. 26848 Count the number of operations involved to see if it's worth it 26849 against the alternatives. A simple counter simd_ops on the 26850 algorithmically-relevant operations is used rather than an rtx_insn count 26851 as all the pointer adjusmtents and mode reinterprets will be optimized 26852 away later. */ 26853 start_sequence (); 26854 unsigned simd_ops = 0; 26855 26856 base = copy_to_mode_reg (Pmode, XEXP (dst, 0)); 26857 dst = adjust_automodify_address (dst, VOIDmode, base, 0); 26858 26859 /* Prepare the val using a DUP/MOVI v0.16B, val. */ 26860 src = expand_vector_broadcast (V16QImode, val); 26861 src = force_reg (V16QImode, src); 26862 simd_ops++; 26863 /* Convert len to bits to make the rest of the code simpler. */ 26864 n = len * BITS_PER_UNIT; 26865 26866 /* Maximum amount to copy in one go. We allow 256-bit chunks based on the 26867 AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS tuning parameter. */ 26868 const int copy_limit = (aarch64_tune_params.extra_tuning_flags 26869 & AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS) 26870 ? GET_MODE_BITSIZE (TImode) : 256; 26871 26872 while (n > 0) 26873 { 26874 /* Find the largest mode in which to do the copy without 26875 over writing. */ 26876 opt_scalar_int_mode mode_iter; 26877 FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT) 26878 if (GET_MODE_BITSIZE (mode_iter.require ()) <= MIN (n, copy_limit)) 26879 cur_mode = mode_iter.require (); 26880 26881 gcc_assert (cur_mode != BLKmode); 26882 26883 mode_bits = GET_MODE_BITSIZE (cur_mode).to_constant (); 26884 aarch64_set_one_block_and_progress_pointer (src, &dst, cur_mode); 26885 simd_ops++; 26886 n -= mode_bits; 26887 26888 /* Emit trailing writes using overlapping unaligned accesses 26889 (when !STRICT_ALIGNMENT) - this is smaller and faster. */ 26890 if (n > 0 && n < copy_limit / 2 && !STRICT_ALIGNMENT) 26891 { 26892 next_mode = smallest_mode_for_size (n, MODE_INT); 26893 int n_bits = GET_MODE_BITSIZE (next_mode).to_constant (); 26894 gcc_assert (n_bits <= mode_bits); 26895 dst = aarch64_move_pointer (dst, (n - n_bits) / BITS_PER_UNIT); 26896 n = n_bits; 26897 } 26898 } 26899 rtx_insn *seq = get_insns (); 26900 end_sequence (); 26901 26902 if (size_p) 26903 { 26904 /* When optimizing for size we have 3 options: the SIMD broadcast sequence, 26905 call to memset or the MOPS expansion. */ 26906 if (TARGET_MOPS 26907 && mops_cost <= libcall_cost 26908 && mops_cost <= simd_ops) 26909 return aarch64_expand_setmem_mops (operands); 26910 /* If MOPS is not available or not shorter pick a libcall if the SIMD 26911 sequence is too long. */ 26912 else if (libcall_cost < simd_ops) 26913 return false; 26914 emit_insn (seq); 26915 return true; 26916 } 26917 26918 /* At this point the SIMD broadcast sequence is the best choice when 26919 optimizing for speed. */ 26920 emit_insn (seq); 26921 return true; 26922 } 26923 26924 26925 /* Split a DImode store of a CONST_INT SRC to MEM DST as two 26926 SImode stores. Handle the case when the constant has identical 26927 bottom and top halves. This is beneficial when the two stores can be 26928 merged into an STP and we avoid synthesising potentially expensive 26929 immediates twice. Return true if such a split is possible. */ 26930 26931 bool 26932 aarch64_split_dimode_const_store (rtx dst, rtx src) 26933 { 26934 rtx lo = gen_lowpart (SImode, src); 26935 rtx hi = gen_highpart_mode (SImode, DImode, src); 26936 26937 if (!rtx_equal_p (lo, hi)) 26938 return false; 26939 26940 unsigned int orig_cost 26941 = aarch64_internal_mov_immediate (NULL_RTX, src, false, DImode); 26942 unsigned int lo_cost 26943 = aarch64_internal_mov_immediate (NULL_RTX, lo, false, SImode); 26944 26945 /* We want to transform: 26946 MOV x1, 49370 26947 MOVK x1, 0x140, lsl 16 26948 MOVK x1, 0xc0da, lsl 32 26949 MOVK x1, 0x140, lsl 48 26950 STR x1, [x0] 26951 into: 26952 MOV w1, 49370 26953 MOVK w1, 0x140, lsl 16 26954 STP w1, w1, [x0] 26955 So we want to perform this when we save at least one instruction. */ 26956 if (orig_cost <= lo_cost) 26957 return false; 26958 26959 rtx mem_lo = adjust_address (dst, SImode, 0); 26960 if (!aarch64_mem_pair_operand (mem_lo, SImode)) 26961 return false; 26962 26963 rtx tmp_reg = gen_reg_rtx (SImode); 26964 aarch64_expand_mov_immediate (tmp_reg, lo); 26965 rtx mem_hi = aarch64_move_pointer (mem_lo, GET_MODE_SIZE (SImode)); 26966 /* Don't emit an explicit store pair as this may not be always profitable. 26967 Let the sched-fusion logic decide whether to merge them. */ 26968 emit_move_insn (mem_lo, tmp_reg); 26969 emit_move_insn (mem_hi, tmp_reg); 26970 26971 return true; 26972 } 26973 26974 /* Generate RTL for a conditional branch with rtx comparison CODE in 26975 mode CC_MODE. The destination of the unlikely conditional branch 26976 is LABEL_REF. */ 26977 26978 void 26979 aarch64_gen_unlikely_cbranch (enum rtx_code code, machine_mode cc_mode, 26980 rtx label_ref) 26981 { 26982 rtx x; 26983 x = gen_rtx_fmt_ee (code, VOIDmode, 26984 gen_rtx_REG (cc_mode, CC_REGNUM), 26985 const0_rtx); 26986 26987 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, 26988 gen_rtx_LABEL_REF (VOIDmode, label_ref), 26989 pc_rtx); 26990 aarch64_emit_unlikely_jump (gen_rtx_SET (pc_rtx, x)); 26991 } 26992 26993 /* Generate DImode scratch registers for 128-bit (TImode) addition. 26994 26995 OP1 represents the TImode destination operand 1 26996 OP2 represents the TImode destination operand 2 26997 LOW_DEST represents the low half (DImode) of TImode operand 0 26998 LOW_IN1 represents the low half (DImode) of TImode operand 1 26999 LOW_IN2 represents the low half (DImode) of TImode operand 2 27000 HIGH_DEST represents the high half (DImode) of TImode operand 0 27001 HIGH_IN1 represents the high half (DImode) of TImode operand 1 27002 HIGH_IN2 represents the high half (DImode) of TImode operand 2. */ 27003 27004 void 27005 aarch64_addti_scratch_regs (rtx op1, rtx op2, rtx *low_dest, 27006 rtx *low_in1, rtx *low_in2, 27007 rtx *high_dest, rtx *high_in1, 27008 rtx *high_in2) 27009 { 27010 *low_dest = gen_reg_rtx (DImode); 27011 *low_in1 = gen_lowpart (DImode, op1); 27012 *low_in2 = simplify_gen_subreg (DImode, op2, TImode, 27013 subreg_lowpart_offset (DImode, TImode)); 27014 *high_dest = gen_reg_rtx (DImode); 27015 *high_in1 = gen_highpart (DImode, op1); 27016 *high_in2 = simplify_gen_subreg (DImode, op2, TImode, 27017 subreg_highpart_offset (DImode, TImode)); 27018 } 27019 27020 /* Generate DImode scratch registers for 128-bit (TImode) subtraction. 27021 27022 This function differs from 'arch64_addti_scratch_regs' in that 27023 OP1 can be an immediate constant (zero). We must call 27024 subreg_highpart_offset with DImode and TImode arguments, otherwise 27025 VOIDmode will be used for the const_int which generates an internal 27026 error from subreg_size_highpart_offset which does not expect a size of zero. 27027 27028 OP1 represents the TImode destination operand 1 27029 OP2 represents the TImode destination operand 2 27030 LOW_DEST represents the low half (DImode) of TImode operand 0 27031 LOW_IN1 represents the low half (DImode) of TImode operand 1 27032 LOW_IN2 represents the low half (DImode) of TImode operand 2 27033 HIGH_DEST represents the high half (DImode) of TImode operand 0 27034 HIGH_IN1 represents the high half (DImode) of TImode operand 1 27035 HIGH_IN2 represents the high half (DImode) of TImode operand 2. */ 27036 27037 27038 void 27039 aarch64_subvti_scratch_regs (rtx op1, rtx op2, rtx *low_dest, 27040 rtx *low_in1, rtx *low_in2, 27041 rtx *high_dest, rtx *high_in1, 27042 rtx *high_in2) 27043 { 27044 *low_dest = gen_reg_rtx (DImode); 27045 *low_in1 = simplify_gen_subreg (DImode, op1, TImode, 27046 subreg_lowpart_offset (DImode, TImode)); 27047 27048 *low_in2 = simplify_gen_subreg (DImode, op2, TImode, 27049 subreg_lowpart_offset (DImode, TImode)); 27050 *high_dest = gen_reg_rtx (DImode); 27051 27052 *high_in1 = simplify_gen_subreg (DImode, op1, TImode, 27053 subreg_highpart_offset (DImode, TImode)); 27054 *high_in2 = simplify_gen_subreg (DImode, op2, TImode, 27055 subreg_highpart_offset (DImode, TImode)); 27056 } 27057 27058 /* Generate RTL for 128-bit (TImode) subtraction with overflow. 27059 27060 OP0 represents the TImode destination operand 0 27061 LOW_DEST represents the low half (DImode) of TImode operand 0 27062 LOW_IN1 represents the low half (DImode) of TImode operand 1 27063 LOW_IN2 represents the low half (DImode) of TImode operand 2 27064 HIGH_DEST represents the high half (DImode) of TImode operand 0 27065 HIGH_IN1 represents the high half (DImode) of TImode operand 1 27066 HIGH_IN2 represents the high half (DImode) of TImode operand 2 27067 UNSIGNED_P is true if the operation is being performed on unsigned 27068 values. */ 27069 void 27070 aarch64_expand_subvti (rtx op0, rtx low_dest, rtx low_in1, 27071 rtx low_in2, rtx high_dest, rtx high_in1, 27072 rtx high_in2, bool unsigned_p) 27073 { 27074 if (low_in2 == const0_rtx) 27075 { 27076 low_dest = low_in1; 27077 high_in2 = force_reg (DImode, high_in2); 27078 if (unsigned_p) 27079 emit_insn (gen_subdi3_compare1 (high_dest, high_in1, high_in2)); 27080 else 27081 emit_insn (gen_subvdi_insn (high_dest, high_in1, high_in2)); 27082 } 27083 else 27084 { 27085 if (aarch64_plus_immediate (low_in2, DImode)) 27086 emit_insn (gen_subdi3_compare1_imm (low_dest, low_in1, low_in2, 27087 GEN_INT (-UINTVAL (low_in2)))); 27088 else 27089 { 27090 low_in2 = force_reg (DImode, low_in2); 27091 emit_insn (gen_subdi3_compare1 (low_dest, low_in1, low_in2)); 27092 } 27093 high_in2 = force_reg (DImode, high_in2); 27094 27095 if (unsigned_p) 27096 emit_insn (gen_usubdi3_carryinC (high_dest, high_in1, high_in2)); 27097 else 27098 emit_insn (gen_subdi3_carryinV (high_dest, high_in1, high_in2)); 27099 } 27100 27101 emit_move_insn (gen_lowpart (DImode, op0), low_dest); 27102 emit_move_insn (gen_highpart (DImode, op0), high_dest); 27103 27104 } 27105 27106 /* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */ 27107 27108 static unsigned HOST_WIDE_INT 27109 aarch64_asan_shadow_offset (void) 27110 { 27111 if (TARGET_ILP32) 27112 return (HOST_WIDE_INT_1 << 29); 27113 else 27114 return (HOST_WIDE_INT_1 << 36); 27115 } 27116 27117 static rtx 27118 aarch64_gen_ccmp_first (rtx_insn **prep_seq, rtx_insn **gen_seq, 27119 rtx_code code, tree treeop0, tree treeop1) 27120 { 27121 machine_mode op_mode, cmp_mode, cc_mode = CCmode; 27122 rtx op0, op1; 27123 int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0)); 27124 insn_code icode; 27125 struct expand_operand ops[4]; 27126 27127 start_sequence (); 27128 expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); 27129 27130 op_mode = GET_MODE (op0); 27131 if (op_mode == VOIDmode) 27132 op_mode = GET_MODE (op1); 27133 27134 switch (op_mode) 27135 { 27136 case E_QImode: 27137 case E_HImode: 27138 case E_SImode: 27139 cmp_mode = SImode; 27140 icode = CODE_FOR_cmpsi; 27141 break; 27142 27143 case E_DImode: 27144 cmp_mode = DImode; 27145 icode = CODE_FOR_cmpdi; 27146 break; 27147 27148 case E_SFmode: 27149 cmp_mode = SFmode; 27150 cc_mode = aarch64_select_cc_mode ((rtx_code) code, op0, op1); 27151 icode = cc_mode == CCFPEmode ? CODE_FOR_fcmpesf : CODE_FOR_fcmpsf; 27152 break; 27153 27154 case E_DFmode: 27155 cmp_mode = DFmode; 27156 cc_mode = aarch64_select_cc_mode ((rtx_code) code, op0, op1); 27157 icode = cc_mode == CCFPEmode ? CODE_FOR_fcmpedf : CODE_FOR_fcmpdf; 27158 break; 27159 27160 default: 27161 end_sequence (); 27162 return NULL_RTX; 27163 } 27164 27165 op0 = prepare_operand (icode, op0, 0, op_mode, cmp_mode, unsignedp); 27166 op1 = prepare_operand (icode, op1, 1, op_mode, cmp_mode, unsignedp); 27167 if (!op0 || !op1) 27168 { 27169 end_sequence (); 27170 return NULL_RTX; 27171 } 27172 *prep_seq = get_insns (); 27173 end_sequence (); 27174 27175 create_fixed_operand (&ops[0], op0); 27176 create_fixed_operand (&ops[1], op1); 27177 27178 start_sequence (); 27179 if (!maybe_expand_insn (icode, 2, ops)) 27180 { 27181 end_sequence (); 27182 return NULL_RTX; 27183 } 27184 *gen_seq = get_insns (); 27185 end_sequence (); 27186 27187 return gen_rtx_fmt_ee ((rtx_code) code, cc_mode, 27188 gen_rtx_REG (cc_mode, CC_REGNUM), const0_rtx); 27189 } 27190 27191 static rtx 27192 aarch64_gen_ccmp_next (rtx_insn **prep_seq, rtx_insn **gen_seq, rtx prev, 27193 rtx_code cmp_code, tree treeop0, tree treeop1, 27194 rtx_code bit_code) 27195 { 27196 rtx op0, op1, target; 27197 machine_mode op_mode, cmp_mode, cc_mode = CCmode; 27198 int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0)); 27199 insn_code icode; 27200 struct expand_operand ops[6]; 27201 int aarch64_cond; 27202 27203 push_to_sequence (*prep_seq); 27204 expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL); 27205 27206 op_mode = GET_MODE (op0); 27207 if (op_mode == VOIDmode) 27208 op_mode = GET_MODE (op1); 27209 27210 switch (op_mode) 27211 { 27212 case E_QImode: 27213 case E_HImode: 27214 case E_SImode: 27215 cmp_mode = SImode; 27216 break; 27217 27218 case E_DImode: 27219 cmp_mode = DImode; 27220 break; 27221 27222 case E_SFmode: 27223 cmp_mode = SFmode; 27224 cc_mode = aarch64_select_cc_mode ((rtx_code) cmp_code, op0, op1); 27225 break; 27226 27227 case E_DFmode: 27228 cmp_mode = DFmode; 27229 cc_mode = aarch64_select_cc_mode ((rtx_code) cmp_code, op0, op1); 27230 break; 27231 27232 default: 27233 end_sequence (); 27234 return NULL_RTX; 27235 } 27236 27237 icode = code_for_ccmp (cc_mode, cmp_mode); 27238 27239 op0 = prepare_operand (icode, op0, 2, op_mode, cmp_mode, unsignedp); 27240 op1 = prepare_operand (icode, op1, 3, op_mode, cmp_mode, unsignedp); 27241 if (!op0 || !op1) 27242 { 27243 end_sequence (); 27244 return NULL_RTX; 27245 } 27246 *prep_seq = get_insns (); 27247 end_sequence (); 27248 27249 target = gen_rtx_REG (cc_mode, CC_REGNUM); 27250 aarch64_cond = aarch64_get_condition_code_1 (cc_mode, (rtx_code) cmp_code); 27251 27252 if (bit_code != AND) 27253 { 27254 /* Treat the ccmp patterns as canonical and use them where possible, 27255 but fall back to ccmp_rev patterns if there's no other option. */ 27256 rtx_code prev_code = GET_CODE (prev); 27257 machine_mode prev_mode = GET_MODE (XEXP (prev, 0)); 27258 if ((prev_mode == CCFPmode || prev_mode == CCFPEmode) 27259 && !(prev_code == EQ 27260 || prev_code == NE 27261 || prev_code == ORDERED 27262 || prev_code == UNORDERED)) 27263 icode = code_for_ccmp_rev (cc_mode, cmp_mode); 27264 else 27265 { 27266 rtx_code code = reverse_condition (prev_code); 27267 prev = gen_rtx_fmt_ee (code, VOIDmode, XEXP (prev, 0), const0_rtx); 27268 } 27269 aarch64_cond = AARCH64_INVERSE_CONDITION_CODE (aarch64_cond); 27270 } 27271 27272 create_fixed_operand (&ops[0], XEXP (prev, 0)); 27273 create_fixed_operand (&ops[1], target); 27274 create_fixed_operand (&ops[2], op0); 27275 create_fixed_operand (&ops[3], op1); 27276 create_fixed_operand (&ops[4], prev); 27277 create_fixed_operand (&ops[5], GEN_INT (aarch64_cond)); 27278 27279 push_to_sequence (*gen_seq); 27280 if (!maybe_expand_insn (icode, 6, ops)) 27281 { 27282 end_sequence (); 27283 return NULL_RTX; 27284 } 27285 27286 *gen_seq = get_insns (); 27287 end_sequence (); 27288 27289 return gen_rtx_fmt_ee ((rtx_code) cmp_code, VOIDmode, target, const0_rtx); 27290 } 27291 27292 #undef TARGET_GEN_CCMP_FIRST 27293 #define TARGET_GEN_CCMP_FIRST aarch64_gen_ccmp_first 27294 27295 #undef TARGET_GEN_CCMP_NEXT 27296 #define TARGET_GEN_CCMP_NEXT aarch64_gen_ccmp_next 27297 27298 /* Implement TARGET_SCHED_MACRO_FUSION_P. Return true if target supports 27299 instruction fusion of some sort. */ 27300 27301 static bool 27302 aarch64_macro_fusion_p (void) 27303 { 27304 return aarch64_tune_params.fusible_ops != AARCH64_FUSE_NOTHING; 27305 } 27306 27307 27308 /* Implement TARGET_SCHED_MACRO_FUSION_PAIR_P. Return true if PREV and CURR 27309 should be kept together during scheduling. */ 27310 27311 static bool 27312 aarch_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr) 27313 { 27314 rtx set_dest; 27315 rtx prev_set = single_set (prev); 27316 rtx curr_set = single_set (curr); 27317 /* prev and curr are simple SET insns i.e. no flag setting or branching. */ 27318 bool simple_sets_p = prev_set && curr_set && !any_condjump_p (curr); 27319 27320 if (!aarch64_macro_fusion_p ()) 27321 return false; 27322 27323 if (simple_sets_p && aarch64_fusion_enabled_p (AARCH64_FUSE_MOV_MOVK)) 27324 { 27325 /* We are trying to match: 27326 prev (mov) == (set (reg r0) (const_int imm16)) 27327 curr (movk) == (set (zero_extract (reg r0) 27328 (const_int 16) 27329 (const_int 16)) 27330 (const_int imm16_1)) */ 27331 27332 set_dest = SET_DEST (curr_set); 27333 27334 if (GET_CODE (set_dest) == ZERO_EXTRACT 27335 && CONST_INT_P (SET_SRC (curr_set)) 27336 && CONST_INT_P (SET_SRC (prev_set)) 27337 && CONST_INT_P (XEXP (set_dest, 2)) 27338 && INTVAL (XEXP (set_dest, 2)) == 16 27339 && REG_P (XEXP (set_dest, 0)) 27340 && REG_P (SET_DEST (prev_set)) 27341 && REGNO (XEXP (set_dest, 0)) == REGNO (SET_DEST (prev_set))) 27342 { 27343 return true; 27344 } 27345 } 27346 27347 if (simple_sets_p && aarch64_fusion_enabled_p (AARCH64_FUSE_ADRP_ADD)) 27348 { 27349 27350 /* We're trying to match: 27351 prev (adrp) == (set (reg r1) 27352 (high (symbol_ref ("SYM")))) 27353 curr (add) == (set (reg r0) 27354 (lo_sum (reg r1) 27355 (symbol_ref ("SYM")))) 27356 Note that r0 need not necessarily be the same as r1, especially 27357 during pre-regalloc scheduling. */ 27358 27359 if (satisfies_constraint_Ush (SET_SRC (prev_set)) 27360 && REG_P (SET_DEST (prev_set)) && REG_P (SET_DEST (curr_set))) 27361 { 27362 if (GET_CODE (SET_SRC (curr_set)) == LO_SUM 27363 && REG_P (XEXP (SET_SRC (curr_set), 0)) 27364 && REGNO (XEXP (SET_SRC (curr_set), 0)) 27365 == REGNO (SET_DEST (prev_set)) 27366 && rtx_equal_p (XEXP (SET_SRC (prev_set), 0), 27367 XEXP (SET_SRC (curr_set), 1))) 27368 return true; 27369 } 27370 } 27371 27372 if (simple_sets_p && aarch64_fusion_enabled_p (AARCH64_FUSE_MOVK_MOVK)) 27373 { 27374 27375 /* We're trying to match: 27376 prev (movk) == (set (zero_extract (reg r0) 27377 (const_int 16) 27378 (const_int 32)) 27379 (const_int imm16_1)) 27380 curr (movk) == (set (zero_extract (reg r0) 27381 (const_int 16) 27382 (const_int 48)) 27383 (const_int imm16_2)) */ 27384 27385 if (GET_CODE (SET_DEST (prev_set)) == ZERO_EXTRACT 27386 && GET_CODE (SET_DEST (curr_set)) == ZERO_EXTRACT 27387 && REG_P (XEXP (SET_DEST (prev_set), 0)) 27388 && REG_P (XEXP (SET_DEST (curr_set), 0)) 27389 && REGNO (XEXP (SET_DEST (prev_set), 0)) 27390 == REGNO (XEXP (SET_DEST (curr_set), 0)) 27391 && CONST_INT_P (XEXP (SET_DEST (prev_set), 2)) 27392 && CONST_INT_P (XEXP (SET_DEST (curr_set), 2)) 27393 && INTVAL (XEXP (SET_DEST (prev_set), 2)) == 32 27394 && INTVAL (XEXP (SET_DEST (curr_set), 2)) == 48 27395 && CONST_INT_P (SET_SRC (prev_set)) 27396 && CONST_INT_P (SET_SRC (curr_set))) 27397 return true; 27398 27399 } 27400 if (simple_sets_p && aarch64_fusion_enabled_p (AARCH64_FUSE_ADRP_LDR)) 27401 { 27402 /* We're trying to match: 27403 prev (adrp) == (set (reg r0) 27404 (high (symbol_ref ("SYM")))) 27405 curr (ldr) == (set (reg r1) 27406 (mem (lo_sum (reg r0) 27407 (symbol_ref ("SYM"))))) 27408 or 27409 curr (ldr) == (set (reg r1) 27410 (zero_extend (mem 27411 (lo_sum (reg r0) 27412 (symbol_ref ("SYM")))))) */ 27413 if (satisfies_constraint_Ush (SET_SRC (prev_set)) 27414 && REG_P (SET_DEST (prev_set)) && REG_P (SET_DEST (curr_set))) 27415 { 27416 rtx curr_src = SET_SRC (curr_set); 27417 27418 if (GET_CODE (curr_src) == ZERO_EXTEND) 27419 curr_src = XEXP (curr_src, 0); 27420 27421 if (MEM_P (curr_src) && GET_CODE (XEXP (curr_src, 0)) == LO_SUM 27422 && REG_P (XEXP (XEXP (curr_src, 0), 0)) 27423 && REGNO (XEXP (XEXP (curr_src, 0), 0)) 27424 == REGNO (SET_DEST (prev_set)) 27425 && rtx_equal_p (XEXP (XEXP (curr_src, 0), 1), 27426 XEXP (SET_SRC (prev_set), 0))) 27427 return true; 27428 } 27429 } 27430 27431 /* Fuse compare (CMP/CMN/TST/BICS) and conditional branch. */ 27432 if (aarch64_fusion_enabled_p (AARCH64_FUSE_CMP_BRANCH) 27433 && prev_set && curr_set && any_condjump_p (curr) 27434 && GET_CODE (SET_SRC (prev_set)) == COMPARE 27435 && SCALAR_INT_MODE_P (GET_MODE (XEXP (SET_SRC (prev_set), 0))) 27436 && reg_referenced_p (SET_DEST (prev_set), PATTERN (curr))) 27437 return true; 27438 27439 /* Fuse flag-setting ALU instructions and conditional branch. */ 27440 if (aarch64_fusion_enabled_p (AARCH64_FUSE_ALU_BRANCH) 27441 && any_condjump_p (curr)) 27442 { 27443 unsigned int condreg1, condreg2; 27444 rtx cc_reg_1; 27445 aarch64_fixed_condition_code_regs (&condreg1, &condreg2); 27446 cc_reg_1 = gen_rtx_REG (CCmode, condreg1); 27447 27448 if (reg_referenced_p (cc_reg_1, PATTERN (curr)) 27449 && prev 27450 && modified_in_p (cc_reg_1, prev)) 27451 { 27452 enum attr_type prev_type = get_attr_type (prev); 27453 27454 /* FIXME: this misses some which is considered simple arthematic 27455 instructions for ThunderX. Simple shifts are missed here. */ 27456 if (prev_type == TYPE_ALUS_SREG 27457 || prev_type == TYPE_ALUS_IMM 27458 || prev_type == TYPE_LOGICS_REG 27459 || prev_type == TYPE_LOGICS_IMM) 27460 return true; 27461 } 27462 } 27463 27464 /* Fuse ALU instructions and CBZ/CBNZ. */ 27465 if (prev_set 27466 && curr_set 27467 && aarch64_fusion_enabled_p (AARCH64_FUSE_ALU_CBZ) 27468 && any_condjump_p (curr)) 27469 { 27470 /* We're trying to match: 27471 prev (alu_insn) == (set (r0) plus ((r0) (r1/imm))) 27472 curr (cbz) == (set (pc) (if_then_else (eq/ne) (r0) 27473 (const_int 0)) 27474 (label_ref ("SYM")) 27475 (pc)) */ 27476 if (SET_DEST (curr_set) == (pc_rtx) 27477 && GET_CODE (SET_SRC (curr_set)) == IF_THEN_ELSE 27478 && REG_P (XEXP (XEXP (SET_SRC (curr_set), 0), 0)) 27479 && REG_P (SET_DEST (prev_set)) 27480 && REGNO (SET_DEST (prev_set)) 27481 == REGNO (XEXP (XEXP (SET_SRC (curr_set), 0), 0))) 27482 { 27483 /* Fuse ALU operations followed by conditional branch instruction. */ 27484 switch (get_attr_type (prev)) 27485 { 27486 case TYPE_ALU_IMM: 27487 case TYPE_ALU_SREG: 27488 case TYPE_ADC_REG: 27489 case TYPE_ADC_IMM: 27490 case TYPE_ADCS_REG: 27491 case TYPE_ADCS_IMM: 27492 case TYPE_LOGIC_REG: 27493 case TYPE_LOGIC_IMM: 27494 case TYPE_CSEL: 27495 case TYPE_ADR: 27496 case TYPE_MOV_IMM: 27497 case TYPE_SHIFT_REG: 27498 case TYPE_SHIFT_IMM: 27499 case TYPE_BFM: 27500 case TYPE_RBIT: 27501 case TYPE_REV: 27502 case TYPE_EXTEND: 27503 return true; 27504 27505 default:; 27506 } 27507 } 27508 } 27509 27510 /* Fuse A+B+1 and A-B-1 */ 27511 if (simple_sets_p 27512 && aarch64_fusion_enabled_p (AARCH64_FUSE_ADDSUB_2REG_CONST1)) 27513 { 27514 /* We're trying to match: 27515 prev == (set (r0) (plus (r0) (r1))) 27516 curr == (set (r0) (plus (r0) (const_int 1))) 27517 or: 27518 prev == (set (r0) (minus (r0) (r1))) 27519 curr == (set (r0) (plus (r0) (const_int -1))) */ 27520 27521 rtx prev_src = SET_SRC (prev_set); 27522 rtx curr_src = SET_SRC (curr_set); 27523 27524 int polarity = 1; 27525 if (GET_CODE (prev_src) == MINUS) 27526 polarity = -1; 27527 27528 if (GET_CODE (curr_src) == PLUS 27529 && (GET_CODE (prev_src) == PLUS || GET_CODE (prev_src) == MINUS) 27530 && CONST_INT_P (XEXP (curr_src, 1)) 27531 && INTVAL (XEXP (curr_src, 1)) == polarity 27532 && REG_P (XEXP (curr_src, 0)) 27533 && REG_P (SET_DEST (prev_set)) 27534 && REGNO (SET_DEST (prev_set)) == REGNO (XEXP (curr_src, 0))) 27535 return true; 27536 } 27537 27538 return false; 27539 } 27540 27541 /* Return true iff the instruction fusion described by OP is enabled. */ 27542 27543 bool 27544 aarch64_fusion_enabled_p (enum aarch64_fusion_pairs op) 27545 { 27546 return (aarch64_tune_params.fusible_ops & op) != 0; 27547 } 27548 27549 /* If MEM is in the form of [base+offset], extract the two parts 27550 of address and set to BASE and OFFSET, otherwise return false 27551 after clearing BASE and OFFSET. */ 27552 27553 bool 27554 extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset) 27555 { 27556 rtx addr; 27557 27558 gcc_assert (MEM_P (mem)); 27559 27560 addr = XEXP (mem, 0); 27561 27562 if (REG_P (addr)) 27563 { 27564 *base = addr; 27565 *offset = const0_rtx; 27566 return true; 27567 } 27568 27569 if (GET_CODE (addr) == PLUS 27570 && REG_P (XEXP (addr, 0)) && CONST_INT_P (XEXP (addr, 1))) 27571 { 27572 *base = XEXP (addr, 0); 27573 *offset = XEXP (addr, 1); 27574 return true; 27575 } 27576 27577 *base = NULL_RTX; 27578 *offset = NULL_RTX; 27579 27580 return false; 27581 } 27582 27583 /* Types for scheduling fusion. */ 27584 enum sched_fusion_type 27585 { 27586 SCHED_FUSION_NONE = 0, 27587 SCHED_FUSION_LD_SIGN_EXTEND, 27588 SCHED_FUSION_LD_ZERO_EXTEND, 27589 SCHED_FUSION_LD, 27590 SCHED_FUSION_ST, 27591 SCHED_FUSION_NUM 27592 }; 27593 27594 /* If INSN is a load or store of address in the form of [base+offset], 27595 extract the two parts and set to BASE and OFFSET. Return scheduling 27596 fusion type this INSN is. */ 27597 27598 static enum sched_fusion_type 27599 fusion_load_store (rtx_insn *insn, rtx *base, rtx *offset) 27600 { 27601 rtx x, dest, src; 27602 enum sched_fusion_type fusion = SCHED_FUSION_LD; 27603 27604 gcc_assert (INSN_P (insn)); 27605 x = PATTERN (insn); 27606 if (GET_CODE (x) != SET) 27607 return SCHED_FUSION_NONE; 27608 27609 src = SET_SRC (x); 27610 dest = SET_DEST (x); 27611 27612 machine_mode dest_mode = GET_MODE (dest); 27613 27614 if (!aarch64_mode_valid_for_sched_fusion_p (dest_mode)) 27615 return SCHED_FUSION_NONE; 27616 27617 if (GET_CODE (src) == SIGN_EXTEND) 27618 { 27619 fusion = SCHED_FUSION_LD_SIGN_EXTEND; 27620 src = XEXP (src, 0); 27621 if (!MEM_P (src) || GET_MODE (src) != SImode) 27622 return SCHED_FUSION_NONE; 27623 } 27624 else if (GET_CODE (src) == ZERO_EXTEND) 27625 { 27626 fusion = SCHED_FUSION_LD_ZERO_EXTEND; 27627 src = XEXP (src, 0); 27628 if (!MEM_P (src) || GET_MODE (src) != SImode) 27629 return SCHED_FUSION_NONE; 27630 } 27631 27632 if (MEM_P (src) && REG_P (dest)) 27633 extract_base_offset_in_addr (src, base, offset); 27634 else if (MEM_P (dest) && (REG_P (src) || src == const0_rtx)) 27635 { 27636 fusion = SCHED_FUSION_ST; 27637 extract_base_offset_in_addr (dest, base, offset); 27638 } 27639 else 27640 return SCHED_FUSION_NONE; 27641 27642 if (*base == NULL_RTX || *offset == NULL_RTX) 27643 fusion = SCHED_FUSION_NONE; 27644 27645 return fusion; 27646 } 27647 27648 /* Implement the TARGET_SCHED_FUSION_PRIORITY hook. 27649 27650 Currently we only support to fuse ldr or str instructions, so FUSION_PRI 27651 and PRI are only calculated for these instructions. For other instruction, 27652 FUSION_PRI and PRI are simply set to MAX_PRI - 1. In the future, other 27653 type instruction fusion can be added by returning different priorities. 27654 27655 It's important that irrelevant instructions get the largest FUSION_PRI. */ 27656 27657 static void 27658 aarch64_sched_fusion_priority (rtx_insn *insn, int max_pri, 27659 int *fusion_pri, int *pri) 27660 { 27661 int tmp, off_val; 27662 rtx base, offset; 27663 enum sched_fusion_type fusion; 27664 27665 gcc_assert (INSN_P (insn)); 27666 27667 tmp = max_pri - 1; 27668 fusion = fusion_load_store (insn, &base, &offset); 27669 if (fusion == SCHED_FUSION_NONE) 27670 { 27671 *pri = tmp; 27672 *fusion_pri = tmp; 27673 return; 27674 } 27675 27676 /* Set FUSION_PRI according to fusion type and base register. */ 27677 *fusion_pri = tmp - fusion * FIRST_PSEUDO_REGISTER - REGNO (base); 27678 27679 /* Calculate PRI. */ 27680 tmp /= 2; 27681 27682 /* INSN with smaller offset goes first. */ 27683 off_val = (int)(INTVAL (offset)); 27684 if (off_val >= 0) 27685 tmp -= (off_val & 0xfffff); 27686 else 27687 tmp += ((- off_val) & 0xfffff); 27688 27689 *pri = tmp; 27690 return; 27691 } 27692 27693 /* Implement the TARGET_SCHED_ADJUST_PRIORITY hook. 27694 Adjust priority of sha1h instructions so they are scheduled before 27695 other SHA1 instructions. */ 27696 27697 static int 27698 aarch64_sched_adjust_priority (rtx_insn *insn, int priority) 27699 { 27700 rtx x = PATTERN (insn); 27701 27702 if (GET_CODE (x) == SET) 27703 { 27704 x = SET_SRC (x); 27705 27706 if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SHA1H) 27707 return priority + 10; 27708 } 27709 27710 return priority; 27711 } 27712 27713 /* If REVERSED is null, return true if memory reference *MEM2 comes 27714 immediately after memory reference *MEM1. Do not change the references 27715 in this case. 27716 27717 Otherwise, check if *MEM1 and *MEM2 are consecutive memory references and, 27718 if they are, try to make them use constant offsets from the same base 27719 register. Return true on success. When returning true, set *REVERSED 27720 to true if *MEM1 comes after *MEM2, false if *MEM1 comes before *MEM2. */ 27721 static bool 27722 aarch64_check_consecutive_mems (rtx *mem1, rtx *mem2, bool *reversed) 27723 { 27724 if (reversed) 27725 *reversed = false; 27726 27727 if (GET_RTX_CLASS (GET_CODE (XEXP (*mem1, 0))) == RTX_AUTOINC 27728 || GET_RTX_CLASS (GET_CODE (XEXP (*mem2, 0))) == RTX_AUTOINC) 27729 return false; 27730 27731 if (!MEM_SIZE_KNOWN_P (*mem1) || !MEM_SIZE_KNOWN_P (*mem2)) 27732 return false; 27733 27734 auto size1 = MEM_SIZE (*mem1); 27735 auto size2 = MEM_SIZE (*mem2); 27736 27737 rtx base1, base2, offset1, offset2; 27738 extract_base_offset_in_addr (*mem1, &base1, &offset1); 27739 extract_base_offset_in_addr (*mem2, &base2, &offset2); 27740 27741 /* Make sure at least one memory is in base+offset form. */ 27742 if (!(base1 && offset1) && !(base2 && offset2)) 27743 return false; 27744 27745 /* If both mems already use the same base register, just check the 27746 offsets. */ 27747 if (base1 && base2 && rtx_equal_p (base1, base2)) 27748 { 27749 if (!offset1 || !offset2) 27750 return false; 27751 27752 if (known_eq (UINTVAL (offset1) + size1, UINTVAL (offset2))) 27753 return true; 27754 27755 if (known_eq (UINTVAL (offset2) + size2, UINTVAL (offset1)) && reversed) 27756 { 27757 *reversed = true; 27758 return true; 27759 } 27760 27761 return false; 27762 } 27763 27764 /* Otherwise, check whether the MEM_EXPRs and MEM_OFFSETs together 27765 guarantee that the values are consecutive. */ 27766 if (MEM_EXPR (*mem1) 27767 && MEM_EXPR (*mem2) 27768 && MEM_OFFSET_KNOWN_P (*mem1) 27769 && MEM_OFFSET_KNOWN_P (*mem2)) 27770 { 27771 poly_int64 expr_offset1; 27772 poly_int64 expr_offset2; 27773 tree expr_base1 = get_addr_base_and_unit_offset (MEM_EXPR (*mem1), 27774 &expr_offset1); 27775 tree expr_base2 = get_addr_base_and_unit_offset (MEM_EXPR (*mem2), 27776 &expr_offset2); 27777 if (!expr_base1 27778 || !expr_base2 27779 || !DECL_P (expr_base1) 27780 || !operand_equal_p (expr_base1, expr_base2, OEP_ADDRESS_OF)) 27781 return false; 27782 27783 expr_offset1 += MEM_OFFSET (*mem1); 27784 expr_offset2 += MEM_OFFSET (*mem2); 27785 27786 if (known_eq (expr_offset1 + size1, expr_offset2)) 27787 ; 27788 else if (known_eq (expr_offset2 + size2, expr_offset1) && reversed) 27789 *reversed = true; 27790 else 27791 return false; 27792 27793 if (reversed) 27794 { 27795 if (base2) 27796 { 27797 rtx addr1 = plus_constant (Pmode, XEXP (*mem2, 0), 27798 expr_offset1 - expr_offset2); 27799 *mem1 = replace_equiv_address_nv (*mem1, addr1); 27800 } 27801 else 27802 { 27803 rtx addr2 = plus_constant (Pmode, XEXP (*mem1, 0), 27804 expr_offset2 - expr_offset1); 27805 *mem2 = replace_equiv_address_nv (*mem2, addr2); 27806 } 27807 } 27808 return true; 27809 } 27810 27811 return false; 27812 } 27813 27814 /* Test if MODE is suitable for a single transfer register in an ldp or stp 27815 instruction. */ 27816 27817 bool 27818 aarch64_ldpstp_operand_mode_p (machine_mode mode) 27819 { 27820 if (!targetm.hard_regno_mode_ok (V0_REGNUM, mode) 27821 || hard_regno_nregs (V0_REGNUM, mode) > 1) 27822 return false; 27823 27824 const auto size = GET_MODE_SIZE (mode); 27825 return known_eq (size, 4) || known_eq (size, 8) || known_eq (size, 16); 27826 } 27827 27828 /* Return true if MEM1 and MEM2 can be combined into a single access 27829 of mode MODE, with the combined access having the same address as MEM1. */ 27830 27831 bool 27832 aarch64_mergeable_load_pair_p (machine_mode mode, rtx mem1, rtx mem2) 27833 { 27834 if (STRICT_ALIGNMENT && MEM_ALIGN (mem1) < GET_MODE_ALIGNMENT (mode)) 27835 return false; 27836 return aarch64_check_consecutive_mems (&mem1, &mem2, nullptr); 27837 } 27838 27839 /* Return true if MEM agrees with the ldp-stp policy model. 27840 Otherwise, false. */ 27841 27842 bool 27843 aarch64_mem_ok_with_ldpstp_policy_model (rtx mem, bool load, machine_mode mode) 27844 { 27845 auto policy = (load 27846 ? aarch64_tune_params.ldp_policy_model 27847 : aarch64_tune_params.stp_policy_model); 27848 27849 /* If we have AARCH64_LDP_STP_POLICY_NEVER, reject the load pair. */ 27850 if (policy == AARCH64_LDP_STP_POLICY_NEVER) 27851 return false; 27852 27853 /* If we have AARCH64_LDP_STP_POLICY_ALIGNED, 27854 do not emit the load pair unless the alignment is checked to be 27855 at least double the alignment of the type. */ 27856 if (policy == AARCH64_LDP_STP_POLICY_ALIGNED 27857 && !optimize_function_for_size_p (cfun) 27858 && MEM_ALIGN (mem) < 2 * GET_MODE_ALIGNMENT (mode)) 27859 return false; 27860 27861 return true; 27862 } 27863 27864 /* Given OPERANDS of consecutive load/store, check if we can merge 27865 them into ldp/stp. LOAD is true if they are load instructions. */ 27866 27867 bool 27868 aarch64_operands_ok_for_ldpstp (rtx *operands, bool load) 27869 { 27870 enum reg_class rclass_1, rclass_2; 27871 rtx mem_1, mem_2, reg_1, reg_2; 27872 27873 if (load) 27874 { 27875 mem_1 = operands[1]; 27876 mem_2 = operands[3]; 27877 reg_1 = operands[0]; 27878 reg_2 = operands[2]; 27879 gcc_assert (REG_P (reg_1) && REG_P (reg_2)); 27880 if (REGNO (reg_1) == REGNO (reg_2)) 27881 return false; 27882 if (reg_overlap_mentioned_p (reg_1, mem_2)) 27883 return false; 27884 } 27885 else 27886 { 27887 mem_1 = operands[0]; 27888 mem_2 = operands[2]; 27889 reg_1 = operands[1]; 27890 reg_2 = operands[3]; 27891 } 27892 27893 /* The mems cannot be volatile. */ 27894 if (MEM_VOLATILE_P (mem_1) || MEM_VOLATILE_P (mem_2)) 27895 return false; 27896 27897 /* Check if the addresses are in the form of [base+offset]. */ 27898 bool reversed = false; 27899 if (!aarch64_check_consecutive_mems (&mem_1, &mem_2, &reversed)) 27900 return false; 27901 27902 /* The operands must be of the same size. */ 27903 gcc_assert (known_eq (GET_MODE_SIZE (GET_MODE (mem_1)), 27904 GET_MODE_SIZE (GET_MODE (mem_2)))); 27905 27906 /* The lower memory access must be a mem-pair operand. */ 27907 rtx lower_mem = reversed ? mem_2 : mem_1; 27908 machine_mode lower_mem_mode = GET_MODE (lower_mem); 27909 if (!aarch64_mem_pair_operand (lower_mem, lower_mem_mode)) 27910 return false; 27911 27912 /* Check if lower_mem is ok with the ldp-stp policy model. */ 27913 if (!aarch64_mem_ok_with_ldpstp_policy_model (lower_mem, load, 27914 lower_mem_mode)) 27915 return false; 27916 27917 if (REG_P (reg_1) && FP_REGNUM_P (REGNO (reg_1))) 27918 rclass_1 = FP_REGS; 27919 else 27920 rclass_1 = GENERAL_REGS; 27921 27922 if (REG_P (reg_2) && FP_REGNUM_P (REGNO (reg_2))) 27923 rclass_2 = FP_REGS; 27924 else 27925 rclass_2 = GENERAL_REGS; 27926 27927 /* Check if the registers are of same class. */ 27928 if (rclass_1 != rclass_2) 27929 return false; 27930 27931 return true; 27932 } 27933 27934 /* Given OPERANDS of consecutive load/store that can be merged, 27935 swap them if they are not in ascending order. */ 27936 void 27937 aarch64_swap_ldrstr_operands (rtx* operands, bool load) 27938 { 27939 int mem_op = load ? 1 : 0; 27940 bool reversed = false; 27941 if (!aarch64_check_consecutive_mems (operands + mem_op, 27942 operands + mem_op + 2, &reversed)) 27943 gcc_unreachable (); 27944 27945 if (reversed) 27946 { 27947 /* Irrespective of whether this is a load or a store, 27948 we do the same swap. */ 27949 std::swap (operands[0], operands[2]); 27950 std::swap (operands[1], operands[3]); 27951 } 27952 } 27953 27954 /* Helper function used for generation of load/store pair instructions, called 27955 from peepholes in aarch64-ldpstp.md. OPERANDS is an array of 27956 operands as matched by the peepholes in that file. LOAD_P is true if we're 27957 generating a load pair, otherwise we're generating a store pair. CODE is 27958 either {ZERO,SIGN}_EXTEND for extending loads or UNKNOWN if we're generating a 27959 standard load/store pair. */ 27960 27961 void 27962 aarch64_finish_ldpstp_peephole (rtx *operands, bool load_p, enum rtx_code code) 27963 { 27964 aarch64_swap_ldrstr_operands (operands, load_p); 27965 27966 if (load_p) 27967 emit_insn (aarch64_gen_load_pair (operands[0], operands[2], 27968 operands[1], code)); 27969 else 27970 { 27971 gcc_assert (code == UNKNOWN); 27972 emit_insn (aarch64_gen_store_pair (operands[0], operands[1], 27973 operands[3])); 27974 } 27975 } 27976 27977 /* Taking X and Y to be HOST_WIDE_INT pointers, return the result of a 27978 comparison between the two. */ 27979 int 27980 aarch64_host_wide_int_compare (const void *x, const void *y) 27981 { 27982 return wi::cmps (* ((const HOST_WIDE_INT *) x), 27983 * ((const HOST_WIDE_INT *) y)); 27984 } 27985 27986 /* Taking X and Y to be pairs of RTX, one pointing to a MEM rtx and the 27987 other pointing to a REG rtx containing an offset, compare the offsets 27988 of the two pairs. 27989 27990 Return: 27991 27992 1 iff offset (X) > offset (Y) 27993 0 iff offset (X) == offset (Y) 27994 -1 iff offset (X) < offset (Y) */ 27995 int 27996 aarch64_ldrstr_offset_compare (const void *x, const void *y) 27997 { 27998 const rtx * operands_1 = (const rtx *) x; 27999 const rtx * operands_2 = (const rtx *) y; 28000 rtx mem_1, mem_2, base, offset_1, offset_2; 28001 28002 if (MEM_P (operands_1[0])) 28003 mem_1 = operands_1[0]; 28004 else 28005 mem_1 = operands_1[1]; 28006 28007 if (MEM_P (operands_2[0])) 28008 mem_2 = operands_2[0]; 28009 else 28010 mem_2 = operands_2[1]; 28011 28012 /* Extract the offsets. */ 28013 extract_base_offset_in_addr (mem_1, &base, &offset_1); 28014 extract_base_offset_in_addr (mem_2, &base, &offset_2); 28015 28016 gcc_assert (offset_1 != NULL_RTX && offset_2 != NULL_RTX); 28017 28018 return wi::cmps (INTVAL (offset_1), INTVAL (offset_2)); 28019 } 28020 28021 /* Given OPERANDS of consecutive load/store, check if we can merge 28022 them into ldp/stp by adjusting the offset. LOAD is true if they 28023 are load instructions. MODE is the mode of memory operands. 28024 28025 Given below consecutive stores: 28026 28027 str w1, [xb, 0x100] 28028 str w1, [xb, 0x104] 28029 str w1, [xb, 0x108] 28030 str w1, [xb, 0x10c] 28031 28032 Though the offsets are out of the range supported by stp, we can 28033 still pair them after adjusting the offset, like: 28034 28035 add scratch, xb, 0x100 28036 stp w1, w1, [scratch] 28037 stp w1, w1, [scratch, 0x8] 28038 28039 The peephole patterns detecting this opportunity should guarantee 28040 the scratch register is avaliable. */ 28041 28042 bool 28043 aarch64_operands_adjust_ok_for_ldpstp (rtx *operands, bool load, 28044 machine_mode mode) 28045 { 28046 const int num_insns = 4; 28047 enum reg_class rclass; 28048 HOST_WIDE_INT offvals[num_insns], msize; 28049 rtx mem[num_insns], reg[num_insns], base[num_insns], offset[num_insns]; 28050 28051 if (load) 28052 { 28053 for (int i = 0; i < num_insns; i++) 28054 { 28055 reg[i] = operands[2 * i]; 28056 mem[i] = operands[2 * i + 1]; 28057 28058 gcc_assert (REG_P (reg[i])); 28059 } 28060 28061 /* Do not attempt to merge the loads if the loads clobber each other. */ 28062 for (int i = 0; i < 8; i += 2) 28063 for (int j = i + 2; j < 8; j += 2) 28064 if (reg_overlap_mentioned_p (operands[i], operands[j])) 28065 return false; 28066 } 28067 else 28068 for (int i = 0; i < num_insns; i++) 28069 { 28070 mem[i] = operands[2 * i]; 28071 reg[i] = operands[2 * i + 1]; 28072 } 28073 28074 /* Skip if memory operand is by itself valid for ldp/stp. */ 28075 if (!MEM_P (mem[0]) || aarch64_mem_pair_operand (mem[0], mode)) 28076 return false; 28077 28078 for (int i = 0; i < num_insns; i++) 28079 { 28080 /* The mems cannot be volatile. */ 28081 if (MEM_VOLATILE_P (mem[i])) 28082 return false; 28083 28084 /* Check if the addresses are in the form of [base+offset]. */ 28085 extract_base_offset_in_addr (mem[i], base + i, offset + i); 28086 if (base[i] == NULL_RTX || offset[i] == NULL_RTX) 28087 return false; 28088 } 28089 28090 /* Check if the registers are of same class. */ 28091 rclass = REG_P (reg[0]) && FP_REGNUM_P (REGNO (reg[0])) 28092 ? FP_REGS : GENERAL_REGS; 28093 28094 for (int i = 1; i < num_insns; i++) 28095 if (REG_P (reg[i]) && FP_REGNUM_P (REGNO (reg[i]))) 28096 { 28097 if (rclass != FP_REGS) 28098 return false; 28099 } 28100 else 28101 { 28102 if (rclass != GENERAL_REGS) 28103 return false; 28104 } 28105 28106 /* Only the last register in the order in which they occur 28107 may be clobbered by the load. */ 28108 if (rclass == GENERAL_REGS && load) 28109 for (int i = 0; i < num_insns - 1; i++) 28110 if (reg_mentioned_p (reg[i], mem[i])) 28111 return false; 28112 28113 /* Check if the bases are same. */ 28114 for (int i = 0; i < num_insns - 1; i++) 28115 if (!rtx_equal_p (base[i], base[i + 1])) 28116 return false; 28117 28118 for (int i = 0; i < num_insns; i++) 28119 offvals[i] = INTVAL (offset[i]); 28120 28121 msize = GET_MODE_SIZE (mode).to_constant (); 28122 28123 /* Check if the offsets can be put in the right order to do a ldp/stp. */ 28124 qsort (offvals, num_insns, sizeof (HOST_WIDE_INT), 28125 aarch64_host_wide_int_compare); 28126 28127 if (!(offvals[1] == offvals[0] + msize 28128 && offvals[3] == offvals[2] + msize)) 28129 return false; 28130 28131 /* Check that offsets are within range of each other. The ldp/stp 28132 instructions have 7 bit immediate offsets, so use 0x80. */ 28133 if (offvals[2] - offvals[0] >= msize * 0x80) 28134 return false; 28135 28136 /* The offsets must be aligned with respect to each other. */ 28137 if (offvals[0] % msize != offvals[2] % msize) 28138 return false; 28139 28140 /* Check if mem[0] is ok with the ldp-stp policy model. */ 28141 if (!aarch64_mem_ok_with_ldpstp_policy_model (mem[0], load, mode)) 28142 return false; 28143 28144 return true; 28145 } 28146 28147 /* Given OPERANDS of consecutive load/store, this function pairs them 28148 into LDP/STP after adjusting the offset. It depends on the fact 28149 that the operands can be sorted so the offsets are correct for STP. 28150 MODE is the mode of memory operands. CODE is the rtl operator 28151 which should be applied to all memory operands, it's SIGN_EXTEND, 28152 ZERO_EXTEND or UNKNOWN. */ 28153 28154 bool 28155 aarch64_gen_adjusted_ldpstp (rtx *operands, bool load, 28156 machine_mode mode, RTX_CODE code) 28157 { 28158 rtx base, offset_1, offset_2; 28159 rtx mem_1, mem_2; 28160 rtx temp_operands[8]; 28161 HOST_WIDE_INT off_val_1, off_val_2, base_off, new_off_1, new_off_2, 28162 stp_off_upper_limit, stp_off_lower_limit, msize; 28163 28164 /* We make changes on a copy as we may still bail out. */ 28165 for (int i = 0; i < 8; i ++) 28166 temp_operands[i] = operands[i]; 28167 28168 /* Sort the operands. Note for cases as below: 28169 [base + 0x310] = A 28170 [base + 0x320] = B 28171 [base + 0x330] = C 28172 [base + 0x320] = D 28173 We need stable sorting otherwise wrong data may be store to offset 0x320. 28174 Also note the dead store in above case should be optimized away, but no 28175 guarantees here. */ 28176 gcc_stablesort(temp_operands, 4, 2 * sizeof (rtx *), 28177 aarch64_ldrstr_offset_compare); 28178 28179 /* Copy the memory operands so that if we have to bail for some 28180 reason the original addresses are unchanged. */ 28181 if (load) 28182 { 28183 mem_1 = copy_rtx (temp_operands[1]); 28184 mem_2 = copy_rtx (temp_operands[5]); 28185 } 28186 else 28187 { 28188 mem_1 = copy_rtx (temp_operands[0]); 28189 mem_2 = copy_rtx (temp_operands[4]); 28190 gcc_assert (code == UNKNOWN); 28191 } 28192 28193 extract_base_offset_in_addr (mem_1, &base, &offset_1); 28194 extract_base_offset_in_addr (mem_2, &base, &offset_2); 28195 gcc_assert (base != NULL_RTX && offset_1 != NULL_RTX 28196 && offset_2 != NULL_RTX); 28197 28198 /* Adjust offset so it can fit in LDP/STP instruction. */ 28199 msize = GET_MODE_SIZE (mode).to_constant(); 28200 stp_off_upper_limit = msize * (0x40 - 1); 28201 stp_off_lower_limit = - msize * 0x40; 28202 28203 off_val_1 = INTVAL (offset_1); 28204 off_val_2 = INTVAL (offset_2); 28205 28206 /* The base offset is optimally half way between the two STP/LDP offsets. */ 28207 if (msize <= 4) 28208 base_off = (off_val_1 + off_val_2) / 2; 28209 else 28210 /* However, due to issues with negative LDP/STP offset generation for 28211 larger modes, for DF, DD, DI and vector modes. we must not use negative 28212 addresses smaller than 9 signed unadjusted bits can store. This 28213 provides the most range in this case. */ 28214 base_off = off_val_1; 28215 28216 /* Adjust the base so that it is aligned with the addresses but still 28217 optimal. */ 28218 if (base_off % msize != off_val_1 % msize) 28219 /* Fix the offset, bearing in mind we want to make it bigger not 28220 smaller. */ 28221 base_off += (((base_off % msize) - (off_val_1 % msize)) + msize) % msize; 28222 else if (msize <= 4) 28223 /* The negative range of LDP/STP is one larger than the positive range. */ 28224 base_off += msize; 28225 28226 /* Check if base offset is too big or too small. We can attempt to resolve 28227 this issue by setting it to the maximum value and seeing if the offsets 28228 still fit. */ 28229 if (base_off >= 0x1000) 28230 { 28231 base_off = 0x1000 - 1; 28232 /* We must still make sure that the base offset is aligned with respect 28233 to the address. But it may not be made any bigger. */ 28234 base_off -= (((base_off % msize) - (off_val_1 % msize)) + msize) % msize; 28235 } 28236 28237 /* Likewise for the case where the base is too small. */ 28238 if (base_off <= -0x1000) 28239 { 28240 base_off = -0x1000 + 1; 28241 base_off += (((base_off % msize) - (off_val_1 % msize)) + msize) % msize; 28242 } 28243 28244 /* Offset of the first STP/LDP. */ 28245 new_off_1 = off_val_1 - base_off; 28246 28247 /* Offset of the second STP/LDP. */ 28248 new_off_2 = off_val_2 - base_off; 28249 28250 /* The offsets must be within the range of the LDP/STP instructions. */ 28251 if (new_off_1 > stp_off_upper_limit || new_off_1 < stp_off_lower_limit 28252 || new_off_2 > stp_off_upper_limit || new_off_2 < stp_off_lower_limit) 28253 return false; 28254 28255 replace_equiv_address_nv (mem_1, plus_constant (Pmode, operands[8], 28256 new_off_1), true); 28257 replace_equiv_address_nv (mem_2, plus_constant (Pmode, operands[8], 28258 new_off_2), true); 28259 28260 if (!aarch64_mem_pair_operand (mem_1, mode) 28261 || !aarch64_mem_pair_operand (mem_2, mode)) 28262 return false; 28263 28264 if (load) 28265 { 28266 operands[0] = temp_operands[0]; 28267 operands[1] = mem_1; 28268 operands[2] = temp_operands[2]; 28269 operands[4] = temp_operands[4]; 28270 operands[5] = mem_2; 28271 operands[6] = temp_operands[6]; 28272 } 28273 else 28274 { 28275 operands[0] = mem_1; 28276 operands[1] = temp_operands[1]; 28277 operands[3] = temp_operands[3]; 28278 operands[4] = mem_2; 28279 operands[5] = temp_operands[5]; 28280 operands[7] = temp_operands[7]; 28281 } 28282 28283 /* Emit adjusting instruction. */ 28284 emit_insn (gen_rtx_SET (operands[8], plus_constant (DImode, base, base_off))); 28285 /* Emit ldp/stp instructions. */ 28286 if (load) 28287 { 28288 emit_insn (aarch64_gen_load_pair (operands[0], operands[2], 28289 operands[1], code)); 28290 emit_insn (aarch64_gen_load_pair (operands[4], operands[6], 28291 operands[5], code)); 28292 } 28293 else 28294 { 28295 emit_insn (aarch64_gen_store_pair (operands[0], operands[1], 28296 operands[3])); 28297 emit_insn (aarch64_gen_store_pair (operands[4], operands[5], 28298 operands[7])); 28299 } 28300 return true; 28301 } 28302 28303 /* Implement TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE. Assume for now that 28304 it isn't worth branching around empty masked ops (including masked 28305 stores). */ 28306 28307 static bool 28308 aarch64_empty_mask_is_expensive (unsigned) 28309 { 28310 return false; 28311 } 28312 28313 /* Return 1 if pseudo register should be created and used to hold 28314 GOT address for PIC code. */ 28315 28316 bool 28317 aarch64_use_pseudo_pic_reg (void) 28318 { 28319 return aarch64_cmodel == AARCH64_CMODEL_SMALL_SPIC; 28320 } 28321 28322 /* Implement TARGET_UNSPEC_MAY_TRAP_P. */ 28323 28324 static int 28325 aarch64_unspec_may_trap_p (const_rtx x, unsigned flags) 28326 { 28327 switch (XINT (x, 1)) 28328 { 28329 case UNSPEC_GOTSMALLPIC: 28330 case UNSPEC_GOTSMALLPIC28K: 28331 case UNSPEC_GOTTINYPIC: 28332 return 0; 28333 default: 28334 break; 28335 } 28336 28337 return default_unspec_may_trap_p (x, flags); 28338 } 28339 28340 28341 /* If X is a positive CONST_DOUBLE with a value that is a power of 2 28342 return the log2 of that value. Otherwise return -1. */ 28343 28344 int 28345 aarch64_fpconst_pow_of_2 (rtx x) 28346 { 28347 const REAL_VALUE_TYPE *r; 28348 28349 if (!CONST_DOUBLE_P (x)) 28350 return -1; 28351 28352 r = CONST_DOUBLE_REAL_VALUE (x); 28353 28354 if (REAL_VALUE_NEGATIVE (*r) 28355 || REAL_VALUE_ISNAN (*r) 28356 || REAL_VALUE_ISINF (*r) 28357 || !real_isinteger (r, DFmode)) 28358 return -1; 28359 28360 return exact_log2 (real_to_integer (r)); 28361 } 28362 28363 /* If X is a positive CONST_DOUBLE with a value that is the reciprocal of a 28364 power of 2 (i.e 1/2^n) return the number of float bits. e.g. for x==(1/2^n) 28365 return n. Otherwise return -1. */ 28366 28367 int 28368 aarch64_fpconst_pow2_recip (rtx x) 28369 { 28370 REAL_VALUE_TYPE r0; 28371 28372 if (!CONST_DOUBLE_P (x)) 28373 return -1; 28374 28375 r0 = *CONST_DOUBLE_REAL_VALUE (x); 28376 if (exact_real_inverse (DFmode, &r0) 28377 && !REAL_VALUE_NEGATIVE (r0)) 28378 { 28379 int ret = exact_log2 (real_to_integer (&r0)); 28380 if (ret >= 1 && ret <= 32) 28381 return ret; 28382 } 28383 return -1; 28384 } 28385 28386 /* If X is a vector of equal CONST_DOUBLE values and that value is 28387 Y, return the aarch64_fpconst_pow_of_2 of Y. Otherwise return -1. */ 28388 28389 int 28390 aarch64_vec_fpconst_pow_of_2 (rtx x) 28391 { 28392 int nelts; 28393 if (!CONST_VECTOR_P (x) 28394 || !CONST_VECTOR_NUNITS (x).is_constant (&nelts)) 28395 return -1; 28396 28397 if (GET_MODE_CLASS (GET_MODE (x)) != MODE_VECTOR_FLOAT) 28398 return -1; 28399 28400 int firstval = aarch64_fpconst_pow_of_2 (CONST_VECTOR_ELT (x, 0)); 28401 if (firstval <= 0) 28402 return -1; 28403 28404 for (int i = 1; i < nelts; i++) 28405 if (aarch64_fpconst_pow_of_2 (CONST_VECTOR_ELT (x, i)) != firstval) 28406 return -1; 28407 28408 return firstval; 28409 } 28410 28411 /* Implement TARGET_PROMOTED_TYPE to promote 16-bit floating point types 28412 to float. 28413 28414 __fp16 always promotes through this hook. 28415 _Float16 may promote if TARGET_FLT_EVAL_METHOD is 16, but we do that 28416 through the generic excess precision logic rather than here. */ 28417 28418 static tree 28419 aarch64_promoted_type (const_tree t) 28420 { 28421 if (SCALAR_FLOAT_TYPE_P (t) 28422 && TYPE_MAIN_VARIANT (t) == aarch64_fp16_type_node) 28423 return float_type_node; 28424 28425 return NULL_TREE; 28426 } 28427 28428 /* Implement the TARGET_OPTAB_SUPPORTED_P hook. */ 28429 28430 static bool 28431 aarch64_optab_supported_p (int op, machine_mode mode1, machine_mode, 28432 optimization_type opt_type) 28433 { 28434 switch (op) 28435 { 28436 case rsqrt_optab: 28437 return opt_type == OPTIMIZE_FOR_SPEED && use_rsqrt_p (mode1); 28438 28439 default: 28440 return true; 28441 } 28442 } 28443 28444 /* Implement the TARGET_DWARF_POLY_INDETERMINATE_VALUE hook. */ 28445 28446 static unsigned int 28447 aarch64_dwarf_poly_indeterminate_value (unsigned int i, unsigned int *factor, 28448 int *offset) 28449 { 28450 /* Polynomial invariant 1 == (VG / 2) - 1. */ 28451 gcc_assert (i == 1); 28452 *factor = 2; 28453 *offset = 1; 28454 return AARCH64_DWARF_VG; 28455 } 28456 28457 /* Implement TARGET_LIBGCC_FLOATING_POINT_MODE_SUPPORTED_P - return TRUE 28458 if MODE is [BH]Fmode, and punt to the generic implementation otherwise. */ 28459 28460 static bool 28461 aarch64_libgcc_floating_mode_supported_p (scalar_float_mode mode) 28462 { 28463 return ((mode == HFmode || mode == BFmode) 28464 ? true 28465 : default_libgcc_floating_mode_supported_p (mode)); 28466 } 28467 28468 /* Implement TARGET_SCALAR_MODE_SUPPORTED_P - return TRUE 28469 if MODE is [BH]Fmode, and punt to the generic implementation otherwise. */ 28470 28471 static bool 28472 aarch64_scalar_mode_supported_p (scalar_mode mode) 28473 { 28474 if (DECIMAL_FLOAT_MODE_P (mode)) 28475 return default_decimal_float_supported_p (); 28476 28477 return ((mode == HFmode || mode == BFmode) 28478 ? true 28479 : default_scalar_mode_supported_p (mode)); 28480 } 28481 28482 /* Set the value of FLT_EVAL_METHOD. 28483 ISO/IEC TS 18661-3 defines two values that we'd like to make use of: 28484 28485 0: evaluate all operations and constants, whose semantic type has at 28486 most the range and precision of type float, to the range and 28487 precision of float; evaluate all other operations and constants to 28488 the range and precision of the semantic type; 28489 28490 N, where _FloatN is a supported interchange floating type 28491 evaluate all operations and constants, whose semantic type has at 28492 most the range and precision of _FloatN type, to the range and 28493 precision of the _FloatN type; evaluate all other operations and 28494 constants to the range and precision of the semantic type; 28495 28496 If we have the ARMv8.2-A extensions then we support _Float16 in native 28497 precision, so we should set this to 16. Otherwise, we support the type, 28498 but want to evaluate expressions in float precision, so set this to 28499 0. */ 28500 28501 static enum flt_eval_method 28502 aarch64_excess_precision (enum excess_precision_type type) 28503 { 28504 switch (type) 28505 { 28506 case EXCESS_PRECISION_TYPE_FAST: 28507 case EXCESS_PRECISION_TYPE_STANDARD: 28508 /* We can calculate either in 16-bit range and precision or 28509 32-bit range and precision. Make that decision based on whether 28510 we have native support for the ARMv8.2-A 16-bit floating-point 28511 instructions or not. */ 28512 return (TARGET_FP_F16INST 28513 ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16 28514 : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT); 28515 case EXCESS_PRECISION_TYPE_IMPLICIT: 28516 case EXCESS_PRECISION_TYPE_FLOAT16: 28517 return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16; 28518 default: 28519 gcc_unreachable (); 28520 } 28521 return FLT_EVAL_METHOD_UNPREDICTABLE; 28522 } 28523 28524 /* Implement TARGET_C_BITINT_TYPE_INFO. 28525 Return true if _BitInt(N) is supported and fill its details into *INFO. */ 28526 bool 28527 aarch64_bitint_type_info (int n, struct bitint_info *info) 28528 { 28529 if (TARGET_BIG_END) 28530 return false; 28531 28532 if (n <= 8) 28533 info->limb_mode = QImode; 28534 else if (n <= 16) 28535 info->limb_mode = HImode; 28536 else if (n <= 32) 28537 info->limb_mode = SImode; 28538 else if (n <= 64) 28539 info->limb_mode = DImode; 28540 else if (n <= 128) 28541 info->limb_mode = TImode; 28542 else 28543 /* The AAPCS for AArch64 defines _BitInt(N > 128) as an array with 28544 type {signed,unsigned} __int128[M] where M*128 >= N. However, to be 28545 able to use libgcc's implementation to support large _BitInt's we need 28546 to use a LIMB_MODE that is no larger than 'long long'. This is why we 28547 use DImode for our internal LIMB_MODE and we define the ABI_LIMB_MODE to 28548 be TImode to ensure we are ABI compliant. */ 28549 info->limb_mode = DImode; 28550 28551 if (n > 128) 28552 info->abi_limb_mode = TImode; 28553 else 28554 info->abi_limb_mode = info->limb_mode; 28555 info->big_endian = TARGET_BIG_END; 28556 info->extended = false; 28557 return true; 28558 } 28559 28560 /* Implement TARGET_SCHED_CAN_SPECULATE_INSN. Return true if INSN can be 28561 scheduled for speculative execution. Reject the long-running division 28562 and square-root instructions. */ 28563 28564 static bool 28565 aarch64_sched_can_speculate_insn (rtx_insn *insn) 28566 { 28567 switch (get_attr_type (insn)) 28568 { 28569 case TYPE_SDIV: 28570 case TYPE_UDIV: 28571 case TYPE_FDIVS: 28572 case TYPE_FDIVD: 28573 case TYPE_FSQRTS: 28574 case TYPE_FSQRTD: 28575 case TYPE_NEON_FP_SQRT_S: 28576 case TYPE_NEON_FP_SQRT_D: 28577 case TYPE_NEON_FP_SQRT_S_Q: 28578 case TYPE_NEON_FP_SQRT_D_Q: 28579 case TYPE_NEON_FP_DIV_S: 28580 case TYPE_NEON_FP_DIV_D: 28581 case TYPE_NEON_FP_DIV_S_Q: 28582 case TYPE_NEON_FP_DIV_D_Q: 28583 return false; 28584 default: 28585 return true; 28586 } 28587 } 28588 28589 /* Implement TARGET_COMPUTE_PRESSURE_CLASSES. */ 28590 28591 static int 28592 aarch64_compute_pressure_classes (reg_class *classes) 28593 { 28594 int i = 0; 28595 classes[i++] = GENERAL_REGS; 28596 classes[i++] = FP_REGS; 28597 /* PR_REGS isn't a useful pressure class because many predicate pseudo 28598 registers need to go in PR_LO_REGS at some point during their 28599 lifetime. Splitting it into two halves has the effect of making 28600 all predicates count against PR_LO_REGS, so that we try whenever 28601 possible to restrict the number of live predicates to 8. This 28602 greatly reduces the amount of spilling in certain loops. */ 28603 classes[i++] = PR_LO_REGS; 28604 classes[i++] = PR_HI_REGS; 28605 return i; 28606 } 28607 28608 /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */ 28609 28610 static bool 28611 aarch64_can_change_mode_class (machine_mode from, 28612 machine_mode to, reg_class_t) 28613 { 28614 return aarch64_modes_compatible_p (from, to); 28615 } 28616 28617 /* Implement TARGET_EARLY_REMAT_MODES. */ 28618 28619 static void 28620 aarch64_select_early_remat_modes (sbitmap modes) 28621 { 28622 /* SVE values are not normally live across a call, so it should be 28623 worth doing early rematerialization even in VL-specific mode. */ 28624 for (int i = 0; i < NUM_MACHINE_MODES; ++i) 28625 if (aarch64_sve_mode_p ((machine_mode) i)) 28626 bitmap_set_bit (modes, i); 28627 } 28628 28629 /* Override the default target speculation_safe_value. */ 28630 static rtx 28631 aarch64_speculation_safe_value (machine_mode mode, 28632 rtx result, rtx val, rtx failval) 28633 { 28634 /* Maybe we should warn if falling back to hard barriers. They are 28635 likely to be noticably more expensive than the alternative below. */ 28636 if (!aarch64_track_speculation) 28637 return default_speculation_safe_value (mode, result, val, failval); 28638 28639 if (!REG_P (val)) 28640 val = copy_to_mode_reg (mode, val); 28641 28642 if (!aarch64_reg_or_zero (failval, mode)) 28643 failval = copy_to_mode_reg (mode, failval); 28644 28645 emit_insn (gen_despeculate_copy (mode, result, val, failval)); 28646 return result; 28647 } 28648 28649 /* Implement TARGET_ESTIMATED_POLY_VALUE. 28650 Look into the tuning structure for an estimate. 28651 KIND specifies the type of requested estimate: min, max or likely. 28652 For cores with a known SVE width all three estimates are the same. 28653 For generic SVE tuning we want to distinguish the maximum estimate from 28654 the minimum and likely ones. 28655 The likely estimate is the same as the minimum in that case to give a 28656 conservative behavior of auto-vectorizing with SVE when it is a win 28657 even for 128-bit SVE. 28658 When SVE width information is available VAL.coeffs[1] is multiplied by 28659 the number of VQ chunks over the initial Advanced SIMD 128 bits. */ 28660 28661 static HOST_WIDE_INT 28662 aarch64_estimated_poly_value (poly_int64 val, 28663 poly_value_estimate_kind kind 28664 = POLY_VALUE_LIKELY) 28665 { 28666 unsigned int width_source = aarch64_tune_params.sve_width; 28667 28668 /* If there is no core-specific information then the minimum and likely 28669 values are based on 128-bit vectors and the maximum is based on 28670 the architectural maximum of 2048 bits. */ 28671 if (width_source == SVE_SCALABLE) 28672 switch (kind) 28673 { 28674 case POLY_VALUE_MIN: 28675 case POLY_VALUE_LIKELY: 28676 return val.coeffs[0]; 28677 case POLY_VALUE_MAX: 28678 return val.coeffs[0] + val.coeffs[1] * 15; 28679 } 28680 28681 /* Allow sve_width to be a bitmask of different VL, treating the lowest 28682 as likely. This could be made more general if future -mtune options 28683 need it to be. */ 28684 if (kind == POLY_VALUE_MAX) 28685 width_source = 1 << floor_log2 (width_source); 28686 else 28687 width_source = least_bit_hwi (width_source); 28688 28689 /* If the core provides width information, use that. */ 28690 HOST_WIDE_INT over_128 = width_source - 128; 28691 return val.coeffs[0] + val.coeffs[1] * over_128 / 128; 28692 } 28693 28694 28695 /* Return true for types that could be supported as SIMD return or 28696 argument types. */ 28697 28698 static bool 28699 supported_simd_type (tree t) 28700 { 28701 if (SCALAR_FLOAT_TYPE_P (t) || INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t)) 28702 { 28703 HOST_WIDE_INT s = tree_to_shwi (TYPE_SIZE_UNIT (t)); 28704 return s == 1 || s == 2 || s == 4 || s == 8; 28705 } 28706 return false; 28707 } 28708 28709 /* Determine the lane size for the clone argument/return type. This follows 28710 the LS(P) rule in the VFABIA64. */ 28711 28712 static unsigned 28713 lane_size (cgraph_simd_clone_arg_type clone_arg_type, tree type) 28714 { 28715 gcc_assert (clone_arg_type != SIMD_CLONE_ARG_TYPE_MASK); 28716 28717 /* For non map-to-vector types that are pointers we use the element type it 28718 points to. */ 28719 if (POINTER_TYPE_P (type)) 28720 switch (clone_arg_type) 28721 { 28722 default: 28723 break; 28724 case SIMD_CLONE_ARG_TYPE_UNIFORM: 28725 case SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP: 28726 case SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP: 28727 type = TREE_TYPE (type); 28728 break; 28729 } 28730 28731 /* For types (or pointers of non map-to-vector types point to) that are 28732 integers or floating point, we use their size if they are 1, 2, 4 or 8. 28733 */ 28734 if (INTEGRAL_TYPE_P (type) 28735 || SCALAR_FLOAT_TYPE_P (type)) 28736 switch (TYPE_PRECISION (type) / BITS_PER_UNIT) 28737 { 28738 default: 28739 break; 28740 case 1: 28741 case 2: 28742 case 4: 28743 case 8: 28744 return TYPE_PRECISION (type); 28745 } 28746 /* For any other we use the size of uintptr_t. For map-to-vector types that 28747 are pointers, using the size of uintptr_t is the same as using the size of 28748 their type, seeing all pointers are the same size as uintptr_t. */ 28749 return POINTER_SIZE; 28750 } 28751 28752 28753 /* Implement TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN. */ 28754 28755 static int 28756 aarch64_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node, 28757 struct cgraph_simd_clone *clonei, 28758 tree base_type ATTRIBUTE_UNUSED, 28759 int num, bool explicit_p) 28760 { 28761 tree t, ret_type; 28762 unsigned int nds_elt_bits; 28763 unsigned HOST_WIDE_INT const_simdlen; 28764 28765 if (!TARGET_SIMD) 28766 return 0; 28767 28768 /* For now, SVE simdclones won't produce illegal simdlen, So only check 28769 const simdlens here. */ 28770 if (maybe_ne (clonei->simdlen, 0U) 28771 && clonei->simdlen.is_constant (&const_simdlen) 28772 && (const_simdlen < 2 28773 || const_simdlen > 1024 28774 || (const_simdlen & (const_simdlen - 1)) != 0)) 28775 { 28776 if (explicit_p) 28777 warning_at (DECL_SOURCE_LOCATION (node->decl), 0, 28778 "unsupported simdlen %wd", const_simdlen); 28779 return 0; 28780 } 28781 28782 ret_type = TREE_TYPE (TREE_TYPE (node->decl)); 28783 /* According to AArch64's Vector ABI the type that determines the simdlen is 28784 the narrowest of types, so we ignore base_type for AArch64. */ 28785 if (TREE_CODE (ret_type) != VOID_TYPE 28786 && !supported_simd_type (ret_type)) 28787 { 28788 if (!explicit_p) 28789 ; 28790 else if (COMPLEX_FLOAT_TYPE_P (ret_type)) 28791 warning_at (DECL_SOURCE_LOCATION (node->decl), 0, 28792 "GCC does not currently support return type %qT " 28793 "for simd", ret_type); 28794 else 28795 warning_at (DECL_SOURCE_LOCATION (node->decl), 0, 28796 "unsupported return type %qT for simd", 28797 ret_type); 28798 return 0; 28799 } 28800 28801 auto_vec<std::pair <tree, unsigned int>> vec_elts (clonei->nargs + 1); 28802 28803 /* We are looking for the NDS type here according to the VFABIA64. */ 28804 if (TREE_CODE (ret_type) != VOID_TYPE) 28805 { 28806 nds_elt_bits = lane_size (SIMD_CLONE_ARG_TYPE_VECTOR, ret_type); 28807 vec_elts.safe_push (std::make_pair (ret_type, nds_elt_bits)); 28808 } 28809 else 28810 nds_elt_bits = POINTER_SIZE; 28811 28812 int i; 28813 tree type_arg_types = TYPE_ARG_TYPES (TREE_TYPE (node->decl)); 28814 bool decl_arg_p = (node->definition || type_arg_types == NULL_TREE); 28815 for (t = (decl_arg_p ? DECL_ARGUMENTS (node->decl) : type_arg_types), i = 0; 28816 t && t != void_list_node; t = TREE_CHAIN (t), i++) 28817 { 28818 tree arg_type = decl_arg_p ? TREE_TYPE (t) : TREE_VALUE (t); 28819 if (clonei->args[i].arg_type != SIMD_CLONE_ARG_TYPE_UNIFORM 28820 && !supported_simd_type (arg_type)) 28821 { 28822 if (!explicit_p) 28823 ; 28824 else if (COMPLEX_FLOAT_TYPE_P (ret_type)) 28825 warning_at (DECL_SOURCE_LOCATION (node->decl), 0, 28826 "GCC does not currently support argument type %qT " 28827 "for simd", arg_type); 28828 else 28829 warning_at (DECL_SOURCE_LOCATION (node->decl), 0, 28830 "unsupported argument type %qT for simd", 28831 arg_type); 28832 return 0; 28833 } 28834 unsigned lane_bits = lane_size (clonei->args[i].arg_type, arg_type); 28835 if (clonei->args[i].arg_type == SIMD_CLONE_ARG_TYPE_VECTOR) 28836 vec_elts.safe_push (std::make_pair (arg_type, lane_bits)); 28837 if (nds_elt_bits > lane_bits) 28838 nds_elt_bits = lane_bits; 28839 } 28840 28841 clonei->vecsize_mangle = 'n'; 28842 clonei->mask_mode = VOIDmode; 28843 poly_uint64 simdlen; 28844 auto_vec<poly_uint64> simdlens (2); 28845 /* Keep track of the possible simdlens the clones of this function can have, 28846 and check them later to see if we support them. */ 28847 if (known_eq (clonei->simdlen, 0U)) 28848 { 28849 simdlen = exact_div (poly_uint64 (64), nds_elt_bits); 28850 if (maybe_ne (simdlen, 1U)) 28851 simdlens.safe_push (simdlen); 28852 simdlens.safe_push (simdlen * 2); 28853 } 28854 else 28855 simdlens.safe_push (clonei->simdlen); 28856 28857 clonei->vecsize_int = 0; 28858 clonei->vecsize_float = 0; 28859 28860 /* We currently do not support generating simdclones where vector arguments 28861 do not fit into a single vector register, i.e. vector types that are more 28862 than 128-bits large. This is because of how we currently represent such 28863 types in ACLE, where we use a struct to allow us to pass them as arguments 28864 and return. 28865 Hence why we have to check whether the simdlens available for this 28866 simdclone would cause a vector type to be larger than 128-bits, and reject 28867 such a clone. */ 28868 unsigned j = 0; 28869 while (j < simdlens.length ()) 28870 { 28871 bool remove_simdlen = false; 28872 for (auto elt : vec_elts) 28873 if (known_gt (simdlens[j] * elt.second, 128U)) 28874 { 28875 /* Don't issue a warning for every simdclone when there is no 28876 specific simdlen clause. */ 28877 if (explicit_p && maybe_ne (clonei->simdlen, 0U)) 28878 warning_at (DECL_SOURCE_LOCATION (node->decl), 0, 28879 "GCC does not currently support simdlen %wd for " 28880 "type %qT", 28881 constant_lower_bound (simdlens[j]), elt.first); 28882 remove_simdlen = true; 28883 break; 28884 } 28885 if (remove_simdlen) 28886 simdlens.ordered_remove (j); 28887 else 28888 j++; 28889 } 28890 28891 28892 int count = simdlens.length (); 28893 if (count == 0) 28894 { 28895 if (explicit_p && known_eq (clonei->simdlen, 0U)) 28896 { 28897 /* Warn the user if we can't generate any simdclone. */ 28898 simdlen = exact_div (poly_uint64 (64), nds_elt_bits); 28899 warning_at (DECL_SOURCE_LOCATION (node->decl), 0, 28900 "GCC does not currently support a simdclone with simdlens" 28901 " %wd and %wd for these types.", 28902 constant_lower_bound (simdlen), 28903 constant_lower_bound (simdlen*2)); 28904 } 28905 return 0; 28906 } 28907 28908 gcc_assert (num < count); 28909 clonei->simdlen = simdlens[num]; 28910 return count; 28911 } 28912 28913 /* Implement TARGET_SIMD_CLONE_ADJUST. */ 28914 28915 static void 28916 aarch64_simd_clone_adjust (struct cgraph_node *node) 28917 { 28918 /* Add aarch64_vector_pcs target attribute to SIMD clones so they 28919 use the correct ABI. */ 28920 28921 tree t = TREE_TYPE (node->decl); 28922 TYPE_ATTRIBUTES (t) = make_attribute ("aarch64_vector_pcs", "default", 28923 TYPE_ATTRIBUTES (t)); 28924 } 28925 28926 /* Implement TARGET_SIMD_CLONE_USABLE. */ 28927 28928 static int 28929 aarch64_simd_clone_usable (struct cgraph_node *node) 28930 { 28931 switch (node->simdclone->vecsize_mangle) 28932 { 28933 case 'n': 28934 if (!TARGET_SIMD) 28935 return -1; 28936 return 0; 28937 default: 28938 gcc_unreachable (); 28939 } 28940 } 28941 28942 /* Implement TARGET_COMP_TYPE_ATTRIBUTES */ 28943 28944 static int 28945 aarch64_comp_type_attributes (const_tree type1, const_tree type2) 28946 { 28947 auto check_attr = [&](const char *ns, const char *name) { 28948 tree attr1 = lookup_attribute (ns, name, TYPE_ATTRIBUTES (type1)); 28949 tree attr2 = lookup_attribute (ns, name, TYPE_ATTRIBUTES (type2)); 28950 if (!attr1 && !attr2) 28951 return true; 28952 28953 return attr1 && attr2 && attribute_value_equal (attr1, attr2); 28954 }; 28955 28956 if (!check_attr ("gnu", "aarch64_vector_pcs")) 28957 return 0; 28958 if (!check_attr ("gnu", "Advanced SIMD type")) 28959 return 0; 28960 if (!check_attr ("gnu", "SVE type")) 28961 return 0; 28962 if (!check_attr ("gnu", "SVE sizeless type")) 28963 return 0; 28964 if (!check_attr ("arm", "streaming")) 28965 return 0; 28966 if (!check_attr ("arm", "streaming_compatible")) 28967 return 0; 28968 if (aarch64_lookup_shared_state_flags (TYPE_ATTRIBUTES (type1), "za") 28969 != aarch64_lookup_shared_state_flags (TYPE_ATTRIBUTES (type2), "za")) 28970 return 0; 28971 if (aarch64_lookup_shared_state_flags (TYPE_ATTRIBUTES (type1), "zt0") 28972 != aarch64_lookup_shared_state_flags (TYPE_ATTRIBUTES (type2), "zt0")) 28973 return 0; 28974 return 1; 28975 } 28976 28977 /* Implement TARGET_MERGE_DECL_ATTRIBUTES. */ 28978 28979 static tree 28980 aarch64_merge_decl_attributes (tree olddecl, tree newdecl) 28981 { 28982 tree old_attrs = DECL_ATTRIBUTES (olddecl); 28983 tree old_new = lookup_attribute ("arm", "new", old_attrs); 28984 28985 tree new_attrs = DECL_ATTRIBUTES (newdecl); 28986 tree new_new = lookup_attribute ("arm", "new", new_attrs); 28987 28988 if (DECL_INITIAL (olddecl) && new_new) 28989 { 28990 error ("cannot apply attribute %qs to %q+D after the function" 28991 " has been defined", "new", newdecl); 28992 inform (DECL_SOURCE_LOCATION (olddecl), "%q+D defined here", 28993 newdecl); 28994 } 28995 else 28996 { 28997 if (old_new && new_new) 28998 { 28999 old_attrs = remove_attribute ("arm", "new", old_attrs); 29000 TREE_VALUE (new_new) = chainon (TREE_VALUE (new_new), 29001 TREE_VALUE (old_new)); 29002 } 29003 if (new_new) 29004 aarch64_check_arm_new_against_type (TREE_VALUE (new_new), newdecl); 29005 } 29006 29007 return merge_attributes (old_attrs, new_attrs); 29008 } 29009 29010 /* Implement TARGET_GET_MULTILIB_ABI_NAME */ 29011 29012 static const char * 29013 aarch64_get_multilib_abi_name (void) 29014 { 29015 if (TARGET_BIG_END) 29016 return TARGET_ILP32 ? "aarch64_be_ilp32" : "aarch64_be"; 29017 return TARGET_ILP32 ? "aarch64_ilp32" : "aarch64"; 29018 } 29019 29020 /* Implement TARGET_STACK_PROTECT_GUARD. In case of a 29021 global variable based guard use the default else 29022 return a null tree. */ 29023 static tree 29024 aarch64_stack_protect_guard (void) 29025 { 29026 if (aarch64_stack_protector_guard == SSP_GLOBAL) 29027 return default_stack_protect_guard (); 29028 29029 return NULL_TREE; 29030 } 29031 29032 /* Return the diagnostic message string if the binary operation OP is 29033 not permitted on TYPE1 and TYPE2, NULL otherwise. */ 29034 29035 static const char * 29036 aarch64_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, 29037 const_tree type2) 29038 { 29039 if (VECTOR_TYPE_P (type1) 29040 && VECTOR_TYPE_P (type2) 29041 && !TYPE_INDIVISIBLE_P (type1) 29042 && !TYPE_INDIVISIBLE_P (type2) 29043 && (aarch64_sve::builtin_type_p (type1) 29044 != aarch64_sve::builtin_type_p (type2))) 29045 return N_("cannot combine GNU and SVE vectors in a binary operation"); 29046 29047 /* Operation allowed. */ 29048 return NULL; 29049 } 29050 29051 /* Implement TARGET_MEMTAG_CAN_TAG_ADDRESSES. Here we tell the rest of the 29052 compiler that we automatically ignore the top byte of our pointers, which 29053 allows using -fsanitize=hwaddress. */ 29054 bool 29055 aarch64_can_tag_addresses () 29056 { 29057 return !TARGET_ILP32; 29058 } 29059 29060 /* Implement TARGET_ASM_FILE_END for AArch64. This adds the AArch64 GNU NOTE 29061 section at the end if needed. */ 29062 #define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 29063 #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0) 29064 #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1) 29065 void 29066 aarch64_file_end_indicate_exec_stack () 29067 { 29068 file_end_indicate_exec_stack (); 29069 29070 unsigned feature_1_and = 0; 29071 if (aarch_bti_enabled ()) 29072 feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI; 29073 29074 if (aarch_ra_sign_scope != AARCH_FUNCTION_NONE) 29075 feature_1_and |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC; 29076 29077 if (feature_1_and) 29078 { 29079 /* Generate .note.gnu.property section. */ 29080 switch_to_section (get_section (".note.gnu.property", 29081 SECTION_NOTYPE, NULL)); 29082 29083 /* PT_NOTE header: namesz, descsz, type. 29084 namesz = 4 ("GNU\0") 29085 descsz = 16 (Size of the program property array) 29086 [(12 + padding) * Number of array elements] 29087 type = 5 (NT_GNU_PROPERTY_TYPE_0). */ 29088 assemble_align (POINTER_SIZE); 29089 assemble_integer (GEN_INT (4), 4, 32, 1); 29090 assemble_integer (GEN_INT (ROUND_UP (12, POINTER_BYTES)), 4, 32, 1); 29091 assemble_integer (GEN_INT (5), 4, 32, 1); 29092 29093 /* PT_NOTE name. */ 29094 assemble_string ("GNU", 4); 29095 29096 /* PT_NOTE contents for NT_GNU_PROPERTY_TYPE_0: 29097 type = GNU_PROPERTY_AARCH64_FEATURE_1_AND 29098 datasz = 4 29099 data = feature_1_and. */ 29100 assemble_integer (GEN_INT (GNU_PROPERTY_AARCH64_FEATURE_1_AND), 4, 32, 1); 29101 assemble_integer (GEN_INT (4), 4, 32, 1); 29102 assemble_integer (GEN_INT (feature_1_and), 4, 32, 1); 29103 29104 /* Pad the size of the note to the required alignment. */ 29105 assemble_align (POINTER_SIZE); 29106 } 29107 } 29108 #undef GNU_PROPERTY_AARCH64_FEATURE_1_PAC 29109 #undef GNU_PROPERTY_AARCH64_FEATURE_1_BTI 29110 #undef GNU_PROPERTY_AARCH64_FEATURE_1_AND 29111 29112 /* Helper function for straight line speculation. 29113 Return what barrier should be emitted for straight line speculation 29114 mitigation. 29115 When not mitigating against straight line speculation this function returns 29116 an empty string. 29117 When mitigating against straight line speculation, use: 29118 * SB when the v8.5-A SB extension is enabled. 29119 * DSB+ISB otherwise. */ 29120 const char * 29121 aarch64_sls_barrier (int mitigation_required) 29122 { 29123 return mitigation_required 29124 ? (TARGET_SB ? "sb" : "dsb\tsy\n\tisb") 29125 : ""; 29126 } 29127 29128 static GTY (()) tree aarch64_sls_shared_thunks[30]; 29129 static GTY (()) bool aarch64_sls_shared_thunks_needed = false; 29130 const char *indirect_symbol_names[30] = { 29131 "__call_indirect_x0", 29132 "__call_indirect_x1", 29133 "__call_indirect_x2", 29134 "__call_indirect_x3", 29135 "__call_indirect_x4", 29136 "__call_indirect_x5", 29137 "__call_indirect_x6", 29138 "__call_indirect_x7", 29139 "__call_indirect_x8", 29140 "__call_indirect_x9", 29141 "__call_indirect_x10", 29142 "__call_indirect_x11", 29143 "__call_indirect_x12", 29144 "__call_indirect_x13", 29145 "__call_indirect_x14", 29146 "__call_indirect_x15", 29147 "", /* "__call_indirect_x16", */ 29148 "", /* "__call_indirect_x17", */ 29149 "__call_indirect_x18", 29150 "__call_indirect_x19", 29151 "__call_indirect_x20", 29152 "__call_indirect_x21", 29153 "__call_indirect_x22", 29154 "__call_indirect_x23", 29155 "__call_indirect_x24", 29156 "__call_indirect_x25", 29157 "__call_indirect_x26", 29158 "__call_indirect_x27", 29159 "__call_indirect_x28", 29160 "__call_indirect_x29", 29161 }; 29162 29163 /* Function to create a BLR thunk. This thunk is used to mitigate straight 29164 line speculation. Instead of a simple BLR that can be speculated past, 29165 we emit a BL to this thunk, and this thunk contains a BR to the relevant 29166 register. These thunks have the relevant speculation barries put after 29167 their indirect branch so that speculation is blocked. 29168 29169 We use such a thunk so the speculation barriers are kept off the 29170 architecturally executed path in order to reduce the performance overhead. 29171 29172 When optimizing for size we use stubs shared by the linked object. 29173 When optimizing for performance we emit stubs for each function in the hope 29174 that the branch predictor can better train on jumps specific for a given 29175 function. */ 29176 rtx 29177 aarch64_sls_create_blr_label (int regnum) 29178 { 29179 gcc_assert (STUB_REGNUM_P (regnum)); 29180 if (optimize_function_for_size_p (cfun)) 29181 { 29182 /* For the thunks shared between different functions in this compilation 29183 unit we use a named symbol -- this is just for users to more easily 29184 understand the generated assembly. */ 29185 aarch64_sls_shared_thunks_needed = true; 29186 const char *thunk_name = indirect_symbol_names[regnum]; 29187 if (aarch64_sls_shared_thunks[regnum] == NULL) 29188 { 29189 /* Build a decl representing this function stub and record it for 29190 later. We build a decl here so we can use the GCC machinery for 29191 handling sections automatically (through `get_named_section` and 29192 `make_decl_one_only`). That saves us a lot of trouble handling 29193 the specifics of different output file formats. */ 29194 tree decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, 29195 get_identifier (thunk_name), 29196 build_function_type_list (void_type_node, 29197 NULL_TREE)); 29198 DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL, 29199 NULL_TREE, void_type_node); 29200 TREE_PUBLIC (decl) = 1; 29201 TREE_STATIC (decl) = 1; 29202 DECL_IGNORED_P (decl) = 1; 29203 DECL_ARTIFICIAL (decl) = 1; 29204 make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl)); 29205 resolve_unique_section (decl, 0, false); 29206 aarch64_sls_shared_thunks[regnum] = decl; 29207 } 29208 29209 return gen_rtx_SYMBOL_REF (Pmode, thunk_name); 29210 } 29211 29212 if (cfun->machine->call_via[regnum] == NULL) 29213 cfun->machine->call_via[regnum] 29214 = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ()); 29215 return cfun->machine->call_via[regnum]; 29216 } 29217 29218 /* Helper function for aarch64_sls_emit_blr_function_thunks and 29219 aarch64_sls_emit_shared_blr_thunks below. */ 29220 static void 29221 aarch64_sls_emit_function_stub (FILE *out_file, int regnum) 29222 { 29223 /* Save in x16 and branch to that function so this transformation does 29224 not prevent jumping to `BTI c` instructions. */ 29225 asm_fprintf (out_file, "\tmov\tx16, x%d\n", regnum); 29226 asm_fprintf (out_file, "\tbr\tx16\n"); 29227 } 29228 29229 /* Emit all BLR stubs for this particular function. 29230 Here we emit all the BLR stubs needed for the current function. Since we 29231 emit these stubs in a consecutive block we know there will be no speculation 29232 gadgets between each stub, and hence we only emit a speculation barrier at 29233 the end of the stub sequences. 29234 29235 This is called in the TARGET_ASM_FUNCTION_EPILOGUE hook. */ 29236 void 29237 aarch64_sls_emit_blr_function_thunks (FILE *out_file) 29238 { 29239 if (! aarch64_harden_sls_blr_p ()) 29240 return; 29241 29242 bool any_functions_emitted = false; 29243 /* We must save and restore the current function section since this assembly 29244 is emitted at the end of the function. This means it can be emitted *just 29245 after* the cold section of a function. That cold part would be emitted in 29246 a different section. That switch would trigger a `.cfi_endproc` directive 29247 to be emitted in the original section and a `.cfi_startproc` directive to 29248 be emitted in the new section. Switching to the original section without 29249 restoring would mean that the `.cfi_endproc` emitted as a function ends 29250 would happen in a different section -- leaving an unmatched 29251 `.cfi_startproc` in the cold text section and an unmatched `.cfi_endproc` 29252 in the standard text section. */ 29253 section *save_text_section = in_section; 29254 switch_to_section (function_section (current_function_decl)); 29255 for (int regnum = 0; regnum < 30; ++regnum) 29256 { 29257 rtx specu_label = cfun->machine->call_via[regnum]; 29258 if (specu_label == NULL) 29259 continue; 29260 29261 targetm.asm_out.print_operand (out_file, specu_label, 0); 29262 asm_fprintf (out_file, ":\n"); 29263 aarch64_sls_emit_function_stub (out_file, regnum); 29264 any_functions_emitted = true; 29265 } 29266 if (any_functions_emitted) 29267 /* Can use the SB if needs be here, since this stub will only be used 29268 by the current function, and hence for the current target. */ 29269 asm_fprintf (out_file, "\t%s\n", aarch64_sls_barrier (true)); 29270 switch_to_section (save_text_section); 29271 } 29272 29273 /* Emit shared BLR stubs for the current compilation unit. 29274 Over the course of compiling this unit we may have converted some BLR 29275 instructions to a BL to a shared stub function. This is where we emit those 29276 stub functions. 29277 This function is for the stubs shared between different functions in this 29278 compilation unit. We share when optimizing for size instead of speed. 29279 29280 This function is called through the TARGET_ASM_FILE_END hook. */ 29281 void 29282 aarch64_sls_emit_shared_blr_thunks (FILE *out_file) 29283 { 29284 if (! aarch64_sls_shared_thunks_needed) 29285 return; 29286 29287 for (int regnum = 0; regnum < 30; ++regnum) 29288 { 29289 tree decl = aarch64_sls_shared_thunks[regnum]; 29290 if (!decl) 29291 continue; 29292 29293 const char *name = indirect_symbol_names[regnum]; 29294 switch_to_section (get_named_section (decl, NULL, 0)); 29295 ASM_OUTPUT_ALIGN (out_file, 2); 29296 targetm.asm_out.globalize_label (out_file, name); 29297 /* Only emits if the compiler is configured for an assembler that can 29298 handle visibility directives. */ 29299 targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN); 29300 ASM_OUTPUT_TYPE_DIRECTIVE (out_file, name, "function"); 29301 ASM_OUTPUT_LABEL (out_file, name); 29302 aarch64_sls_emit_function_stub (out_file, regnum); 29303 /* Use the most conservative target to ensure it can always be used by any 29304 function in the translation unit. */ 29305 asm_fprintf (out_file, "\tdsb\tsy\n\tisb\n"); 29306 ASM_DECLARE_FUNCTION_SIZE (out_file, name, decl); 29307 } 29308 } 29309 29310 /* Implement TARGET_ASM_FILE_END. */ 29311 void 29312 aarch64_asm_file_end () 29313 { 29314 aarch64_sls_emit_shared_blr_thunks (asm_out_file); 29315 /* Since this function will be called for the ASM_FILE_END hook, we ensure 29316 that what would be called otherwise (e.g. `file_end_indicate_exec_stack` 29317 for FreeBSD) still gets called. */ 29318 #ifdef TARGET_ASM_FILE_END 29319 TARGET_ASM_FILE_END (); 29320 #endif 29321 } 29322 29323 const char * 29324 aarch64_indirect_call_asm (rtx addr) 29325 { 29326 gcc_assert (REG_P (addr)); 29327 if (aarch64_harden_sls_blr_p ()) 29328 { 29329 rtx stub_label = aarch64_sls_create_blr_label (REGNO (addr)); 29330 output_asm_insn ("bl\t%0", &stub_label); 29331 } 29332 else 29333 output_asm_insn ("blr\t%0", &addr); 29334 return ""; 29335 } 29336 29337 /* Emit the assembly instruction to load the thread pointer into DEST. 29338 Select between different tpidr_elN registers depending on -mtp= setting. */ 29339 29340 const char * 29341 aarch64_output_load_tp (rtx dest) 29342 { 29343 const char *tpidrs[] = {"tpidr_el0", "tpidr_el1", "tpidr_el2", 29344 "tpidr_el3", "tpidrro_el0"}; 29345 char buffer[64]; 29346 snprintf (buffer, sizeof (buffer), "mrs\t%%0, %s", 29347 tpidrs[aarch64_tpidr_register]); 29348 output_asm_insn (buffer, &dest); 29349 return ""; 29350 } 29351 29352 /* Set up the value of REG_ALLOC_ORDER from scratch. 29353 29354 It was previously good practice to put call-clobbered registers ahead 29355 of call-preserved registers, but that isn't necessary these days. 29356 IRA's model of register save/restore costs is much more sophisticated 29357 than the model that a simple ordering could provide. We leave 29358 HONOR_REG_ALLOC_ORDER undefined so that we can get the full benefit 29359 of IRA's model. 29360 29361 However, it is still useful to list registers that are members of 29362 multiple classes after registers that are members of fewer classes. 29363 For example, we have: 29364 29365 - FP_LO8_REGS: v0-v7 29366 - FP_LO_REGS: v0-v15 29367 - FP_REGS: v0-v31 29368 29369 If, as a tie-breaker, we allocate FP_REGS in the order v0-v31, 29370 we run the risk of starving other (lower-priority) pseudos that 29371 require FP_LO8_REGS or FP_LO_REGS. Allocating FP_LO_REGS in the 29372 order v0-v15 could similarly starve pseudos that require FP_LO8_REGS. 29373 Allocating downwards rather than upwards avoids this problem, at least 29374 in code that has reasonable register pressure. 29375 29376 The situation for predicate registers is similar. */ 29377 29378 void 29379 aarch64_adjust_reg_alloc_order () 29380 { 29381 for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i) 29382 if (IN_RANGE (i, V0_REGNUM, V31_REGNUM)) 29383 reg_alloc_order[i] = V31_REGNUM - (i - V0_REGNUM); 29384 else if (IN_RANGE (i, P0_REGNUM, P15_REGNUM)) 29385 reg_alloc_order[i] = P15_REGNUM - (i - P0_REGNUM); 29386 else 29387 reg_alloc_order[i] = i; 29388 } 29389 29390 /* Return true if the PARALLEL PAR can be used in a VEC_SELECT expression 29391 of vector mode MODE to select half the elements of that vector. 29392 Allow any combination of indices except duplicates (or out of range of 29393 the mode units). */ 29394 29395 bool 29396 aarch64_parallel_select_half_p (machine_mode mode, rtx par) 29397 { 29398 int nunits = XVECLEN (par, 0); 29399 if (!known_eq (GET_MODE_NUNITS (mode), nunits * 2)) 29400 return false; 29401 int mode_nunits = nunits * 2; 29402 /* Put all the elements of PAR into a hash_set and use its 29403 uniqueness guarantees to check that we don't try to insert the same 29404 element twice. */ 29405 hash_set<rtx> parset; 29406 for (int i = 0; i < nunits; ++i) 29407 { 29408 rtx elt = XVECEXP (par, 0, i); 29409 if (!CONST_INT_P (elt) 29410 || !IN_RANGE (INTVAL (elt), 0, mode_nunits - 1) 29411 || parset.add (elt)) 29412 return false; 29413 } 29414 return true; 29415 } 29416 29417 /* Return true if PAR1 and PAR2, two PARALLEL rtxes of CONST_INT values, 29418 contain any common elements. */ 29419 29420 bool 29421 aarch64_pars_overlap_p (rtx par1, rtx par2) 29422 { 29423 int len1 = XVECLEN (par1, 0); 29424 int len2 = XVECLEN (par2, 0); 29425 hash_set<rtx> parset; 29426 for (int i = 0; i < len1; ++i) 29427 parset.add (XVECEXP (par1, 0, i)); 29428 for (int i = 0; i < len2; ++i) 29429 if (parset.contains (XVECEXP (par2, 0, i))) 29430 return true; 29431 return false; 29432 } 29433 29434 /* Implement OPTIMIZE_MODE_SWITCHING. */ 29435 29436 bool 29437 aarch64_optimize_mode_switching (aarch64_mode_entity entity) 29438 { 29439 bool have_sme_state = (aarch64_cfun_incoming_pstate_za () != 0 29440 || (aarch64_cfun_has_new_state ("za") 29441 && df_regs_ever_live_p (ZA_REGNUM)) 29442 || (aarch64_cfun_has_new_state ("zt0") 29443 && df_regs_ever_live_p (ZT0_REGNUM))); 29444 29445 if (have_sme_state && nonlocal_goto_handler_labels) 29446 { 29447 static bool reported; 29448 if (!reported) 29449 { 29450 sorry ("non-local gotos in functions with SME state"); 29451 reported = true; 29452 } 29453 } 29454 29455 switch (entity) 29456 { 29457 case aarch64_mode_entity::HAVE_ZA_SAVE_BUFFER: 29458 case aarch64_mode_entity::LOCAL_SME_STATE: 29459 return have_sme_state && !nonlocal_goto_handler_labels; 29460 } 29461 gcc_unreachable (); 29462 } 29463 29464 /* Implement TARGET_MODE_EMIT for ZA_SAVE_BUFFER. */ 29465 29466 static void 29467 aarch64_mode_emit_za_save_buffer (aarch64_tristate_mode mode, 29468 aarch64_tristate_mode prev_mode) 29469 { 29470 if (mode == aarch64_tristate_mode::YES) 29471 { 29472 gcc_assert (prev_mode == aarch64_tristate_mode::NO); 29473 aarch64_init_tpidr2_block (); 29474 } 29475 else 29476 gcc_unreachable (); 29477 } 29478 29479 /* Implement TARGET_MODE_EMIT for LOCAL_SME_STATE. */ 29480 29481 static void 29482 aarch64_mode_emit_local_sme_state (aarch64_local_sme_state mode, 29483 aarch64_local_sme_state prev_mode) 29484 { 29485 /* Back-propagation should ensure that we're always starting from 29486 a known mode. */ 29487 gcc_assert (prev_mode != aarch64_local_sme_state::ANY); 29488 29489 if (prev_mode == aarch64_local_sme_state::INACTIVE_CALLER) 29490 { 29491 /* Commit any uncommitted lazy save. This leaves ZA either active 29492 and zero (lazy save case) or off (normal case). 29493 29494 The sequence is: 29495 29496 mrs <temp>, tpidr2_el0 29497 cbz <temp>, no_save 29498 bl __arm_tpidr2_save 29499 msr tpidr2_el0, xzr 29500 zero { za } // Only if ZA is live 29501 zero { zt0 } // Only if ZT0 is live 29502 no_save: */ 29503 auto tmp_reg = gen_reg_rtx (DImode); 29504 emit_insn (gen_aarch64_read_tpidr2 (tmp_reg)); 29505 auto label = gen_label_rtx (); 29506 rtx branch = aarch64_gen_compare_zero_and_branch (EQ, tmp_reg, label); 29507 auto jump = emit_jump_insn (branch); 29508 JUMP_LABEL (jump) = label; 29509 emit_insn (gen_aarch64_tpidr2_save ()); 29510 emit_insn (gen_aarch64_clear_tpidr2 ()); 29511 if (mode == aarch64_local_sme_state::ACTIVE_LIVE 29512 || mode == aarch64_local_sme_state::ACTIVE_DEAD) 29513 { 29514 if (aarch64_cfun_has_state ("za")) 29515 emit_insn (gen_aarch64_initial_zero_za ()); 29516 if (aarch64_cfun_has_state ("zt0")) 29517 emit_insn (gen_aarch64_sme_zero_zt0 ()); 29518 } 29519 emit_label (label); 29520 } 29521 29522 if (mode == aarch64_local_sme_state::ACTIVE_LIVE 29523 || mode == aarch64_local_sme_state::ACTIVE_DEAD) 29524 { 29525 if (prev_mode == aarch64_local_sme_state::INACTIVE_LOCAL) 29526 { 29527 /* Make ZA active after being inactive. 29528 29529 First handle the case in which the lazy save we set up was 29530 committed by a callee. If the function's source-level ZA state 29531 is live then we must conditionally restore it from the lazy 29532 save buffer. Otherwise we can just force PSTATE.ZA to 1. */ 29533 if (mode == aarch64_local_sme_state::ACTIVE_LIVE) 29534 emit_insn (gen_aarch64_restore_za (aarch64_get_tpidr2_ptr ())); 29535 else 29536 emit_insn (gen_aarch64_smstart_za ()); 29537 29538 /* Now handle the case in which the lazy save was not committed. 29539 In that case, ZA still contains the current function's ZA state, 29540 and we just need to cancel the lazy save. */ 29541 emit_insn (gen_aarch64_clear_tpidr2 ()); 29542 29543 /* Restore the ZT0 state, if we have some. */ 29544 if (aarch64_cfun_has_state ("zt0")) 29545 aarch64_restore_zt0 (true); 29546 29547 return; 29548 } 29549 29550 if (prev_mode == aarch64_local_sme_state::SAVED_LOCAL) 29551 { 29552 /* Retrieve the current function's ZA state from the lazy save 29553 buffer. */ 29554 aarch64_restore_za (aarch64_get_tpidr2_ptr ()); 29555 29556 /* Restore the ZT0 state, if we have some. */ 29557 if (aarch64_cfun_has_state ("zt0")) 29558 aarch64_restore_zt0 (true); 29559 return; 29560 } 29561 29562 if (prev_mode == aarch64_local_sme_state::INACTIVE_CALLER 29563 || prev_mode == aarch64_local_sme_state::OFF) 29564 { 29565 /* INACTIVE_CALLER means that we are enabling ZA for the first 29566 time in this function. The code above means that ZA is either 29567 active and zero (if we committed a lazy save) or off. Handle 29568 the latter case by forcing ZA on. 29569 29570 OFF means that PSTATE.ZA is guaranteed to be 0. We just need 29571 to force it to 1. 29572 29573 Both cases leave ZA zeroed. */ 29574 emit_insn (gen_aarch64_smstart_za ()); 29575 29576 /* Restore the ZT0 state, if we have some. */ 29577 if (prev_mode == aarch64_local_sme_state::OFF 29578 && aarch64_cfun_has_state ("zt0")) 29579 aarch64_restore_zt0 (true); 29580 return; 29581 } 29582 29583 if (prev_mode == aarch64_local_sme_state::ACTIVE_DEAD 29584 || prev_mode == aarch64_local_sme_state::ACTIVE_LIVE) 29585 /* A simple change in liveness, such as in a CFG structure where 29586 ZA is only conditionally defined. No code is needed. */ 29587 return; 29588 29589 gcc_unreachable (); 29590 } 29591 29592 if (mode == aarch64_local_sme_state::INACTIVE_LOCAL) 29593 { 29594 if (prev_mode == aarch64_local_sme_state::ACTIVE_LIVE 29595 || prev_mode == aarch64_local_sme_state::ACTIVE_DEAD 29596 || prev_mode == aarch64_local_sme_state::INACTIVE_CALLER) 29597 { 29598 /* Save the ZT0 state, if we have some. */ 29599 if (aarch64_cfun_has_state ("zt0")) 29600 aarch64_save_zt0 (); 29601 29602 /* A transition from ACTIVE_LIVE to INACTIVE_LOCAL is the usual 29603 case of setting up a lazy save buffer before a call. 29604 A transition from INACTIVE_CALLER is similar, except that 29605 the contents of ZA are known to be zero. 29606 29607 A transition from ACTIVE_DEAD means that ZA is live at the 29608 point of the transition, but is dead on at least one incoming 29609 edge. (That is, ZA is only conditionally initialized.) 29610 For efficiency, we want to set up a lazy save even for 29611 dead contents, since forcing ZA off would make later code 29612 restore ZA from the lazy save buffer. */ 29613 emit_insn (gen_aarch64_write_tpidr2 (aarch64_get_tpidr2_ptr ())); 29614 return; 29615 } 29616 29617 if (prev_mode == aarch64_local_sme_state::SAVED_LOCAL 29618 || prev_mode == aarch64_local_sme_state::OFF) 29619 /* We're simply discarding the information about which inactive 29620 state applies. */ 29621 return; 29622 29623 gcc_unreachable (); 29624 } 29625 29626 if (mode == aarch64_local_sme_state::INACTIVE_CALLER 29627 || mode == aarch64_local_sme_state::OFF) 29628 { 29629 /* Save the ZT0 state, if we have some. */ 29630 if ((prev_mode == aarch64_local_sme_state::ACTIVE_LIVE 29631 || prev_mode == aarch64_local_sme_state::ACTIVE_DEAD) 29632 && mode == aarch64_local_sme_state::OFF 29633 && aarch64_cfun_has_state ("zt0")) 29634 aarch64_save_zt0 (); 29635 29636 /* The transition to INACTIVE_CALLER is used before returning from 29637 new("za") functions. Any state in ZA belongs to the current 29638 function rather than a caller, but that state is no longer 29639 needed. Clear any pending lazy save and turn ZA off. 29640 29641 The transition to OFF is used before calling a private-ZA function. 29642 We committed any incoming lazy save above, so at this point any 29643 contents in ZA belong to the current function. */ 29644 if (prev_mode == aarch64_local_sme_state::INACTIVE_LOCAL) 29645 emit_insn (gen_aarch64_clear_tpidr2 ()); 29646 29647 if (prev_mode != aarch64_local_sme_state::OFF 29648 && prev_mode != aarch64_local_sme_state::SAVED_LOCAL) 29649 emit_insn (gen_aarch64_smstop_za ()); 29650 29651 return; 29652 } 29653 29654 if (mode == aarch64_local_sme_state::SAVED_LOCAL) 29655 { 29656 /* This is a transition to an exception handler. */ 29657 gcc_assert (prev_mode == aarch64_local_sme_state::OFF 29658 || prev_mode == aarch64_local_sme_state::INACTIVE_LOCAL); 29659 return; 29660 } 29661 29662 gcc_unreachable (); 29663 } 29664 29665 /* Implement TARGET_MODE_EMIT. */ 29666 29667 static void 29668 aarch64_mode_emit (int entity, int mode, int prev_mode, HARD_REG_SET live) 29669 { 29670 if (mode == prev_mode) 29671 return; 29672 29673 start_sequence (); 29674 switch (aarch64_mode_entity (entity)) 29675 { 29676 case aarch64_mode_entity::HAVE_ZA_SAVE_BUFFER: 29677 aarch64_mode_emit_za_save_buffer (aarch64_tristate_mode (mode), 29678 aarch64_tristate_mode (prev_mode)); 29679 break; 29680 29681 case aarch64_mode_entity::LOCAL_SME_STATE: 29682 aarch64_mode_emit_local_sme_state (aarch64_local_sme_state (mode), 29683 aarch64_local_sme_state (prev_mode)); 29684 break; 29685 } 29686 rtx_insn *seq = get_insns (); 29687 end_sequence (); 29688 29689 /* Get the set of clobbered registers that are currently live. */ 29690 HARD_REG_SET clobbers = {}; 29691 for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn)) 29692 { 29693 if (!NONDEBUG_INSN_P (insn)) 29694 continue; 29695 vec_rtx_properties properties; 29696 properties.add_insn (insn, false); 29697 for (rtx_obj_reference ref : properties.refs ()) 29698 if (ref.is_write () && HARD_REGISTER_NUM_P (ref.regno)) 29699 SET_HARD_REG_BIT (clobbers, ref.regno); 29700 } 29701 clobbers &= live; 29702 29703 /* Emit instructions to save clobbered registers to pseudos. Queue 29704 instructions to restore the registers afterwards. 29705 29706 This should only needed in rare situations. */ 29707 auto_vec<rtx, 33> after; 29708 for (unsigned int regno = R0_REGNUM; regno < R30_REGNUM; ++regno) 29709 if (TEST_HARD_REG_BIT (clobbers, regno)) 29710 { 29711 rtx hard_reg = gen_rtx_REG (DImode, regno); 29712 rtx pseudo_reg = gen_reg_rtx (DImode); 29713 emit_move_insn (pseudo_reg, hard_reg); 29714 after.quick_push (gen_move_insn (hard_reg, pseudo_reg)); 29715 } 29716 if (TEST_HARD_REG_BIT (clobbers, CC_REGNUM)) 29717 { 29718 rtx pseudo_reg = gen_reg_rtx (DImode); 29719 emit_insn (gen_aarch64_save_nzcv (pseudo_reg)); 29720 after.quick_push (gen_aarch64_restore_nzcv (pseudo_reg)); 29721 } 29722 29723 /* Emit the transition instructions themselves. */ 29724 emit_insn (seq); 29725 29726 /* Restore the clobbered registers. */ 29727 for (auto *insn : after) 29728 emit_insn (insn); 29729 } 29730 29731 /* Return true if INSN references the SME state represented by hard register 29732 REGNO. */ 29733 29734 static bool 29735 aarch64_insn_references_sme_state_p (rtx_insn *insn, unsigned int regno) 29736 { 29737 df_ref ref; 29738 FOR_EACH_INSN_DEF (ref, insn) 29739 if (!DF_REF_FLAGS_IS_SET (ref, DF_REF_MUST_CLOBBER) 29740 && DF_REF_REGNO (ref) == regno) 29741 return true; 29742 FOR_EACH_INSN_USE (ref, insn) 29743 if (DF_REF_REGNO (ref) == regno) 29744 return true; 29745 return false; 29746 } 29747 29748 /* Implement TARGET_MODE_NEEDED for LOCAL_SME_STATE. */ 29749 29750 static aarch64_local_sme_state 29751 aarch64_mode_needed_local_sme_state (rtx_insn *insn, HARD_REG_SET live) 29752 { 29753 if (!CALL_P (insn) 29754 && find_reg_note (insn, REG_EH_REGION, NULL_RTX)) 29755 { 29756 static bool reported; 29757 if (!reported) 29758 { 29759 sorry ("catching non-call exceptions in functions with SME state"); 29760 reported = true; 29761 } 29762 /* Aim for graceful error recovery by picking the value that is 29763 least likely to generate an ICE. */ 29764 return aarch64_local_sme_state::INACTIVE_LOCAL; 29765 } 29766 29767 /* A non-local goto is equivalent to a return. We disallow non-local 29768 receivers in functions with SME state, so we know that the target 29769 expects ZA to be dormant or off. */ 29770 if (JUMP_P (insn) 29771 && find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX)) 29772 return aarch64_local_sme_state::INACTIVE_CALLER; 29773 29774 /* start_private_za_call and end_private_za_call bracket a sequence 29775 that calls a private-ZA function. Force ZA to be turned off if the 29776 function doesn't have any live ZA state, otherwise require ZA to be 29777 inactive. */ 29778 auto icode = recog_memoized (insn); 29779 if (icode == CODE_FOR_aarch64_start_private_za_call 29780 || icode == CODE_FOR_aarch64_end_private_za_call) 29781 return (TEST_HARD_REG_BIT (live, ZA_REGNUM) 29782 ? aarch64_local_sme_state::INACTIVE_LOCAL 29783 : aarch64_local_sme_state::OFF); 29784 29785 /* Force ZA to contain the current function's ZA state if INSN wants 29786 to access it. Do the same for accesses to ZT0, since ZA and ZT0 29787 are both controlled by PSTATE.ZA. */ 29788 if (aarch64_insn_references_sme_state_p (insn, ZA_REGNUM) 29789 || aarch64_insn_references_sme_state_p (insn, ZT0_REGNUM)) 29790 return (TEST_HARD_REG_BIT (live, ZA_REGNUM) 29791 ? aarch64_local_sme_state::ACTIVE_LIVE 29792 : aarch64_local_sme_state::ACTIVE_DEAD); 29793 29794 return aarch64_local_sme_state::ANY; 29795 } 29796 29797 /* Implement TARGET_MODE_NEEDED for ZA_SAVE_BUFFER. */ 29798 29799 static aarch64_tristate_mode 29800 aarch64_mode_needed_za_save_buffer (rtx_insn *insn, HARD_REG_SET live) 29801 { 29802 /* We need to set up a lazy save buffer no later than the first 29803 transition to INACTIVE_LOCAL (which involves setting up a lazy save). */ 29804 if (aarch64_mode_needed_local_sme_state (insn, live) 29805 == aarch64_local_sme_state::INACTIVE_LOCAL) 29806 return aarch64_tristate_mode::YES; 29807 29808 /* Also make sure that the lazy save buffer is set up before the first 29809 insn that throws internally. The exception handler will sometimes 29810 load from it. */ 29811 if (find_reg_note (insn, REG_EH_REGION, NULL_RTX)) 29812 return aarch64_tristate_mode::YES; 29813 29814 return aarch64_tristate_mode::MAYBE; 29815 } 29816 29817 /* Implement TARGET_MODE_NEEDED. */ 29818 29819 static int 29820 aarch64_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET live) 29821 { 29822 switch (aarch64_mode_entity (entity)) 29823 { 29824 case aarch64_mode_entity::HAVE_ZA_SAVE_BUFFER: 29825 return int (aarch64_mode_needed_za_save_buffer (insn, live)); 29826 29827 case aarch64_mode_entity::LOCAL_SME_STATE: 29828 return int (aarch64_mode_needed_local_sme_state (insn, live)); 29829 } 29830 gcc_unreachable (); 29831 } 29832 29833 /* Implement TARGET_MODE_AFTER for LOCAL_SME_STATE. */ 29834 29835 static aarch64_local_sme_state 29836 aarch64_mode_after_local_sme_state (aarch64_local_sme_state mode, 29837 HARD_REG_SET live) 29838 { 29839 /* Note places where ZA dies, so that we can try to avoid saving and 29840 restoring state that isn't needed. */ 29841 if (mode == aarch64_local_sme_state::ACTIVE_LIVE 29842 && !TEST_HARD_REG_BIT (live, ZA_REGNUM)) 29843 return aarch64_local_sme_state::ACTIVE_DEAD; 29844 29845 /* Note where ZA is born, e.g. when moving past an __arm_out("za") 29846 function. */ 29847 if (mode == aarch64_local_sme_state::ACTIVE_DEAD 29848 && TEST_HARD_REG_BIT (live, ZA_REGNUM)) 29849 return aarch64_local_sme_state::ACTIVE_LIVE; 29850 29851 return mode; 29852 } 29853 29854 /* Implement TARGET_MODE_AFTER. */ 29855 29856 static int 29857 aarch64_mode_after (int entity, int mode, rtx_insn *, HARD_REG_SET live) 29858 { 29859 switch (aarch64_mode_entity (entity)) 29860 { 29861 case aarch64_mode_entity::HAVE_ZA_SAVE_BUFFER: 29862 return mode; 29863 29864 case aarch64_mode_entity::LOCAL_SME_STATE: 29865 return int (aarch64_mode_after_local_sme_state 29866 (aarch64_local_sme_state (mode), live)); 29867 } 29868 gcc_unreachable (); 29869 } 29870 29871 /* Implement TARGET_MODE_CONFLUENCE for LOCAL_SME_STATE. */ 29872 29873 static aarch64_local_sme_state 29874 aarch64_local_sme_confluence (aarch64_local_sme_state mode1, 29875 aarch64_local_sme_state mode2) 29876 { 29877 /* Perform a symmetrical check for two values. */ 29878 auto is_pair = [&](aarch64_local_sme_state val1, 29879 aarch64_local_sme_state val2) 29880 { 29881 return ((mode1 == val1 && mode2 == val2) 29882 || (mode1 == val2 && mode2 == val1)); 29883 }; 29884 29885 /* INACTIVE_CALLER means ZA is off or it has dormant contents belonging 29886 to a caller. OFF is one of the options. */ 29887 if (is_pair (aarch64_local_sme_state::INACTIVE_CALLER, 29888 aarch64_local_sme_state::OFF)) 29889 return aarch64_local_sme_state::INACTIVE_CALLER; 29890 29891 /* Similarly for dormant contents belonging to the current function. */ 29892 if (is_pair (aarch64_local_sme_state::INACTIVE_LOCAL, 29893 aarch64_local_sme_state::OFF)) 29894 return aarch64_local_sme_state::INACTIVE_LOCAL; 29895 29896 /* Treat a conditionally-initialized value as a fully-initialized value. */ 29897 if (is_pair (aarch64_local_sme_state::ACTIVE_LIVE, 29898 aarch64_local_sme_state::ACTIVE_DEAD)) 29899 return aarch64_local_sme_state::ACTIVE_LIVE; 29900 29901 return aarch64_local_sme_state::ANY; 29902 } 29903 29904 /* Implement TARGET_MODE_CONFLUENCE. */ 29905 29906 static int 29907 aarch64_mode_confluence (int entity, int mode1, int mode2) 29908 { 29909 gcc_assert (mode1 != mode2); 29910 switch (aarch64_mode_entity (entity)) 29911 { 29912 case aarch64_mode_entity::HAVE_ZA_SAVE_BUFFER: 29913 return int (aarch64_tristate_mode::MAYBE); 29914 29915 case aarch64_mode_entity::LOCAL_SME_STATE: 29916 return int (aarch64_local_sme_confluence 29917 (aarch64_local_sme_state (mode1), 29918 aarch64_local_sme_state (mode2))); 29919 } 29920 gcc_unreachable (); 29921 } 29922 29923 /* Implement TARGET_MODE_BACKPROP for an entity that either stays 29924 NO throughput, or makes one transition from NO to YES. */ 29925 29926 static aarch64_tristate_mode 29927 aarch64_one_shot_backprop (aarch64_tristate_mode mode1, 29928 aarch64_tristate_mode mode2) 29929 { 29930 /* Keep bringing the transition forward until it starts from NO. */ 29931 if (mode1 == aarch64_tristate_mode::MAYBE 29932 && mode2 == aarch64_tristate_mode::YES) 29933 return mode2; 29934 29935 return aarch64_tristate_mode::MAYBE; 29936 } 29937 29938 /* Implement TARGET_MODE_BACKPROP for LOCAL_SME_STATE. */ 29939 29940 static aarch64_local_sme_state 29941 aarch64_local_sme_backprop (aarch64_local_sme_state mode1, 29942 aarch64_local_sme_state mode2) 29943 { 29944 /* We always need to know what the current state is when transitioning 29945 to a new state. Force any location with indeterminate starting state 29946 to be active. */ 29947 if (mode1 == aarch64_local_sme_state::ANY) 29948 switch (mode2) 29949 { 29950 case aarch64_local_sme_state::INACTIVE_CALLER: 29951 case aarch64_local_sme_state::OFF: 29952 case aarch64_local_sme_state::ACTIVE_DEAD: 29953 /* The current function's ZA state is not live. */ 29954 return aarch64_local_sme_state::ACTIVE_DEAD; 29955 29956 case aarch64_local_sme_state::INACTIVE_LOCAL: 29957 case aarch64_local_sme_state::ACTIVE_LIVE: 29958 /* The current function's ZA state is live. */ 29959 return aarch64_local_sme_state::ACTIVE_LIVE; 29960 29961 case aarch64_local_sme_state::SAVED_LOCAL: 29962 /* This is a transition to an exception handler. Since we don't 29963 support non-call exceptions for SME functions, the source of 29964 the transition must be known. We'll assert later if that's 29965 not the case. */ 29966 return aarch64_local_sme_state::ANY; 29967 29968 case aarch64_local_sme_state::ANY: 29969 return aarch64_local_sme_state::ANY; 29970 } 29971 29972 return aarch64_local_sme_state::ANY; 29973 } 29974 29975 /* Implement TARGET_MODE_BACKPROP. */ 29976 29977 static int 29978 aarch64_mode_backprop (int entity, int mode1, int mode2) 29979 { 29980 switch (aarch64_mode_entity (entity)) 29981 { 29982 case aarch64_mode_entity::HAVE_ZA_SAVE_BUFFER: 29983 return int (aarch64_one_shot_backprop (aarch64_tristate_mode (mode1), 29984 aarch64_tristate_mode (mode2))); 29985 29986 case aarch64_mode_entity::LOCAL_SME_STATE: 29987 return int (aarch64_local_sme_backprop 29988 (aarch64_local_sme_state (mode1), 29989 aarch64_local_sme_state (mode2))); 29990 } 29991 gcc_unreachable (); 29992 } 29993 29994 /* Implement TARGET_MODE_ENTRY. */ 29995 29996 static int 29997 aarch64_mode_entry (int entity) 29998 { 29999 switch (aarch64_mode_entity (entity)) 30000 { 30001 case aarch64_mode_entity::HAVE_ZA_SAVE_BUFFER: 30002 return int (aarch64_tristate_mode::NO); 30003 30004 case aarch64_mode_entity::LOCAL_SME_STATE: 30005 return int (aarch64_cfun_shared_flags ("za") != 0 30006 ? aarch64_local_sme_state::ACTIVE_LIVE 30007 : aarch64_cfun_incoming_pstate_za () != 0 30008 ? aarch64_local_sme_state::ACTIVE_DEAD 30009 : aarch64_local_sme_state::INACTIVE_CALLER); 30010 } 30011 gcc_unreachable (); 30012 } 30013 30014 /* Implement TARGET_MODE_EXIT. */ 30015 30016 static int 30017 aarch64_mode_exit (int entity) 30018 { 30019 switch (aarch64_mode_entity (entity)) 30020 { 30021 case aarch64_mode_entity::HAVE_ZA_SAVE_BUFFER: 30022 return int (aarch64_tristate_mode::MAYBE); 30023 30024 case aarch64_mode_entity::LOCAL_SME_STATE: 30025 return int (aarch64_cfun_shared_flags ("za") != 0 30026 ? aarch64_local_sme_state::ACTIVE_LIVE 30027 : aarch64_cfun_incoming_pstate_za () != 0 30028 ? aarch64_local_sme_state::ACTIVE_DEAD 30029 : aarch64_local_sme_state::INACTIVE_CALLER); 30030 } 30031 gcc_unreachable (); 30032 } 30033 30034 /* Implement TARGET_MODE_EH_HANDLER. */ 30035 30036 static int 30037 aarch64_mode_eh_handler (int entity) 30038 { 30039 switch (aarch64_mode_entity (entity)) 30040 { 30041 case aarch64_mode_entity::HAVE_ZA_SAVE_BUFFER: 30042 /* Require a lazy save buffer to be allocated before the first 30043 insn that can throw. */ 30044 return int (aarch64_tristate_mode::YES); 30045 30046 case aarch64_mode_entity::LOCAL_SME_STATE: 30047 return int (aarch64_local_sme_state::SAVED_LOCAL); 30048 } 30049 gcc_unreachable (); 30050 } 30051 30052 /* Implement TARGET_MODE_PRIORITY. */ 30053 30054 static int 30055 aarch64_mode_priority (int, int n) 30056 { 30057 return n; 30058 } 30059 30060 /* Implement TARGET_MD_ASM_ADJUST. */ 30061 30062 static rtx_insn * 30063 aarch64_md_asm_adjust (vec<rtx> &outputs, vec<rtx> &inputs, 30064 vec<machine_mode> &input_modes, 30065 vec<const char *> &constraints, 30066 vec<rtx> &uses, vec<rtx> &clobbers, 30067 HARD_REG_SET &clobbered_regs, location_t loc) 30068 { 30069 rtx_insn *seq = arm_md_asm_adjust (outputs, inputs, input_modes, constraints, 30070 uses, clobbers, clobbered_regs, loc); 30071 30072 /* "za" in the clobber list of a function with ZA state is defined to 30073 mean that the asm can read from and write to ZA. We can model the 30074 read using a USE, but unfortunately, it's not possible to model the 30075 write directly. Use a separate insn to model the effect. 30076 30077 We must ensure that ZA is active on entry, which is enforced by using 30078 SME_STATE_REGNUM. The asm must ensure that ZA is active on return. 30079 30080 The same thing applies to ZT0. */ 30081 if (TARGET_ZA) 30082 for (unsigned int i = clobbers.length (); i-- > 0; ) 30083 { 30084 rtx x = clobbers[i]; 30085 if (REG_P (x) 30086 && (REGNO (x) == ZA_REGNUM || REGNO (x) == ZT0_REGNUM)) 30087 { 30088 auto id = cfun->machine->next_asm_update_za_id++; 30089 30090 start_sequence (); 30091 if (seq) 30092 emit_insn (seq); 30093 rtx id_rtx = gen_int_mode (id, SImode); 30094 emit_insn (REGNO (x) == ZA_REGNUM 30095 ? gen_aarch64_asm_update_za (id_rtx) 30096 : gen_aarch64_asm_update_zt0 (id_rtx)); 30097 seq = get_insns (); 30098 end_sequence (); 30099 30100 auto mode = REGNO (x) == ZA_REGNUM ? VNx16QImode : V8DImode; 30101 uses.safe_push (gen_rtx_REG (mode, REGNO (x))); 30102 uses.safe_push (gen_rtx_REG (DImode, SME_STATE_REGNUM)); 30103 30104 clobbers.ordered_remove (i); 30105 CLEAR_HARD_REG_BIT (clobbered_regs, REGNO (x)); 30106 } 30107 } 30108 return seq; 30109 } 30110 30111 /* BB is the target of an exception or nonlocal goto edge, which means 30112 that PSTATE.SM is known to be 0 on entry. Put it into the state that 30113 the current function requires. */ 30114 30115 static bool 30116 aarch64_switch_pstate_sm_for_landing_pad (basic_block bb) 30117 { 30118 if (TARGET_NON_STREAMING) 30119 return false; 30120 30121 start_sequence (); 30122 rtx_insn *guard_label = nullptr; 30123 if (TARGET_STREAMING_COMPATIBLE) 30124 guard_label = aarch64_guard_switch_pstate_sm (IP0_REGNUM, 30125 AARCH64_FL_SM_OFF); 30126 aarch64_sme_mode_switch_regs args_switch; 30127 args_switch.add_call_preserved_regs (df_get_live_in (bb)); 30128 args_switch.emit_prologue (); 30129 aarch64_switch_pstate_sm (AARCH64_FL_SM_OFF, AARCH64_FL_SM_ON); 30130 args_switch.emit_epilogue (); 30131 if (guard_label) 30132 emit_label (guard_label); 30133 auto seq = get_insns (); 30134 end_sequence (); 30135 30136 emit_insn_after (seq, bb_note (bb)); 30137 return true; 30138 } 30139 30140 /* JUMP is a nonlocal goto. Its target requires PSTATE.SM to be 0 on entry, 30141 so arrange to make it so. */ 30142 30143 static bool 30144 aarch64_switch_pstate_sm_for_jump (rtx_insn *jump) 30145 { 30146 if (TARGET_NON_STREAMING) 30147 return false; 30148 30149 start_sequence (); 30150 rtx_insn *guard_label = nullptr; 30151 if (TARGET_STREAMING_COMPATIBLE) 30152 guard_label = aarch64_guard_switch_pstate_sm (IP0_REGNUM, 30153 AARCH64_FL_SM_OFF); 30154 aarch64_switch_pstate_sm (AARCH64_FL_SM_ON, AARCH64_FL_SM_OFF); 30155 if (guard_label) 30156 emit_label (guard_label); 30157 auto seq = get_insns (); 30158 end_sequence (); 30159 30160 emit_insn_before (seq, jump); 30161 return true; 30162 } 30163 30164 /* If CALL involves a change in PSTATE.SM, emit the instructions needed 30165 to switch to the new mode and the instructions needed to restore the 30166 original mode. Return true if something changed. */ 30167 static bool 30168 aarch64_switch_pstate_sm_for_call (rtx_call_insn *call) 30169 { 30170 /* Mode switches for sibling calls are handled via the epilogue. */ 30171 if (SIBLING_CALL_P (call)) 30172 return false; 30173 30174 auto callee_isa_mode = aarch64_insn_callee_isa_mode (call); 30175 if (!aarch64_call_switches_pstate_sm (callee_isa_mode)) 30176 return false; 30177 30178 /* Switch mode before the call, preserving any argument registers 30179 across the switch. */ 30180 start_sequence (); 30181 rtx_insn *args_guard_label = nullptr; 30182 if (TARGET_STREAMING_COMPATIBLE) 30183 args_guard_label = aarch64_guard_switch_pstate_sm (IP0_REGNUM, 30184 callee_isa_mode); 30185 aarch64_sme_mode_switch_regs args_switch; 30186 args_switch.add_call_args (call); 30187 args_switch.emit_prologue (); 30188 aarch64_switch_pstate_sm (AARCH64_ISA_MODE, callee_isa_mode); 30189 args_switch.emit_epilogue (); 30190 if (args_guard_label) 30191 emit_label (args_guard_label); 30192 auto args_seq = get_insns (); 30193 end_sequence (); 30194 emit_insn_before (args_seq, call); 30195 30196 if (find_reg_note (call, REG_NORETURN, NULL_RTX)) 30197 return true; 30198 30199 /* Switch mode after the call, preserving any return registers across 30200 the switch. */ 30201 start_sequence (); 30202 rtx_insn *return_guard_label = nullptr; 30203 if (TARGET_STREAMING_COMPATIBLE) 30204 return_guard_label = aarch64_guard_switch_pstate_sm (IP0_REGNUM, 30205 callee_isa_mode); 30206 aarch64_sme_mode_switch_regs return_switch; 30207 return_switch.add_call_result (call); 30208 return_switch.emit_prologue (); 30209 aarch64_switch_pstate_sm (callee_isa_mode, AARCH64_ISA_MODE); 30210 return_switch.emit_epilogue (); 30211 if (return_guard_label) 30212 emit_label (return_guard_label); 30213 auto result_seq = get_insns (); 30214 end_sequence (); 30215 emit_insn_after (result_seq, call); 30216 return true; 30217 } 30218 30219 namespace { 30220 30221 const pass_data pass_data_switch_pstate_sm = 30222 { 30223 RTL_PASS, // type 30224 "smstarts", // name 30225 OPTGROUP_NONE, // optinfo_flags 30226 TV_NONE, // tv_id 30227 0, // properties_required 30228 0, // properties_provided 30229 0, // properties_destroyed 30230 0, // todo_flags_start 30231 TODO_df_finish, // todo_flags_finish 30232 }; 30233 30234 class pass_switch_pstate_sm : public rtl_opt_pass 30235 { 30236 public: 30237 pass_switch_pstate_sm (gcc::context *ctxt) 30238 : rtl_opt_pass (pass_data_switch_pstate_sm, ctxt) 30239 {} 30240 30241 // opt_pass methods: 30242 bool gate (function *) override final; 30243 unsigned int execute (function *) override final; 30244 }; 30245 30246 bool 30247 pass_switch_pstate_sm::gate (function *fn) 30248 { 30249 return (aarch64_fndecl_pstate_sm (fn->decl) != AARCH64_FL_SM_OFF 30250 || cfun->machine->call_switches_pstate_sm); 30251 } 30252 30253 /* Emit any instructions needed to switch PSTATE.SM. */ 30254 unsigned int 30255 pass_switch_pstate_sm::execute (function *fn) 30256 { 30257 basic_block bb; 30258 30259 auto_sbitmap blocks (last_basic_block_for_fn (cfun)); 30260 bitmap_clear (blocks); 30261 FOR_EACH_BB_FN (bb, fn) 30262 { 30263 if (has_abnormal_call_or_eh_pred_edge_p (bb) 30264 && aarch64_switch_pstate_sm_for_landing_pad (bb)) 30265 bitmap_set_bit (blocks, bb->index); 30266 30267 if (cfun->machine->call_switches_pstate_sm) 30268 { 30269 rtx_insn *insn; 30270 FOR_BB_INSNS (bb, insn) 30271 if (auto *call = dyn_cast<rtx_call_insn *> (insn)) 30272 if (aarch64_switch_pstate_sm_for_call (call)) 30273 bitmap_set_bit (blocks, bb->index); 30274 } 30275 30276 auto end = BB_END (bb); 30277 if (JUMP_P (end) 30278 && find_reg_note (end, REG_NON_LOCAL_GOTO, NULL_RTX) 30279 && aarch64_switch_pstate_sm_for_jump (end)) 30280 bitmap_set_bit (blocks, bb->index); 30281 } 30282 find_many_sub_basic_blocks (blocks); 30283 clear_aux_for_blocks (); 30284 return 0; 30285 } 30286 30287 } 30288 30289 rtl_opt_pass * 30290 make_pass_switch_pstate_sm (gcc::context *ctxt) 30291 { 30292 return new pass_switch_pstate_sm (ctxt); 30293 } 30294 30295 /* Parse an implementation-defined system register name of 30296 the form S[0-3]_[0-7]_C[0-15]_C[0-15]_[0-7]. 30297 Return true if name matched against above pattern, false 30298 otherwise. */ 30299 bool 30300 aarch64_is_implem_def_reg (const char *regname) 30301 { 30302 unsigned pos = 0; 30303 unsigned name_len = strlen (regname); 30304 if (name_len < 12 || name_len > 14) 30305 return false; 30306 30307 auto cterm_valid_p = [&]() 30308 { 30309 bool leading_zero_p = false; 30310 unsigned i = 0; 30311 char n[3] = {0}; 30312 30313 if (regname[pos] != 'c') 30314 return false; 30315 pos++; 30316 while (regname[pos] != '_') 30317 { 30318 if (leading_zero_p) 30319 return false; 30320 if (i == 0 && regname[pos] == '0') 30321 leading_zero_p = true; 30322 if (i > 2) 30323 return false; 30324 if (!ISDIGIT (regname[pos])) 30325 return false; 30326 n[i++] = regname[pos++]; 30327 } 30328 if (atoi (n) > 15) 30329 return false; 30330 return true; 30331 }; 30332 30333 if (regname[pos] != 's') 30334 return false; 30335 pos++; 30336 if (regname[pos] < '0' || regname[pos] > '3') 30337 return false; 30338 pos++; 30339 if (regname[pos++] != '_') 30340 return false; 30341 if (regname[pos] < '0' || regname[pos] > '7') 30342 return false; 30343 pos++; 30344 if (regname[pos++] != '_') 30345 return false; 30346 if (!cterm_valid_p ()) 30347 return false; 30348 if (regname[pos++] != '_') 30349 return false; 30350 if (!cterm_valid_p ()) 30351 return false; 30352 if (regname[pos++] != '_') 30353 return false; 30354 if (regname[pos] < '0' || regname[pos] > '7') 30355 return false; 30356 return true; 30357 } 30358 30359 /* Return true if REGNAME matches either a known permitted system 30360 register name, or a generic sysreg specification. For use in 30361 back-end predicate `aarch64_sysreg_string'. */ 30362 bool 30363 aarch64_valid_sysreg_name_p (const char *regname) 30364 { 30365 const sysreg_t *sysreg = aarch64_lookup_sysreg_map (regname); 30366 if (sysreg == NULL) 30367 return aarch64_is_implem_def_reg (regname); 30368 return true; 30369 } 30370 30371 /* Return the generic sysreg specification for a valid system register 30372 name, otherwise NULL. WRITE_P is true iff the register is being 30373 written to. IS128OP indicates the requested system register should 30374 be checked for a 128-bit implementation. */ 30375 const char * 30376 aarch64_retrieve_sysreg (const char *regname, bool write_p, bool is128op) 30377 { 30378 const sysreg_t *sysreg = aarch64_lookup_sysreg_map (regname); 30379 if (sysreg == NULL) 30380 { 30381 if (aarch64_is_implem_def_reg (regname)) 30382 return regname; 30383 else 30384 return NULL; 30385 } 30386 if (is128op && !(sysreg->properties & F_REG_128)) 30387 return NULL; 30388 if ((write_p && (sysreg->properties & F_REG_READ)) 30389 || (!write_p && (sysreg->properties & F_REG_WRITE))) 30390 return NULL; 30391 return sysreg->encoding; 30392 } 30393 30394 /* Target-specific selftests. */ 30395 30396 #if CHECKING_P 30397 30398 namespace selftest { 30399 30400 /* Selftest for the RTL loader. 30401 Verify that the RTL loader copes with a dump from 30402 print_rtx_function. This is essentially just a test that class 30403 function_reader can handle a real dump, but it also verifies 30404 that lookup_reg_by_dump_name correctly handles hard regs. 30405 The presence of hard reg names in the dump means that the test is 30406 target-specific, hence it is in this file. */ 30407 30408 static void 30409 aarch64_test_loading_full_dump () 30410 { 30411 rtl_dump_test t (SELFTEST_LOCATION, locate_file ("aarch64/times-two.rtl")); 30412 30413 ASSERT_STREQ ("times_two", IDENTIFIER_POINTER (DECL_NAME (cfun->decl))); 30414 30415 rtx_insn *insn_1 = get_insn_by_uid (1); 30416 ASSERT_EQ (NOTE, GET_CODE (insn_1)); 30417 30418 rtx_insn *insn_15 = get_insn_by_uid (15); 30419 ASSERT_EQ (INSN, GET_CODE (insn_15)); 30420 ASSERT_EQ (USE, GET_CODE (PATTERN (insn_15))); 30421 30422 /* Verify crtl->return_rtx. */ 30423 ASSERT_EQ (REG, GET_CODE (crtl->return_rtx)); 30424 ASSERT_EQ (0, REGNO (crtl->return_rtx)); 30425 ASSERT_EQ (SImode, GET_MODE (crtl->return_rtx)); 30426 } 30427 30428 /* Test the fractional_cost class. */ 30429 30430 static void 30431 aarch64_test_fractional_cost () 30432 { 30433 using cf = fractional_cost; 30434 30435 ASSERT_EQ (cf (0, 20), 0); 30436 30437 ASSERT_EQ (cf (4, 2), 2); 30438 ASSERT_EQ (3, cf (9, 3)); 30439 30440 ASSERT_NE (cf (5, 2), 2); 30441 ASSERT_NE (3, cf (8, 3)); 30442 30443 ASSERT_EQ (cf (7, 11) + cf (15, 11), 2); 30444 ASSERT_EQ (cf (2, 3) + cf (3, 5), cf (19, 15)); 30445 ASSERT_EQ (cf (2, 3) + cf (1, 6) + cf (1, 6), 1); 30446 30447 ASSERT_EQ (cf (14, 15) - cf (4, 15), cf (2, 3)); 30448 ASSERT_EQ (cf (1, 4) - cf (1, 2), 0); 30449 ASSERT_EQ (cf (3, 5) - cf (1, 10), cf (1, 2)); 30450 ASSERT_EQ (cf (11, 3) - 3, cf (2, 3)); 30451 ASSERT_EQ (3 - cf (7, 3), cf (2, 3)); 30452 ASSERT_EQ (3 - cf (10, 3), 0); 30453 30454 ASSERT_EQ (cf (2, 3) * 5, cf (10, 3)); 30455 ASSERT_EQ (14 * cf (11, 21), cf (22, 3)); 30456 30457 ASSERT_TRUE (cf (4, 15) <= cf (5, 15)); 30458 ASSERT_TRUE (cf (5, 15) <= cf (5, 15)); 30459 ASSERT_FALSE (cf (6, 15) <= cf (5, 15)); 30460 ASSERT_TRUE (cf (1, 3) <= cf (2, 5)); 30461 ASSERT_TRUE (cf (1, 12) <= cf (1, 6)); 30462 ASSERT_TRUE (cf (5, 3) <= cf (5, 3)); 30463 ASSERT_TRUE (cf (239, 240) <= 1); 30464 ASSERT_TRUE (cf (240, 240) <= 1); 30465 ASSERT_FALSE (cf (241, 240) <= 1); 30466 ASSERT_FALSE (2 <= cf (207, 104)); 30467 ASSERT_TRUE (2 <= cf (208, 104)); 30468 ASSERT_TRUE (2 <= cf (209, 104)); 30469 30470 ASSERT_TRUE (cf (4, 15) < cf (5, 15)); 30471 ASSERT_FALSE (cf (5, 15) < cf (5, 15)); 30472 ASSERT_FALSE (cf (6, 15) < cf (5, 15)); 30473 ASSERT_TRUE (cf (1, 3) < cf (2, 5)); 30474 ASSERT_TRUE (cf (1, 12) < cf (1, 6)); 30475 ASSERT_FALSE (cf (5, 3) < cf (5, 3)); 30476 ASSERT_TRUE (cf (239, 240) < 1); 30477 ASSERT_FALSE (cf (240, 240) < 1); 30478 ASSERT_FALSE (cf (241, 240) < 1); 30479 ASSERT_FALSE (2 < cf (207, 104)); 30480 ASSERT_FALSE (2 < cf (208, 104)); 30481 ASSERT_TRUE (2 < cf (209, 104)); 30482 30483 ASSERT_FALSE (cf (4, 15) >= cf (5, 15)); 30484 ASSERT_TRUE (cf (5, 15) >= cf (5, 15)); 30485 ASSERT_TRUE (cf (6, 15) >= cf (5, 15)); 30486 ASSERT_FALSE (cf (1, 3) >= cf (2, 5)); 30487 ASSERT_FALSE (cf (1, 12) >= cf (1, 6)); 30488 ASSERT_TRUE (cf (5, 3) >= cf (5, 3)); 30489 ASSERT_FALSE (cf (239, 240) >= 1); 30490 ASSERT_TRUE (cf (240, 240) >= 1); 30491 ASSERT_TRUE (cf (241, 240) >= 1); 30492 ASSERT_TRUE (2 >= cf (207, 104)); 30493 ASSERT_TRUE (2 >= cf (208, 104)); 30494 ASSERT_FALSE (2 >= cf (209, 104)); 30495 30496 ASSERT_FALSE (cf (4, 15) > cf (5, 15)); 30497 ASSERT_FALSE (cf (5, 15) > cf (5, 15)); 30498 ASSERT_TRUE (cf (6, 15) > cf (5, 15)); 30499 ASSERT_FALSE (cf (1, 3) > cf (2, 5)); 30500 ASSERT_FALSE (cf (1, 12) > cf (1, 6)); 30501 ASSERT_FALSE (cf (5, 3) > cf (5, 3)); 30502 ASSERT_FALSE (cf (239, 240) > 1); 30503 ASSERT_FALSE (cf (240, 240) > 1); 30504 ASSERT_TRUE (cf (241, 240) > 1); 30505 ASSERT_TRUE (2 > cf (207, 104)); 30506 ASSERT_FALSE (2 > cf (208, 104)); 30507 ASSERT_FALSE (2 > cf (209, 104)); 30508 30509 ASSERT_EQ (cf (1, 2).ceil (), 1); 30510 ASSERT_EQ (cf (11, 7).ceil (), 2); 30511 ASSERT_EQ (cf (20, 1).ceil (), 20); 30512 ASSERT_EQ ((cf (0xfffffffd) + 1).ceil (), 0xfffffffe); 30513 ASSERT_EQ ((cf (0xfffffffd) + 2).ceil (), 0xffffffff); 30514 ASSERT_EQ ((cf (0xfffffffd) + 3).ceil (), 0xffffffff); 30515 ASSERT_EQ ((cf (0x7fffffff) * 2).ceil (), 0xfffffffe); 30516 ASSERT_EQ ((cf (0x80000000) * 2).ceil (), 0xffffffff); 30517 30518 ASSERT_EQ (cf (1, 2).as_double (), 0.5); 30519 } 30520 30521 /* Calculate whether our system register data, as imported from 30522 `aarch64-sys-reg.def' has any duplicate entries. */ 30523 static void 30524 aarch64_test_sysreg_encoding_clashes (void) 30525 { 30526 using dup_instances_t = hash_map<nofree_string_hash, 30527 std::vector<const sysreg_t*>>; 30528 30529 dup_instances_t duplicate_instances; 30530 30531 /* Every time an encoding is established to come up more than once 30532 we add it to a "clash-analysis queue", which is then used to extract 30533 necessary information from our hash map when establishing whether 30534 repeated encodings are valid. */ 30535 30536 /* 1) Collect recurrence information. */ 30537 for (unsigned i = 0; i < ARRAY_SIZE (aarch64_sysregs); i++) 30538 { 30539 const sysreg_t *reg = aarch64_sysregs + i; 30540 30541 std::vector<const sysreg_t*> *tmp 30542 = &duplicate_instances.get_or_insert (reg->encoding); 30543 30544 tmp->push_back (reg); 30545 } 30546 30547 /* 2) Carry out analysis on collected data. */ 30548 for (auto instance : duplicate_instances) 30549 { 30550 unsigned nrep = instance.second.size (); 30551 if (nrep > 1) 30552 for (unsigned i = 0; i < nrep; i++) 30553 for (unsigned j = i + 1; j < nrep; j++) 30554 { 30555 const sysreg_t *a = instance.second[i]; 30556 const sysreg_t *b = instance.second[j]; 30557 ASSERT_TRUE ((a->properties != b->properties) 30558 || (a->arch_reqs != b->arch_reqs)); 30559 } 30560 } 30561 } 30562 30563 /* Test SVE arithmetic folding. */ 30564 30565 static void 30566 aarch64_test_sve_folding () 30567 { 30568 tree res = fold_unary (BIT_NOT_EXPR, ssizetype, 30569 ssize_int (poly_int64 (1, 1))); 30570 ASSERT_TRUE (operand_equal_p (res, ssize_int (poly_int64 (-2, -1)))); 30571 } 30572 30573 /* Run all target-specific selftests. */ 30574 30575 static void 30576 aarch64_run_selftests (void) 30577 { 30578 aarch64_test_loading_full_dump (); 30579 aarch64_test_fractional_cost (); 30580 aarch64_test_sysreg_encoding_clashes (); 30581 aarch64_test_sve_folding (); 30582 } 30583 30584 } // namespace selftest 30585 30586 #endif /* #if CHECKING_P */ 30587 30588 #undef TARGET_STACK_PROTECT_GUARD 30589 #define TARGET_STACK_PROTECT_GUARD aarch64_stack_protect_guard 30590 30591 #undef TARGET_ADDRESS_COST 30592 #define TARGET_ADDRESS_COST aarch64_address_cost 30593 30594 /* This hook will determines whether unnamed bitfields affect the alignment 30595 of the containing structure. The hook returns true if the structure 30596 should inherit the alignment requirements of an unnamed bitfield's 30597 type. */ 30598 #undef TARGET_ALIGN_ANON_BITFIELD 30599 #define TARGET_ALIGN_ANON_BITFIELD hook_bool_void_true 30600 30601 #undef TARGET_ASM_ALIGNED_DI_OP 30602 #define TARGET_ASM_ALIGNED_DI_OP "\t.xword\t" 30603 30604 #undef TARGET_ASM_ALIGNED_HI_OP 30605 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t" 30606 30607 #undef TARGET_ASM_ALIGNED_SI_OP 30608 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" 30609 30610 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK 30611 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK \ 30612 hook_bool_const_tree_hwi_hwi_const_tree_true 30613 30614 #undef TARGET_ASM_FILE_START 30615 #define TARGET_ASM_FILE_START aarch64_start_file 30616 30617 #undef TARGET_ASM_OUTPUT_MI_THUNK 30618 #define TARGET_ASM_OUTPUT_MI_THUNK aarch64_output_mi_thunk 30619 30620 #undef TARGET_ASM_SELECT_RTX_SECTION 30621 #define TARGET_ASM_SELECT_RTX_SECTION aarch64_select_rtx_section 30622 30623 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE 30624 #define TARGET_ASM_TRAMPOLINE_TEMPLATE aarch64_asm_trampoline_template 30625 30626 #undef TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY 30627 #define TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY aarch64_print_patchable_function_entry 30628 30629 #undef TARGET_BUILD_BUILTIN_VA_LIST 30630 #define TARGET_BUILD_BUILTIN_VA_LIST aarch64_build_builtin_va_list 30631 30632 #undef TARGET_CALLEE_COPIES 30633 #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_arg_info_false 30634 30635 #undef TARGET_FRAME_POINTER_REQUIRED 30636 #define TARGET_FRAME_POINTER_REQUIRED aarch64_frame_pointer_required 30637 30638 #undef TARGET_CAN_ELIMINATE 30639 #define TARGET_CAN_ELIMINATE aarch64_can_eliminate 30640 30641 #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P 30642 #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P \ 30643 aarch64_function_attribute_inlinable_p 30644 30645 #undef TARGET_NEED_IPA_FN_TARGET_INFO 30646 #define TARGET_NEED_IPA_FN_TARGET_INFO aarch64_need_ipa_fn_target_info 30647 30648 #undef TARGET_UPDATE_IPA_FN_TARGET_INFO 30649 #define TARGET_UPDATE_IPA_FN_TARGET_INFO aarch64_update_ipa_fn_target_info 30650 30651 #undef TARGET_CAN_INLINE_P 30652 #define TARGET_CAN_INLINE_P aarch64_can_inline_p 30653 30654 #undef TARGET_CANNOT_FORCE_CONST_MEM 30655 #define TARGET_CANNOT_FORCE_CONST_MEM aarch64_cannot_force_const_mem 30656 30657 #undef TARGET_CASE_VALUES_THRESHOLD 30658 #define TARGET_CASE_VALUES_THRESHOLD aarch64_case_values_threshold 30659 30660 #undef TARGET_CONDITIONAL_REGISTER_USAGE 30661 #define TARGET_CONDITIONAL_REGISTER_USAGE aarch64_conditional_register_usage 30662 30663 #undef TARGET_MEMBER_TYPE_FORCES_BLK 30664 #define TARGET_MEMBER_TYPE_FORCES_BLK aarch64_member_type_forces_blk 30665 30666 /* Only the least significant bit is used for initialization guard 30667 variables. */ 30668 #undef TARGET_CXX_GUARD_MASK_BIT 30669 #define TARGET_CXX_GUARD_MASK_BIT hook_bool_void_true 30670 30671 #undef TARGET_C_MODE_FOR_SUFFIX 30672 #define TARGET_C_MODE_FOR_SUFFIX aarch64_c_mode_for_suffix 30673 30674 #ifdef TARGET_BIG_ENDIAN_DEFAULT 30675 #undef TARGET_DEFAULT_TARGET_FLAGS 30676 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_END) 30677 #endif 30678 30679 #undef TARGET_CLASS_MAX_NREGS 30680 #define TARGET_CLASS_MAX_NREGS aarch64_class_max_nregs 30681 30682 #undef TARGET_BUILTIN_DECL 30683 #define TARGET_BUILTIN_DECL aarch64_builtin_decl 30684 30685 #undef TARGET_BUILTIN_RECIPROCAL 30686 #define TARGET_BUILTIN_RECIPROCAL aarch64_builtin_reciprocal 30687 30688 #undef TARGET_C_EXCESS_PRECISION 30689 #define TARGET_C_EXCESS_PRECISION aarch64_excess_precision 30690 30691 #undef TARGET_C_BITINT_TYPE_INFO 30692 #define TARGET_C_BITINT_TYPE_INFO aarch64_bitint_type_info 30693 30694 #undef TARGET_EXPAND_BUILTIN 30695 #define TARGET_EXPAND_BUILTIN aarch64_expand_builtin 30696 30697 #undef TARGET_EXPAND_BUILTIN_VA_START 30698 #define TARGET_EXPAND_BUILTIN_VA_START aarch64_expand_builtin_va_start 30699 30700 #undef TARGET_FOLD_BUILTIN 30701 #define TARGET_FOLD_BUILTIN aarch64_fold_builtin 30702 30703 #undef TARGET_FUNCTION_ARG 30704 #define TARGET_FUNCTION_ARG aarch64_function_arg 30705 30706 #undef TARGET_FUNCTION_ARG_ADVANCE 30707 #define TARGET_FUNCTION_ARG_ADVANCE aarch64_function_arg_advance 30708 30709 #undef TARGET_FUNCTION_ARG_BOUNDARY 30710 #define TARGET_FUNCTION_ARG_BOUNDARY aarch64_function_arg_boundary 30711 30712 #undef TARGET_FUNCTION_ARG_PADDING 30713 #define TARGET_FUNCTION_ARG_PADDING aarch64_function_arg_padding 30714 30715 #undef TARGET_GET_RAW_RESULT_MODE 30716 #define TARGET_GET_RAW_RESULT_MODE aarch64_get_reg_raw_mode 30717 #undef TARGET_GET_RAW_ARG_MODE 30718 #define TARGET_GET_RAW_ARG_MODE aarch64_get_reg_raw_mode 30719 30720 #undef TARGET_FUNCTION_OK_FOR_SIBCALL 30721 #define TARGET_FUNCTION_OK_FOR_SIBCALL aarch64_function_ok_for_sibcall 30722 30723 #undef TARGET_FUNCTION_VALUE 30724 #define TARGET_FUNCTION_VALUE aarch64_function_value 30725 30726 #undef TARGET_FUNCTION_VALUE_REGNO_P 30727 #define TARGET_FUNCTION_VALUE_REGNO_P aarch64_function_value_regno_p 30728 30729 #undef TARGET_START_CALL_ARGS 30730 #define TARGET_START_CALL_ARGS aarch64_start_call_args 30731 30732 #undef TARGET_END_CALL_ARGS 30733 #define TARGET_END_CALL_ARGS aarch64_end_call_args 30734 30735 #undef TARGET_GIMPLE_FOLD_BUILTIN 30736 #define TARGET_GIMPLE_FOLD_BUILTIN aarch64_gimple_fold_builtin 30737 30738 #undef TARGET_GIMPLIFY_VA_ARG_EXPR 30739 #define TARGET_GIMPLIFY_VA_ARG_EXPR aarch64_gimplify_va_arg_expr 30740 30741 #undef TARGET_INIT_BUILTINS 30742 #define TARGET_INIT_BUILTINS aarch64_init_builtins 30743 30744 #undef TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS 30745 #define TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS \ 30746 aarch64_ira_change_pseudo_allocno_class 30747 30748 #undef TARGET_LEGITIMATE_ADDRESS_P 30749 #define TARGET_LEGITIMATE_ADDRESS_P aarch64_legitimate_address_hook_p 30750 30751 #undef TARGET_LEGITIMATE_CONSTANT_P 30752 #define TARGET_LEGITIMATE_CONSTANT_P aarch64_legitimate_constant_p 30753 30754 #undef TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT 30755 #define TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT \ 30756 aarch64_legitimize_address_displacement 30757 30758 #undef TARGET_LIBGCC_CMP_RETURN_MODE 30759 #define TARGET_LIBGCC_CMP_RETURN_MODE aarch64_libgcc_cmp_return_mode 30760 30761 #undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P 30762 #define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \ 30763 aarch64_libgcc_floating_mode_supported_p 30764 30765 #undef TARGET_MANGLE_TYPE 30766 #define TARGET_MANGLE_TYPE aarch64_mangle_type 30767 30768 #undef TARGET_INVALID_BINARY_OP 30769 #define TARGET_INVALID_BINARY_OP aarch64_invalid_binary_op 30770 30771 #undef TARGET_VERIFY_TYPE_CONTEXT 30772 #define TARGET_VERIFY_TYPE_CONTEXT aarch64_verify_type_context 30773 30774 #undef TARGET_MEMORY_MOVE_COST 30775 #define TARGET_MEMORY_MOVE_COST aarch64_memory_move_cost 30776 30777 #undef TARGET_MIN_DIVISIONS_FOR_RECIP_MUL 30778 #define TARGET_MIN_DIVISIONS_FOR_RECIP_MUL aarch64_min_divisions_for_recip_mul 30779 30780 #undef TARGET_MUST_PASS_IN_STACK 30781 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size 30782 30783 /* This target hook should return true if accesses to volatile bitfields 30784 should use the narrowest mode possible. It should return false if these 30785 accesses should use the bitfield container type. */ 30786 #undef TARGET_NARROW_VOLATILE_BITFIELD 30787 #define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false 30788 30789 #undef TARGET_OPTION_OVERRIDE 30790 #define TARGET_OPTION_OVERRIDE aarch64_override_options 30791 30792 #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE 30793 #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE \ 30794 aarch64_override_options_after_change 30795 30796 #undef TARGET_OFFLOAD_OPTIONS 30797 #define TARGET_OFFLOAD_OPTIONS aarch64_offload_options 30798 30799 #undef TARGET_OPTION_RESTORE 30800 #define TARGET_OPTION_RESTORE aarch64_option_restore 30801 30802 #undef TARGET_OPTION_PRINT 30803 #define TARGET_OPTION_PRINT aarch64_option_print 30804 30805 #undef TARGET_OPTION_VALID_ATTRIBUTE_P 30806 #define TARGET_OPTION_VALID_ATTRIBUTE_P aarch64_option_valid_attribute_p 30807 30808 #undef TARGET_OPTION_VALID_VERSION_ATTRIBUTE_P 30809 #define TARGET_OPTION_VALID_VERSION_ATTRIBUTE_P \ 30810 aarch64_option_valid_version_attribute_p 30811 30812 #undef TARGET_SET_CURRENT_FUNCTION 30813 #define TARGET_SET_CURRENT_FUNCTION aarch64_set_current_function 30814 30815 #undef TARGET_PASS_BY_REFERENCE 30816 #define TARGET_PASS_BY_REFERENCE aarch64_pass_by_reference 30817 30818 #undef TARGET_PREFERRED_RELOAD_CLASS 30819 #define TARGET_PREFERRED_RELOAD_CLASS aarch64_preferred_reload_class 30820 30821 #undef TARGET_SCHED_REASSOCIATION_WIDTH 30822 #define TARGET_SCHED_REASSOCIATION_WIDTH aarch64_reassociation_width 30823 30824 #undef TARGET_DWARF_FRAME_REG_MODE 30825 #define TARGET_DWARF_FRAME_REG_MODE aarch64_dwarf_frame_reg_mode 30826 30827 #undef TARGET_PROMOTED_TYPE 30828 #define TARGET_PROMOTED_TYPE aarch64_promoted_type 30829 30830 #undef TARGET_SECONDARY_RELOAD 30831 #define TARGET_SECONDARY_RELOAD aarch64_secondary_reload 30832 30833 #undef TARGET_SECONDARY_MEMORY_NEEDED 30834 #define TARGET_SECONDARY_MEMORY_NEEDED aarch64_secondary_memory_needed 30835 30836 #undef TARGET_SHIFT_TRUNCATION_MASK 30837 #define TARGET_SHIFT_TRUNCATION_MASK aarch64_shift_truncation_mask 30838 30839 #undef TARGET_SETUP_INCOMING_VARARGS 30840 #define TARGET_SETUP_INCOMING_VARARGS aarch64_setup_incoming_varargs 30841 30842 #undef TARGET_STRUCT_VALUE_RTX 30843 #define TARGET_STRUCT_VALUE_RTX aarch64_struct_value_rtx 30844 30845 #undef TARGET_REGISTER_MOVE_COST 30846 #define TARGET_REGISTER_MOVE_COST aarch64_register_move_cost 30847 30848 #undef TARGET_RETURN_IN_MEMORY 30849 #define TARGET_RETURN_IN_MEMORY aarch64_return_in_memory 30850 30851 #undef TARGET_RETURN_IN_MSB 30852 #define TARGET_RETURN_IN_MSB aarch64_return_in_msb 30853 30854 #undef TARGET_RTX_COSTS 30855 #define TARGET_RTX_COSTS aarch64_rtx_costs_wrapper 30856 30857 #undef TARGET_INSN_COST 30858 #define TARGET_INSN_COST aarch64_insn_cost 30859 30860 #undef TARGET_SCALAR_MODE_SUPPORTED_P 30861 #define TARGET_SCALAR_MODE_SUPPORTED_P aarch64_scalar_mode_supported_p 30862 30863 #undef TARGET_SCHED_ISSUE_RATE 30864 #define TARGET_SCHED_ISSUE_RATE aarch64_sched_issue_rate 30865 30866 #undef TARGET_SCHED_VARIABLE_ISSUE 30867 #define TARGET_SCHED_VARIABLE_ISSUE aarch64_sched_variable_issue 30868 30869 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD 30870 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \ 30871 aarch64_sched_first_cycle_multipass_dfa_lookahead 30872 30873 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD 30874 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD \ 30875 aarch64_first_cycle_multipass_dfa_lookahead_guard 30876 30877 #undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS 30878 #define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS \ 30879 aarch64_get_separate_components 30880 30881 #undef TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB 30882 #define TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB \ 30883 aarch64_components_for_bb 30884 30885 #undef TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS 30886 #define TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS \ 30887 aarch64_disqualify_components 30888 30889 #undef TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS 30890 #define TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS \ 30891 aarch64_emit_prologue_components 30892 30893 #undef TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS 30894 #define TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS \ 30895 aarch64_emit_epilogue_components 30896 30897 #undef TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS 30898 #define TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS \ 30899 aarch64_set_handled_components 30900 30901 #undef TARGET_TRAMPOLINE_INIT 30902 #define TARGET_TRAMPOLINE_INIT aarch64_trampoline_init 30903 30904 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P 30905 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P aarch64_use_blocks_for_constant_p 30906 30907 #undef TARGET_VECTOR_MODE_SUPPORTED_P 30908 #define TARGET_VECTOR_MODE_SUPPORTED_P aarch64_vector_mode_supported_p 30909 30910 #undef TARGET_VECTOR_MODE_SUPPORTED_ANY_TARGET_P 30911 #define TARGET_VECTOR_MODE_SUPPORTED_ANY_TARGET_P aarch64_vector_mode_supported_any_target_p 30912 30913 #undef TARGET_COMPATIBLE_VECTOR_TYPES_P 30914 #define TARGET_COMPATIBLE_VECTOR_TYPES_P aarch64_compatible_vector_types_p 30915 30916 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT 30917 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \ 30918 aarch64_builtin_support_vector_misalignment 30919 30920 #undef TARGET_ARRAY_MODE 30921 #define TARGET_ARRAY_MODE aarch64_array_mode 30922 30923 #undef TARGET_ARRAY_MODE_SUPPORTED_P 30924 #define TARGET_ARRAY_MODE_SUPPORTED_P aarch64_array_mode_supported_p 30925 30926 #undef TARGET_VECTORIZE_CREATE_COSTS 30927 #define TARGET_VECTORIZE_CREATE_COSTS aarch64_vectorize_create_costs 30928 30929 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST 30930 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \ 30931 aarch64_builtin_vectorization_cost 30932 30933 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE 30934 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE aarch64_preferred_simd_mode 30935 30936 #undef TARGET_VECTORIZE_BUILTINS 30937 #define TARGET_VECTORIZE_BUILTINS 30938 30939 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES 30940 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES \ 30941 aarch64_autovectorize_vector_modes 30942 30943 #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV 30944 #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV \ 30945 aarch64_atomic_assign_expand_fenv 30946 30947 /* Section anchor support. */ 30948 30949 #undef TARGET_MIN_ANCHOR_OFFSET 30950 #define TARGET_MIN_ANCHOR_OFFSET -256 30951 30952 /* Limit the maximum anchor offset to 4k-1, since that's the limit for a 30953 byte offset; we can do much more for larger data types, but have no way 30954 to determine the size of the access. We assume accesses are aligned. */ 30955 #undef TARGET_MAX_ANCHOR_OFFSET 30956 #define TARGET_MAX_ANCHOR_OFFSET 4095 30957 30958 #undef TARGET_VECTORIZE_PREFERRED_DIV_AS_SHIFTS_OVER_MULT 30959 #define TARGET_VECTORIZE_PREFERRED_DIV_AS_SHIFTS_OVER_MULT \ 30960 aarch64_vectorize_preferred_div_as_shifts_over_mult 30961 30962 #undef TARGET_VECTOR_ALIGNMENT 30963 #define TARGET_VECTOR_ALIGNMENT aarch64_simd_vector_alignment 30964 30965 #undef TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT 30966 #define TARGET_VECTORIZE_PREFERRED_VECTOR_ALIGNMENT \ 30967 aarch64_vectorize_preferred_vector_alignment 30968 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE 30969 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE \ 30970 aarch64_simd_vector_alignment_reachable 30971 30972 /* vec_perm support. */ 30973 30974 #undef TARGET_VECTORIZE_VEC_PERM_CONST 30975 #define TARGET_VECTORIZE_VEC_PERM_CONST \ 30976 aarch64_vectorize_vec_perm_const 30977 30978 #undef TARGET_VECTORIZE_RELATED_MODE 30979 #define TARGET_VECTORIZE_RELATED_MODE aarch64_vectorize_related_mode 30980 #undef TARGET_VECTORIZE_GET_MASK_MODE 30981 #define TARGET_VECTORIZE_GET_MASK_MODE aarch64_get_mask_mode 30982 #undef TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE 30983 #define TARGET_VECTORIZE_EMPTY_MASK_IS_EXPENSIVE \ 30984 aarch64_empty_mask_is_expensive 30985 #undef TARGET_PREFERRED_ELSE_VALUE 30986 #define TARGET_PREFERRED_ELSE_VALUE \ 30987 aarch64_preferred_else_value 30988 30989 #undef TARGET_INIT_LIBFUNCS 30990 #define TARGET_INIT_LIBFUNCS aarch64_init_libfuncs 30991 30992 #undef TARGET_FIXED_CONDITION_CODE_REGS 30993 #define TARGET_FIXED_CONDITION_CODE_REGS aarch64_fixed_condition_code_regs 30994 30995 #undef TARGET_FLAGS_REGNUM 30996 #define TARGET_FLAGS_REGNUM CC_REGNUM 30997 30998 #undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS 30999 #define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true 31000 31001 #undef TARGET_ASAN_SHADOW_OFFSET 31002 #define TARGET_ASAN_SHADOW_OFFSET aarch64_asan_shadow_offset 31003 31004 #undef TARGET_LEGITIMIZE_ADDRESS 31005 #define TARGET_LEGITIMIZE_ADDRESS aarch64_legitimize_address 31006 31007 #undef TARGET_SCHED_CAN_SPECULATE_INSN 31008 #define TARGET_SCHED_CAN_SPECULATE_INSN aarch64_sched_can_speculate_insn 31009 31010 #undef TARGET_CAN_USE_DOLOOP_P 31011 #define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost 31012 31013 #undef TARGET_SCHED_ADJUST_PRIORITY 31014 #define TARGET_SCHED_ADJUST_PRIORITY aarch64_sched_adjust_priority 31015 31016 #undef TARGET_SCHED_MACRO_FUSION_P 31017 #define TARGET_SCHED_MACRO_FUSION_P aarch64_macro_fusion_p 31018 31019 #undef TARGET_SCHED_MACRO_FUSION_PAIR_P 31020 #define TARGET_SCHED_MACRO_FUSION_PAIR_P aarch_macro_fusion_pair_p 31021 31022 #undef TARGET_SCHED_FUSION_PRIORITY 31023 #define TARGET_SCHED_FUSION_PRIORITY aarch64_sched_fusion_priority 31024 31025 #undef TARGET_UNSPEC_MAY_TRAP_P 31026 #define TARGET_UNSPEC_MAY_TRAP_P aarch64_unspec_may_trap_p 31027 31028 #undef TARGET_USE_PSEUDO_PIC_REG 31029 #define TARGET_USE_PSEUDO_PIC_REG aarch64_use_pseudo_pic_reg 31030 31031 #undef TARGET_PRINT_OPERAND 31032 #define TARGET_PRINT_OPERAND aarch64_print_operand 31033 31034 #undef TARGET_PRINT_OPERAND_ADDRESS 31035 #define TARGET_PRINT_OPERAND_ADDRESS aarch64_print_operand_address 31036 31037 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA 31038 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA aarch64_output_addr_const_extra 31039 31040 #undef TARGET_OPTAB_SUPPORTED_P 31041 #define TARGET_OPTAB_SUPPORTED_P aarch64_optab_supported_p 31042 31043 #undef TARGET_OMIT_STRUCT_RETURN_REG 31044 #define TARGET_OMIT_STRUCT_RETURN_REG true 31045 31046 #undef TARGET_DWARF_POLY_INDETERMINATE_VALUE 31047 #define TARGET_DWARF_POLY_INDETERMINATE_VALUE \ 31048 aarch64_dwarf_poly_indeterminate_value 31049 31050 /* The architecture reserves bits 0 and 1 so use bit 2 for descriptors. */ 31051 #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS 31052 #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 4 31053 31054 #undef TARGET_HARD_REGNO_NREGS 31055 #define TARGET_HARD_REGNO_NREGS aarch64_hard_regno_nregs 31056 #undef TARGET_HARD_REGNO_MODE_OK 31057 #define TARGET_HARD_REGNO_MODE_OK aarch64_hard_regno_mode_ok 31058 31059 #undef TARGET_MODES_TIEABLE_P 31060 #define TARGET_MODES_TIEABLE_P aarch64_modes_tieable_p 31061 31062 #undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED 31063 #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \ 31064 aarch64_hard_regno_call_part_clobbered 31065 31066 #undef TARGET_INSN_CALLEE_ABI 31067 #define TARGET_INSN_CALLEE_ABI aarch64_insn_callee_abi 31068 31069 #undef TARGET_CONSTANT_ALIGNMENT 31070 #define TARGET_CONSTANT_ALIGNMENT aarch64_constant_alignment 31071 31072 #undef TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE 31073 #define TARGET_STACK_CLASH_PROTECTION_ALLOCA_PROBE_RANGE \ 31074 aarch64_stack_clash_protection_alloca_probe_range 31075 31076 #undef TARGET_COMPUTE_PRESSURE_CLASSES 31077 #define TARGET_COMPUTE_PRESSURE_CLASSES aarch64_compute_pressure_classes 31078 31079 #undef TARGET_CAN_CHANGE_MODE_CLASS 31080 #define TARGET_CAN_CHANGE_MODE_CLASS aarch64_can_change_mode_class 31081 31082 #undef TARGET_SELECT_EARLY_REMAT_MODES 31083 #define TARGET_SELECT_EARLY_REMAT_MODES aarch64_select_early_remat_modes 31084 31085 #undef TARGET_SPECULATION_SAFE_VALUE 31086 #define TARGET_SPECULATION_SAFE_VALUE aarch64_speculation_safe_value 31087 31088 #undef TARGET_ESTIMATED_POLY_VALUE 31089 #define TARGET_ESTIMATED_POLY_VALUE aarch64_estimated_poly_value 31090 31091 #undef TARGET_ATTRIBUTE_TABLE 31092 #define TARGET_ATTRIBUTE_TABLE aarch64_attribute_table 31093 31094 #undef TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN 31095 #define TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN \ 31096 aarch64_simd_clone_compute_vecsize_and_simdlen 31097 31098 #undef TARGET_SIMD_CLONE_ADJUST 31099 #define TARGET_SIMD_CLONE_ADJUST aarch64_simd_clone_adjust 31100 31101 #undef TARGET_SIMD_CLONE_USABLE 31102 #define TARGET_SIMD_CLONE_USABLE aarch64_simd_clone_usable 31103 31104 #undef TARGET_COMP_TYPE_ATTRIBUTES 31105 #define TARGET_COMP_TYPE_ATTRIBUTES aarch64_comp_type_attributes 31106 31107 #undef TARGET_MERGE_DECL_ATTRIBUTES 31108 #define TARGET_MERGE_DECL_ATTRIBUTES aarch64_merge_decl_attributes 31109 31110 #undef TARGET_GET_MULTILIB_ABI_NAME 31111 #define TARGET_GET_MULTILIB_ABI_NAME aarch64_get_multilib_abi_name 31112 31113 #undef TARGET_FNTYPE_ABI 31114 #define TARGET_FNTYPE_ABI aarch64_fntype_abi 31115 31116 #undef TARGET_MEMTAG_CAN_TAG_ADDRESSES 31117 #define TARGET_MEMTAG_CAN_TAG_ADDRESSES aarch64_can_tag_addresses 31118 31119 #if CHECKING_P 31120 #undef TARGET_RUN_TARGET_SELFTESTS 31121 #define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests 31122 #endif /* #if CHECKING_P */ 31123 31124 #undef TARGET_ASM_POST_CFI_STARTPROC 31125 #define TARGET_ASM_POST_CFI_STARTPROC aarch64_post_cfi_startproc 31126 31127 #undef TARGET_STRICT_ARGUMENT_NAMING 31128 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true 31129 31130 #undef TARGET_MODE_EMIT 31131 #define TARGET_MODE_EMIT aarch64_mode_emit 31132 31133 #undef TARGET_MODE_NEEDED 31134 #define TARGET_MODE_NEEDED aarch64_mode_needed 31135 31136 #undef TARGET_MODE_AFTER 31137 #define TARGET_MODE_AFTER aarch64_mode_after 31138 31139 #undef TARGET_MODE_CONFLUENCE 31140 #define TARGET_MODE_CONFLUENCE aarch64_mode_confluence 31141 31142 #undef TARGET_MODE_BACKPROP 31143 #define TARGET_MODE_BACKPROP aarch64_mode_backprop 31144 31145 #undef TARGET_MODE_ENTRY 31146 #define TARGET_MODE_ENTRY aarch64_mode_entry 31147 31148 #undef TARGET_MODE_EXIT 31149 #define TARGET_MODE_EXIT aarch64_mode_exit 31150 31151 #undef TARGET_MODE_EH_HANDLER 31152 #define TARGET_MODE_EH_HANDLER aarch64_mode_eh_handler 31153 31154 #undef TARGET_MODE_PRIORITY 31155 #define TARGET_MODE_PRIORITY aarch64_mode_priority 31156 31157 #undef TARGET_MD_ASM_ADJUST 31158 #define TARGET_MD_ASM_ADJUST aarch64_md_asm_adjust 31159 31160 #undef TARGET_ASM_FILE_END 31161 #define TARGET_ASM_FILE_END aarch64_asm_file_end 31162 31163 #undef TARGET_ASM_FUNCTION_EPILOGUE 31164 #define TARGET_ASM_FUNCTION_EPILOGUE aarch64_sls_emit_blr_function_thunks 31165 31166 #undef TARGET_HAVE_SHADOW_CALL_STACK 31167 #define TARGET_HAVE_SHADOW_CALL_STACK true 31168 31169 #undef TARGET_CONST_ANCHOR 31170 #define TARGET_CONST_ANCHOR 0x1000000 31171 31172 #undef TARGET_EXTRA_LIVE_ON_ENTRY 31173 #define TARGET_EXTRA_LIVE_ON_ENTRY aarch64_extra_live_on_entry 31174 31175 #undef TARGET_USE_LATE_PROLOGUE_EPILOGUE 31176 #define TARGET_USE_LATE_PROLOGUE_EPILOGUE aarch64_use_late_prologue_epilogue 31177 31178 #undef TARGET_EMIT_EPILOGUE_FOR_SIBCALL 31179 #define TARGET_EMIT_EPILOGUE_FOR_SIBCALL aarch64_expand_epilogue 31180 31181 #undef TARGET_OPTION_FUNCTION_VERSIONS 31182 #define TARGET_OPTION_FUNCTION_VERSIONS aarch64_common_function_versions 31183 31184 #undef TARGET_COMPARE_VERSION_PRIORITY 31185 #define TARGET_COMPARE_VERSION_PRIORITY aarch64_compare_version_priority 31186 31187 #undef TARGET_GENERATE_VERSION_DISPATCHER_BODY 31188 #define TARGET_GENERATE_VERSION_DISPATCHER_BODY \ 31189 aarch64_generate_version_dispatcher_body 31190 31191 #undef TARGET_GET_FUNCTION_VERSIONS_DISPATCHER 31192 #define TARGET_GET_FUNCTION_VERSIONS_DISPATCHER \ 31193 aarch64_get_function_versions_dispatcher 31194 31195 #undef TARGET_MANGLE_DECL_ASSEMBLER_NAME 31196 #define TARGET_MANGLE_DECL_ASSEMBLER_NAME aarch64_mangle_decl_assembler_name 31197 31198 struct gcc_target targetm = TARGET_INITIALIZER; 31199 31200 #include "gt-aarch64.h" 31201