This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] [AArch64] Fix +nofp16 handling


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=93d8990cba700abdf9d2be06a5022e588d097fc8

commit 93d8990cba700abdf9d2be06a5022e588d097fc8
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date:   Fri Jul 1 16:20:50 2016 +0100

    [AArch64] Fix +nofp16 handling
    
    Feature flag handling was not perfect, +nofp16 disabled fp
    instructions too.
    
    New feature flag macros were added to check features with multiple
    bits set (matters for FP_F16 and SIMD_F16 opcode feature tests).
    The unused AARCH64_OPCODE_HAS_FEATURE was removed, all checks should
    use one of the AARCH64_CPU_HAS_* macros.  AARCH64_CPU_HAS_FEATURE
    now checks all feature bits.
    
    The aarch64_features table now contains the dependencies as
    a separate field (so when the feature is enabled all dependencies
    are enabled and when it is disabled everything that depends on it
    is disabled).
    
    Note that armv8-a+foo+nofoo is not equivalent to armv8-a if
    +foo turns on dependent features that nofoo does not turn off.
    
    gas/
    	* config/tc-aarch64.c (struct aarch64_option_cpu_value_table): Add
    	require field.
    	(aarch64_features): Initialize require fields.
    	(aarch64_parse_features): Handle dependencies.
    	(aarch64_feature_enable_set, aarch64_feature_disable_set): New.
    	(md_assemble): Use AARCH64_CPU_HAS_ALL_FEATURES.
    	* testsuite/gas/aarch64/illegal-nofp16.s: New.
    	* testsuite/gas/aarch64/illegal-nofp16.l: New.
    	* testsuite/gas/aarch64/illegal-nofp16.d: New.
    
    include/
    	* opcode/aarch64.h (AARCH64_CPU_HAS_ALL_FEATURES): New.
    	(AARCH64_CPU_HAS_ANY_FEATURES): New.
    	(AARCH64_CPU_HAS_FEATURE): Define as AARCH64_CPU_HAS_ALL_FEATURES.
    	(AARCH64_OPCODE_HAS_FEATURE): Remove.

Diff:
---
 gas/ChangeLog                              | 12 +++++
 gas/config/tc-aarch64.c                    | 84 ++++++++++++++++++++++++------
 gas/testsuite/gas/aarch64/illegal-nofp16.d |  2 +
 gas/testsuite/gas/aarch64/illegal-nofp16.l |  3 ++
 gas/testsuite/gas/aarch64/illegal-nofp16.s |  7 +++
 include/ChangeLog                          |  7 +++
 include/opcode/aarch64.h                   | 11 ++--
 7 files changed, 105 insertions(+), 21 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 40a9a2b..5cb62e2 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,15 @@
