diff mbox

[AArch64,3/3] Fix up for pr70133

Message ID 1459937403-22657-4-git-send-email-james.greenhalgh@arm.com
State Superseded
Headers show

Commit Message

James Greenhalgh April 6, 2016, 10:10 a.m. UTC
Hi,

Having updated the way we parse and output extension strings, now we just
need to wire up the native detection to use these new features.

In doing some cleanup and rename I ended up fixing 8-spaces to tabs in
about half the file. I've done the rest while I'm here to save us from
some a mixed-style file.

Bootstrapped on aarch64-none-linux-gnu, then tested with defaults and
an explicit -march=native passed (on a system detected as
cortex-a57+crypto, and again on a system detected as
cortex-a72.cortex-a53+crypto). I also set up a dummy /proc/cpuinfo and
used that to manually check the input data in pr70133.

OK?

Thanks,
James

---
2016-04-06  James Greenhalgh  <james.greenhalgh@arm.com>

	PR target/70133

	* config/aarch64/driver-aarch64.c
	(aarch64_get_extension_string_for_isa_flags): New.
	(arch_extension): Rename to...
	(aarch64_arch_extension): ...This.
	(ext_to_feat_string): Rename to...
	(aarch64_extensions): ...This.
	(aarch64_core_data): Keep track of architecture extension flags.
	(cpu_data): Rename to...
	(aarch64_cpu_data): ...This.
	(aarch64_arch_driver_info): Keep track of architecture extension
	flags.
	(get_arch_name_from_id): Rename to...
	(get_arch_from_id): ...This, change return type.
	(host_detect_local_cpu): Update and reformat for renames, handle
	extensions through common infrastructure.
diff mbox

Patch

diff --git a/gcc/config/aarch64/driver-aarch64.c b/gcc/config/aarch64/driver-aarch64.c
index 8925ec1..ce771ec 100644
--- a/gcc/config/aarch64/driver-aarch64.c
+++ b/gcc/config/aarch64/driver-aarch64.c
@@ -18,9 +18,16 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
+#define INCLUDE_STRING
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 
-struct arch_extension
+/* Defined in common/config/aarch64/aarch64-common.c.  */
+std::string aarch64_get_extension_string_for_isa_flags (unsigned long,
+							unsigned long);
+
+struct aarch64_arch_extension
 {
   const char *ext;
   unsigned int flag;
@@ -29,7 +36,7 @@  struct arch_extension
 
 #define AARCH64_OPT_EXTENSION(EXT_NAME, FLAG_CANONICAL, FLAGS_ON, FLAGS_OFF, FEATURE_STRING) \
   { EXT_NAME, FLAG_CANONICAL, FEATURE_STRING },
-static struct arch_extension ext_to_feat_string[] =
+static struct aarch64_arch_extension aarch64_extensions[] =
 {
 #include "aarch64-option-extensions.def"
 };
@@ -42,15 +49,16 @@  struct aarch64_core_data
   const char* arch;
   const char* implementer_id;
   const char* part_no;
+  const unsigned long flags;
 };
 
 #define AARCH64_CORE(CORE_NAME, CORE_IDENT, SCHED, ARCH, FLAGS, COSTS, IMP, PART) \
