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 ""; } }
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 ""; } }