From ae527cd876fe35de72d876d3484e194ccc66232f Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 18 Nov 2014 14:08:28 +0100 Subject: [PATCH] aarch64: allow adding/removing just feature flags via .arch_extension Rather than requiring to always also set/change the base architecture, allow just en-/disabling of architecture extensions, matching what ARM has. --- gas/ChangeLog | 9 ++++ gas/config/tc-aarch64.c | 51 +++++++++++++++----- gas/testsuite/ChangeLog | 7 +++ gas/testsuite/gas/aarch64/crc32-directive.d | 17 +++++++ gas/testsuite/gas/aarch64/crc32.s | 6 +++ gas/testsuite/gas/aarch64/crypto-directive.d | 27 +++++++++++ gas/testsuite/gas/aarch64/crypto.s | 6 +++ 7 files changed, 111 insertions(+), 12 deletions(-) create mode 100644 gas/testsuite/gas/aarch64/crc32-directive.d create mode 100644 gas/testsuite/gas/aarch64/crypto-directive.d diff --git a/gas/ChangeLog b/gas/ChangeLog index fc95fbf25f..cd4467faba 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2014-11-18 Jan Beulich + + * config/tc-aarch64.c (s_aarch64_arch_extension): New. + (md_pseudo_table): Add arch_extension. + (aarch64_parse_features): New parameter "ext_only". Handle it. + (aarch64_parse_cpu, aarch64_parse_arch, s_aarch64_cpu, + s_aarch64_arch): Pass FALSE as new third argument of + aarch64_parse_features(). + 2014-11-17 Philipp Tomsich * config/tc-aarch64.c (aarch64_cpus): Add "xgene2". diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 7f22ba44e8..8cecfd0646 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -1917,6 +1917,7 @@ s_tlsdesccall (int ignored ATTRIBUTE_UNUSED) static void s_aarch64_arch (int); static void s_aarch64_cpu (int); +static void s_aarch64_arch_extension (int); /* This table describes all the machine specific pseudo-ops the assembler has to support. The fields are: @@ -1934,6 +1935,7 @@ const pseudo_typeS md_pseudo_table[] = { {"pool", s_ltorg, 0}, {"cpu", s_aarch64_cpu, 0}, {"arch", s_aarch64_arch, 0}, + {"arch_extension", s_aarch64_arch_extension, 0}, {"inst", s_aarch64_inst, 0}, #ifdef OBJ_ELF {"tlsdesccall", s_tlsdesccall, 0}, @@ -7238,7 +7240,8 @@ struct aarch64_long_option_table }; static int -aarch64_parse_features (char *str, const aarch64_feature_set **opt_p) +aarch64_parse_features (char *str, const aarch64_feature_set **opt_p, + bfd_boolean ext_only) { /* We insist on extensions being added before being removed. We achieve this by using the ADDING_VALUE variable to indicate whether we are @@ -7254,17 +7257,19 @@ aarch64_parse_features (char *str, const aarch64_feature_set **opt_p) while (str != NULL && *str != 0) { const struct aarch64_option_cpu_value_table *opt; - char *ext; + char *ext = NULL; int optlen; - if (*str != '+') + if (!ext_only) { - as_bad (_("invalid architectural extension")); - return 0; - } + if (*str != '+') + { + as_bad (_("invalid architectural extension")); + return 0; + } - str++; - ext = strchr (str, '+'); + ext = strchr (++str, '+'); + } if (ext != NULL) optlen = ext - str; @@ -7344,7 +7349,7 @@ aarch64_parse_cpu (char *str) { mcpu_cpu_opt = &opt->value; if (ext != NULL) - return aarch64_parse_features (ext, &mcpu_cpu_opt); + return aarch64_parse_features (ext, &mcpu_cpu_opt, FALSE); return 1; } @@ -7376,7 +7381,7 @@ aarch64_parse_arch (char *str) { march_cpu_opt = &opt->value; if (ext != NULL) - return aarch64_parse_features (ext, &march_cpu_opt); + return aarch64_parse_features (ext, &march_cpu_opt, FALSE); return 1; } @@ -7559,7 +7564,7 @@ s_aarch64_cpu (int ignored ATTRIBUTE_UNUSED) { mcpu_cpu_opt = &opt->value; if (ext != NULL) - if (!aarch64_parse_features (ext, &mcpu_cpu_opt)) + if (!aarch64_parse_features (ext, &mcpu_cpu_opt, FALSE)) return; cpu_variant = *mcpu_cpu_opt; @@ -7605,7 +7610,7 @@ s_aarch64_arch (int ignored ATTRIBUTE_UNUSED) { mcpu_cpu_opt = &opt->value; if (ext != NULL) - if (!aarch64_parse_features (ext, &mcpu_cpu_opt)) + if (!aarch64_parse_features (ext, &mcpu_cpu_opt, FALSE)) return; cpu_variant = *mcpu_cpu_opt; @@ -7620,6 +7625,28 @@ s_aarch64_arch (int ignored ATTRIBUTE_UNUSED) ignore_rest_of_line (); } +/* Parse a .arch_extension directive. */ + +static void +s_aarch64_arch_extension (int ignored ATTRIBUTE_UNUSED) +{ + char saved_char; + char *ext = input_line_pointer;; + + while (*input_line_pointer && !ISSPACE (*input_line_pointer)) + input_line_pointer++; + saved_char = *input_line_pointer; + *input_line_pointer = 0; + + if (!aarch64_parse_features (ext, &mcpu_cpu_opt, TRUE)) + return; + + cpu_variant = *mcpu_cpu_opt; + + *input_line_pointer = saved_char; + demand_empty_rest_of_line (); +} + /* Copy symbol information. */ void diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 67e6d18e2e..bf37ba8bcd 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-11-18 Jan Beulich + + * gas/aarch64/crc32-directive.d: New. + * gas/aarch64/crypto-directive.d: New. + * gas/aarch64/crc32.s: Adjust to allow for directive use. + * gas/aarch64/crypto.s: Likewise. + 2014-11-17 Ilya Tocar * gas/i386/i386.exp: Run new tests. diff --git a/gas/testsuite/gas/aarch64/crc32-directive.d b/gas/testsuite/gas/aarch64/crc32-directive.d new file mode 100644 index 0000000000..5f9075584f --- /dev/null +++ b/gas/testsuite/gas/aarch64/crc32-directive.d @@ -0,0 +1,17 @@ +#objdump: -dr +#as: --defsym DIRECTIVE=1 +#source: crc32.s + +.*: file format .* + +Disassembly of section \.text: + +0000000000000000 <.*>: + 0: 1acf40e3 crc32b w3, w7, w15 + 4: 1ac345e7 crc32h w7, w15, w3 + 8: 1ac7486f crc32w w15, w3, w7 + c: 9acf4ce3 crc32x w3, w7, x15 + 10: 1acf50e3 crc32cb w3, w7, w15 + 14: 1ac355e7 crc32ch w7, w15, w3 + 18: 1ac7586f crc32cw w15, w3, w7 + 1c: 9acf5ce3 crc32cx w3, w7, x15 diff --git a/gas/testsuite/gas/aarch64/crc32.s b/gas/testsuite/gas/aarch64/crc32.s index 621d3ccd1a..c5fe297562 100644 --- a/gas/testsuite/gas/aarch64/crc32.s +++ b/gas/testsuite/gas/aarch64/crc32.s @@ -21,6 +21,10 @@ .text + .ifdef DIRECTIVE + .arch_extension crc + .endif + crc32b w3, w7, w15 crc32h w7, w15, w3 crc32w w15, w3, w7 @@ -29,3 +33,5 @@ crc32ch w7, w15, w3 crc32cw w15, w3, w7 crc32cx w3, w7, x15 + + .arch_extension nocrc diff --git a/gas/testsuite/gas/aarch64/crypto-directive.d b/gas/testsuite/gas/aarch64/crypto-directive.d new file mode 100644 index 0000000000..9fa067182b --- /dev/null +++ b/gas/testsuite/gas/aarch64/crypto-directive.d @@ -0,0 +1,27 @@ +#objdump: -dr +#as: --defsym DIRECTIVE=1 +#source: crypto.s + +.*: file format .* + +Disassembly of section \.text: + +0000000000000000 <.*>: + 0: 4e284be7 aese v7.16b, v31.16b + 4: 4e285be7 aesd v7.16b, v31.16b + 8: 4e286be7 aesmc v7.16b, v31.16b + c: 4e287be7 aesimc v7.16b, v31.16b + 10: 5e280be7 sha1h s7, s31 + 14: 5e281be7 sha1su1 v7.4s, v31.4s + 18: 5e282be7 sha256su0 v7.4s, v31.4s + 1c: 5e1f01e7 sha1c q7, s15, v31.4s + 20: 5e1f11e7 sha1p q7, s15, v31.4s + 24: 5e1f21e7 sha1m q7, s15, v31.4s + 28: 5e1f31e7 sha1su0 v7.4s, v15.4s, v31.4s + 2c: 5e1f41e7 sha256h q7, q15, v31.4s + 30: 5e1f51e7 sha256h2 q7, q15, v31.4s + 34: 5e1f61e7 sha256su1 v7.4s, v15.4s, v31.4s + 38: 0e3fe1e7 pmull v7.8h, v15.8b, v31.8b + 3c: 0effe1e7 pmull v7.1q, v15.1d, v31.1d + 40: 4e3fe1e7 pmull2 v7.8h, v15.16b, v31.16b + 44: 4effe1e7 pmull2 v7.1q, v15.2d, v31.2d diff --git a/gas/testsuite/gas/aarch64/crypto.s b/gas/testsuite/gas/aarch64/crypto.s index 01cb954b4d..9e7e9d46f5 100644 --- a/gas/testsuite/gas/aarch64/crypto.s +++ b/gas/testsuite/gas/aarch64/crypto.s @@ -20,6 +20,10 @@ .text + .ifdef DIRECTIVE + .arch_extension crypto + .endif + aese v7.16b, v31.16b aesd v7.16b, v31.16b aesmc v7.16b, v31.16b @@ -42,3 +46,5 @@ pmull v7.1q, v15.1d, v31.1d pmull2 v7.8h, v15.16b, v31.16b pmull2 v7.1q, v15.2d, v31.2d + + .arch_extension nocrypto