Пример #1
0
const char *
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 (aarch64_extensions);
    char buf[128];
    FILE *f = NULL;
    bool arch = false;
    bool tune = false;
    bool cpu = false;
    unsigned int i = 0;
    unsigned int core_idx = 0;
    const char* imps[2] = { NULL, NULL };
    const char* cores[2] = { NULL, NULL };
    unsigned int n_cores = 0;
    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);

    if (!argv[0])
        goto not_found;

    /* Are we processing -march, mtune or mcpu?  */
    arch = strcmp (argv[0], "arch") == 0;
    if (!arch)
        tune = strcmp (argv[0], "tune") == 0;

    if (!arch && !tune)
        cpu = strcmp (argv[0], "cpu") == 0;

    if (!arch && !tune && !cpu)
        goto not_found;

    f = fopen ("/proc/cpuinfo", "r");

    if (f == NULL)
        goto not_found;

    /* Look through /proc/cpuinfo to determine the implementer
       and then the part number that identifies a particular core.  */
    while (fgets (buf, sizeof (buf), f) != NULL)
    {
        if (strstr (buf, "implementer") != NULL)
        {
            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;

                    imps[n_imps++] = aarch64_cpu_data[i].implementer_id;

                    break;
                }
            continue;
        }

        if (strstr (buf, "part") != NULL)
        {
            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;

                    cores[n_cores++] = aarch64_cpu_data[i].part_no;
                    core_idx = i;
                    arch_id = aarch64_cpu_data[i].arch;
                    break;
                }
            continue;
        }
        if (!tune && !processed_exts && strstr (buf, "Features") != NULL)
        {
            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);
    f = NULL;

    /* Weird cpuinfo format that we don't know how to handle.  */
    if (n_cores == 0 || n_cores > 2 || n_imps != 1)
        goto not_found;

    if (arch && !arch_id)
        goto not_found;

    if (arch)
    {
        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_info)
            goto not_found;

        res = concat ("-march=", arch_info->name, NULL);
        default_flags = arch_info->flags;
    }
    /* We have big.LITTLE.  */
    else if (n_cores == 2)
    {
        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;
    }
    /* The simple, non-big.LITTLE case.  */
    else
    {
        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", "=",
                      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;

not_found:
    {
        /* If detection fails we ignore the option.
           Clean up and return empty string.  */

        if (f)
            fclose (f);

        return "";
    }
}
Пример #2
0
const char *
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);
  char buf[128];
  FILE *f = NULL;
  bool arch = false;
  bool tune = false;
  bool cpu = false;
  unsigned int i = 0;
  unsigned int core_idx = 0;
  const char* imps[2] = { NULL, NULL };
  const char* cores[2] = { NULL, NULL };
  unsigned int n_cores = 0;
  unsigned int n_imps = 0;
  bool processed_exts = false;
  const char *ext_string = "";

  gcc_assert (argc);

  if (!argv[0])
    goto not_found;

  /* Are we processing -march, mtune or mcpu?  */
  arch = strcmp (argv[0], "arch") == 0;
  if (!arch)
    tune = strcmp (argv[0], "tune") == 0;

  if (!arch && !tune)
    cpu = strcmp (argv[0], "cpu") == 0;

  if (!arch && !tune && !cpu)
    goto not_found;

  f = fopen ("/proc/cpuinfo", "r");

  if (f == NULL)
    goto not_found;

  /* Look through /proc/cpuinfo to determine the implementer
     and then the part number that identifies a particular core.  */
  while (fgets (buf, sizeof (buf), f) != NULL)
    {
      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))
	      {
                if (n_imps == 2)
                  goto not_found;

                imps[n_imps++] = cpu_data[i].implementer_id;

                break;
	      }
          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))
	      {
                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;
	      }
          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;
        }
    }

  fclose (f);
  f = NULL;

  /* Weird cpuinfo format that we don't know how to handle.  */
  if (n_cores == 0 || n_cores > 2 || n_imps != 1)
    goto not_found;

  if (arch && !arch_id)
    goto not_found;

  if (arch)
    {
      const char* arch_name = get_arch_name_from_id (arch_id);

      /* We got some arch indentifier that's not in aarch64-arches.def?  */
      if (!arch_name)
        goto not_found;

      res = concat ("-march=", arch_name, NULL);
    }
  /* 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;
            }
        }
      if (!res)
        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;

      res = concat ("-m", cpu ? "cpu" : "tune", "=",
                      cpu_data[core_idx].name, NULL);
    }

  if (tune)
    return res;

  res = concat (res, ext_string, NULL);

  return res;

not_found:
  {
   /* If detection fails we ignore the option.
      Clean up and return empty string.  */

    if (f)
      fclose (f);

    return "";
  }
}