]>
Commit | Line | Data |
---|---|---|
df401d54 | 1 | /* Machine description for AArch64 architecture. |
fbd26352 | 2 | Copyright (C) 2009-2019 Free Software Foundation, Inc. |
df401d54 | 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 | ||
aadb8e17 | 25 | #include "input.h" |
26 | ||
df401d54 | 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 | |
33 | ||
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] | |
37 | or | |
38 | str x1, [x0, :lo12:foo] | |
39 | ||
40 | This corresponds to the small code model of the compiler. | |
41 | ||
41754803 | 42 | SYMBOL_SMALL_GOT_4G: Similar to the one above but this |
df401d54 | 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 | |
41754803 | 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. | |
df401d54 | 49 | |
50 | adrp x0, :got:foo | |
51 | ldr x0, [x0, :gotoff_lo12:foo] | |
52 | ||
53 | This corresponds to the small PIC model of the compiler. | |
54 | ||
65f988f7 | 55 | SYMBOL_SMALL_GOT_28K: Similar to SYMBOL_SMALL_GOT_4G, but used for symbol |
56 | restricted within 28K GOT table size. | |
57 | ||
58 | ldr reg, [gp, #:gotpage_lo15:sym] | |
59 | ||
60 | This corresponds to -fpic model for small memory model of the compiler. | |
61 | ||
df401d54 | 62 | SYMBOL_SMALL_TLSGD |
63 | SYMBOL_SMALL_TLSDESC | |
7bff97c2 | 64 | SYMBOL_SMALL_TLSIE |
f546e2d1 | 65 | SYMBOL_TINY_TLSIE |
57507fa5 | 66 | SYMBOL_TLSLE12 |
950cf06f | 67 | SYMBOL_TLSLE24 |
57507fa5 | 68 | SYMBOL_TLSLE32 |
69 | SYMBOL_TLSLE48 | |
47ae02b7 | 70 | Each of these represents a thread-local symbol, and corresponds to the |
df401d54 | 71 | thread local storage relocation operator for the symbol being referred to. |
72 | ||
586bb065 | 73 | SYMBOL_TINY_ABSOLUTE |
74 | ||
75 | Generate symbol accesses as a PC relative address using a single | |
76 | instruction. To compute the address of symbol foo, we generate: | |
77 | ||
78 | ADR x0, foo | |
79 | ||
2c97ec73 | 80 | SYMBOL_TINY_GOT |
81 | ||
82 | Generate symbol accesses via the GOT using a single PC relative | |
83 | instruction. To compute the address of symbol foo, we generate: | |
84 | ||
85 | ldr t0, :got:foo | |
86 | ||
87 | The value of foo can subsequently read using: | |
88 | ||
89 | ldrb t0, [t0] | |
90 | ||
df401d54 | 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. | |
95 | */ | |
96 | enum aarch64_symbol_type | |
97 | { | |
98 | SYMBOL_SMALL_ABSOLUTE, | |
65f988f7 | 99 | SYMBOL_SMALL_GOT_28K, |
41754803 | 100 | SYMBOL_SMALL_GOT_4G, |
df401d54 | 101 | SYMBOL_SMALL_TLSGD, |
102 | SYMBOL_SMALL_TLSDESC, | |
7bff97c2 | 103 | SYMBOL_SMALL_TLSIE, |
5137d3cb | 104 | SYMBOL_TINY_ABSOLUTE, |
2c97ec73 | 105 | SYMBOL_TINY_GOT, |
f546e2d1 | 106 | SYMBOL_TINY_TLSIE, |
57507fa5 | 107 | SYMBOL_TLSLE12, |
950cf06f | 108 | SYMBOL_TLSLE24, |
57507fa5 | 109 | SYMBOL_TLSLE32, |
110 | SYMBOL_TLSLE48, | |
df401d54 | 111 | SYMBOL_FORCE_TO_MEM |
112 | }; | |
113 | ||
f9e58550 | 114 | /* Classifies the type of an address query. |
115 | ||
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). | |
119 | ||
120 | ADDR_QUERY_LDP_STP | |
8fa7f434 | 121 | Query what is valid for a load/store pair. |
122 | ||
813c397b | 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. | |
126 | ||
8fa7f434 | 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. */ | |
f9e58550 | 132 | enum aarch64_addr_query_type { |
133 | ADDR_QUERY_M, | |
8fa7f434 | 134 | ADDR_QUERY_LDP_STP, |
813c397b | 135 | ADDR_QUERY_LDP_STP_N, |
8fa7f434 | 136 | ADDR_QUERY_ANY |
f9e58550 | 137 | }; |
138 | ||
df401d54 | 139 | /* A set of tuning parameters contains references to size and time |
140 | cost models and vectors for address cost calculations, register | |
141 | move costs and memory move costs. */ | |
142 | ||
3d70178f | 143 | /* Scaled addressing modes can vary cost depending on the mode of the |
144 | value to be loaded/stored. QImode values cannot use scaled | |
145 | addressing modes. */ | |
146 | ||
147 | struct scale_addr_mode_cost | |
148 | { | |
149 | const int hi; | |
150 | const int si; | |
151 | const int di; | |
152 | const int ti; | |
153 | }; | |
154 | ||
df401d54 | 155 | /* Additional cost for addresses. */ |
156 | struct cpu_addrcost_table | |
157 | { | |
3d70178f | 158 | const struct scale_addr_mode_cost addr_scale_costs; |
df401d54 | 159 | const int pre_modify; |
160 | const int post_modify; | |
161 | const int register_offset; | |
85258792 | 162 | const int register_sextend; |
163 | const int register_zextend; | |
df401d54 | 164 | const int imm_offset; |
165 | }; | |
166 | ||
167 | /* Additional costs for register copies. Cost is for one register. */ | |
168 | struct cpu_regmove_cost | |
169 | { | |
170 | const int GP2GP; | |
171 | const int GP2FP; | |
172 | const int FP2GP; | |
173 | const int FP2FP; | |
174 | }; | |
175 | ||
61d9499e | 176 | /* Cost for vector insn classes. */ |
177 | struct cpu_vector_cost | |
178 | { | |
a1b0b75c | 179 | const int scalar_int_stmt_cost; /* Cost of any int scalar operation, |
180 | excluding load and store. */ | |
181 | const int scalar_fp_stmt_cost; /* Cost of any fp scalar operation, | |
61d9499e | 182 | excluding load and store. */ |
183 | const int scalar_load_cost; /* Cost of scalar load. */ | |
184 | const int scalar_store_cost; /* Cost of scalar store. */ | |
a1b0b75c | 185 | const int vec_int_stmt_cost; /* Cost of any int vector operation, |
186 | excluding load, store, permute, | |
187 | vector-to-scalar and | |
188 | scalar-to-vector operation. */ | |
189 | const int vec_fp_stmt_cost; /* Cost of any fp vector operation, | |
b2b28d24 | 190 | excluding load, store, permute, |
61d9499e | 191 | vector-to-scalar and |
192 | scalar-to-vector operation. */ | |
b2b28d24 | 193 | const int vec_permute_cost; /* Cost of permute operation. */ |
61d9499e | 194 | const int vec_to_scalar_cost; /* Cost of vec-to-scalar operation. */ |
195 | const int scalar_to_vec_cost; /* Cost of scalar-to-vector | |
196 | operation. */ | |
197 | const int vec_align_load_cost; /* Cost of aligned vector load. */ | |
198 | const int vec_unalign_load_cost; /* Cost of unaligned vector load. */ | |
199 | const int vec_unalign_store_cost; /* Cost of unaligned vector store. */ | |
200 | const int vec_store_cost; /* Cost of vector store. */ | |
201 | const int cond_taken_branch_cost; /* Cost of taken branch. */ | |
202 | const int cond_not_taken_branch_cost; /* Cost of not taken branch. */ | |
203 | }; | |
204 | ||
d05ee6d2 | 205 | /* Branch costs. */ |
206 | struct cpu_branch_cost | |
207 | { | |
208 | const int predictable; /* Predictable branch or optimizing for size. */ | |
209 | const int unpredictable; /* Unpredictable branch or optimizing for speed. */ | |
210 | }; | |
211 | ||
c2389549 | 212 | /* Control approximate alternatives to certain FP operators. */ |
213 | #define AARCH64_APPROX_MODE(MODE) \ | |
214 | ((MIN_MODE_FLOAT <= (MODE) && (MODE) <= MAX_MODE_FLOAT) \ | |
215 | ? (1 << ((MODE) - MIN_MODE_FLOAT)) \ | |
216 | : (MIN_MODE_VECTOR_FLOAT <= (MODE) && (MODE) <= MAX_MODE_VECTOR_FLOAT) \ | |
217 | ? (1 << ((MODE) - MIN_MODE_VECTOR_FLOAT \ | |
218 | + MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1)) \ | |
219 | : (0)) | |
220 | #define AARCH64_APPROX_NONE (0) | |
221 | #define AARCH64_APPROX_ALL (-1) | |
222 | ||
223 | /* Allowed modes for approximations. */ | |
224 | struct cpu_approx_modes | |
225 | { | |
31985950 | 226 | const unsigned int division; /* Division. */ |
ea713c3d | 227 | const unsigned int sqrt; /* Square root. */ |
228 | const unsigned int recip_sqrt; /* Reciprocal square root. */ | |
c2389549 | 229 | }; |
230 | ||
3bf398e1 | 231 | /* Cache prefetch settings for prefetch-loop-arrays. */ |
232 | struct cpu_prefetch_tune | |
233 | { | |
234 | const int num_slots; | |
235 | const int l1_cache_size; | |
236 | const int l1_cache_line_size; | |
237 | const int l2_cache_size; | |
48956da3 | 238 | /* Whether software prefetch hints should be issued for non-constant |
239 | strides. */ | |
240 | const bool prefetch_dynamic_strides; | |
6dc01178 | 241 | /* The minimum constant stride beyond which we should use prefetch |
242 | hints for. */ | |
243 | const int minimum_stride; | |
067e1201 | 244 | const int default_opt_level; |
3bf398e1 | 245 | }; |
246 | ||
df401d54 | 247 | struct tune_params |
248 | { | |
14677da9 | 249 | const struct cpu_cost_table *insn_extra_cost; |
250 | const struct cpu_addrcost_table *addr_cost; | |
251 | const struct cpu_regmove_cost *regmove_cost; | |
252 | const struct cpu_vector_cost *vec_costs; | |
253 | const struct cpu_branch_cost *branch_costs; | |
c2389549 | 254 | const struct cpu_approx_modes *approx_modes; |
6537af8f | 255 | /* Width of the SVE registers or SVE_NOT_IMPLEMENTED if not applicable. |
256 | Only used for tuning decisions, does not disable VLA | |
257 | vectorization. */ | |
258 | enum aarch64_sve_vector_bits_enum sve_width; | |
14677da9 | 259 | int memmov_cost; |
260 | int issue_rate; | |
261 | unsigned int fusible_ops; | |
6848a0ae | 262 | const char *function_align; |
263 | const char *jump_align; | |
264 | const char *loop_align; | |
14677da9 | 265 | int int_reassoc_width; |
266 | int fp_reassoc_width; | |
267 | int vec_reassoc_width; | |
268 | int min_div_recip_mul_sf; | |
269 | int min_div_recip_mul_df; | |
35c51aa0 | 270 | /* Value for aarch64_case_values_threshold; or 0 for the default. */ |
271 | unsigned int max_case_values; | |
5f73ddf0 | 272 | /* An enum specifying how to take into account CPU autoprefetch capabilities |
273 | during instruction scheduling: | |
274 | - AUTOPREFETCHER_OFF: Do not take autoprefetch capabilities into account. | |
275 | - AUTOPREFETCHER_WEAK: Attempt to sort sequences of loads/store in order of | |
276 | offsets but allow the pipeline hazard recognizer to alter that order to | |
277 | maximize multi-issue opportunities. | |
278 | - AUTOPREFETCHER_STRONG: Attempt to sort sequences of loads/store in order of | |
279 | offsets and prefer this even if it restricts multi-issue opportunities. */ | |
280 | ||
281 | enum aarch64_autoprefetch_model | |
282 | { | |
283 | AUTOPREFETCHER_OFF, | |
284 | AUTOPREFETCHER_WEAK, | |
285 | AUTOPREFETCHER_STRONG | |
286 | } autoprefetcher_model; | |
287 | ||
14677da9 | 288 | unsigned int extra_tuning_flags; |
3bf398e1 | 289 | |
290 | /* Place prefetch struct pointer at the end to enable type checking | |
291 | errors when tune_params misses elements (e.g., from erroneous merges). */ | |
292 | const struct cpu_prefetch_tune *prefetch; | |
df401d54 | 293 | }; |
294 | ||
8df53f4d | 295 | /* Classifies an address. |
296 | ||
297 | ADDRESS_REG_IMM | |
298 | A simple base register plus immediate offset. | |
299 | ||
300 | ADDRESS_REG_WB | |
301 | A base register indexed by immediate offset with writeback. | |
302 | ||
303 | ADDRESS_REG_REG | |
304 | A base register indexed by (optionally scaled) register. | |
305 | ||
306 | ADDRESS_REG_UXTW | |
307 | A base register indexed by (optionally scaled) zero-extended register. | |
308 | ||
309 | ADDRESS_REG_SXTW | |
310 | A base register indexed by (optionally scaled) sign-extended register. | |
311 | ||
312 | ADDRESS_LO_SUM | |
313 | A LO_SUM rtx with a base register and "LO12" symbol relocation. | |
314 | ||
315 | ADDRESS_SYMBOLIC: | |
316 | A constant symbolic address, in pc-relative literal pool. */ | |
317 | ||
318 | enum aarch64_address_type { | |
319 | ADDRESS_REG_IMM, | |
320 | ADDRESS_REG_WB, | |
321 | ADDRESS_REG_REG, | |
322 | ADDRESS_REG_UXTW, | |
323 | ADDRESS_REG_SXTW, | |
324 | ADDRESS_LO_SUM, | |
325 | ADDRESS_SYMBOLIC | |
326 | }; | |
327 | ||
328 | /* Address information. */ | |
329 | struct aarch64_address_info { | |
330 | enum aarch64_address_type type; | |
331 | rtx base; | |
332 | rtx offset; | |
333 | poly_int64 const_offset; | |
334 | int shift; | |
335 | enum aarch64_symbol_type symbol_type; | |
336 | }; | |
337 | ||
a3541110 | 338 | #define AARCH64_FUSION_PAIR(x, name) \ |
339 | AARCH64_FUSE_##name##_index, | |
12dfa5b6 | 340 | /* Supported fusion operations. */ |
a3541110 | 341 | enum aarch64_fusion_pairs_index |
12dfa5b6 | 342 | { |
12dfa5b6 | 343 | #include "aarch64-fusion-pairs.def" |
a3541110 | 344 | AARCH64_FUSE_index_END |
345 | }; | |
12dfa5b6 | 346 | |
a3541110 | 347 | #define AARCH64_FUSION_PAIR(x, name) \ |
348 | AARCH64_FUSE_##name = (1u << AARCH64_FUSE_##name##_index), | |
349 | /* Supported fusion operations. */ | |
350 | enum aarch64_fusion_pairs | |
351 | { | |
352 | AARCH64_FUSE_NOTHING = 0, | |
12dfa5b6 | 353 | #include "aarch64-fusion-pairs.def" |
a3541110 | 354 | AARCH64_FUSE_ALL = (1u << AARCH64_FUSE_index_END) - 1 |
12dfa5b6 | 355 | }; |
12dfa5b6 | 356 | |
7b30250d | 357 | #define AARCH64_EXTRA_TUNING_OPTION(x, name) \ |
358 | AARCH64_EXTRA_TUNE_##name##_index, | |
359 | /* Supported tuning flags indexes. */ | |
360 | enum aarch64_extra_tuning_flags_index | |
361 | { | |
362 | #include "aarch64-tuning-flags.def" | |
363 | AARCH64_EXTRA_TUNE_index_END | |
364 | }; | |
7b30250d | 365 | |
366 | ||
367 | #define AARCH64_EXTRA_TUNING_OPTION(x, name) \ | |
368 | AARCH64_EXTRA_TUNE_##name = (1u << AARCH64_EXTRA_TUNE_##name##_index), | |
5e9fcc70 | 369 | /* Supported tuning flags. */ |
370 | enum aarch64_extra_tuning_flags | |
371 | { | |
372 | AARCH64_EXTRA_TUNE_NONE = 0, | |
373 | #include "aarch64-tuning-flags.def" | |
7b30250d | 374 | AARCH64_EXTRA_TUNE_ALL = (1u << AARCH64_EXTRA_TUNE_index_END) - 1 |
5e9fcc70 | 375 | }; |
5e9fcc70 | 376 | |
a702492c | 377 | /* Enum describing the various ways that the |
378 | aarch64_parse_{arch,tune,cpu,extension} functions can fail. | |
379 | This way their callers can choose what kind of error to give. */ | |
380 | ||
381 | enum aarch64_parse_opt_result | |
382 | { | |
383 | AARCH64_PARSE_OK, /* Parsing was successful. */ | |
384 | AARCH64_PARSE_MISSING_ARG, /* Missing argument. */ | |
385 | AARCH64_PARSE_INVALID_FEATURE, /* Invalid feature modifier. */ | |
386 | AARCH64_PARSE_INVALID_ARG /* Invalid arch, tune, cpu arg. */ | |
387 | }; | |
388 | ||
aa22cf6e | 389 | /* Enum to distinguish which type of check is to be done in |
390 | aarch64_simd_valid_immediate. This is used as a bitmask where | |
391 | AARCH64_CHECK_MOV has both bits set. Thus AARCH64_CHECK_MOV will | |
392 | perform all checks. Adding new types would require changes accordingly. */ | |
393 | enum simd_immediate_check { | |
394 | AARCH64_CHECK_ORR = 1 << 0, | |
395 | AARCH64_CHECK_BIC = 1 << 1, | |
396 | AARCH64_CHECK_MOV = AARCH64_CHECK_ORR | AARCH64_CHECK_BIC | |
397 | }; | |
398 | ||
14677da9 | 399 | extern struct tune_params aarch64_tune_params; |
5e9fcc70 | 400 | |
cb4d071f | 401 | poly_int64 aarch64_initial_elimination_offset (unsigned, unsigned); |
1e757156 | 402 | int aarch64_get_condition_code (rtx); |
4328bd71 | 403 | bool aarch64_address_valid_for_prefetch_p (rtx, bool); |
3754d046 | 404 | bool aarch64_bitmask_imm (HOST_WIDE_INT val, machine_mode); |
b2aa1313 | 405 | unsigned HOST_WIDE_INT aarch64_and_split_imm1 (HOST_WIDE_INT val_in); |
406 | unsigned HOST_WIDE_INT aarch64_and_split_imm2 (HOST_WIDE_INT val_in); | |
407 | bool aarch64_and_bitmask_imm (unsigned HOST_WIDE_INT val_in, machine_mode mode); | |
d05ee6d2 | 408 | int aarch64_branch_cost (bool, bool); |
82882dbd | 409 | enum aarch64_symbol_type aarch64_classify_symbolic_expression (rtx); |
a38a83dd | 410 | bool aarch64_can_const_movi_rtx_p (rtx x, machine_mode mode); |
bead021f | 411 | bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT); |
8fa7f434 | 412 | bool aarch64_const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT, |
413 | HOST_WIDE_INT); | |
df401d54 | 414 | bool aarch64_constant_address_p (rtx); |
31985950 | 415 | bool aarch64_emit_approx_div (rtx, rtx, rtx); |
ea713c3d | 416 | bool aarch64_emit_approx_sqrt (rtx, rtx, bool); |
551c1eae | 417 | void aarch64_expand_call (rtx, rtx, bool); |
a7007121 | 418 | bool aarch64_expand_movmem (rtx *); |
72841352 | 419 | bool aarch64_float_const_zero_rtx_p (rtx); |
a38a83dd | 420 | bool aarch64_float_const_rtx_p (rtx); |
df401d54 | 421 | bool aarch64_function_arg_regno_p (unsigned); |
8401eca8 | 422 | bool aarch64_fusion_enabled_p (enum aarch64_fusion_pairs); |
df401d54 | 423 | bool aarch64_gen_movmemqi (rtx *); |
58aab7ce | 424 | bool aarch64_gimple_fold_builtin (gimple_stmt_iterator *); |
2a2ad9a1 | 425 | bool aarch64_is_extend_from_extract (scalar_int_mode, rtx, rtx); |
df401d54 | 426 | bool aarch64_is_long_call_p (rtx); |
2bcb7473 | 427 | bool aarch64_is_noplt_call_p (rtx); |
df401d54 | 428 | bool aarch64_label_mentioned_p (rtx); |
a0db861f | 429 | void aarch64_declare_function_name (FILE *, const char*, tree); |
df401d54 | 430 | bool aarch64_legitimate_pic_operand_p (rtx); |
2a2ad9a1 | 431 | bool aarch64_mask_and_shift_for_ubfiz_p (scalar_int_mode, rtx, rtx); |
25653d4b | 432 | bool aarch64_zero_extend_const_eq (machine_mode, rtx, machine_mode, rtx); |
3754d046 | 433 | bool aarch64_move_imm (HOST_WIDE_INT, machine_mode); |
8fa7f434 | 434 | opt_machine_mode aarch64_sve_pred_mode (unsigned int); |
435 | bool aarch64_sve_cnt_immediate_p (rtx); | |
436 | bool aarch64_sve_addvl_addpl_immediate_p (rtx); | |
437 | bool aarch64_sve_inc_dec_immediate_p (rtx); | |
438 | int aarch64_add_offset_temporaries (rtx); | |
439 | void aarch64_split_add_offset (scalar_int_mode, rtx, rtx, rtx, rtx, rtx); | |
82882dbd | 440 | bool aarch64_mov_operand_p (rtx, machine_mode); |
82da56a3 | 441 | rtx aarch64_reverse_mask (machine_mode, unsigned int); |
cb4d071f | 442 | bool aarch64_offset_7bit_signed_scaled_p (machine_mode, poly_int64); |
97bffee9 | 443 | bool aarch64_offset_9bit_signed_unscaled_p (machine_mode, poly_int64); |
8fa7f434 | 444 | char *aarch64_output_sve_cnt_immediate (const char *, const char *, rtx); |
445 | char *aarch64_output_sve_addvl_addpl (rtx, rtx, rtx); | |
446 | char *aarch64_output_sve_inc_dec_immediate (const char *, rtx); | |
2a2ad9a1 | 447 | char *aarch64_output_scalar_simd_mov_immediate (rtx, scalar_int_mode); |
e256967d | 448 | char *aarch64_output_simd_mov_immediate (rtx, unsigned, |
aa22cf6e | 449 | enum simd_immediate_check w = AARCH64_CHECK_MOV); |
8fa7f434 | 450 | char *aarch64_output_sve_mov_immediate (rtx); |
451 | char *aarch64_output_ptrue (machine_mode, char); | |
3754d046 | 452 | bool aarch64_pad_reg_upward (machine_mode, const_tree, bool); |
df401d54 | 453 | bool aarch64_regno_ok_for_base_p (int, bool); |
454 | bool aarch64_regno_ok_for_index_p (int, bool); | |
a38a83dd | 455 | bool aarch64_reinterpret_float_as_int (rtx value, unsigned HOST_WIDE_INT *fail); |
3754d046 | 456 | bool aarch64_simd_check_vect_par_cnst_half (rtx op, machine_mode mode, |
e71cd518 | 457 | bool high); |
2a2ad9a1 | 458 | bool aarch64_simd_scalar_immediate_valid_for_move (rtx, scalar_int_mode); |
3754d046 | 459 | bool aarch64_simd_shift_imm_p (rtx, machine_mode, bool); |
e256967d | 460 | bool aarch64_simd_valid_immediate (rtx, struct simd_immediate_info *, |
aa22cf6e | 461 | enum simd_immediate_check w = AARCH64_CHECK_MOV); |
8fa7f434 | 462 | rtx aarch64_check_zero_based_sve_index_immediate (rtx); |
463 | bool aarch64_sve_index_immediate_p (rtx); | |
464 | bool aarch64_sve_arith_immediate_p (rtx, bool); | |
465 | bool aarch64_sve_bitmask_immediate_p (rtx); | |
466 | bool aarch64_sve_dup_immediate_p (rtx); | |
467 | bool aarch64_sve_cmp_immediate_p (rtx, bool); | |
468 | bool aarch64_sve_float_arith_immediate_p (rtx, bool); | |
469 | bool aarch64_sve_float_mul_immediate_p (rtx); | |
9794389d | 470 | bool aarch64_split_dimode_const_store (rtx, rtx); |
df401d54 | 471 | bool aarch64_symbolic_address_p (rtx); |
df401d54 | 472 | bool aarch64_uimm12_shift (HOST_WIDE_INT); |
a45f86df | 473 | bool aarch64_use_return_insn_p (void); |
9b34415e | 474 | bool aarch64_use_simple_return_insn_p (void); |
f3731846 | 475 | const char *aarch64_mangle_builtin_type (const_tree); |
df401d54 | 476 | const char *aarch64_output_casesi (rtx *); |
60ae84fc | 477 | |
8fa7f434 | 478 | enum aarch64_symbol_type aarch64_classify_symbol (rtx, HOST_WIDE_INT); |
df401d54 | 479 | enum aarch64_symbol_type aarch64_classify_tls_symbol (rtx); |
480 | enum reg_class aarch64_regno_regclass (unsigned); | |
481 | int aarch64_asm_preferred_eh_data_format (int, int); | |
ac80c076 | 482 | int aarch64_fpconst_pow_of_2 (rtx); |
3754d046 | 483 | machine_mode aarch64_hard_regno_caller_save_mode (unsigned, unsigned, |
484 | machine_mode); | |
df401d54 | 485 | int aarch64_uxt_size (int, HOST_WIDE_INT); |
ac80c076 | 486 | int aarch64_vec_fpconst_pow_of_2 (rtx); |
e31ad92e | 487 | rtx aarch64_eh_return_handler_rtx (void); |
050a2b40 | 488 | rtx aarch64_mask_from_zextract_ops (rtx, rtx); |
df401d54 | 489 | const char *aarch64_output_move_struct (rtx *operands); |
490 | rtx aarch64_return_addr (int, rtx); | |
f6a65527 | 491 | rtx aarch64_simd_gen_const_vector_dup (machine_mode, HOST_WIDE_INT); |
df401d54 | 492 | bool aarch64_simd_mem_operand_p (rtx); |
8fa7f434 | 493 | bool aarch64_sve_ld1r_operand_p (rtx); |
494 | bool aarch64_sve_ldr_operand_p (rtx); | |
0ac5a51b | 495 | bool aarch64_sve_struct_memory_operand_p (rtx); |
abeff20d | 496 | rtx aarch64_simd_vect_par_cnst_half (machine_mode, int, bool); |
df401d54 | 497 | rtx aarch64_tls_get_addr (void); |
f164e9a5 | 498 | tree aarch64_fold_builtin (tree, int, tree *, bool); |
df401d54 | 499 | unsigned aarch64_dbx_register_number (unsigned); |
500 | unsigned aarch64_trampoline_size (void); | |
df401d54 | 501 | void aarch64_asm_output_labelref (FILE *, const char *); |
26db5325 | 502 | void aarch64_cpu_cpp_builtins (cpp_reader *); |
050af05b | 503 | const char * aarch64_gen_far_branch (rtx *, int, const char *, const char *); |
6a979f73 | 504 | const char * aarch64_output_probe_stack_range (rtx, rtx); |
a79985f5 | 505 | const char * aarch64_output_probe_sve_stack_clash (rtx, rtx, rtx, rtx); |
53ac3483 | 506 | void aarch64_err_no_fpadvsimd (machine_mode); |
df401d54 | 507 | void aarch64_expand_epilogue (bool); |
8fa7f434 | 508 | void aarch64_expand_mov_immediate (rtx, rtx, rtx (*) (rtx, rtx) = 0); |
509 | void aarch64_emit_sve_pred_move (rtx, rtx, rtx); | |
510 | void aarch64_expand_sve_mem_move (rtx, rtx, machine_mode); | |
70857087 | 511 | bool aarch64_maybe_expand_sve_subreg_move (rtx, rtx); |
512 | void aarch64_split_sve_subreg_move (rtx, rtx, rtx); | |
df401d54 | 513 | void aarch64_expand_prologue (void); |
501336f7 | 514 | void aarch64_expand_vector_init (rtx, rtx); |
df401d54 | 515 | void aarch64_init_cumulative_args (CUMULATIVE_ARGS *, const_tree, rtx, |
516 | const_tree, unsigned); | |
517 | void aarch64_init_expanders (void); | |
dad9014c | 518 | void aarch64_init_simd_builtins (void); |
3bc53c66 | 519 | void aarch64_emit_call_insn (rtx); |
26db5325 | 520 | void aarch64_register_pragmas (void); |
dad9014c | 521 | void aarch64_relayout_simd_types (void); |
26db5325 | 522 | void aarch64_reset_previous_fndecl (void); |
06f29de1 | 523 | bool aarch64_return_address_signing_enabled (void); |
1f5ef87e | 524 | void aarch64_save_restore_target_globals (tree); |
c6ab95ff | 525 | void aarch64_addti_scratch_regs (rtx, rtx, rtx *, |
526 | rtx *, rtx *, | |
527 | rtx *, rtx *, | |
528 | rtx *); | |
529 | void aarch64_subvti_scratch_regs (rtx, rtx, rtx *, | |
530 | rtx *, rtx *, | |
531 | rtx *, rtx *, rtx *); | |
532 | void aarch64_expand_subvti (rtx, rtx, rtx, | |
533 | rtx, rtx, rtx, rtx); | |
534 | ||
e1a2ea91 | 535 | |
df401d54 | 536 | /* Initialize builtins for SIMD intrinsics. */ |
537 | void init_aarch64_simd_builtins (void); | |
538 | ||
582adad1 | 539 | void aarch64_simd_emit_reg_reg_move (rtx *, machine_mode, unsigned int); |
df401d54 | 540 | |
df401d54 | 541 | /* Expand builtins for SIMD intrinsics. */ |
542 | rtx aarch64_simd_expand_builtin (int, tree, rtx); | |
543 | ||
650ad49e | 544 | void aarch64_simd_lane_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT, const_tree); |
94bd6cb3 | 545 | rtx aarch64_endian_lane_rtx (machine_mode, unsigned int); |
df401d54 | 546 | |
df401d54 | 547 | void aarch64_split_128bit_move (rtx, rtx); |
548 | ||
549 | bool aarch64_split_128bit_move_p (rtx, rtx); | |
550 | ||
2c1c4ac9 | 551 | bool aarch64_mov128_immediate (rtx); |
552 | ||
d820433c | 553 | void aarch64_split_simd_combine (rtx, rtx, rtx); |
554 | ||
e0e03aa1 | 555 | void aarch64_split_simd_move (rtx, rtx); |
556 | ||
72841352 | 557 | /* Check for a legitimate floating point constant for FMOV. */ |
558 | bool aarch64_float_const_representable_p (rtx); | |
559 | ||
9b34415e | 560 | extern int aarch64_epilogue_uses (int); |
561 | ||
df401d54 | 562 | #if defined (RTX_CODE) |
c6ab95ff | 563 | void aarch64_gen_unlikely_cbranch (enum rtx_code, machine_mode cc_mode, |
564 | rtx label_ref); | |
f9e58550 | 565 | bool aarch64_legitimate_address_p (machine_mode, rtx, bool, |
566 | aarch64_addr_query_type = ADDR_QUERY_M); | |
3754d046 | 567 | machine_mode aarch64_select_cc_mode (RTX_CODE, rtx, rtx); |
df401d54 | 568 | rtx aarch64_gen_compare_reg (RTX_CODE, rtx, rtx); |
c844530e | 569 | rtx aarch64_load_tp (rtx); |
df401d54 | 570 | |
3667870b | 571 | void aarch64_expand_compare_and_swap (rtx op[]); |
572 | void aarch64_split_compare_and_swap (rtx op[]); | |
b8a8b19c | 573 | |
3667870b | 574 | void aarch64_split_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx, rtx); |
575 | ||
724582b9 | 576 | bool aarch64_gen_adjusted_ldpstp (rtx *, bool, scalar_mode, RTX_CODE); |
8fa7f434 | 577 | |
578 | void aarch64_expand_sve_vec_cmp_int (rtx, rtx_code, rtx, rtx); | |
579 | bool aarch64_expand_sve_vec_cmp_float (rtx, rtx_code, rtx, rtx, bool); | |
580 | void aarch64_expand_sve_vcond (machine_mode, machine_mode, rtx *); | |
df401d54 | 581 | #endif /* RTX_CODE */ |
582 | ||
23d550c5 | 583 | void aarch64_init_builtins (void); |
26db5325 | 584 | |
72e6ef12 | 585 | bool aarch64_process_target_attr (tree); |
26db5325 | 586 | void aarch64_override_options_internal (struct gcc_options *); |
587 | ||
23d550c5 | 588 | rtx aarch64_expand_builtin (tree exp, |
589 | rtx target, | |
590 | rtx subtarget ATTRIBUTE_UNUSED, | |
3754d046 | 591 | machine_mode mode ATTRIBUTE_UNUSED, |
23d550c5 | 592 | int ignore ATTRIBUTE_UNUSED); |
18cee018 | 593 | tree aarch64_builtin_decl (unsigned, bool ATTRIBUTE_UNUSED); |
4cfd27a5 | 594 | tree aarch64_builtin_rsqrt (unsigned int); |
b6c464fe | 595 | tree aarch64_builtin_vectorized_function (unsigned int, tree, tree); |
ba640418 | 596 | |
5de1fcdb | 597 | extern void aarch64_split_combinev16qi (rtx operands[3]); |
b0cebee7 | 598 | extern void aarch64_expand_vec_perm (rtx, rtx, rtx, rtx, unsigned int); |
8fa7f434 | 599 | extern void aarch64_expand_sve_vec_perm (rtx, rtx, rtx, rtx); |
aa96b575 | 600 | extern bool aarch64_madd_needs_nop (rtx_insn *); |
601 | extern void aarch64_final_prescan_insn (rtx_insn *); | |
1343c5e0 | 602 | void aarch64_atomic_assign_expand_fenv (tree *, tree *, tree *); |
582adad1 | 603 | int aarch64_ccmp_mode_to_code (machine_mode mode); |
18852586 | 604 | |
605 | bool extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset); | |
582adad1 | 606 | bool aarch64_operands_ok_for_ldpstp (rtx *, bool, machine_mode); |
724582b9 | 607 | bool aarch64_operands_adjust_ok_for_ldpstp (rtx *, bool, scalar_mode); |
30370ebb | 608 | void aarch64_swap_ldrstr_operands (rtx *, bool); |
f12c84ab | 609 | |
610 | extern void aarch64_asm_output_pool_epilogue (FILE *, const char *, | |
611 | tree, HOST_WIDE_INT); | |
612 | ||
8df53f4d | 613 | |
614 | extern bool aarch64_classify_address (struct aarch64_address_info *, rtx, | |
615 | machine_mode, bool, | |
616 | aarch64_addr_query_type = ADDR_QUERY_M); | |
617 | ||
a702492c | 618 | /* Defined in common/config/aarch64-common.c. */ |
619 | bool aarch64_handle_option (struct gcc_options *, struct gcc_options *, | |
620 | const struct cl_decoded_option *, location_t); | |
621 | const char *aarch64_rewrite_selected_cpu (const char *name); | |
622 | enum aarch64_parse_opt_result aarch64_parse_extension (const char *, | |
242dc50c | 623 | unsigned long *, |
624 | std::string *); | |
625 | void aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates); | |
a702492c | 626 | std::string aarch64_get_extension_string_for_isa_flags (unsigned long, |
627 | unsigned long); | |
628 | ||
03385ed3 | 629 | /* Defined in aarch64-d.c */ |
630 | extern void aarch64_d_target_versions (void); | |
631 | ||
b19562a8 | 632 | rtl_opt_pass *make_pass_fma_steering (gcc::context *); |
633 | rtl_opt_pass *make_pass_track_speculation (gcc::context *); | |
8df53f4d | 634 | rtl_opt_pass *make_pass_tag_collision_avoidance (gcc::context *); |
e8ebfb45 | 635 | |
8fa7f434 | 636 | poly_uint64 aarch64_regmode_natural_size (machine_mode); |
637 | ||
4b603f8b | 638 | bool aarch64_high_bits_all_ones_p (HOST_WIDE_INT); |
639 | ||
df401d54 | 640 | #endif /* GCC_AARCH64_PROTOS_H */ |