Hi Kyrill, Thanks for the review,
I have respun the patch on top of trunk and here is the new changelog to account for the updates of the new extensions. Bootstrapped Regtested on aarch64-none-linux-gnu and no issues. Ok for trunk? Thanks, Tamar gcc/ChangeLog: 2019-01-15 Tamar Christina <tamar.christ...@arm.com> PR target/88530 * common/config/aarch64/aarch64-common.c (struct aarch64_option_extension): Add is_synthetic. (all_extensions): Use it. (TARGET_OPTION_INIT_STRUCT): Define hook. (struct gcc_targetm_common): Moved to end. (all_extensions_by_on): New. (opt_ext_cmp, typedef opt_ext): New. (aarch64_option_init_struct): New. (aarch64_contains_opt): New. (aarch64_get_extension_string_for_isa_flags): Output smallest set. * config/aarch64/aarch64-option-extensions.def (AARCH64_OPT_EXTENSION): Explicitly include AES and SHA2 in crypto. (fp, simd, crc, lse, fp16, rcpc, rdma, dotprod, aes, sha2, sha3, sm4, fp16fml, sve, profile, rng, memtag, sb, ssbs, predres): Set is_synthetic to false. (crypto): Set is_synthetic to true. gcc/testsuite/ChangeLog: 2019-01-15 Tamar Christina <tamar.christ...@arm.com> PR target/88530 * gcc.target/aarch64/options_set_1.c: New test. * gcc.target/aarch64/options_set_2.c: New test. * gcc.target/aarch64/options_set_3.c: New test. * gcc.target/aarch64/options_set_4.c: New test. * gcc.target/aarch64/options_set_5.c: New test. * gcc.target/aarch64/options_set_6.c: New test. * gcc.target/aarch64/options_set_7.c: New test. * gcc.target/aarch64/options_set_8.c: New test. * gcc.target/aarch64/options_set_9.c: New test. The 01/10/2019 17:15, Kyrill Tkachov wrote: > Hi Tamar, > > On 17/12/18 19:18, Tamar Christina wrote: > > Hi All, > > > > The options don't seem to get canonicalized into the smallest possible set > > before output to the assembler. This means that overlapping feature sets are > > emitted with superfluous parts. > > > > Normally this isn't an issue, but in the case of crypto we have > > retro-actively > > split it into aes and sha2. We need to emit only +crypto to the assembler > > so old assemblers continue to work. > > > > Because of how -mcpu=native and -march=native work they end up enabling all > > feature > > bits, so we need to get the smallest possible set, which would also fix the > > problem with older the assemblers and the retro-active split. > > > > Admittedly this should be done earlier in options processing, but the > > problem > > with the way AArch64 currently processes options is that where the isa_bits > > are > > determined we don't know which options are part of the default set yet. > > > > Which is why we instead do it late in processing when we have all the > > information. This however requires us to make a duplicate of the extensions > > list. > > > > The Option handling structures have been extended to have a boolean to > > indicate > > whether the option is synthetic, with that I mean if the option flag itself > > has a bit. > > > > e.g. +crypto isn't an actual bit, it just enables other bits, but other > > features flags > > like +rdma also enable multiple options but are themselves also a feature. > > > > There are two ways to solve this. > > > > 1) Either have the options that are feature bits also turn themselves on, > > e.g. change > > rdma to turn on FP, SIMD and RDMA as dependency bits. > > 2) Make a distinction between these two different type of features and have > > the framework > > handle it correctly. > > > > Even though it's more code I went for the second approach, as it's the one > > that'll be less > > fragile and give the least surprises. > > > > This is a stop-gap measure that's has the lowest impact and is > > back-portable. > > > > Effectively this patch changes the following: > > > > The values before the => are the old compiler and after the => the new code. > > > > -march=armv8.2-a+crypto+sha2 => -march=armv8.2-a+crypto > > -march=armv8.2-a+sha2+aes => -march=armv8.2-a+crypto > > > > The remaining behaviors stay the same. > > > > > > Bootstrapped Regtested on aarch64-none-linux-gnu and no issues. > > > > Ok for trunk? > > > > This will need rebasing over the Armv8.5-A patches as there are new entries > in config/aarch64/aarch64-option-extensions.def. > Since this has to be done anyway, I've also pointed out a few comment typos > inline. > > Apart from that, the patch looks good to me (this is a subtle area of GCC). > > Thanks, > Kyrill > > > > Thanks, > > Tamar > > > > gcc/ChangeLog: > > > > 2018-12-17 Tamar Christina <tamar.christ...@arm.com> > > > > PR target/88530 > > * common/config/aarch64/aarch64-common.c > > (struct aarch64_option_extension): Add is_synthetic. > > (all_extensions): Use it. > > (TARGET_OPTION_INIT_STRUCT): Define hook. > > (struct gcc_targetm_common): Moved to end. > > (all_extensions_by_on): New. > > (opt_ext_cmp, typedef opt_ext): New. > > (aarch64_option_init_struct): New. > > (aarch64_contains_opt): New. > > (aarch64_get_extension_string_for_isa_flags): Output smallest set. > > * config/aarch64/aarch64-option-extensions.def > > (AARCH64_OPT_EXTENSION): Explicitly include AES and SHA2 in crypto. > > (fp, simd, crc, lse, fp16, rcpc, rdma, dotprod, aes, sha2, sha3, > > sm4, fp16fml, sve, profile): Set is_synthetic to false. > > (crypto): Set is_synthetic to true. > > > > gcc/testsuite/ChangeLog: > > > > 2018-12-17 Tamar Christina <tamar.christ...@arm.com> > > > > PR target/88530 > > * gcc.target/aarch64/options_set_1.c: New test. > > * gcc.target/aarch64/options_set_2.c: New test. > > * gcc.target/aarch64/options_set_3.c: New test. > > * gcc.target/aarch64/options_set_4.c: New test. > > * gcc.target/aarch64/options_set_5.c: New test. > > * gcc.target/aarch64/options_set_6.c: New test. > > * gcc.target/aarch64/options_set_7.c: New test. > > * gcc.target/aarch64/options_set_8.c: New test. > > * gcc.target/aarch64/options_set_9.c: New test. > > > > -- > > diff --git a/gcc/common/config/aarch64/aarch64-common.c > b/gcc/common/config/aarch64/aarch64-common.c > index > dd7d42673402c3cf16ebce009d263d62d574690a..d14237d229fd958c940aee32d3d6404b04cc137e > 100644 > --- a/gcc/common/config/aarch64/aarch64-common.c > +++ b/gcc/common/config/aarch64/aarch64-common.c > @@ -46,6 +46,8 @@ > #define TARGET_OPTION_DEFAULT_PARAMS aarch64_option_default_params > #undef TARGET_OPTION_VALIDATE_PARAM > #define TARGET_OPTION_VALIDATE_PARAM aarch64_option_validate_param > +#undef TARGET_OPTION_INIT_STRUCT > +#define TARGET_OPTION_INIT_STRUCT aarch64_option_init_struct > > /* Set default optimization options. */ > static const struct default_options aarch_option_optimization_table[] = > @@ -164,8 +166,6 @@ aarch64_handle_option (struct gcc_options *opts, > } > } > > -struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; > - > /* An ISA extension in the co-processor and main instruction set space. */ > struct aarch64_option_extension > { > @@ -173,15 +173,28 @@ struct aarch64_option_extension > const unsigned long flag_canonical; > const unsigned long flags_on; > const unsigned long flags_off; > + const bool is_synthetic; > }; > > /* ISA extensions in AArch64. */ > static const struct aarch64_option_extension all_extensions[] = > { > -#define AARCH64_OPT_EXTENSION(NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, Z) \ > - {NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF}, > +#define AARCH64_OPT_EXTENSION(NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \ > + SYNTHETIC, Z) \ > + {NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, SYNTHETIC}, > #include "config/aarch64/aarch64-option-extensions.def" > - {NULL, 0, 0, 0} > + {NULL, 0, 0, 0, false} > +}; > + > +/* A copy of the ISA extensions list for AArch64 sorted by the popcount of > + bits and extension turned on. Cached for efficiency. */ > +static struct aarch64_option_extension all_extensions_by_on[] = > +{ > +#define AARCH64_OPT_EXTENSION(NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \ > + SYNTHETIC, Z) \ > + {NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, SYNTHETIC}, > +#include "config/aarch64/aarch64-option-extensions.def" > + {NULL, 0, 0, 0, false} > }; > > struct processor_name_to_arch > @@ -298,6 +311,69 @@ aarch64_get_all_extension_candidates (auto_vec<const > char *> *candidates) > candidates->safe_push (opt->name); > } > > +/* Comparer to sort aarch64's feature extensions by population count. Largest > + first. */ > + > +typedef const struct aarch64_option_extension opt_ext; > + > +int opt_ext_cmp (const void* a, const void* b) > +{ > + opt_ext *opt_a = (opt_ext *)a; > + opt_ext *opt_b = (opt_ext *)b; > + /* We consider an option to set the bit it turns on, and the other flags it > + turns on as well. */ > + unsigned long total_flags_a = opt_a->flag_canonical & opt_a->flags_on; > + unsigned long total_flags_b = opt_b->flag_canonical & opt_b->flags_on; > + int popcnt_a = popcount_hwi ((HOST_WIDE_INT)total_flags_a); > + int popcnt_b = popcount_hwi ((HOST_WIDE_INT)total_flags_b); > + int order = popcnt_b - popcnt_a; > + > + /* If they have the same amount of bits set, try to give it a more > + deterministic ordering by using the value of the bits themselves. */ > + if (order == 0) > + return total_flags_b - total_flags_a; > + > + return order; > +} > + > +/* Implement TARGET_OPTION_INIT_STRUCT. */ > + > +static void > +aarch64_option_init_struct (struct gcc_options *opts ATTRIBUTE_UNUSED) > +{ > + /* Sort the extensions based on how many bits they set, order the larger > + bits first. */ > + int n_extensions > + = sizeof (all_extensions) / sizeof (struct aarch64_option_extension); > + qsort (&all_extensions_by_on, n_extensions, > + sizeof (struct aarch64_option_extension), opt_ext_cmp); > +} > + > +/* Checks to see if enough bits from the option OPT is enabled in > > "is enabled" -> "are enabled" > > + ISA_FLAG_BITS to be able to replace the invididual options with the > > "individual" > > + canonicalized version of the option. The rules are a bit tricky as we > have > + two kinds of options. > + > + 1) Synthetic groups, such as +crypto which on their own don't have a > feature > + bit but turn on multiple bits. These kind of options should be used > when > + ever the bits they turn on are all available. > + > + 2) Options that themselves have a bit, such as +rdma, in this case, all > the > + feature bits they turn on must be available and the bit for the option > + itself must be. In this case it's effectively a reduction rather than > a > + grouping. > +*/ > + > +static bool > +aarch64_contains_opt (unsigned long isa_flag_bits, opt_ext *opt) > +{ > + unsigned long flags_check = opt->flags_on; > + if (!opt->is_synthetic) > + flags_check |= opt->flag_canonical; > + > + return (isa_flag_bits & flags_check) == flags_check; > +} > + > /* Return a string representation of ISA_FLAGS. DEFAULT_ARCH_FLAGS > gives the default set of flags which are implied by whatever -march > we'd put out. Our job is to figure out the minimal set of "+" and > @@ -311,27 +387,49 @@ aarch64_get_extension_string_for_isa_flags (unsigned > long isa_flags, > const struct aarch64_option_extension *opt = NULL; > std::string outstr = ""; > > - /* Pass one: Find all the things we need to turn on. As a special case, > - we always want to put out +crc if it is enabled. */ > - for (opt = all_extensions; opt->name != NULL; opt++) > - if ((isa_flags & opt->flag_canonical > + unsigned long isa_flag_bits = isa_flags; > + > + /* Pass one: For the bits that turn on multiple bits, remove the invidual > bits > > "individual" again. > > + it they are all present. The option on it's own is enough to trigger > their > + inclusion. */ > + for (opt = all_extensions_by_on; opt->name != NULL; opt++) > + if ((popcount_hwi ((HOST_WIDE_INT)opt->flags_on) > 1 > + && aarch64_contains_opt (isa_flag_bits, opt) > + && !(default_arch_flags & opt->flag_canonical))) > + { > + isa_flag_bits &= ~opt->flags_on; > + isa_flag_bits |= opt->flag_canonical; > + } > + > + /* Pass two: Find all the things we need to turn on. As a special case, > + we always want to put out +crc if it is enabled. Once a bit has been > + "claimed" but an option we clear it so another option doesn't get set > > "but" -> "by"? > > + due to it. This relies on the options being processed in order of > largest > + population to smallest. */ > + for (opt = all_extensions_by_on; opt->name != NULL; opt++) > + if ((isa_flag_bits & opt->flag_canonical > && !(default_arch_flags & opt->flag_canonical)) > || (default_arch_flags & opt->flag_canonical > && opt->flag_canonical == AARCH64_ISA_CRC)) > { > outstr += "+"; > outstr += opt->name; > + isa_flag_bits &= ~(opt->flag_canonical | opt->flags_on); > } > > - /* Pass two: Find all the things we need to turn off. */ > - for (opt = all_extensions; opt->name != NULL; opt++) > + /* Pass three: Find all the things we need to turn off, we aim to give the > + small-ish set possible by looking at the amount of things the feature > turns > + on. By reasoning it probably also turns off a bunch of things when you > + turn it off. Unlike the above we don't care about the smallest set in > this > + case as "+no" flags are rarely passed along to the assembler. */ > + for (opt = all_extensions_by_on; opt->name != NULL; opt++) > if ((~isa_flags) & opt->flag_canonical > && !((~default_arch_flags) & opt->flag_canonical)) > { > outstr += "+no"; > outstr += opt->name; > + isa_flags &= ~(opt->flag_canonical | opt->flags_off); > } > - > return outstr; > } > > @@ -411,5 +509,7 @@ aarch64_rewrite_mcpu (int argc, const char **argv) > return aarch64_rewrite_selected_cpu (argv[argc - 1]); > } > > +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; > + > #undef AARCH64_CPU_NAME_LENGTH > > diff --git a/gcc/config/aarch64/aarch64-option-extensions.def > b/gcc/config/aarch64/aarch64-option-extensions.def > index > 69ab796a4e1a959b89ebb55b599919c442cfb088..cdf04e2d5fcccb8b9a32af8f83501ce23212bbab > 100644 > --- a/gcc/config/aarch64/aarch64-option-extensions.def > +++ b/gcc/config/aarch64/aarch64-option-extensions.def > @@ -30,6 +30,13 @@ > FLAGS_OFF are the bitwise-or of the features that disabling the extension > removes, or zero if disabling this extension has no effect on other > features. > + SYNTHETIC is a boolean to indicate whether the option is a purely > synthetic > + grouping of options and that the option itself has no feature bit (e.g. > + crypto). This is used to determine when sum of the individual options in > + FLAGS_ON can be replaced by FLAG_CANONICAL in options minimization. If > the > + group is synthetic then they can be replaced when all options in FLAGS_ON > + are enabled, otherwise they can only replaced when FLAGS_ON | > FLAG_CANONICAL > > "can only replaced" -> "can only be replaced" > > + are enabled. > FEAT_STRING is a string containing the entries in the 'Features' field of > /proc/cpuinfo on a GNU/Linux system that correspond to this architecture > extension being available. Sometimes multiple entries are needed to > enable > @@ -43,7 +50,8 @@ > "sha3", sm3/sm4 and "sve". */ > AARCH64_OPT_EXTENSION("fp", AARCH64_FL_FP, 0, AARCH64_FL_SIMD | > AARCH64_FL_CRYPTO |\ > AARCH64_FL_F16 | AARCH64_FL_AES | AARCH64_FL_SHA2 |\ > - AARCH64_FL_SHA3 | AARCH64_FL_SM4 | AARCH64_FL_SVE, "fp") > + AARCH64_FL_SHA3 | AARCH64_FL_SM4 | AARCH64_FL_SVE, \ > + false, "fp") > > /* Enabling "simd" also enables "fp". > Disabling "simd" also disables "crypto", "dotprod", "aes", "sha2", > "sha3", > @@ -51,61 +59,71 @@ AARCH64_OPT_EXTENSION("fp", AARCH64_FL_FP, 0, > AARCH64_FL_SIMD | AARCH64_FL_CRYPT > AARCH64_OPT_EXTENSION("simd", AARCH64_FL_SIMD, AARCH64_FL_FP, > AARCH64_FL_CRYPTO |\ > AARCH64_FL_DOTPROD | AARCH64_FL_AES | AARCH64_FL_SHA2 |\ > AARCH64_FL_SHA3 | AARCH64_FL_SM4 | AARCH64_FL_SVE, > - "asimd") > + false, "asimd") > > -/* Enabling "crypto" also enables "fp" and "simd". > +/* Enabling "crypto" also enables "fp", "simd", "aes" and "sha2". > Disabling "crypto" disables "crypto", "aes", "sha2", "sha3" and > "sm3/sm4". */ > -AARCH64_OPT_EXTENSION("crypto", AARCH64_FL_CRYPTO, AARCH64_FL_FP | > AARCH64_FL_SIMD,\ > +AARCH64_OPT_EXTENSION("crypto", AARCH64_FL_CRYPTO, > + AARCH64_FL_FP | AARCH64_FL_SIMD | AARCH64_FL_AES |\ > + AARCH64_FL_SHA2,\ > AARCH64_FL_AES | AARCH64_FL_SHA2 |AARCH64_FL_SHA3 | > AARCH64_FL_SM4,\ > - "aes pmull sha1 sha2") > + true, "aes pmull sha1 sha2") > > /* Enabling or disabling "crc" only changes "crc". */ > -AARCH64_OPT_EXTENSION("crc", AARCH64_FL_CRC, 0, 0, "crc32") > +AARCH64_OPT_EXTENSION("crc", AARCH64_FL_CRC, 0, 0, false, "crc32") > > /* Enabling or disabling "lse" only changes "lse". */ > -AARCH64_OPT_EXTENSION("lse", AARCH64_FL_LSE, 0, 0, "atomics") > +AARCH64_OPT_EXTENSION("lse", AARCH64_FL_LSE, 0, 0, false, "atomics") > > /* Enabling "fp16" also enables "fp". > Disabling "fp16" disables "fp16", "fp16fml" and "sve". */ > AARCH64_OPT_EXTENSION("fp16", AARCH64_FL_F16, AARCH64_FL_FP, > - AARCH64_FL_F16FML | AARCH64_FL_SVE, "fphp asimdhp") > + AARCH64_FL_F16FML | AARCH64_FL_SVE, false, "fphp asimdhp") > > /* Enabling or disabling "rcpc" only changes "rcpc". */ > -AARCH64_OPT_EXTENSION("rcpc", AARCH64_FL_RCPC, 0, 0, "lrcpc") > +AARCH64_OPT_EXTENSION("rcpc", AARCH64_FL_RCPC, 0, 0, false, "lrcpc") > > /* Enabling "rdma" also enables "fp", "simd". > Disabling "rdma" just disables "rdma". */ > -AARCH64_OPT_EXTENSION("rdma", AARCH64_FL_RDMA, AARCH64_FL_FP | > AARCH64_FL_SIMD, 0, "asimdrdm") > +AARCH64_OPT_EXTENSION("rdma", AARCH64_FL_RDMA, \ > + AARCH64_FL_FP | AARCH64_FL_SIMD, 0, false, "asimdrdm") > > /* Enabling "dotprod" also enables "simd". > Disabling "dotprod" only disables "dotprod". */ > -AARCH64_OPT_EXTENSION("dotprod", AARCH64_FL_DOTPROD, AARCH64_FL_SIMD, 0, > "asimddp") > +AARCH64_OPT_EXTENSION("dotprod", AARCH64_FL_DOTPROD, AARCH64_FL_SIMD, 0, \ > + false, "asimddp") > > /* Enabling "aes" also enables "simd". > Disabling "aes" just disables "aes". */ > -AARCH64_OPT_EXTENSION("aes", AARCH64_FL_AES, AARCH64_FL_SIMD, 0, "aes") > +AARCH64_OPT_EXTENSION("aes", AARCH64_FL_AES, AARCH64_FL_SIMD, 0, false, > "aes") > > /* Enabling "sha2" also enables "simd". > Disabling "sha2" just disables "sha2". */ > -AARCH64_OPT_EXTENSION("sha2", AARCH64_FL_SHA2, AARCH64_FL_SIMD, 0, "sha1 > sha2") > +AARCH64_OPT_EXTENSION("sha2", AARCH64_FL_SHA2, AARCH64_FL_SIMD, 0, false, \ > + "sha1 sha2") > > /* Enabling "sha3" enables "simd" and "sha2". > Disabling "sha3" just disables "sha3". */ > -AARCH64_OPT_EXTENSION("sha3", AARCH64_FL_SHA3, AARCH64_FL_SIMD | > AARCH64_FL_SHA2, 0, "sha3 sha512") > +AARCH64_OPT_EXTENSION("sha3", AARCH64_FL_SHA3, \ > + AARCH64_FL_SIMD | AARCH64_FL_SHA2, 0, false, \ > + "sha3 sha512") > > /* Enabling "sm4" also enables "simd". > Disabling "sm4" just disables "sm4". */ > -AARCH64_OPT_EXTENSION("sm4", AARCH64_FL_SM4, AARCH64_FL_SIMD, 0, "sm3 sm4") > +AARCH64_OPT_EXTENSION("sm4", AARCH64_FL_SM4, AARCH64_FL_SIMD, 0, false, \ > + "sm3 sm4") > > /* Enabling "fp16fml" also enables "fp" and "fp16". > Disabling "fp16fml" just disables "fp16fml". */ > -AARCH64_OPT_EXTENSION("fp16fml", AARCH64_FL_F16FML, AARCH64_FL_FP | > AARCH64_FL_F16, 0, "asimdfml") > +AARCH64_OPT_EXTENSION("fp16fml", AARCH64_FL_F16FML, \ > + AARCH64_FL_FP | AARCH64_FL_F16, 0, false, "asimdfml") > > /* Enabling "sve" also enables "fp16", "fp" and "simd". > Disabling "sve" just disables "sve". */ > -AARCH64_OPT_EXTENSION("sve", AARCH64_FL_SVE, AARCH64_FL_FP | AARCH64_FL_SIMD > | AARCH64_FL_F16, 0, "sve") > +AARCH64_OPT_EXTENSION("sve", AARCH64_FL_SVE, AARCH64_FL_FP | AARCH64_FL_SIMD > | \ > + AARCH64_FL_F16, 0, false, "sve") > > /* Enabling/Disabling "profile" does not enable/disable any other feature. > */ > -AARCH64_OPT_EXTENSION("profile", AARCH64_FL_PROFILE, 0, 0, "") > +AARCH64_OPT_EXTENSION("profile", AARCH64_FL_PROFILE, 0, 0, false, "") > > #undef AARCH64_OPT_EXTENSION > diff --git a/gcc/config/aarch64/driver-aarch64.c > b/gcc/config/aarch64/driver-aarch64.c > index > 4e83c7a7679fa683af221fb5f726bc8da339081e..98f9d7959506338bd6a8524500a168cc22ef5396 > 100644 > --- a/gcc/config/aarch64/driver-aarch64.c > +++ b/gcc/config/aarch64/driver-aarch64.c > @@ -36,7 +36,8 @@ struct aarch64_arch_extension > const char *feat_string; > }; > > -#define AARCH64_OPT_EXTENSION(EXT_NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, > FEATURE_STRING) \ > +#define AARCH64_OPT_EXTENSION(EXT_NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, > \ > + SYNTHETIC, FEATURE_STRING) \ > { EXT_NAME, FLAG_CANONICAL, FEATURE_STRING }, > static struct aarch64_arch_extension aarch64_extensions[] = > { > diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_1.c > b/gcc/testsuite/gcc.target/aarch64/options_set_1.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..40d9a05c905eb07103d3b437b5c1351e8620ab33 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/options_set_1.c > @@ -0,0 +1,11 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-march=armv8.2-a" } */ > + > +int main () > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crc} 1 } } */ > + > +/* Check to see if crc is output by default. */ > diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_2.c > b/gcc/testsuite/gcc.target/aarch64/options_set_2.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..3476febce706b34430682e879a4aa3aac8f752db > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/options_set_2.c > @@ -0,0 +1,11 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-march=armv8.2-a+crypto" } */ > + > +int main () > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crypto\+crc} 1 } } > */ > + > +/* Check to see if crc and crypto are maintained if crypto specified. */ > diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_3.c > b/gcc/testsuite/gcc.target/aarch64/options_set_3.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..4558339f16c19555801899c357c50cedb23c28b0 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/options_set_3.c > @@ -0,0 +1,11 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-march=armv8.2-a+aes+sha2+crypto" } */ > + > +int main () > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crypto\+crc} 1 } } > */ > + > +/* Check if smallest set is maintained when outputting. */ > diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_4.c > b/gcc/testsuite/gcc.target/aarch64/options_set_4.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..15514bfe93e61e63cbce1262ee951358cd22d6ce > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/options_set_4.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-march=armv8.2-a+aes+sha2" } */ > + > +int main () > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crypto\+crc} 1 } } > */ > + > +/* Check if individual bits that make up a grouping is specified that only > the > + grouping is kept. */ > \ No newline at end of file > diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_5.c > b/gcc/testsuite/gcc.target/aarch64/options_set_5.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..b4c0901195ede4fe0dd71fbe02a47c35e9dedbbd > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/options_set_5.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-march=armv8.2-a+aes+sha2+nosha2" } */ > + > +int main () > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crc\+aes} 1 } } */ > + > +/* Check if turning off feature bits works correctly and grouping is no > + longer valid. */ > diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_6.c > b/gcc/testsuite/gcc.target/aarch64/options_set_6.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..90a055928a273f06e08124a250e3107ad0704e47 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/options_set_6.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-march=armv8.2-a+crypto+nosha2" } */ > + > +int main () > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crypto\+crc} 1 } } > */ > + > +/* Group as a whole was requested to be turned on, crypto itself is a bit > and so > + just turning off one feature can't turn it off. */ > diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_7.c > b/gcc/testsuite/gcc.target/aarch64/options_set_7.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..71a2c8a19058c0ec25546085076503d206129e10 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/options_set_7.c > @@ -0,0 +1,11 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-march=armv8.4-a+dotprod" } */ > + > +int main () > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler-times {\.arch armv8\.4\-a} 1 } } */ > + > +/* Checking if enabling default features drops the superfluous bits. */ > diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_8.c > b/gcc/testsuite/gcc.target/aarch64/options_set_8.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..83be1bd7a5c3f2bc8d11a14f2c16415c6a7056f2 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/options_set_8.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-march=armv8.4-a+nodotprod" } */ > + > +int main () > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler-times {\.arch armv8\.4\-a} 1 } } */ > + > +/* Checking if trying to turn off default features propagates the commandline > + option. */ > diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_9.c > b/gcc/testsuite/gcc.target/aarch64/options_set_9.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..e3c7cdc54ffb0616877260c562354496cfdcb688 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/options_set_9.c > @@ -0,0 +1,14 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-march=armv8-a+simd+fp" } */ > + > +int main () > +{ > + return 0; > +} > + > +/* { dg-final { scan-assembler-times {\.arch armv8\-a} 1 } } */ > + > + /* Check that grouping of bits that don't form a synthetic group don't turn > + on the parent. e.g. rdma turns on simd+fp, but simd+fp does not turn on > + rdma since rdma is it's own group. crypto however turns on aes and sha2 > + and turning on sha2 and eas should turn on crypto!. */ > > > --
diff --git a/gcc/common/config/aarch64/aarch64-common.c b/gcc/common/config/aarch64/aarch64-common.c index fd870e187a6634b929bc058f99e768e829008179..45f56ebad5848c646dcb2c5640ddf93a083d2edf 100644 --- a/gcc/common/config/aarch64/aarch64-common.c +++ b/gcc/common/config/aarch64/aarch64-common.c @@ -46,6 +46,8 @@ #define TARGET_OPTION_DEFAULT_PARAMS aarch64_option_default_params #undef TARGET_OPTION_VALIDATE_PARAM #define TARGET_OPTION_VALIDATE_PARAM aarch64_option_validate_param +#undef TARGET_OPTION_INIT_STRUCT +#define TARGET_OPTION_INIT_STRUCT aarch64_option_init_struct /* Set default optimization options. */ static const struct default_options aarch_option_optimization_table[] = @@ -164,8 +166,6 @@ aarch64_handle_option (struct gcc_options *opts, } } -struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; - /* An ISA extension in the co-processor and main instruction set space. */ struct aarch64_option_extension { @@ -173,15 +173,28 @@ struct aarch64_option_extension const unsigned long flag_canonical; const unsigned long flags_on; const unsigned long flags_off; + const bool is_synthetic; }; /* ISA extensions in AArch64. */ static const struct aarch64_option_extension all_extensions[] = { -#define AARCH64_OPT_EXTENSION(NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, Z) \ - {NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF}, +#define AARCH64_OPT_EXTENSION(NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \ + SYNTHETIC, Z) \ + {NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, SYNTHETIC}, #include "config/aarch64/aarch64-option-extensions.def" - {NULL, 0, 0, 0} + {NULL, 0, 0, 0, false} +}; + +/* A copy of the ISA extensions list for AArch64 sorted by the popcount of + bits and extension turned on. Cached for efficiency. */ +static struct aarch64_option_extension all_extensions_by_on[] = +{ +#define AARCH64_OPT_EXTENSION(NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \ + SYNTHETIC, Z) \ + {NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, SYNTHETIC}, +#include "config/aarch64/aarch64-option-extensions.def" + {NULL, 0, 0, 0, false} }; struct processor_name_to_arch @@ -298,6 +311,69 @@ aarch64_get_all_extension_candidates (auto_vec<const char *> *candidates) candidates->safe_push (opt->name); } +/* Comparer to sort aarch64's feature extensions by population count. Largest + first. */ + +typedef const struct aarch64_option_extension opt_ext; + +int opt_ext_cmp (const void* a, const void* b) +{ + opt_ext *opt_a = (opt_ext *)a; + opt_ext *opt_b = (opt_ext *)b; + /* We consider an option to set the bit it turns on, and the other flags it + turns on as well. */ + unsigned long total_flags_a = opt_a->flag_canonical & opt_a->flags_on; + unsigned long total_flags_b = opt_b->flag_canonical & opt_b->flags_on; + int popcnt_a = popcount_hwi ((HOST_WIDE_INT)total_flags_a); + int popcnt_b = popcount_hwi ((HOST_WIDE_INT)total_flags_b); + int order = popcnt_b - popcnt_a; + + /* If they have the same amount of bits set, try to give it a more + deterministic ordering by using the value of the bits themselves. */ + if (order == 0) + return total_flags_b - total_flags_a; + + return order; +} + +/* Implement TARGET_OPTION_INIT_STRUCT. */ + +static void +aarch64_option_init_struct (struct gcc_options *opts ATTRIBUTE_UNUSED) +{ + /* Sort the extensions based on how many bits they set, order the larger + bits first. */ + int n_extensions + = sizeof (all_extensions) / sizeof (struct aarch64_option_extension); + qsort (&all_extensions_by_on, n_extensions, + sizeof (struct aarch64_option_extension), opt_ext_cmp); +} + +/* Checks to see if enough bits from the option OPT are enabled in + ISA_FLAG_BITS to be able to replace the individual options with the + canonicalized version of the option. The rules are a bit tricky as we have + two kinds of options. + + 1) Synthetic groups, such as +crypto which on their own don't have a feature + bit but turn on multiple bits. These kind of options should be used when + ever the bits they turn on are all available. + + 2) Options that themselves have a bit, such as +rdma, in this case, all the + feature bits they turn on must be available and the bit for the option + itself must be. In this case it's effectively a reduction rather than a + grouping. +*/ + +static bool +aarch64_contains_opt (unsigned long isa_flag_bits, opt_ext *opt) +{ + unsigned long flags_check = opt->flags_on; + if (!opt->is_synthetic) + flags_check |= opt->flag_canonical; + + return (isa_flag_bits & flags_check) == flags_check; +} + /* Return a string representation of ISA_FLAGS. DEFAULT_ARCH_FLAGS gives the default set of flags which are implied by whatever -march we'd put out. Our job is to figure out the minimal set of "+" and @@ -311,27 +387,49 @@ aarch64_get_extension_string_for_isa_flags (unsigned long isa_flags, const struct aarch64_option_extension *opt = NULL; std::string outstr = ""; - /* Pass one: Find all the things we need to turn on. As a special case, - we always want to put out +crc if it is enabled. */ - for (opt = all_extensions; opt->name != NULL; opt++) - if ((isa_flags & opt->flag_canonical + unsigned long isa_flag_bits = isa_flags; + + /* Pass one: For the bits that turn on multiple bits, remove the individual bits + it they are all present. The option on it's own is enough to trigger their + inclusion. */ + for (opt = all_extensions_by_on; opt->name != NULL; opt++) + if ((popcount_hwi ((HOST_WIDE_INT)opt->flags_on) > 1 + && aarch64_contains_opt (isa_flag_bits, opt) + && !(default_arch_flags & opt->flag_canonical))) + { + isa_flag_bits &= ~opt->flags_on; + isa_flag_bits |= opt->flag_canonical; + } + + /* Pass two: Find all the things we need to turn on. As a special case, + we always want to put out +crc if it is enabled. Once a bit has been + "claimed" by an option we clear it so another option doesn't get set + due to it. This relies on the options being processed in order of largest + population to smallest. */ + for (opt = all_extensions_by_on; opt->name != NULL; opt++) + if ((isa_flag_bits & opt->flag_canonical && !(default_arch_flags & opt->flag_canonical)) || (default_arch_flags & opt->flag_canonical && opt->flag_canonical == AARCH64_ISA_CRC)) { outstr += "+"; outstr += opt->name; + isa_flag_bits &= ~(opt->flag_canonical | opt->flags_on); } - /* Pass two: Find all the things we need to turn off. */ - for (opt = all_extensions; opt->name != NULL; opt++) + /* Pass three: Find all the things we need to turn off, we aim to give the + small-ish set possible by looking at the amount of things the feature turns + on. By reasoning it probably also turns off a bunch of things when you + turn it off. Unlike the above we don't care about the smallest set in this + case as "+no" flags are rarely passed along to the assembler. */ + for (opt = all_extensions_by_on; opt->name != NULL; opt++) if ((~isa_flags) & opt->flag_canonical && !((~default_arch_flags) & opt->flag_canonical)) { outstr += "+no"; outstr += opt->name; + isa_flags &= ~(opt->flag_canonical | opt->flags_off); } - return outstr; } @@ -411,5 +509,7 @@ aarch64_rewrite_mcpu (int argc, const char **argv) return aarch64_rewrite_selected_cpu (argv[argc - 1]); } +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; + #undef AARCH64_CPU_NAME_LENGTH diff --git a/gcc/config/aarch64/aarch64-option-extensions.def b/gcc/config/aarch64/aarch64-option-extensions.def index 2879e35cf2d41d96cb41bb3edd82c0f50091b077..50909debf5455d57b86db91a0a5539fed1d5b91e 100644 --- a/gcc/config/aarch64/aarch64-option-extensions.def +++ b/gcc/config/aarch64/aarch64-option-extensions.def @@ -30,6 +30,13 @@ FLAGS_OFF are the bitwise-or of the features that disabling the extension removes, or zero if disabling this extension has no effect on other features. + SYNTHETIC is a boolean to indicate whether the option is a purely synthetic + grouping of options and that the option itself has no feature bit (e.g. + crypto). This is used to determine when sum of the individual options in + FLAGS_ON can be replaced by FLAG_CANONICAL in options minimization. If the + group is synthetic then they can be replaced when all options in FLAGS_ON + are enabled, otherwise they can only be replaced when FLAGS_ON | FLAG_CANONICAL + are enabled. FEAT_STRING is a string containing the entries in the 'Features' field of /proc/cpuinfo on a GNU/Linux system that correspond to this architecture extension being available. Sometimes multiple entries are needed to enable @@ -43,7 +50,8 @@ "sha3", sm3/sm4 and "sve". */ AARCH64_OPT_EXTENSION("fp", AARCH64_FL_FP, 0, AARCH64_FL_SIMD | AARCH64_FL_CRYPTO |\ AARCH64_FL_F16 | AARCH64_FL_AES | AARCH64_FL_SHA2 |\ - AARCH64_FL_SHA3 | AARCH64_FL_SM4 | AARCH64_FL_SVE, "fp") + AARCH64_FL_SHA3 | AARCH64_FL_SM4 | AARCH64_FL_SVE, \ + false, "fp") /* Enabling "simd" also enables "fp". Disabling "simd" also disables "crypto", "dotprod", "aes", "sha2", "sha3", @@ -51,76 +59,86 @@ AARCH64_OPT_EXTENSION("fp", AARCH64_FL_FP, 0, AARCH64_FL_SIMD | AARCH64_FL_CRYPT AARCH64_OPT_EXTENSION("simd", AARCH64_FL_SIMD, AARCH64_FL_FP, AARCH64_FL_CRYPTO |\ AARCH64_FL_DOTPROD | AARCH64_FL_AES | AARCH64_FL_SHA2 |\ AARCH64_FL_SHA3 | AARCH64_FL_SM4 | AARCH64_FL_SVE, - "asimd") + false, "asimd") -/* Enabling "crypto" also enables "fp" and "simd". +/* Enabling "crypto" also enables "fp", "simd", "aes" and "sha2". Disabling "crypto" disables "crypto", "aes", "sha2", "sha3" and "sm3/sm4". */ -AARCH64_OPT_EXTENSION("crypto", AARCH64_FL_CRYPTO, AARCH64_FL_FP | AARCH64_FL_SIMD,\ +AARCH64_OPT_EXTENSION("crypto", AARCH64_FL_CRYPTO, + AARCH64_FL_FP | AARCH64_FL_SIMD | AARCH64_FL_AES |\ + AARCH64_FL_SHA2,\ AARCH64_FL_AES | AARCH64_FL_SHA2 |AARCH64_FL_SHA3 | AARCH64_FL_SM4,\ - "aes pmull sha1 sha2") + true, "aes pmull sha1 sha2") /* Enabling or disabling "crc" only changes "crc". */ -AARCH64_OPT_EXTENSION("crc", AARCH64_FL_CRC, 0, 0, "crc32") +AARCH64_OPT_EXTENSION("crc", AARCH64_FL_CRC, 0, 0, false, "crc32") /* Enabling or disabling "lse" only changes "lse". */ -AARCH64_OPT_EXTENSION("lse", AARCH64_FL_LSE, 0, 0, "atomics") +AARCH64_OPT_EXTENSION("lse", AARCH64_FL_LSE, 0, 0, false, "atomics") /* Enabling "fp16" also enables "fp". Disabling "fp16" disables "fp16", "fp16fml" and "sve". */ AARCH64_OPT_EXTENSION("fp16", AARCH64_FL_F16, AARCH64_FL_FP, - AARCH64_FL_F16FML | AARCH64_FL_SVE, "fphp asimdhp") + AARCH64_FL_F16FML | AARCH64_FL_SVE, false, "fphp asimdhp") /* Enabling or disabling "rcpc" only changes "rcpc". */ -AARCH64_OPT_EXTENSION("rcpc", AARCH64_FL_RCPC, 0, 0, "lrcpc") +AARCH64_OPT_EXTENSION("rcpc", AARCH64_FL_RCPC, 0, 0, false, "lrcpc") /* Enabling "rdma" also enables "fp", "simd". Disabling "rdma" just disables "rdma". */ -AARCH64_OPT_EXTENSION("rdma", AARCH64_FL_RDMA, AARCH64_FL_FP | AARCH64_FL_SIMD, 0, "asimdrdm") +AARCH64_OPT_EXTENSION("rdma", AARCH64_FL_RDMA, \ + AARCH64_FL_FP | AARCH64_FL_SIMD, 0, false, "asimdrdm") /* Enabling "dotprod" also enables "simd". Disabling "dotprod" only disables "dotprod". */ -AARCH64_OPT_EXTENSION("dotprod", AARCH64_FL_DOTPROD, AARCH64_FL_SIMD, 0, "asimddp") +AARCH64_OPT_EXTENSION("dotprod", AARCH64_FL_DOTPROD, AARCH64_FL_SIMD, 0, \ + false, "asimddp") /* Enabling "aes" also enables "simd". Disabling "aes" just disables "aes". */ -AARCH64_OPT_EXTENSION("aes", AARCH64_FL_AES, AARCH64_FL_SIMD, 0, "aes") +AARCH64_OPT_EXTENSION("aes", AARCH64_FL_AES, AARCH64_FL_SIMD, 0, false, "aes") /* Enabling "sha2" also enables "simd". Disabling "sha2" just disables "sha2". */ -AARCH64_OPT_EXTENSION("sha2", AARCH64_FL_SHA2, AARCH64_FL_SIMD, 0, "sha1 sha2") +AARCH64_OPT_EXTENSION("sha2", AARCH64_FL_SHA2, AARCH64_FL_SIMD, 0, false, \ + "sha1 sha2") /* Enabling "sha3" enables "simd" and "sha2". Disabling "sha3" just disables "sha3". */ -AARCH64_OPT_EXTENSION("sha3", AARCH64_FL_SHA3, AARCH64_FL_SIMD | AARCH64_FL_SHA2, 0, "sha3 sha512") +AARCH64_OPT_EXTENSION("sha3", AARCH64_FL_SHA3, \ + AARCH64_FL_SIMD | AARCH64_FL_SHA2, 0, false, \ + "sha3 sha512") /* Enabling "sm4" also enables "simd". Disabling "sm4" just disables "sm4". */ -AARCH64_OPT_EXTENSION("sm4", AARCH64_FL_SM4, AARCH64_FL_SIMD, 0, "sm3 sm4") +AARCH64_OPT_EXTENSION("sm4", AARCH64_FL_SM4, AARCH64_FL_SIMD, 0, false, \ + "sm3 sm4") /* Enabling "fp16fml" also enables "fp" and "fp16". Disabling "fp16fml" just disables "fp16fml". */ -AARCH64_OPT_EXTENSION("fp16fml", AARCH64_FL_F16FML, AARCH64_FL_FP | AARCH64_FL_F16, 0, "asimdfml") +AARCH64_OPT_EXTENSION("fp16fml", AARCH64_FL_F16FML, \ + AARCH64_FL_FP | AARCH64_FL_F16, 0, false, "asimdfml") /* Enabling "sve" also enables "fp16", "fp" and "simd". Disabling "sve" just disables "sve". */ -AARCH64_OPT_EXTENSION("sve", AARCH64_FL_SVE, AARCH64_FL_FP | AARCH64_FL_SIMD | AARCH64_FL_F16, 0, "sve") +AARCH64_OPT_EXTENSION("sve", AARCH64_FL_SVE, AARCH64_FL_FP | AARCH64_FL_SIMD | \ + AARCH64_FL_F16, 0, false, "sve") /* Enabling/Disabling "profile" does not enable/disable any other feature. */ -AARCH64_OPT_EXTENSION("profile", AARCH64_FL_PROFILE, 0, 0, "") +AARCH64_OPT_EXTENSION("profile", AARCH64_FL_PROFILE, 0, 0, false, "") /* Enabling/Disabling "rng" only changes "rng". */ -AARCH64_OPT_EXTENSION("rng", AARCH64_FL_RNG, 0, 0, "") +AARCH64_OPT_EXTENSION("rng", AARCH64_FL_RNG, 0, 0, false, "") /* Enabling/Disabling "memtag" only changes "memtag". */ -AARCH64_OPT_EXTENSION("memtag", AARCH64_FL_MEMTAG, 0, 0, "") +AARCH64_OPT_EXTENSION("memtag", AARCH64_FL_MEMTAG, 0, 0, false, "") /* Enabling/Disabling "sb" only changes "sb". */ -AARCH64_OPT_EXTENSION("sb", AARCH64_FL_SB, 0, 0, "") +AARCH64_OPT_EXTENSION("sb", AARCH64_FL_SB, 0, 0, false, "") /* Enabling/Disabling "ssbs" only changes "ssbs". */ -AARCH64_OPT_EXTENSION("ssbs", AARCH64_FL_SSBS, 0, 0, "") +AARCH64_OPT_EXTENSION("ssbs", AARCH64_FL_SSBS, 0, 0, false, "") /* Enabling/Disabling "predres" only changes "predres". */ -AARCH64_OPT_EXTENSION("predres", AARCH64_FL_PREDRES, 0, 0, "") +AARCH64_OPT_EXTENSION("predres", AARCH64_FL_PREDRES, 0, 0, false, "") #undef AARCH64_OPT_EXTENSION diff --git a/gcc/config/aarch64/driver-aarch64.c b/gcc/config/aarch64/driver-aarch64.c index 2bf1f9a8c13880dd53980cfb7b829d4263d3d7b6..05f1360d48583473820c8008cc09ed139bddc0ce 100644 --- a/gcc/config/aarch64/driver-aarch64.c +++ b/gcc/config/aarch64/driver-aarch64.c @@ -36,7 +36,8 @@ struct aarch64_arch_extension const char *feat_string; }; -#define AARCH64_OPT_EXTENSION(EXT_NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, FEATURE_STRING) \ +#define AARCH64_OPT_EXTENSION(EXT_NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, \ + SYNTHETIC, FEATURE_STRING) \ { EXT_NAME, FLAG_CANONICAL, FEATURE_STRING }, static struct aarch64_arch_extension aarch64_extensions[] = { diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_1.c b/gcc/testsuite/gcc.target/aarch64/options_set_1.c new file mode 100644 index 0000000000000000000000000000000000000000..40d9a05c905eb07103d3b437b5c1351e8620ab33 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/options_set_1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8.2-a" } */ + +int main () +{ + return 0; +} + +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crc} 1 } } */ + +/* Check to see if crc is output by default. */ diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_2.c b/gcc/testsuite/gcc.target/aarch64/options_set_2.c new file mode 100644 index 0000000000000000000000000000000000000000..3476febce706b34430682e879a4aa3aac8f752db --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/options_set_2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8.2-a+crypto" } */ + +int main () +{ + return 0; +} + +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crypto\+crc} 1 } } */ + +/* Check to see if crc and crypto are maintained if crypto specified. */ diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_3.c b/gcc/testsuite/gcc.target/aarch64/options_set_3.c new file mode 100644 index 0000000000000000000000000000000000000000..4558339f16c19555801899c357c50cedb23c28b0 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/options_set_3.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8.2-a+aes+sha2+crypto" } */ + +int main () +{ + return 0; +} + +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crypto\+crc} 1 } } */ + +/* Check if smallest set is maintained when outputting. */ diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_4.c b/gcc/testsuite/gcc.target/aarch64/options_set_4.c new file mode 100644 index 0000000000000000000000000000000000000000..15514bfe93e61e63cbce1262ee951358cd22d6ce --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/options_set_4.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8.2-a+aes+sha2" } */ + +int main () +{ + return 0; +} + +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crypto\+crc} 1 } } */ + +/* Check if individual bits that make up a grouping is specified that only the + grouping is kept. */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_5.c b/gcc/testsuite/gcc.target/aarch64/options_set_5.c new file mode 100644 index 0000000000000000000000000000000000000000..b4c0901195ede4fe0dd71fbe02a47c35e9dedbbd --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/options_set_5.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8.2-a+aes+sha2+nosha2" } */ + +int main () +{ + return 0; +} + +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crc\+aes} 1 } } */ + +/* Check if turning off feature bits works correctly and grouping is no + longer valid. */ diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_6.c b/gcc/testsuite/gcc.target/aarch64/options_set_6.c new file mode 100644 index 0000000000000000000000000000000000000000..90a055928a273f06e08124a250e3107ad0704e47 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/options_set_6.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8.2-a+crypto+nosha2" } */ + +int main () +{ + return 0; +} + +/* { dg-final { scan-assembler-times {\.arch armv8\.2\-a\+crypto\+crc} 1 } } */ + +/* Group as a whole was requested to be turned on, crypto itself is a bit and so + just turning off one feature can't turn it off. */ diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_7.c b/gcc/testsuite/gcc.target/aarch64/options_set_7.c new file mode 100644 index 0000000000000000000000000000000000000000..71a2c8a19058c0ec25546085076503d206129e10 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/options_set_7.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8.4-a+dotprod" } */ + +int main () +{ + return 0; +} + +/* { dg-final { scan-assembler-times {\.arch armv8\.4\-a} 1 } } */ + +/* Checking if enabling default features drops the superfluous bits. */ diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_8.c b/gcc/testsuite/gcc.target/aarch64/options_set_8.c new file mode 100644 index 0000000000000000000000000000000000000000..83be1bd7a5c3f2bc8d11a14f2c16415c6a7056f2 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/options_set_8.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8.4-a+nodotprod" } */ + +int main () +{ + return 0; +} + +/* { dg-final { scan-assembler-times {\.arch armv8\.4\-a} 1 } } */ + +/* Checking if trying to turn off default features propagates the commandline + option. */ diff --git a/gcc/testsuite/gcc.target/aarch64/options_set_9.c b/gcc/testsuite/gcc.target/aarch64/options_set_9.c new file mode 100644 index 0000000000000000000000000000000000000000..e3c7cdc54ffb0616877260c562354496cfdcb688 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/options_set_9.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8-a+simd+fp" } */ + +int main () +{ + return 0; +} + +/* { dg-final { scan-assembler-times {\.arch armv8\-a} 1 } } */ + + /* Check that grouping of bits that don't form a synthetic group don't turn + on the parent. e.g. rdma turns on simd+fp, but simd+fp does not turn on + rdma since rdma is it's own group. crypto however turns on aes and sha2 + and turning on sha2 and eas should turn on crypto!. */