-  { CORE_NAME, #ARCH, IMP, PART },
+  { CORE_NAME, #ARCH, IMP, PART, FLAGS },
 
-static struct aarch64_core_data cpu_data [] =
+static struct aarch64_core_data aarch64_cpu_data[] =
 {
 #include "aarch64-cores.def"
-  { NULL, NULL, NULL, NULL }
+  { NULL, NULL, NULL, NULL, 0 }
 };
 
 #undef AARCH64_CORE
@@ -59,37 +67,37 @@  struct aarch64_arch_driver_info
 {
   const char* id;
   const char* name;
+  const unsigned long flags;
 };
 
 #define AARCH64_ARCH(NAME, CORE, ARCH_IDENT, ARCH_REV, FLAGS) \
-  { #ARCH_IDENT, NAME  },
+  { #ARCH_IDENT, NAME, FLAGS },
 
-static struct aarch64_arch_driver_info aarch64_arches [] =
+static struct aarch64_arch_driver_info aarch64_arches[] =
 {
 #include "aarch64-arches.def"
-  {NULL, NULL}
+  {NULL, NULL, 0}
 };
 
 #undef AARCH64_ARCH
 
-/* Return the full architecture name string corresponding to the
-   identifier ID.  */
+/* Return an aarch64_arch_driver_info for the architecture described
+   by ID, or NULL if ID describes something we don't know about.  */
 
-static const char*
-get_arch_name_from_id (const char* id)
+static struct aarch64_arch_driver_info*
+get_arch_from_id (const char* id)
 {
   unsigned int i = 0;
 
   for (i = 0; aarch64_arches[i].id != NULL; i++)
     {
       if (strcmp (id, aarch64_arches[i].id) == 0)
-        return aarch64_arches[i].name;
+	return &aarch64_arches[i];
     }
 
   return NULL;
 }
 
-
 /* Check wether the string CORE contains the same CPU part numbers
    as BL_STRING.  For example CORE="{0xd03, 0xd07}" and BL_STRING="0xd07.0xd03"
    should return true.  */
@@ -98,7 +106,7 @@  static bool
 valid_bL_string_p (const char** core, const char* bL_string)
 {
   return strstr (bL_string, core[0]) != NULL
-         && strstr (bL_string, core[1]) != NULL;
+    && strstr (bL_string, core[1]) != NULL;
 }
 
 /*  Return true iff ARR contains STR in one of its two elements.  */
@@ -142,7 +150,7 @@  host_detect_local_cpu (int argc, const char **argv)
 {
   const char *arch_id = NULL;
   const char *res = NULL;
-  static const int num_exts = ARRAY_SIZE (ext_to_feat_string);
+  static const int num_exts = ARRAY_SIZE (aarch64_extensions);
   char buf[128];
   FILE *f = NULL;
   bool arch = false;
@@ -156,6 +164,8 @@  host_detect_local_cpu (int argc, const char **argv)
   unsigned int n_imps = 0;
   bool processed_exts = false;
   const char *ext_string = "";
+  unsigned long extension_flags = 0;
+  unsigned long default_flags = 0;
 
   gcc_assert (argc);
 
@@ -184,60 +194,71 @@  host_detect_local_cpu (int argc, const char **argv)
     {
       if (strstr (buf, "implementer") != NULL)
 	{
-	  for (i = 0; cpu_data[i].name != NULL; i++)
-	    if (strstr (buf, cpu_data[i].implementer_id) != NULL
-                && !contains_string_p (imps, cpu_data[i].implementer_id))
+	  for (i = 0; aarch64_cpu_data[i].name != NULL; i++)
+	    if (strstr (buf, aarch64_cpu_data[i].implementer_id) != NULL
+		&& !contains_string_p (imps,
+				       aarch64_cpu_data[i].implementer_id))
 	      {
-                if (n_imps == 2)
-                  goto not_found;
+		if (n_imps == 2)
+		  goto not_found;
 
-                imps[n_imps++] = cpu_data[i].implementer_id;
+		imps[n_imps++] = aarch64_cpu_data[i].implementer_id;
 
-                break;
+		break;
 	      }
-          continue;
+	  continue;
 	}
 
       if (strstr (buf, "part") != NULL)
 	{
-	  for (i = 0; cpu_data[i].name != NULL; i++)
-	    if (strstr (buf, cpu_data[i].part_no) != NULL
-                && !contains_string_p (cores, cpu_data[i].part_no))
+	  for (i = 0; aarch64_cpu_data[i].name != NULL; i++)
+	    if (strstr (buf, aarch64_cpu_data[i].part_no) != NULL
+		&& !contains_string_p (cores, aarch64_cpu_data[i].part_no))
 	      {
-                if (n_cores == 2)
-                  goto not_found;
+		if (n_cores == 2)
+		  goto not_found;
 
-                cores[n_cores++] = cpu_data[i].part_no;
-	        core_idx = i;
-	        arch_id = cpu_data[i].arch;
-	        break;
+		cores[n_cores++] = aarch64_cpu_data[i].part_no;
+		core_idx = i;
+		arch_id = aarch64_cpu_data[i].arch;
+		break;
 	      }
-          continue;
-        }
+	  continue;
+	}
       if (!tune && !processed_exts && strstr (buf, "Features") != NULL)
-        {
-          for (i = 0; i < num_exts; i++)
-            {
-              bool enabled = true;
-              char *p = NULL;
-              char *feat_string = concat (ext_to_feat_string[i].feat_string, NULL);
-
-              p = strtok (feat_string, " ");
-
-              while (p != NULL)
-                {
-                  if (strstr (buf, p) == NULL)
-                    {
-                      enabled = false;
-                      break;
-                    }
-                  p = strtok (NULL, " ");
-                }
-              ext_string = concat (ext_string, "+", enabled ? "" : "no",
-                                   ext_to_feat_string[i].ext, NULL);
-            }
-          processed_exts = true;
-        }
+	{
+	  for (i = 0; i < num_exts; i++)
+	    {
+	      char *p = NULL;
+	      char *feat_string
+		= concat (aarch64_extensions[i].feat_string, NULL);
+	      bool enabled = true;
+
+	      /* This may be a multi-token feature string.  We need
+		 to match all parts, which could be in any order.
+		 If this isn't a multi-token feature string, strtok is
+		 just going to return a pointer to feat_string.  */
+	      p = strtok (feat_string, " ");
+	      while (p != NULL)
+		{
+		  if (strstr (buf, p) == NULL)
+		    {
+		      /* Failed to match this token.  Turn off the
+			 features we'd otherwise enable.  */
+		      enabled = false;
+		      break;
+		    }
+		  p = strtok (NULL, " ");
+		}
+
+	      if (enabled)
+		extension_flags |= aarch64_extensions[i].flag;
+	      else
+		extension_flags &= ~(aarch64_extensions[i].flag);
+	    }
+
+	  processed_exts = true;
+	}
     }
 
   fclose (f);
@@ -252,44 +273,56 @@  host_detect_local_cpu (int argc, const char **argv)
 
   if (arch)
     {
-      const char* arch_name = get_arch_name_from_id (arch_id);
+      struct aarch64_arch_driver_info* arch_info = get_arch_from_id (arch_id);
 
       /* We got some arch indentifier that's not in aarch64-arches.def?  */
-      if (!arch_name)
-        goto not_found;
+      if (!arch_info)
+	goto not_found;
 
-      res = concat ("-march=", arch_name, NULL);
+      res = concat ("-march=", arch_info->name, NULL);
+      default_flags = arch_info->flags;
     }
   /* We have big.LITTLE.  */
   else if (n_cores == 2)
     {
-      for (i = 0; cpu_data[i].name != NULL; i++)
-        {
-          if (strchr (cpu_data[i].part_no, '.') != NULL
-              && strncmp (cpu_data[i].implementer_id, imps[0], strlen (imps[0]) - 1) == 0
-              && valid_bL_string_p (cores, cpu_data[i].part_no))
-            {
-              res = concat ("-m", cpu ? "cpu" : "tune", "=", cpu_data[i].name, NULL);
-              break;
-            }
-        }
+      for (i = 0; aarch64_cpu_data[i].name != NULL; i++)
+	{
+	  if (strchr (aarch64_cpu_data[i].part_no, '.') != NULL
+	      && strncmp (aarch64_cpu_data[i].implementer_id,
+			  imps[0],
+			  strlen (imps[0]) - 1) == 0
+	      && valid_bL_string_p (cores, aarch64_cpu_data[i].part_no))
+	    {
+	      res = concat ("-m",
+			    cpu ? "cpu" : "tune", "=",
+			    aarch64_cpu_data[i].name,
+			    NULL);
+	      default_flags = aarch64_cpu_data[i].flags;
+	      break;
+	    }
+	}
       if (!res)
-        goto not_found;
+	goto not_found;
     }
   /* The simple, non-big.LITTLE case.  */
   else
     {
-      if (strncmp (cpu_data[core_idx].implementer_id, imps[0],
-                   strlen (imps[0]) - 1) != 0)
-        goto not_found;
+      if (strncmp (aarch64_cpu_data[core_idx].implementer_id, imps[0],
+		   strlen (imps[0]) - 1) != 0)
+	goto not_found;
 
       res = concat ("-m", cpu ? "cpu" : "tune", "=",
-                      cpu_data[core_idx].name, NULL);
+		    aarch64_cpu_data[core_idx].name, NULL);
+      default_flags = aarch64_cpu_data[core_idx].flags;
     }
 
   if (tune)
     return res;
 
+  ext_string
+    = aarch64_get_extension_string_for_isa_flags (extension_flags,
+						  default_flags).c_str ();
+
   res = concat (res, ext_string, NULL);
 
   return res;