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] Allow extension availability to depend on several architecture bits


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

commit d942732e829030b8eab483dd48b979f8eed7c9e2
Author: Thomas Preud'homme <thomas.preudhomme@arm.com>
Date:   Tue May 10 15:06:41 2016 +0100

    Allow extension availability to depend on several architecture bits
    
    2016-05-10  Thomas Preud'homme  <thomas.preudhomme@arm.com>
    
    gas/
    	* config/tc-arm.c (struct arm_option_extension_value_table): Make
    	allowed_archs an array with 2 entries.
    	(ARM_EXT_OPT): Adapt to only fill the first entry of allowed_archs.
    	(ARM_EXT_OPT2): New macro filling the two entries of allowed_archs.
    	(arm_extensions): Use separate entries in allowed_archs when several
    	archs are allowed to use an extension and change ARCH_ANY in
    	ARM_ARCH_NONE in allowed_archs.
    	(arm_parse_extension): Check that, for each allowed_archs entry, all
    	bits are set in the current architecture, ignoring ARM_ANY entries.
    	(s_arm_arch_extension): Likewise.
    
    include/
    	* arm.h (ARM_FSET_CPU_SUBSET): Define macro.

Diff:
---
 gas/ChangeLog        | 13 ++++++++++++
 gas/config/tc-arm.c  | 60 +++++++++++++++++++++++++++++++++++++++-------------
 include/ChangeLog    |  4 ++++
 include/opcode/arm.h |  6 ++++++
 4 files changed, 68 insertions(+), 15 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index c13366e..7980edb 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,18 @@
 2016-05-10  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
+	* config/tc-arm.c (struct arm_option_extension_value_table): Make
+	allowed_archs an array with 2 entries.
+	(ARM_EXT_OPT): Adapt to only fill the first entry of allowed_archs.
+	(ARM_EXT_OPT2): New macro filling the two entries of allowed_archs.
+	(arm_extensions): Use separate entries in allowed_archs when several
+	archs are allowed to use an extension and change ARCH_ANY in
+	ARM_ARCH_NONE in allowed_archs.
+	(arm_parse_extension): Check that, for each allowed_archs entry, all
+	bits are set in the current architecture, ignoring ARM_ANY entries.
+	(s_arm_arch_extension): Likewise.
+
+2016-05-10  Thomas Preud'homme  <thomas.preudhomme@arm.com>
+
 	* config/tc-arm.c (arm_ext_m): Add feature bit ARM_EXT2_V8M_MAIN.
 	(arm_ext_v8m_main): New feature set for bit ARM_EXT2_V8M_MAIN.
 	(arm_ext_v8m_m_only): New feature set for instructions in ARMv8-M not
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 6a9d655..d4dee3f 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -25470,12 +25470,16 @@ struct arm_option_extension_value_table
   size_t name_len;
   const arm_feature_set merge_value;
   const arm_feature_set clear_value;
-  const arm_feature_set allowed_archs;
+  /* List of architectures for which an extension is available.  ARM_ARCH_NONE
+     indicates that an extension is available for all architectures while
+     ARM_ANY marks an empty entry.  */
+  const arm_feature_set allowed_archs[2];
 };
 
 /* The following table must be in alphabetical order with a NULL last entry.
    */
-#define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, AA }
+#define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, { AA, ARM_ANY } }
+#define ARM_EXT_OPT2(N, M, C, AA1, AA2) { N, sizeof (N) - 1, M, C, {AA1, AA2} }
 static const struct arm_option_extension_value_table arm_extensions[] =
 {
   ARM_EXT_OPT ("crc",  ARCH_CRC_ARMV8, ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
@@ -25488,18 +25492,20 @@ static const struct arm_option_extension_value_table arm_extensions[] =
   ARM_EXT_OPT ("fp16",  ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
 			ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
 			ARM_ARCH_V8_2A),
-  ARM_EXT_OPT ("idiv",	ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
+  ARM_EXT_OPT2 ("idiv",	ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
 			ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
-				   ARM_FEATURE_CORE_LOW (ARM_EXT_V7A | ARM_EXT_V7R)),
+			ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
+			ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
   ARM_EXT_OPT ("iwmmxt",ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT),
-			ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT), ARM_ANY),
+			ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT), ARM_ARCH_NONE),
   ARM_EXT_OPT ("iwmmxt2", ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2),
-			ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2), ARM_ANY),
+			ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2), ARM_ARCH_NONE),
   ARM_EXT_OPT ("maverick", ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK),
-			ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK), ARM_ANY),
-  ARM_EXT_OPT ("mp",	ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
+			ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK), ARM_ARCH_NONE),
+  ARM_EXT_OPT2 ("mp",	ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
 			ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
-				   ARM_FEATURE_CORE_LOW (ARM_EXT_V7A | ARM_EXT_V7R)),
+			ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
+			ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
   ARM_EXT_OPT ("os",	ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
 			ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
 				   ARM_FEATURE_CORE_LOW (ARM_EXT_V6M)),