+2016-07-01  Szabolcs Nagy  <szabolcs.nagy@arm.com>
+
+	* config/tc-aarch64.c (struct aarch64_option_cpu_value_table): Add
+	require field.
+	(aarch64_features): Initialize require fields.
+	(aarch64_parse_features): Handle dependencies.
+	(aarch64_feature_enable_set, aarch64_feature_disable_set): New.
+	(md_assemble): Use AARCH64_CPU_HAS_ALL_FEATURES.
+	* testsuite/gas/aarch64/illegal-nofp16.s: New.
+	* testsuite/gas/aarch64/illegal-nofp16.l: New.
+	* testsuite/gas/aarch64/illegal-nofp16.d: New.
+
 2016-07-01  Nick Clifton  <nickc@redhat.com>
 
 	* macro.c (macro_expand_body): Use a buffer big enough to hold an
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index ddc40f2..2d491f6 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -6080,7 +6080,7 @@ md_assemble (char *str)
 	{
 	  /* Check that this instruction is supported for this CPU.  */
 	  if (!opcode->avariant
-	      || !AARCH64_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant))
+	      || !AARCH64_CPU_HAS_ALL_FEATURES (cpu_variant, *opcode->avariant))
 	    {
 	      as_bad (_("selected processor does not support `%s'"), str);
 	      return;
@@ -7801,23 +7801,33 @@ struct aarch64_option_cpu_value_table
 {
   const char *name;
   const aarch64_feature_set value;
+  const aarch64_feature_set require; /* Feature dependencies.  */
 };
 
 static const struct aarch64_option_cpu_value_table aarch64_features[] = {
-  {"crc",		AARCH64_FEATURE (AARCH64_FEATURE_CRC, 0)},
-  {"crypto",		AARCH64_FEATURE (AARCH64_FEATURE_CRYPTO, 0)},
-  {"fp",		AARCH64_FEATURE (AARCH64_FEATURE_FP, 0)},
-  {"lse",		AARCH64_FEATURE (AARCH64_FEATURE_LSE, 0)},
-  {"simd",		AARCH64_FEATURE (AARCH64_FEATURE_SIMD, 0)},
-  {"pan",		AARCH64_FEATURE (AARCH64_FEATURE_PAN, 0)},
-  {"lor",		AARCH64_FEATURE (AARCH64_FEATURE_LOR, 0)},
-  {"ras",		AARCH64_FEATURE (AARCH64_FEATURE_RAS, 0)},
-  {"rdma",		AARCH64_FEATURE (AARCH64_FEATURE_SIMD
-					 | AARCH64_FEATURE_RDMA, 0)},
-  {"fp16",		AARCH64_FEATURE (AARCH64_FEATURE_F16
-					 | AARCH64_FEATURE_FP, 0)},
-  {"profile",		AARCH64_FEATURE (AARCH64_FEATURE_PROFILE, 0)},
-  {NULL,		AARCH64_ARCH_NONE}
+  {"crc",		AARCH64_FEATURE (AARCH64_FEATURE_CRC, 0),
+			AARCH64_ARCH_NONE},
+  {"crypto",		AARCH64_FEATURE (AARCH64_FEATURE_CRYPTO, 0),
+			AARCH64_ARCH_NONE},
+  {"fp",		AARCH64_FEATURE (AARCH64_FEATURE_FP, 0),
+			AARCH64_ARCH_NONE},
+  {"lse",		AARCH64_FEATURE (AARCH64_FEATURE_LSE, 0),
+			AARCH64_ARCH_NONE},
+  {"simd",		AARCH64_FEATURE (AARCH64_FEATURE_SIMD, 0),
+			AARCH64_ARCH_NONE},
+  {"pan",		AARCH64_FEATURE (AARCH64_FEATURE_PAN, 0),
+			AARCH64_ARCH_NONE},
+  {"lor",		AARCH64_FEATURE (AARCH64_FEATURE_LOR, 0),
+			AARCH64_ARCH_NONE},
+  {"ras",		AARCH64_FEATURE (AARCH64_FEATURE_RAS, 0),
+			AARCH64_ARCH_NONE},
+  {"rdma",		AARCH64_FEATURE (AARCH64_FEATURE_RDMA, 0),
+			AARCH64_FEATURE (AARCH64_FEATURE_SIMD, 0)},
+  {"fp16",		AARCH64_FEATURE (AARCH64_FEATURE_F16, 0),
+			AARCH64_FEATURE (AARCH64_FEATURE_FP, 0)},
+  {"profile",		AARCH64_FEATURE (AARCH64_FEATURE_PROFILE, 0),
+			AARCH64_ARCH_NONE},
+  {NULL,		AARCH64_ARCH_NONE, AARCH64_ARCH_NONE},
 };
 
 struct aarch64_long_option_table
@@ -7828,6 +7838,38 @@ struct aarch64_long_option_table
   char *deprecated;		/* If non-null, print this message.  */
 };
 
+/* Transitive closure of features depending on set.  */
+static aarch64_feature_set
+aarch64_feature_disable_set (aarch64_feature_set set)
+{
+  const struct aarch64_option_cpu_value_table *opt;
+  aarch64_feature_set prev = 0;
+
+  while (prev != set) {
+    prev = set;
+    for (opt = aarch64_features; opt->name != NULL; opt++)
+      if (AARCH64_CPU_HAS_ANY_FEATURES (opt->require, set))
+        AARCH64_MERGE_FEATURE_SETS (set, set, opt->value);
+  }
+  return set;
+}
+
+/* Transitive closure of dependencies of set.  */
+static aarch64_feature_set
+aarch64_feature_enable_set (aarch64_feature_set set)
+{
+  const struct aarch64_option_cpu_value_table *opt;
+  aarch64_feature_set prev = 0;
+
+  while (prev != set) {
+    prev = set;
+    for (opt = aarch64_features; opt->name != NULL; opt++)
+      if (AARCH64_CPU_HAS_FEATURE (set, opt->value))
+        AARCH64_MERGE_FEATURE_SETS (set, set, opt->require);
+  }
+  return set;
+}
+
 static int
 aarch64_parse_features (const char *str, const aarch64_feature_set **opt_p,
 			bfd_boolean ext_only)
