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