@@ -25509,9 +25515,10 @@ static const struct arm_option_extension_value_table arm_extensions[] =
   ARM_EXT_OPT ("rdma",  FPU_ARCH_NEON_VFP_ARMV8_1,
 			ARM_FEATURE_COPROC (FPU_NEON_ARMV8 | FPU_NEON_EXT_RDMA),
 			ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
-  ARM_EXT_OPT ("sec",	ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
+  ARM_EXT_OPT2 ("sec",	ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
 			ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
-				   ARM_FEATURE_CORE_LOW (ARM_EXT_V6K | ARM_EXT_V7A)),
+			ARM_FEATURE_CORE_LOW (ARM_EXT_V6K),
+			ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
   ARM_EXT_OPT ("simd",  FPU_ARCH_NEON_VFP_ARMV8,
 			ARM_FEATURE_COPROC (FPU_NEON_ARMV8),
 			ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
@@ -25520,8 +25527,8 @@ static const struct arm_option_extension_value_table arm_extensions[] =
 			ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT),
 				   ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
   ARM_EXT_OPT ("xscale",ARM_FEATURE_COPROC (ARM_CEXT_XSCALE),
-			ARM_FEATURE_COPROC (ARM_CEXT_XSCALE), ARM_ANY),
-  { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, ARM_ARCH_NONE }
+			ARM_FEATURE_COPROC (ARM_CEXT_XSCALE), ARM_ARCH_NONE),
+  { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, { ARM_ARCH_NONE, ARM_ARCH_NONE } }
 };
 #undef ARM_EXT_OPT
 
@@ -25627,6 +25634,7 @@ arm_parse_extension (const char *str, const arm_feature_set **opt_p)
      or removing it (0) and only allowing it to change in the order
      -1 -> 1 -> 0.  */
   const struct arm_option_extension_value_table * opt = NULL;
+  const arm_feature_set arm_any = ARM_ANY;
   int adding_value = -1;
 
   /* Copy the feature set, so that we can modify it.  */
@@ -25691,8 +25699,18 @@ arm_parse_extension (const char *str, const arm_feature_set **opt_p)
       for (; opt->name != NULL; opt++)
 	if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
 	  {
+	    int i, nb_allowed_archs =
+	      sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
 	    /* Check we can apply the extension to this architecture.  */
-	    if (!ARM_CPU_HAS_FEATURE (*ext_set, opt->allowed_archs))
+	    for (i = 0; i < nb_allowed_archs; i++)
+	      {
+		/* Empty entry.  */
+		if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_any))
+		  continue;
+		if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *ext_set))
+		  break;
+	      }
+	    if (i == nb_allowed_archs)
 	      {
 		as_bad (_("extension does not apply to the base architecture"));
 		return FALSE;
@@ -26448,6 +26466,7 @@ static void
 s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED)
 {
   const struct arm_option_extension_value_table *opt;
+  const arm_feature_set arm_any = ARM_ANY;
   char saved_char;
   char *name;
   int adding_value = 1;
@@ -26468,7 +26487,18 @@ s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED)
   for (opt = arm_extensions; opt->name != NULL; opt++)
     if (streq (opt->name, name))
       {
-	if (!ARM_CPU_HAS_FEATURE (*mcpu_cpu_opt, opt->allowed_archs))
+	int i, nb_allowed_archs =
+	  sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[i]);
+	for (i = 0; i < nb_allowed_archs; i++)
+	  {
+	    /* Empty entry.  */
+	    if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_any))
+	      continue;
+	    if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *mcpu_cpu_opt))
+	      break;
+	  }
+
+	if (i == nb_allowed_archs)
 	  {
 	    as_bad (_("architectural extension `%s' is not allowed for the "
 		      "current base architecture"), name);
diff --git a/include/ChangeLog b/include/ChangeLog
index c9668e4..eef571b 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,5 +1,9 @@
 2016-05-10  Thomas Preud'homme  <thomas.preudhomme@arm.com>
 
+	* arm.h (ARM_FSET_CPU_SUBSET): Define macro.
+
+2016-05-10  Thomas Preud'homme  <thomas.preudhomme@arm.com>
+
 	* opcode/arm.h (ARM_EXT2_V8M_MAIN): new feature bit.
 	(ARM_AEXT2_V8M_MAIN): New architecture extension feature set.
 	(ARM_ARCH_V8M_MAIN): Use ARM_AEXT2_V8M_MAIN instead of ARM_AEXT2_V8M
diff --git a/include/opcode/arm.h b/include/opcode/arm.h
index 36dcc20..c8883db 100644
--- a/include/opcode/arm.h
+++ b/include/opcode/arm.h
@@ -330,6 +330,12 @@ typedef struct
    || ((CPU).core[1] & (FEAT).core[1]) != 0 \
    || ((CPU).coproc & (FEAT).coproc) != 0)
 
+/* Tests whether the features of A are a subset of B.  */
+#define ARM_FSET_CPU_SUBSET(A,B) \
+  (((A).core[0] & (B).core[0]) == (A).core[0] \
+   && ((A).core[1] & (B).core[1]) == (A).core[1] \
+   && ((A).coproc & (B).coproc) == (A).coproc)
+
 #define ARM_CPU_IS_ANY(CPU) \
   ((CPU).core[0] == ((arm_feature_set)ARM_ANY).core[0] \
    && (CPU).core[1] == ((arm_feature_set)ARM_ANY).core[1])


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