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