@@ -7895,11 +7937,19 @@ aarch64_parse_features (const char *str, const aarch64_feature_set **opt_p,
       for (opt = aarch64_features; opt->name != NULL; opt++)
 	if (strncmp (opt->name, str, optlen) == 0)
 	  {
+	    aarch64_feature_set set;
+
 	    /* Add or remove the extension.  */
 	    if (adding_value)
-	      AARCH64_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->value);
+	      {
+		set = aarch64_feature_enable_set (opt->value);
+		AARCH64_MERGE_FEATURE_SETS (*ext_set, *ext_set, set);
+	      }
 	    else
-	      AARCH64_CLEAR_FEATURE (*ext_set, *ext_set, opt->value);
+	      {
+		set = aarch64_feature_disable_set (opt->value);
+		AARCH64_CLEAR_FEATURE (*ext_set, *ext_set, set);
+	      }
 	    break;
 	  }
 
diff --git a/gas/testsuite/gas/aarch64/illegal-nofp16.d b/gas/testsuite/gas/aarch64/illegal-nofp16.d
new file mode 100644
index 0000000..669e85d
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/illegal-nofp16.d
@@ -0,0 +1,2 @@
+#as: -march=armv8.2-a+nofp16 -mno-verbose-error
+#error-output: illegal-nofp16.l
diff --git a/gas/testsuite/gas/aarch64/illegal-nofp16.l b/gas/testsuite/gas/aarch64/illegal-nofp16.l
new file mode 100644
index 0000000..99d586b
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/illegal-nofp16.l
@@ -0,0 +1,3 @@
+[^:]*: Assembler messages:
+^[^:]+:4: Error: selected processor does not support `fneg h0,h1'
+^[^:]+:6: Error: selected processor does not support `fneg v0\.8h,v1\.8h'
diff --git a/gas/testsuite/gas/aarch64/illegal-nofp16.s b/gas/testsuite/gas/aarch64/illegal-nofp16.s
new file mode 100644
index 0000000..7718444
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/illegal-nofp16.s
@@ -0,0 +1,7 @@
+// Test -march=armv8.2-a+nofp16 to only disable fp16, not fp.
+.text
+	fneg s0, s1
+	fneg h0, h1
+	fneg v0.4s, v1.4s
+	fneg v0.8h, v1.8h
+	neg v0.16b, v1.16b
diff --git a/include/ChangeLog b/include/ChangeLog
index a766ecf..e4db8b8 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,10 @@
+2016-07-01  Szabolcs Nagy  <szabolcs.nagy@arm.com>
+
+	* opcode/aarch64.h (AARCH64_CPU_HAS_ALL_FEATURES): New.
+	(AARCH64_CPU_HAS_ANY_FEATURES): New.
+	(AARCH64_CPU_HAS_FEATURE): Define as AARCH64_CPU_HAS_ALL_FEATURES.
+	(AARCH64_OPCODE_HAS_FEATURE): Remove.
+
 2016-06-30  Matthew Wahab  <matthew.wahab@arm.com>
 
 	* opcode/arm.h (ARM_ARCH_V8_2a): Add FPU_NEON_EXT_RDMA to the set
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index b35a818..1e38749 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -84,9 +84,15 @@ typedef uint32_t aarch64_insn;
 /* CPU-specific features.  */
 typedef unsigned long aarch64_feature_set;
 
-#define AARCH64_CPU_HAS_FEATURE(CPU,FEAT)	\
+#define AARCH64_CPU_HAS_ALL_FEATURES(CPU,FEAT)	\
+  ((~(CPU) & (FEAT)) == 0)
+
+#define AARCH64_CPU_HAS_ANY_FEATURES(CPU,FEAT)	\
   (((CPU) & (FEAT)) != 0)
 
+#define AARCH64_CPU_HAS_FEATURE(CPU,FEAT)	\
+  AARCH64_CPU_HAS_ALL_FEATURES (CPU,FEAT)
+
 #define AARCH64_MERGE_FEATURE_SETS(TARG,F1,F2)	\
   do						\
     {						\
@@ -103,9 +109,6 @@ typedef unsigned long aarch64_feature_set;
 
 #define AARCH64_FEATURE(core,coproc) ((core) | (coproc))
 
-#define AARCH64_OPCODE_HAS_FEATURE(OPC,FEAT)	\
-  (((OPC) & (FEAT)) != 0)
-
 enum aarch64_operand_class
 {
   AARCH64_OPND_CLASS_NIL,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]