Mercurial > hg > CbC > CbC_gcc
comparison gcc/common/config/aarch64/aarch64-common.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* Common hooks for AArch64. | 1 /* Common hooks for AArch64. |
2 Copyright (C) 2012-2018 Free Software Foundation, Inc. | 2 Copyright (C) 2012-2020 Free Software Foundation, Inc. |
3 Contributed by ARM Ltd. | 3 Contributed by ARM Ltd. |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it | 7 GCC is free software; you can redistribute it and/or modify it |
28 #include "common/common-target.h" | 28 #include "common/common-target.h" |
29 #include "common/common-target-def.h" | 29 #include "common/common-target-def.h" |
30 #include "opts.h" | 30 #include "opts.h" |
31 #include "flags.h" | 31 #include "flags.h" |
32 #include "diagnostic.h" | 32 #include "diagnostic.h" |
33 #include "params.h" | |
34 | 33 |
35 #ifdef TARGET_BIG_ENDIAN_DEFAULT | 34 #ifdef TARGET_BIG_ENDIAN_DEFAULT |
36 #undef TARGET_DEFAULT_TARGET_FLAGS | 35 #undef TARGET_DEFAULT_TARGET_FLAGS |
37 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_END) | 36 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_END) |
38 #endif | 37 #endif |
40 #undef TARGET_HANDLE_OPTION | 39 #undef TARGET_HANDLE_OPTION |
41 #define TARGET_HANDLE_OPTION aarch64_handle_option | 40 #define TARGET_HANDLE_OPTION aarch64_handle_option |
42 | 41 |
43 #undef TARGET_OPTION_OPTIMIZATION_TABLE | 42 #undef TARGET_OPTION_OPTIMIZATION_TABLE |
44 #define TARGET_OPTION_OPTIMIZATION_TABLE aarch_option_optimization_table | 43 #define TARGET_OPTION_OPTIMIZATION_TABLE aarch_option_optimization_table |
45 #undef TARGET_OPTION_DEFAULT_PARAMS | 44 #undef TARGET_OPTION_INIT_STRUCT |
46 #define TARGET_OPTION_DEFAULT_PARAMS aarch64_option_default_params | 45 #define TARGET_OPTION_INIT_STRUCT aarch64_option_init_struct |
47 #undef TARGET_OPTION_VALIDATE_PARAM | |
48 #define TARGET_OPTION_VALIDATE_PARAM aarch64_option_validate_param | |
49 | 46 |
50 /* Set default optimization options. */ | 47 /* Set default optimization options. */ |
51 static const struct default_options aarch_option_optimization_table[] = | 48 static const struct default_options aarch_option_optimization_table[] = |
52 { | 49 { |
53 /* Enable section anchors by default at -O1 or higher. */ | 50 /* Enable section anchors by default at -O1 or higher. */ |
60 { OPT_LEVELS_2_PLUS, OPT_free, NULL, 1 }, | 57 { OPT_LEVELS_2_PLUS, OPT_free, NULL, 1 }, |
61 #if (TARGET_DEFAULT_ASYNC_UNWIND_TABLES == 1) | 58 #if (TARGET_DEFAULT_ASYNC_UNWIND_TABLES == 1) |
62 { OPT_LEVELS_ALL, OPT_fasynchronous_unwind_tables, NULL, 1 }, | 59 { OPT_LEVELS_ALL, OPT_fasynchronous_unwind_tables, NULL, 1 }, |
63 { OPT_LEVELS_ALL, OPT_funwind_tables, NULL, 1}, | 60 { OPT_LEVELS_ALL, OPT_funwind_tables, NULL, 1}, |
64 #endif | 61 #endif |
62 { OPT_LEVELS_ALL, OPT__param_stack_clash_protection_guard_size_, NULL, | |
63 DEFAULT_STK_CLASH_GUARD_SIZE == 0 ? 16 : DEFAULT_STK_CLASH_GUARD_SIZE }, | |
64 | |
65 { OPT_LEVELS_NONE, 0, NULL, 0 } | 65 { OPT_LEVELS_NONE, 0, NULL, 0 } |
66 }; | 66 }; |
67 | |
68 /* Implement target validation TARGET_OPTION_DEFAULT_PARAM. */ | |
69 | |
70 static bool | |
71 aarch64_option_validate_param (const int value, const int param) | |
72 { | |
73 /* Check that both parameters are the same. */ | |
74 if (param == (int) PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE) | |
75 { | |
76 if (value != 12 && value != 16) | |
77 { | |
78 error ("only values 12 (4 KB) and 16 (64 KB) are supported for guard " | |
79 "size. Given value %d (%llu KB) is out of range", | |
80 value, (1ULL << value) / 1024ULL); | |
81 return false; | |
82 } | |
83 } | |
84 | |
85 return true; | |
86 } | |
87 | |
88 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */ | |
89 | |
90 static void | |
91 aarch64_option_default_params (void) | |
92 { | |
93 /* We assume the guard page is 64k. */ | |
94 int index = (int) PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE; | |
95 set_default_param_value (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE, | |
96 DEFAULT_STK_CLASH_GUARD_SIZE == 0 | |
97 ? 16 : DEFAULT_STK_CLASH_GUARD_SIZE); | |
98 | |
99 int guard_size | |
100 = default_param_value (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE); | |
101 | |
102 /* Set the interval parameter to be the same as the guard size. This way the | |
103 mid-end code does the right thing for us. */ | |
104 set_default_param_value (PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL, | |
105 guard_size); | |
106 | |
107 /* Validate the options. */ | |
108 aarch64_option_validate_param (guard_size, index); | |
109 } | |
110 | 67 |
111 /* Implement TARGET_HANDLE_OPTION. | 68 /* Implement TARGET_HANDLE_OPTION. |
112 This function handles the target specific options for CPU/target selection. | 69 This function handles the target specific options for CPU/target selection. |
113 | 70 |
114 -mcpu=CPU is shorthand for -march=ARCH_FOR_CPU, -mtune=CPU. | 71 -mcpu=CPU is shorthand for -march=ARCH_FOR_CPU, -mtune=CPU. |
162 default: | 119 default: |
163 return true; | 120 return true; |
164 } | 121 } |
165 } | 122 } |
166 | 123 |
167 struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; | |
168 | |
169 /* An ISA extension in the co-processor and main instruction set space. */ | 124 /* An ISA extension in the co-processor and main instruction set space. */ |
170 struct aarch64_option_extension | 125 struct aarch64_option_extension |
171 { | 126 { |
172 const char *const name; | 127 const char *const name; |
173 const unsigned long flag_canonical; | 128 const uint64_t flag_canonical; |
174 const unsigned long flags_on; | 129 const uint64_t flags_on; |
175 const unsigned long flags_off; | 130 const uint64_t flags_off; |
131 const bool is_synthetic; | |
176 }; | 132 }; |
177 | 133 |
178 /* ISA extensions in AArch64. */ | 134 /* ISA extensions in AArch64. */ |
179 static const struct aarch64_option_extension all_extensions[] = | 135 static const struct aarch64_option_extension all_extensions[] = |
180 { | 136 { |
181 #define AARCH64_OPT_EXTENSION(NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, Z) \ | 137 #define AARCH64_OPT_EXTENSION(NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \ |
182 {NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF}, | 138 SYNTHETIC, Z) \ |
139 {NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, SYNTHETIC}, | |
183 #include "config/aarch64/aarch64-option-extensions.def" | 140 #include "config/aarch64/aarch64-option-extensions.def" |
184 {NULL, 0, 0, 0} | 141 {NULL, 0, 0, 0, false} |
142 }; | |
143 | |
144 /* A copy of the ISA extensions list for AArch64 sorted by the popcount of | |
145 bits and extension turned on. Cached for efficiency. */ | |
146 static struct aarch64_option_extension all_extensions_by_on[] = | |
147 { | |
148 #define AARCH64_OPT_EXTENSION(NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \ | |
149 SYNTHETIC, Z) \ | |
150 {NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, SYNTHETIC}, | |
151 #include "config/aarch64/aarch64-option-extensions.def" | |
152 {NULL, 0, 0, 0, false} | |
185 }; | 153 }; |
186 | 154 |
187 struct processor_name_to_arch | 155 struct processor_name_to_arch |
188 { | 156 { |
189 const std::string processor_name; | 157 const std::string processor_name; |
190 const enum aarch64_arch arch; | 158 const enum aarch64_arch arch; |
191 const unsigned long flags; | 159 const uint64_t flags; |
192 }; | 160 }; |
193 | 161 |
194 struct arch_to_arch_name | 162 struct arch_to_arch_name |
195 { | 163 { |
196 const enum aarch64_arch arch; | 164 const enum aarch64_arch arch; |
197 const std::string arch_name; | 165 const std::string arch_name; |
198 const unsigned long flags; | 166 const uint64_t flags; |
199 }; | 167 }; |
200 | 168 |
201 /* Map processor names to the architecture revision they implement and | 169 /* Map processor names to the architecture revision they implement and |
202 the default set of architectural feature flags they support. */ | 170 the default set of architectural feature flags they support. */ |
203 static const struct processor_name_to_arch all_cores[] = | 171 static const struct processor_name_to_arch all_cores[] = |
218 {aarch64_no_arch, "", 0} | 186 {aarch64_no_arch, "", 0} |
219 }; | 187 }; |
220 | 188 |
221 /* Parse the architecture extension string STR and update ISA_FLAGS | 189 /* Parse the architecture extension string STR and update ISA_FLAGS |
222 with the architecture features turned on or off. Return a | 190 with the architecture features turned on or off. Return a |
223 aarch64_parse_opt_result describing the result. */ | 191 aarch64_parse_opt_result describing the result. |
192 When the STR string contains an invalid extension, | |
193 a copy of the string is created and stored to INVALID_EXTENSION. */ | |
224 | 194 |
225 enum aarch64_parse_opt_result | 195 enum aarch64_parse_opt_result |
226 aarch64_parse_extension (const char *str, unsigned long *isa_flags) | 196 aarch64_parse_extension (const char *str, uint64_t *isa_flags, |
197 std::string *invalid_extension) | |
227 { | 198 { |
228 /* The extension string is parsed left to right. */ | 199 /* The extension string is parsed left to right. */ |
229 const struct aarch64_option_extension *opt = NULL; | 200 const struct aarch64_option_extension *opt = NULL; |
230 | 201 |
231 /* Flag to say whether we are adding or removing an extension. */ | 202 /* Flag to say whether we are adding or removing an extension. */ |
272 } | 243 } |
273 | 244 |
274 if (opt->name == NULL) | 245 if (opt->name == NULL) |
275 { | 246 { |
276 /* Extension not found in list. */ | 247 /* Extension not found in list. */ |
248 if (invalid_extension) | |
249 *invalid_extension = std::string (str, len); | |
277 return AARCH64_PARSE_INVALID_FEATURE; | 250 return AARCH64_PARSE_INVALID_FEATURE; |
278 } | 251 } |
279 | 252 |
280 str = ext; | 253 str = ext; |
281 }; | 254 }; |
282 | 255 |
283 return AARCH64_PARSE_OK; | 256 return AARCH64_PARSE_OK; |
257 } | |
258 | |
259 /* Append all architecture extension candidates to the CANDIDATES vector. */ | |
260 | |
261 void | |
262 aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates) | |
263 { | |
264 const struct aarch64_option_extension *opt; | |
265 for (opt = all_extensions; opt->name != NULL; opt++) | |
266 candidates->safe_push (opt->name); | |
267 } | |
268 | |
269 /* Comparer to sort aarch64's feature extensions by population count. Largest | |
270 first. */ | |
271 | |
272 typedef const struct aarch64_option_extension opt_ext; | |
273 | |
274 int opt_ext_cmp (const void* a, const void* b) | |
275 { | |
276 opt_ext *opt_a = (opt_ext *)a; | |
277 opt_ext *opt_b = (opt_ext *)b; | |
278 | |
279 /* We consider the total set of bits an options turns on to be the union of | |
280 the singleton set containing the option itself and the set of options it | |
281 turns on as a dependency. As an example +dotprod turns on FL_DOTPROD and | |
282 FL_SIMD. As such the set of bits represented by this option is | |
283 {FL_DOTPROD, FL_SIMD}. */ | |
284 uint64_t total_flags_a = opt_a->flag_canonical & opt_a->flags_on; | |
285 uint64_t total_flags_b = opt_b->flag_canonical & opt_b->flags_on; | |
286 int popcnt_a = popcount_hwi ((HOST_WIDE_INT)total_flags_a); | |
287 int popcnt_b = popcount_hwi ((HOST_WIDE_INT)total_flags_b); | |
288 int order = popcnt_b - popcnt_a; | |
289 | |
290 /* If they have the same amount of bits set, give it a more | |
291 deterministic ordering by using the value of the bits themselves. */ | |
292 if (order != 0) | |
293 return order; | |
294 | |
295 if (total_flags_a != total_flags_b) | |
296 return total_flags_a < total_flags_b ? 1 : -1; | |
297 | |
298 return 0; | |
299 } | |
300 | |
301 /* Implement TARGET_OPTION_INIT_STRUCT. */ | |
302 | |
303 static void | |
304 aarch64_option_init_struct (struct gcc_options *opts ATTRIBUTE_UNUSED) | |
305 { | |
306 /* Sort the extensions based on how many bits they set, order the larger | |
307 counts first. We sort the list because this makes processing the | |
308 feature bits O(n) instead of O(n^2). While n is small, the function | |
309 to calculate the feature strings is called on every options push, | |
310 pop and attribute change (arm_neon headers, lto etc all cause this to | |
311 happen quite frequently). It is a trade-off between time and space and | |
312 so time won. */ | |
313 int n_extensions | |
314 = sizeof (all_extensions) / sizeof (struct aarch64_option_extension); | |
315 qsort (&all_extensions_by_on, n_extensions, | |
316 sizeof (struct aarch64_option_extension), opt_ext_cmp); | |
317 } | |
318 | |
319 /* Checks to see if enough bits from the option OPT are enabled in | |
320 ISA_FLAG_BITS to be able to replace the individual options with the | |
321 canonicalized version of the option. This is done based on two rules: | |
322 | |
323 1) Synthetic groups, such as +crypto we only care about the bits that are | |
324 turned on. e.g. +aes+sha2 can be replaced with +crypto. | |
325 | |
326 2) Options that themselves have a bit, such as +rdma, in this case, all the | |
327 feature bits they turn on must be available and the bit for the option | |
328 itself must be. In this case it's effectively a reduction rather than a | |
329 grouping. e.g. +fp+simd is not enough to turn on +rdma, for that you would | |
330 need +rdma+fp+simd which is reduced down to +rdma. | |
331 */ | |
332 | |
333 static bool | |
334 aarch64_contains_opt (uint64_t isa_flag_bits, opt_ext *opt) | |
335 { | |
336 uint64_t flags_check | |
337 = opt->is_synthetic ? opt->flags_on : opt->flag_canonical; | |
338 | |
339 return (isa_flag_bits & flags_check) == flags_check; | |
284 } | 340 } |
285 | 341 |
286 /* Return a string representation of ISA_FLAGS. DEFAULT_ARCH_FLAGS | 342 /* Return a string representation of ISA_FLAGS. DEFAULT_ARCH_FLAGS |
287 gives the default set of flags which are implied by whatever -march | 343 gives the default set of flags which are implied by whatever -march |
288 we'd put out. Our job is to figure out the minimal set of "+" and | 344 we'd put out. Our job is to figure out the minimal set of "+" and |
289 "+no" feature flags to put out, and to put them out grouped such | 345 "+no" feature flags to put out, and to put them out grouped such |
290 that all the "+" flags come before the "+no" flags. */ | 346 that all the "+" flags come before the "+no" flags. */ |
291 | 347 |
292 std::string | 348 std::string |
293 aarch64_get_extension_string_for_isa_flags (unsigned long isa_flags, | 349 aarch64_get_extension_string_for_isa_flags (uint64_t isa_flags, |
294 unsigned long default_arch_flags) | 350 uint64_t default_arch_flags) |
295 { | 351 { |
296 const struct aarch64_option_extension *opt = NULL; | 352 const struct aarch64_option_extension *opt = NULL; |
297 std::string outstr = ""; | 353 std::string outstr = ""; |
298 | 354 |
299 /* Pass one: Find all the things we need to turn on. As a special case, | 355 uint64_t isa_flag_bits = isa_flags; |
300 we always want to put out +crc if it is enabled. */ | 356 |
301 for (opt = all_extensions; opt->name != NULL; opt++) | 357 /* Pass one: Minimize the search space by reducing the set of options |
302 if ((isa_flags & opt->flag_canonical | 358 to the smallest set that still turns on the same features as before in |
303 && !(default_arch_flags & opt->flag_canonical)) | 359 conjunction with the bits that are turned on by default for the selected |
304 || (default_arch_flags & opt->flag_canonical | 360 architecture. */ |
305 && opt->flag_canonical == AARCH64_ISA_CRC)) | 361 for (opt = all_extensions_by_on; opt->name != NULL; opt++) |
362 { | |
363 /* If the bit is on by default, then all the options it turns on are also | |
364 on by default due to the transitive dependencies. | |
365 | |
366 If the option is enabled explicitly in the set then we need to emit | |
367 an option for it. Since this list is sorted by extensions setting the | |
368 largest number of featers first, we can be sure that nothing else will | |
369 ever need to set the bits we already set. Consider the following | |
370 situation: | |
371 | |
372 Feat1 = A + B + C | |
373 Feat2 = A + B | |
374 Feat3 = A + D | |
375 Feat4 = B + C | |
376 Feat5 = C | |
377 | |
378 The following results are expected: | |
379 | |
380 A + C = A + Feat5 | |
381 B + C = Feat4 | |
382 Feat4 + A = Feat1 | |
383 Feat2 + Feat5 = Feat1 | |
384 Feat1 + C = Feat1 | |
385 Feat3 + Feat4 = Feat1 + D | |
386 | |
387 This search assumes that all invidual feature bits are use visible, | |
388 in other words the user must be able to do +A, +B, +C and +D. */ | |
389 if (aarch64_contains_opt (isa_flag_bits | default_arch_flags, opt)) | |
306 { | 390 { |
307 outstr += "+"; | 391 /* We remove all the dependent bits, to prevent them from being turned |
308 outstr += opt->name; | 392 on twice. This only works because we assume that all there are |
393 individual options to set all bits standalone. */ | |
394 isa_flag_bits &= ~opt->flags_on; | |
395 isa_flag_bits |= opt->flag_canonical; | |
309 } | 396 } |
310 | 397 } |
311 /* Pass two: Find all the things we need to turn off. */ | 398 |
312 for (opt = all_extensions; opt->name != NULL; opt++) | 399 /* By toggling bits on and off, we may have set bits on that are already |
313 if ((~isa_flags) & opt->flag_canonical | 400 enabled by default. So we mask the default set out so we don't emit an |
314 && !((~default_arch_flags) & opt->flag_canonical)) | 401 option for them. Instead of checking for this each time during Pass One |
315 { | 402 we just mask all default bits away at the end. */ |
316 outstr += "+no"; | 403 isa_flag_bits &= ~default_arch_flags; |
317 outstr += opt->name; | 404 |
318 } | 405 /* We now have the smallest set of features we need to process. A subsequent |
406 linear scan of the bits in isa_flag_bits will allow us to print the ext | |
407 names. However as a special case if CRC was enabled before, always print | |
408 it. This is required because some CPUs have an incorrect specification | |
409 in older assemblers. Even though CRC should be the default for these | |
410 cases the -mcpu values won't turn it on. */ | |
411 if (isa_flags & AARCH64_ISA_CRC) | |
412 isa_flag_bits |= AARCH64_ISA_CRC; | |
413 | |
414 /* Pass Two: | |
415 Print the option names that we're sure we must turn on. These are only | |
416 optional extension names. Mandatory ones have already been removed and | |
417 ones we explicitly want off have been too. */ | |
418 for (opt = all_extensions_by_on; opt->name != NULL; opt++) | |
419 { | |
420 if (isa_flag_bits & opt->flag_canonical) | |
421 { | |
422 outstr += "+"; | |
423 outstr += opt->name; | |
424 } | |
425 } | |
426 | |
427 /* Pass Three: | |
428 Print out a +no for any mandatory extension that we are | |
429 turning off. By this point aarch64_parse_extension would have ensured | |
430 that any optional extensions are turned off. The only things left are | |
431 things that can't be turned off usually, e.g. something that is on by | |
432 default because it's mandatory and we want it off. For turning off bits | |
433 we don't guarantee the smallest set of flags, but instead just emit all | |
434 options the user has specified. | |
435 | |
436 The assembler requires all +<opts> to be printed before +no<opts>. */ | |
437 for (opt = all_extensions_by_on; opt->name != NULL; opt++) | |
438 { | |
439 if ((~isa_flags) & opt->flag_canonical | |
440 && !((~default_arch_flags) & opt->flag_canonical)) | |
441 { | |
442 outstr += "+no"; | |
443 outstr += opt->name; | |
444 } | |
445 } | |
319 | 446 |
320 return outstr; | 447 return outstr; |
321 } | 448 } |
322 | 449 |
323 /* Attempt to rewrite NAME, which has been passed on the command line | 450 /* Attempt to rewrite NAME, which has been passed on the command line |
365 | 492 |
366 /* We couldn't find that proceesor name, or the processor name we | 493 /* We couldn't find that proceesor name, or the processor name we |
367 found does not map to an architecture we understand. */ | 494 found does not map to an architecture we understand. */ |
368 if (p_to_a->arch == aarch64_no_arch | 495 if (p_to_a->arch == aarch64_no_arch |
369 || a_to_an->arch == aarch64_no_arch) | 496 || a_to_an->arch == aarch64_no_arch) |
370 fatal_error (input_location, "unknown value %qs for -mcpu", name); | 497 fatal_error (input_location, "unknown value %qs for %<-mcpu%>", name); |
371 | 498 |
372 unsigned long extensions = p_to_a->flags; | 499 uint64_t extensions = p_to_a->flags; |
373 aarch64_parse_extension (extension_str.c_str (), &extensions); | 500 aarch64_parse_extension (extension_str.c_str (), &extensions, NULL); |
374 | 501 |
375 std::string outstr = a_to_an->arch_name | 502 std::string outstr = a_to_an->arch_name |
376 + aarch64_get_extension_string_for_isa_flags (extensions, | 503 + aarch64_get_extension_string_for_isa_flags (extensions, |
377 a_to_an->flags); | 504 a_to_an->flags); |
378 | 505 |
394 { | 521 { |
395 gcc_assert (argc); | 522 gcc_assert (argc); |
396 return aarch64_rewrite_selected_cpu (argv[argc - 1]); | 523 return aarch64_rewrite_selected_cpu (argv[argc - 1]); |
397 } | 524 } |
398 | 525 |
526 struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; | |
527 | |
399 #undef AARCH64_CPU_NAME_LENGTH | 528 #undef AARCH64_CPU_NAME_LENGTH |
400 | 529 |